Browse Source

Merge remote-tracking branch 'upstream/master' into feature/node_json_path

pull/7243/head
Yuriy Lytvynchuk 4 years ago
parent
commit
3c4618c8dc
  1. 2
      application/pom.xml
  2. 3
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  3. 2
      application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
  4. 2
      application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
  5. 3
      application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
  6. 2
      application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
  7. 2
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  8. 2
      application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
  9. 6
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  10. 2
      application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
  11. 2
      application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
  12. 2
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  13. 3
      application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
  14. 5
      application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java
  15. 2
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java
  16. 4
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
  17. 2
      application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java
  18. 9
      application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java
  19. 7
      application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
  20. 4
      application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java
  21. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  22. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java
  23. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java
  24. 24
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java
  25. 2
      application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java
  26. 3
      application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java
  27. 3
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  28. 2
      application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java
  29. 2
      application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java
  30. 2
      application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java
  31. 14
      application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
  32. 2
      application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java
  33. 6
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  34. 6
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  35. 2
      application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
  36. 2
      application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java
  37. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java
  38. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
  39. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java
  40. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java
  41. 4
      application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/BackupCodeTwoFaProvider.java
  42. 4
      application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/OtpBasedTwoFaProvider.java
  43. 4
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java
  44. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java
  45. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java
  46. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java
  47. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java
  48. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java
  49. 2
      application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
  50. 2
      application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java
  51. 4
      application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
  52. 4
      application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java
  53. 2
      application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java
  54. 6
      application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java
  55. 4
      application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java
  56. 247
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java
  57. 29
      application/src/main/java/org/thingsboard/server/service/subscription/ReadTsKvQueryInfo.java
  58. 25
      application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java
  59. 2
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java
  60. 4
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java
  61. 8
      application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggHistoryCmd.java
  62. 32
      application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggKey.java
  63. 29
      application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggTimeSeriesCmd.java
  64. 21
      application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/EntityDataCmd.java
  65. 16
      application/src/main/resources/thingsboard.yml
  66. 67
      application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
  67. 25
      application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java
  68. 51
      application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java
  69. 43
      application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java
  70. 64
      application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java
  71. 50
      application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java
  72. 28
      application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java
  73. 48
      application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java
  74. 29
      application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
  75. 8
      application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java
  76. 29
      application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java
  77. 4
      application/src/test/java/org/thingsboard/server/controller/BaseTbResourceControllerTest.java
  78. 8
      application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java
  79. 4
      application/src/test/java/org/thingsboard/server/controller/BaseTenantProfileControllerTest.java
  80. 53
      application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java
  81. 4
      application/src/test/java/org/thingsboard/server/controller/BaseWidgetsBundleControllerTest.java
  82. 9
      application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java
  83. 318
      application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java
  84. 7
      application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java
  85. 8
      application/src/test/java/org/thingsboard/server/transport/AbstractTransportIntegrationTest.java
  86. 2
      application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java
  87. 4
      application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java
  88. 7
      application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java
  89. 8
      application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java
  90. 2
      application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java
  91. 2
      common/actor/pom.xml
  92. 2
      common/cache/pom.xml
  93. 2
      common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java
  94. 2
      common/cluster-api/pom.xml
  95. 2
      common/coap-server/pom.xml
  96. 2
      common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java
  97. 2
      common/dao-api/pom.xml
  98. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java
  99. 3
      common/dao-api/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java
  100. 2
      common/data/pom.xml

2
application/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>application</artifactId> <artifactId>application</artifactId>

3
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.RuleEngineAlarmService; import org.thingsboard.rule.engine.api.RuleEngineAlarmService;
@ -39,6 +38,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;

2
application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java

@ -33,9 +33,9 @@ import org.springframework.security.web.util.UrlUtils;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.dao.oauth2.OAuth2Configuration; import org.thingsboard.server.dao.oauth2.OAuth2Configuration;
import org.thingsboard.server.dao.oauth2.OAuth2Service; import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.service.security.auth.oauth2.TbOAuth2ParameterNames; import org.thingsboard.server.service.security.auth.oauth2.TbOAuth2ParameterNames;

2
application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java

@ -16,7 +16,6 @@
package org.thingsboard.server.config; package org.thingsboard.server.config;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
@ -24,6 +23,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.GenericFilterBean;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;

3
application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java

@ -17,7 +17,6 @@ package org.thingsboard.server.config;
import com.fasterxml.classmate.TypeResolver; import com.fasterxml.classmate.TypeResolver;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -333,7 +332,7 @@ public class SwaggerConfiguration {
errorResponse("401 ", "Unauthorized (**Expired credentials**)", errorResponse("401 ", "Unauthorized (**Expired credentials**)",
List.of( List.of(
errorExample("credentials-expired", "Expired credentials", errorExample("credentials-expired", "Expired credentials",
ThingsboardCredentialsExpiredResponse.of("User password expired!", RandomStringUtils.randomAlphanumeric(30))) ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30)))
), ThingsboardCredentialsExpiredResponse.class ), ThingsboardCredentialsExpiredResponse.class
) )
); );

2
application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java

@ -22,10 +22,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;

2
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -18,7 +18,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.alarm.AlarmQuery;

2
application/src/main/java/org/thingsboard/server/controller/AuditLogController.java

@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.audit.AuditLog;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;

6
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -23,7 +23,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.context.support.DefaultMessageSourceResolvable;
@ -47,6 +46,7 @@ import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackage;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
@ -84,7 +84,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
@ -146,15 +145,12 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_PAGE_SIZE;
import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID; import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID;
import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION; import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;

2
application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java

@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -25,6 +24,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;

2
application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java

@ -19,7 +19,6 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -33,6 +32,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;

2
application/src/main/java/org/thingsboard/server/controller/TelemetryController.java

@ -35,7 +35,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -49,6 +48,7 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;

3
application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java

@ -16,7 +16,6 @@
package org.thingsboard.server.controller.plugin; package org.thingsboard.server.controller.plugin;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -28,6 +27,7 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.NativeWebSocketSession; import org.springframework.web.socket.adapter.NativeWebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler; import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -49,7 +49,6 @@ import javax.websocket.SendResult;
import javax.websocket.Session; import javax.websocket.Session;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.nio.ByteBuffer;
import java.security.InvalidParameterException; import java.security.InvalidParameterException;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;

5
application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java

@ -20,13 +20,13 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@ -41,7 +41,6 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -199,7 +198,7 @@ public class EntityActionService {
} }
} }
TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
if (tenantId.isNullUid()) { if (tenantId == null || tenantId.isNullUid()) {
if (entity instanceof HasTenantId) { if (entity instanceof HasTenantId) {
tenantId = ((HasTenantId) entity).getTenantId(); tenantId = ((HasTenantId) entity).getTenantId();
} }

2
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java

@ -16,8 +16,8 @@
package org.thingsboard.server.service.apiusage; package org.thingsboard.server.service.apiusage;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.common.msg.tools.TbRateLimits;

4
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java

@ -16,10 +16,8 @@
package org.thingsboard.server.service.apiusage; package org.thingsboard.server.service.apiusage;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -34,6 +32,7 @@ import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateMailMessage; import org.thingsboard.server.common.data.ApiUsageStateMailMessage;
import org.thingsboard.server.common.data.ApiUsageStateValue; import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -80,7 +79,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;

2
application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java

@ -27,13 +27,13 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;

9
application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java

@ -21,8 +21,6 @@ import com.fasterxml.jackson.databind.node.TextNode;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
@ -31,6 +29,7 @@ import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
@ -44,15 +43,15 @@ import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingC
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportColumnType;
import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.sync.ie.importing.csv.AbstractBulkImportService;
import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportColumnType;
import org.thingsboard.server.service.entitiy.device.TbDeviceService; import org.thingsboard.server.service.entitiy.device.TbDeviceService;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.ie.importing.csv.AbstractBulkImportService;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -157,7 +156,7 @@ public class DeviceBulkImportService extends AbstractBulkImportService<Device> {
private void setUpAccessTokenCredentials(Map<BulkImportColumnType, String> fields, DeviceCredentials credentials) { private void setUpAccessTokenCredentials(Map<BulkImportColumnType, String> fields, DeviceCredentials credentials) {
credentials.setCredentialsId(Optional.ofNullable(fields.get(BulkImportColumnType.ACCESS_TOKEN)) credentials.setCredentialsId(Optional.ofNullable(fields.get(BulkImportColumnType.ACCESS_TOKEN))
.orElseGet(() -> RandomStringUtils.randomAlphanumeric(20))); .orElseGet(() -> StringUtils.randomAlphanumeric(20)));
} }
private void setUpBasicMqttCredentials(Map<BulkImportColumnType, String> fields, DeviceCredentials credentials) { private void setUpBasicMqttCredentials(Map<BulkImportColumnType, String> fields, DeviceCredentials credentials) {

7
application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java

@ -20,14 +20,14 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -51,7 +51,6 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionRequest;
import org.thingsboard.server.dao.device.provision.ProvisionResponse; import org.thingsboard.server.dao.device.provision.ProvisionResponse;
import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueCallback;
@ -189,7 +188,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
private ProvisionResponse processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { private ProvisionResponse processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) {
try { try {
if (StringUtils.isEmpty(provisionRequest.getDeviceName())) { if (StringUtils.isEmpty(provisionRequest.getDeviceName())) {
String newDeviceName = RandomStringUtils.randomAlphanumeric(20); String newDeviceName = StringUtils.randomAlphanumeric(20);
log.info("Device name not found in provision request. Generated name is: {}", newDeviceName); log.info("Device name not found in provision request. Generated name is: {}", newDeviceName);
provisionRequest.setDeviceName(newDeviceName); provisionRequest.setDeviceName(newDeviceName);
} }

4
application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java

@ -20,6 +20,7 @@ import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.dashboard.DashboardService;
@ -61,6 +62,9 @@ import org.thingsboard.server.service.executors.GrpcCallbackExecutorService;
@Lazy @Lazy
public class EdgeContextComponent { public class EdgeContextComponent {
@Autowired
private TbClusterService clusterService;
@Autowired @Autowired
private EdgeService edgeService; private EdgeService edgeService;

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -211,6 +211,7 @@ public final class EdgeGrpcSession implements Closeable {
@Override @Override
public void onSuccess(Void result) { public void onSuccess(Void result) {
syncCompleted = true; syncCompleted = true;
ctx.getClusterService().onEdgeEventUpdate(edge.getTenantId(), edge.getId());
} }
@Override @Override

10
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java

@ -16,7 +16,8 @@
package org.thingsboard.server.service.edge.rpc.constructor; package org.thingsboard.server.service.edge.rpc.constructor;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.ByteString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
@ -28,6 +29,7 @@ import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg;
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RpcRequestMsg; import org.thingsboard.server.gen.edge.v1.RpcRequestMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; 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.queue.util.TbCoreComponent;
import java.util.UUID; import java.util.UUID;
@ -36,7 +38,8 @@ import java.util.UUID;
@TbCoreComponent @TbCoreComponent
public class DeviceMsgConstructor { public class DeviceMsgConstructor {
protected static final ObjectMapper mapper = new ObjectMapper(); @Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId, String conflictName) { public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId, String conflictName) {
DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder() DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder()
@ -66,6 +69,9 @@ public class DeviceMsgConstructor {
if (conflictName != null) { if (conflictName != null) {
builder.setConflictName(conflictName); builder.setConflictName(conflictName);
} }
if (device.getDeviceData() != null) {
builder.setDeviceDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(device.getDeviceData())));
}
return builder.build(); return builder.build();
} }

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java

@ -23,10 +23,10 @@ import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;

24
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java

@ -22,14 +22,15 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.SettableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils; import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@ -60,9 +61,11 @@ import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -71,6 +74,9 @@ import java.util.concurrent.locks.ReentrantLock;
@TbCoreComponent @TbCoreComponent
public class DeviceEdgeProcessor extends BaseEdgeProcessor { public class DeviceEdgeProcessor extends BaseEdgeProcessor {
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
private static final ReentrantLock deviceCreationLock = new ReentrantLock(); private static final ReentrantLock deviceCreationLock = new ReentrantLock();
public ListenableFuture<Void> processDeviceFromEdge(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { public ListenableFuture<Void> processDeviceFromEdge(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) {
@ -88,7 +94,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
} else { } else {
log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." +
"Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg);
String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); String newDeviceName = deviceUpdateMsg.getName() + "_" + StringUtils.randomAlphabetic(15);
Device newDevice; Device newDevice;
try { try {
newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName);
@ -192,6 +198,11 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
deviceUpdateMsg.getDeviceProfileIdLSB())); deviceUpdateMsg.getDeviceProfileIdLSB()));
device.setDeviceProfileId(deviceProfileId); device.setDeviceProfileId(deviceProfileId);
} }
Optional<DeviceData> deviceDataOpt =
dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray());
if (deviceDataOpt.isPresent()) {
device.setDeviceData(deviceDataOpt.get());
}
Device savedDevice = deviceService.saveDevice(device); Device savedDevice = deviceService.saveDevice(device);
tbClusterService.onDeviceUpdated(savedDevice, device); tbClusterService.onDeviceUpdated(savedDevice, device);
return saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); return saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null);
@ -232,6 +243,11 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
deviceUpdateMsg.getDeviceProfileIdLSB())); deviceUpdateMsg.getDeviceProfileIdLSB()));
device.setDeviceProfileId(deviceProfileId); device.setDeviceProfileId(deviceProfileId);
} }
Optional<DeviceData> deviceDataOpt =
dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray());
if (deviceDataOpt.isPresent()) {
device.setDeviceData(deviceDataOpt.get());
}
if (created) { if (created) {
deviceValidator.validate(device, Device::getTenantId); deviceValidator.validate(device, Device::getTenantId);
device.setId(deviceId); device.setId(deviceId);
@ -244,7 +260,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
DeviceCredentials deviceCredentials = new DeviceCredentials(); DeviceCredentials deviceCredentials = new DeviceCredentials();
deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId()));
deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
deviceCredentials.setCredentialsId(org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(20)); deviceCredentials.setCredentialsId(StringUtils.randomAlphanumeric(20));
deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials);
} }
createRelationFromEdge(tenantId, edge.getId(), device.getId()); createRelationFromEdge(tenantId, edge.getId(), device.getId());

2
application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java

@ -59,7 +59,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.thingsboard.server.common.data.StringUtils.isBlank;
@Service @Service
@AllArgsConstructor @AllArgsConstructor

3
application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java

@ -20,12 +20,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVParser;
import org.apache.commons.lang3.StringUtils;
import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.UUIDConverter; import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.dashboard.DashboardService;

3
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -20,10 +20,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;

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

@ -16,11 +16,11 @@
package org.thingsboard.server.service.install; package org.thingsboard.server.service.install;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.dao.util.SqlTsDao; import org.thingsboard.server.dao.util.SqlTsDao;
import java.io.File; import java.io.File;

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

@ -16,12 +16,12 @@
package org.thingsboard.server.service.install; package org.thingsboard.server.service.install;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.dao.util.TimescaleDBTsDao; import org.thingsboard.server.dao.util.TimescaleDBTsDao;
import java.io.File; import java.io.File;

2
application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java

@ -16,12 +16,12 @@
package org.thingsboard.server.service.install.migrate; package org.thingsboard.server.service.install.migrate;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.UUIDConverter; import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.dao.cassandra.CassandraCluster; import org.thingsboard.server.dao.cassandra.CassandraCluster;
import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary; import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;

14
application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java

@ -37,7 +37,10 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.id.*; import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
@ -46,7 +49,11 @@ import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.query.DynamicValue; import org.thingsboard.server.common.data.query.DynamicValue;
import org.thingsboard.server.common.data.query.FilterPredicateValue; import org.thingsboard.server.common.data.query.FilterPredicateValue;
import org.thingsboard.server.common.data.queue.*; import org.thingsboard.server.common.data.queue.ProcessingStrategy;
import org.thingsboard.server.common.data.queue.ProcessingStrategyType;
import org.thingsboard.server.common.data.queue.Queue;
import org.thingsboard.server.common.data.queue.SubmitStrategy;
import org.thingsboard.server.common.data.queue.SubmitStrategyType;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
@ -74,12 +81,11 @@ import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.thingsboard.server.common.data.StringUtils.isBlank;
@Service @Service
@Profile("install") @Profile("install")

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

@ -15,10 +15,10 @@
*/ */
package org.thingsboard.server.service.install.update; package org.thingsboard.server.service.install.update;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;

6
application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java

@ -19,10 +19,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.core.NestedRuntimeException; import org.springframework.core.NestedRuntimeException;
@ -39,6 +37,7 @@ import org.thingsboard.server.common.data.ApiFeature;
import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageStateMailMessage; import org.thingsboard.server.common.data.ApiUsageStateMailMessage;
import org.thingsboard.server.common.data.ApiUsageStateValue; import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
@ -49,15 +48,12 @@ import org.thingsboard.server.queue.usagestats.TbApiUsageClient;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;

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

@ -41,7 +41,6 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
@ -53,7 +52,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -68,11 +66,11 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.NotificationsTopicService; import org.thingsboard.server.queue.discovery.NotificationsTopicService;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider; 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.gateway_device.GatewayNotificationsService;
import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -167,7 +165,7 @@ public class DefaultTbClusterService implements TbClusterService {
@Override @Override
public void pushMsgToRuleEngine(TenantId tenantId, EntityId entityId, TbMsg tbMsg, TbQueueCallback callback) { public void pushMsgToRuleEngine(TenantId tenantId, EntityId entityId, TbMsg tbMsg, TbQueueCallback callback) {
if (tenantId.isNullUid()) { if (tenantId == null || tenantId.isNullUid()) {
if (entityId.getEntityType().equals(EntityType.TENANT)) { if (entityId.getEntityType().equals(EntityType.TENANT)) {
tenantId = TenantId.fromUUID(entityId.getId()); tenantId = TenantId.fromUUID(entityId.getId());
} else { } else {

2
application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.resource; package org.thingsboard.server.service.resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.leshan.core.model.DDFFileParser; import org.eclipse.leshan.core.model.DDFFileParser;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator; import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.InvalidDDFFileException; import org.eclipse.leshan.core.model.InvalidDDFFileException;
@ -24,6 +23,7 @@ import org.eclipse.leshan.core.model.ObjectModel;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;

2
application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java

@ -22,7 +22,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;

2
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java

@ -17,7 +17,6 @@ package org.thingsboard.server.service.security.auth.jwt;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -26,6 +25,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken; import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.token.RawAccessJwtToken; import org.thingsboard.server.service.security.model.token.RawAccessJwtToken;

2
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java

@ -15,9 +15,9 @@
*/ */
package org.thingsboard.server.service.security.auth.jwt.extractor; package org.thingsboard.server.service.security.auth.jwt.extractor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration; import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;

2
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java

@ -15,9 +15,9 @@
*/ */
package org.thingsboard.server.service.security.auth.jwt.extractor; package org.thingsboard.server.service.security.auth.jwt.extractor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration; import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;

8
application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java

@ -16,23 +16,23 @@
package org.thingsboard.server.service.security.auth.mfa; package org.thingsboard.server.service.security.auth.mfa;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.LockedException; import org.springframework.security.authentication.LockedException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
import org.thingsboard.server.common.data.security.model.mfa.account.TwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType;
import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.common.msg.tools.TbRateLimits;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
import org.thingsboard.server.common.data.security.model.mfa.account.TwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig;
import org.thingsboard.server.service.security.auth.mfa.provider.TwoFaProvider; import org.thingsboard.server.service.security.auth.mfa.provider.TwoFaProvider;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.system.SystemSecurityService; import org.thingsboard.server.service.security.system.SystemSecurityService;

4
application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/BackupCodeTwoFaProvider.java

@ -15,11 +15,11 @@
*/ */
package org.thingsboard.server.service.security.auth.mfa.provider.impl; package org.thingsboard.server.service.security.auth.mfa.provider.impl;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.CollectionsUtil; import org.thingsboard.common.util.CollectionsUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.security.model.mfa.account.BackupCodeTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.BackupCodeTwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.BackupCodeTwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.BackupCodeTwoFaProviderConfig;
@ -49,7 +49,7 @@ public class BackupCodeTwoFaProvider implements TwoFaProvider<BackupCodeTwoFaPro
} }
private static Set<String> generateCodes(int count, int length) { private static Set<String> generateCodes(int count, int length) {
return Stream.generate(() -> RandomStringUtils.random(length, "0123456789abcdef")) return Stream.generate(() -> StringUtils.random(length, "0123456789abcdef"))
.distinct().limit(count) .distinct().limit(count)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }

4
application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/OtpBasedTwoFaProvider.java

@ -16,10 +16,10 @@
package org.thingsboard.server.service.security.auth.mfa.provider.impl; package org.thingsboard.server.service.security.auth.mfa.provider.impl;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.security.model.mfa.account.OtpBasedTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.OtpBasedTwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.OtpBasedTwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.OtpBasedTwoFaProviderConfig;
@ -40,7 +40,7 @@ public abstract class OtpBasedTwoFaProvider<C extends OtpBasedTwoFaProviderConfi
@Override @Override
public final void prepareVerificationCode(SecurityUser user, C providerConfig, A accountConfig) throws ThingsboardException { public final void prepareVerificationCode(SecurityUser user, C providerConfig, A accountConfig) throws ThingsboardException {
String verificationCode = RandomStringUtils.randomNumeric(6); String verificationCode = StringUtils.randomNumeric(6);
sendVerificationCode(user, verificationCode, providerConfig, accountConfig); sendVerificationCode(user, verificationCode, providerConfig, accountConfig);
verificationCodesCache.put(user.getId(), new Otp(System.currentTimeMillis(), verificationCode, accountConfig)); verificationCodesCache.put(user.getId(), new Otp(System.currentTimeMillis(), verificationCode, accountConfig));
} }

4
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java

@ -24,9 +24,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
@ -47,7 +48,6 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.InstallScripts;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.UserPrincipal;

2
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java

@ -21,8 +21,8 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; import org.thingsboard.server.common.data.oauth2.OAuth2Registration;
import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.dao.oauth2.OAuth2User;

2
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java

@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.oauth2;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.text.StrSubstitutor; import org.apache.commons.lang3.text.StrSubstitutor;
import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.dao.oauth2.OAuth2User;

2
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java

@ -22,8 +22,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; import org.thingsboard.server.common.data.oauth2.OAuth2Registration;

3
application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java

@ -17,7 +17,6 @@ package org.thingsboard.server.service.security.auth.rest;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
@ -28,7 +27,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.UserPrincipal;

2
application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java

@ -17,7 +17,6 @@ package org.thingsboard.server.service.security.auth.rest;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -27,6 +26,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.UserPrincipal;

2
application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java

@ -25,11 +25,11 @@ import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.UnsupportedJwtException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;

2
application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java

@ -22,9 +22,9 @@ import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.UnsupportedJwtException;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;

4
application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java

@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.passay.CharacterRule; import org.passay.CharacterRule;
import org.passay.EnglishCharacterData; import org.passay.EnglishCharacterData;
import org.passay.LengthRule; import org.passay.LengthRule;
@ -40,6 +39,7 @@ import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -49,12 +49,12 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.SecuritySettings;
import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.user.UserServiceImpl; import org.thingsboard.server.dao.user.UserServiceImpl;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;

4
application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java

@ -23,10 +23,10 @@ import com.amazonaws.services.sns.AmazonSNSClient;
import com.amazonaws.services.sns.model.MessageAttributeValue; import com.amazonaws.services.sns.model.MessageAttributeValue;
import com.amazonaws.services.sns.model.PublishRequest; import com.amazonaws.services.sns.model.PublishRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.thingsboard.server.common.data.sms.config.AwsSnsSmsProviderConfiguration;
import org.thingsboard.rule.engine.api.sms.exception.SmsException; import org.thingsboard.rule.engine.api.sms.exception.SmsException;
import org.thingsboard.rule.engine.api.sms.exception.SmsSendException; import org.thingsboard.rule.engine.api.sms.exception.SmsSendException;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.sms.config.AwsSnsSmsProviderConfiguration;
import org.thingsboard.server.service.sms.AbstractSmsSender; import org.thingsboard.server.service.sms.AbstractSmsSender;
import java.util.HashMap; import java.util.HashMap;

2
application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.sms.smpp; package org.thingsboard.server.service.sms.smpp;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.smpp.Connection; import org.smpp.Connection;
import org.smpp.Data; import org.smpp.Data;
@ -34,6 +33,7 @@ import org.smpp.pdu.PDUException;
import org.smpp.pdu.SubmitSM; import org.smpp.pdu.SubmitSM;
import org.smpp.pdu.SubmitSMResp; import org.smpp.pdu.SubmitSMResp;
import org.thingsboard.rule.engine.api.sms.exception.SmsException; import org.thingsboard.rule.engine.api.sms.exception.SmsException;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration; import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration;
import org.thingsboard.server.service.sms.AbstractSmsSender; import org.thingsboard.server.service.sms.AbstractSmsSender;

6
application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java

@ -18,11 +18,11 @@ package org.thingsboard.server.service.sms.twilio;
import com.twilio.http.TwilioRestClient; import com.twilio.http.TwilioRestClient;
import com.twilio.rest.api.v2010.account.Message; import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber; import com.twilio.type.PhoneNumber;
import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.sms.exception.SmsParseException;
import org.thingsboard.server.common.data.sms.config.TwilioSmsProviderConfiguration;
import org.thingsboard.rule.engine.api.sms.exception.SmsException; import org.thingsboard.rule.engine.api.sms.exception.SmsException;
import org.thingsboard.rule.engine.api.sms.exception.SmsParseException;
import org.thingsboard.rule.engine.api.sms.exception.SmsSendException; import org.thingsboard.rule.engine.api.sms.exception.SmsSendException;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.sms.config.TwilioSmsProviderConfiguration;
import org.thingsboard.server.service.sms.AbstractSmsSender; import org.thingsboard.server.service.sms.AbstractSmsSender;
import java.util.regex.Pattern; import java.util.regex.Pattern;

4
application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java

@ -28,15 +28,14 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceIdInfo; import org.thingsboard.server.common.data.DeviceIdInfo;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -90,7 +89,6 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;

247
application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java

@ -22,7 +22,6 @@ import com.google.common.util.concurrent.MoreExecutors;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@ -30,13 +29,13 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.CloseStatus;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.AlarmDataQuery; import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.common.data.query.ComparisonTsValue;
import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityData;
import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityDataQuery;
import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityKey;
@ -51,6 +50,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketService;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef; import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef;
import org.thingsboard.server.service.telemetry.cmd.v2.AggHistoryCmd;
import org.thingsboard.server.service.telemetry.cmd.v2.AggKey;
import org.thingsboard.server.service.telemetry.cmd.v2.AggTimeSeriesCmd;
import org.thingsboard.server.service.telemetry.cmd.v2.AlarmDataCmd; import org.thingsboard.server.service.telemetry.cmd.v2.AlarmDataCmd;
import org.thingsboard.server.service.telemetry.cmd.v2.AlarmDataUpdate; import org.thingsboard.server.service.telemetry.cmd.v2.AlarmDataUpdate;
import org.thingsboard.server.service.telemetry.cmd.v2.EntityCountCmd; import org.thingsboard.server.service.telemetry.cmd.v2.EntityCountCmd;
@ -68,12 +70,12 @@ import javax.annotation.PreDestroy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -83,6 +85,7 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@SuppressWarnings("UnstableApiUsage")
@Slf4j @Slf4j
@TbCoreComponent @TbCoreComponent
@Service @Service
@ -131,6 +134,8 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
private int maxEntitiesPerAlarmSubscription; private int maxEntitiesPerAlarmSubscription;
@Value("${server.ws.dynamic_page_link.max_alarm_queries_per_refresh_interval:10}") @Value("${server.ws.dynamic_page_link.max_alarm_queries_per_refresh_interval:10}")
private int maxAlarmQueriesPerRefreshInterval; private int maxAlarmQueriesPerRefreshInterval;
@Value("${ui.dashboard.max_datapoints_limit:50000}")
private int maxDatapointLimit;
private ExecutorService wsCallBackExecutor; private ExecutorService wsCallBackExecutor;
private boolean tsInSqlDB; private boolean tsInSqlDB;
@ -165,7 +170,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
TbEntityDataSubCtx ctx = getSubCtx(session.getSessionId(), cmd.getCmdId()); TbEntityDataSubCtx ctx = getSubCtx(session.getSessionId(), cmd.getCmdId());
if (ctx != null) { if (ctx != null) {
log.debug("[{}][{}] Updating existing subscriptions using: {}", session.getSessionId(), cmd.getCmdId(), cmd); log.debug("[{}][{}] Updating existing subscriptions using: {}", session.getSessionId(), cmd.getCmdId(), cmd);
if (cmd.getLatestCmd() != null || cmd.getTsCmd() != null || cmd.getHistoryCmd() != null) { if (cmd.hasAnyCmd()) {
ctx.clearEntitySubscriptions(); ctx.clearEntitySubscriptions();
} }
} else { } else {
@ -173,6 +178,8 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
ctx = createSubCtx(session, cmd); ctx = createSubCtx(session, cmd);
} }
ctx.setCurrentCmd(cmd); ctx.setCurrentCmd(cmd);
// Fetch entity list using entity data query
if (cmd.getQuery() != null) { if (cmd.getQuery() != null) {
if (ctx.getQuery() == null) { if (ctx.getQuery() == null) {
log.debug("[{}][{}] Initializing data using query: {}", session.getSessionId(), cmd.getCmdId(), cmd.getQuery()); log.debug("[{}][{}] Initializing data using query: {}", session.getSessionId(), cmd.getCmdId(), cmd.getQuery());
@ -204,43 +211,143 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
finalCtx.setRefreshTask(task); finalCtx.setRefreshTask(task);
} }
} }
ListenableFuture<TbEntityDataSubCtx> historyFuture;
if (cmd.getHistoryCmd() != null) { try {
log.trace("[{}][{}] Going to process history command: {}", session.getSessionId(), cmd.getCmdId(), cmd.getHistoryCmd()); List<ListenableFuture<?>> cmdFutures = new ArrayList<>();
try { if (cmd.getAggHistoryCmd() != null) {
historyFuture = handleHistoryCmd(ctx, cmd.getHistoryCmd()); cmdFutures.add(handleAggHistoryCmd(ctx, cmd.getAggHistoryCmd()));
} catch (RuntimeException e) {
handleWsCmdRuntimeException(ctx.getSessionId(), e, cmd);
return;
} }
} else { if (cmd.getAggTsCmd() != null) {
historyFuture = Futures.immediateFuture(ctx); cmdFutures.add(handleAggTsCmd(ctx, cmd.getAggTsCmd()));
}
if (cmd.getHistoryCmd() != null) {
cmdFutures.add(handleHistoryCmd(ctx, cmd.getHistoryCmd()));
}
if (cmdFutures.isEmpty()) {
handleRegularCommands(ctx, cmd);
} else {
TbEntityDataSubCtx finalCtx = ctx;
Futures.addCallback(Futures.allAsList(cmdFutures), new FutureCallback<>() {
@Override
public void onSuccess(@Nullable List<Object> result) {
handleRegularCommands(finalCtx, cmd);
}
@Override
public void onFailure(Throwable t) {
log.warn("[{}][{}] Failed to process command", finalCtx.getSessionId(), finalCtx.getCmdId());
}
}, wsCallBackExecutor);
}
} catch (RuntimeException e) {
handleWsCmdRuntimeException(ctx.getSessionId(), e, cmd);
}
}
private void handleRegularCommands(TbEntityDataSubCtx ctx, EntityDataCmd cmd) {
try {
if (cmd.getLatestCmd() != null || cmd.getTsCmd() != null) {
if (cmd.getLatestCmd() != null) {
handleLatestCmd(ctx, cmd.getLatestCmd());
}
if (cmd.getTsCmd() != null) {
handleTimeSeriesCmd(ctx, cmd.getTsCmd());
}
} else {
checkAndSendInitialData(ctx);
}
} catch (RuntimeException e) {
handleWsCmdRuntimeException(ctx.getSessionId(), e, cmd);
} }
Futures.addCallback(historyFuture, new FutureCallback<>() { }
@Override
public void onSuccess(@Nullable TbEntityDataSubCtx theCtx) { private void checkAndSendInitialData(@Nullable TbEntityDataSubCtx theCtx) {
if (!theCtx.isInitialDataSent()) {
EntityDataUpdate update = new EntityDataUpdate(theCtx.getCmdId(), theCtx.getData(), null, theCtx.getMaxEntitiesPerDataSubscription());
theCtx.sendWsMsg(update);
theCtx.setInitialDataSent(true);
}
}
private ListenableFuture<TbEntityDataSubCtx> handleAggHistoryCmd(TbEntityDataSubCtx ctx, AggHistoryCmd cmd) {
ConcurrentMap<Integer, ReadTsKvQueryInfo> queries = new ConcurrentHashMap<>();
for (AggKey key : cmd.getKeys()) {
if (key.getPreviousValueOnly() == null || !key.getPreviousValueOnly()) {
var query = new BaseReadTsKvQuery(key.getKey(), cmd.getStartTs(), cmd.getEndTs(), cmd.getEndTs() - cmd.getStartTs(), 1, key.getAgg());
queries.put(query.getId(), new ReadTsKvQueryInfo(key, query, false));
}
if (key.getPreviousStartTs() != null && key.getPreviousEndTs() != null && key.getPreviousEndTs() >= key.getPreviousStartTs()) {
var query = new BaseReadTsKvQuery(key.getKey(), key.getPreviousStartTs(), key.getPreviousEndTs(), key.getPreviousEndTs() - key.getPreviousStartTs(), 1, key.getAgg());
queries.put(query.getId(), new ReadTsKvQueryInfo(key, query, true));
}
}
return handleAggCmd(ctx, cmd.getKeys(), queries, cmd.getStartTs(), cmd.getEndTs(), false);
}
private ListenableFuture<TbEntityDataSubCtx> handleAggTsCmd(TbEntityDataSubCtx ctx, AggTimeSeriesCmd cmd) {
ConcurrentMap<Integer, ReadTsKvQueryInfo> queries = new ConcurrentHashMap<>();
for (AggKey key : cmd.getKeys()) {
var query = new BaseReadTsKvQuery(key.getKey(), cmd.getStartTs(), cmd.getStartTs() + cmd.getTimeWindow(), cmd.getTimeWindow(), 1, key.getAgg());
queries.put(query.getId(), new ReadTsKvQueryInfo(key, query, false));
}
return handleAggCmd(ctx, cmd.getKeys(), queries, cmd.getStartTs(), cmd.getStartTs() + cmd.getTimeWindow(), true);
}
private ListenableFuture<TbEntityDataSubCtx> handleAggCmd(TbEntityDataSubCtx ctx, List<AggKey> keys, ConcurrentMap<Integer, ReadTsKvQueryInfo> queries,
long startTs, long endTs, boolean subscribe) {
Map<EntityData, ListenableFuture<List<ReadTsKvQueryResult>>> fetchResultMap = new HashMap<>();
List<EntityData> entityDataList = ctx.getData().getData();
List<ReadTsKvQuery> queryList = queries.values().stream().map(ReadTsKvQueryInfo::getQuery).collect(Collectors.toList());
entityDataList.forEach(entityData -> fetchResultMap.put(entityData,
tsService.findAllByQueries(ctx.getTenantId(), entityData.getEntityId(), queryList)));
return Futures.transform(Futures.allAsList(fetchResultMap.values()), f -> {
// Map that holds last ts for each key for each entity.
Map<EntityData, Map<String, Long>> lastTsEntityMap = new HashMap<>();
fetchResultMap.forEach((entityData, future) -> {
try { try {
if (cmd.getLatestCmd() != null || cmd.getTsCmd() != null) { Map<String, Long> lastTsMap = new HashMap<>();
if (cmd.getLatestCmd() != null) { lastTsEntityMap.put(entityData, lastTsMap);
handleLatestCmd(theCtx, cmd.getLatestCmd());
} List<ReadTsKvQueryResult> queryResults = future.get();
if (cmd.getTsCmd() != null) { if (queryResults != null) {
handleTimeSeriesCmd(theCtx, cmd.getTsCmd()); for (ReadTsKvQueryResult queryResult : queryResults) {
ReadTsKvQueryInfo queryInfo = queries.get(queryResult.getQueryId());
ComparisonTsValue comparisonTsValue = entityData.getAggLatest().computeIfAbsent(queryInfo.getKey().getId(), agg -> new ComparisonTsValue());
if (queryInfo.isPrevious()) {
comparisonTsValue.setPrevious(queryResult.toTsValue());
} else {
comparisonTsValue.setCurrent(queryResult.toTsValue());
lastTsMap.put(queryInfo.getQuery().getKey(), queryResult.getLastEntryTs());
}
} }
} else if (!theCtx.isInitialDataSent()) {
EntityDataUpdate update = new EntityDataUpdate(theCtx.getCmdId(), theCtx.getData(), null, theCtx.getMaxEntitiesPerDataSubscription());
theCtx.sendWsMsg(update);
theCtx.setInitialDataSent(true);
} }
} catch (RuntimeException e) { // Populate with empty values if no data found.
handleWsCmdRuntimeException(theCtx.getSessionId(), e, cmd); keys.forEach(key -> {
entityData.getAggLatest().putIfAbsent(key.getId(), new ComparisonTsValue(TsValue.EMPTY, TsValue.EMPTY));
});
} catch (InterruptedException | ExecutionException e) {
log.warn("[{}][{}][{}] Failed to fetch historical data", ctx.getSessionId(), ctx.getCmdId(), entityData.getEntityId(), e);
ctx.sendWsMsg(new EntityDataUpdate(ctx.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR.getCode(), "Failed to fetch historical data!"));
} }
});
ctx.getWsLock().lock();
try {
EntityDataUpdate update;
if (!ctx.isInitialDataSent()) {
update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
ctx.setInitialDataSent(true);
} else {
update = new EntityDataUpdate(ctx.getCmdId(), null, entityDataList, ctx.getMaxEntitiesPerDataSubscription());
}
if (subscribe) {
ctx.createTimeSeriesSubscriptions(lastTsEntityMap, startTs, endTs, true);
}
ctx.sendWsMsg(update);
entityDataList.forEach(ed -> ed.getTimeseries().clear());
} finally {
ctx.getWsLock().unlock();
} }
return ctx;
@Override
public void onFailure(Throwable t) {
log.warn("[{}][{}] Failed to process command", session.getSessionId(), cmd.getCmdId());
}
}, wsCallBackExecutor); }, wsCallBackExecutor);
} }
@ -416,36 +523,58 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
} }
private ListenableFuture<TbEntityDataSubCtx> handleGetTsCmd(TbEntityDataSubCtx ctx, GetTsCmd cmd, boolean subscribe) { private ListenableFuture<TbEntityDataSubCtx> handleGetTsCmd(TbEntityDataSubCtx ctx, GetTsCmd cmd, boolean subscribe) {
Map<Integer, String> queriesKeys = new ConcurrentHashMap<>();
List<String> keys = cmd.getKeys(); List<String> keys = cmd.getKeys();
List<ReadTsKvQuery> finalTsKvQueryList; List<ReadTsKvQuery> finalTsKvQueryList;
List<ReadTsKvQuery> tsKvQueryList = cmd.getKeys().stream().map(key -> new BaseReadTsKvQuery( List<ReadTsKvQuery> tsKvQueryList = keys.stream().map(key -> {
key, cmd.getStartTs(), cmd.getEndTs(), cmd.getInterval(), getLimit(cmd.getLimit()), cmd.getAgg() var query = new BaseReadTsKvQuery(
)).collect(Collectors.toList()); key, cmd.getStartTs(), cmd.getEndTs(), cmd.getInterval(), getLimit(cmd.getLimit()), cmd.getAgg()
);
queriesKeys.put(query.getId(), query.getKey());
return query;
}).collect(Collectors.toList());
if (cmd.isFetchLatestPreviousPoint()) { if (cmd.isFetchLatestPreviousPoint()) {
finalTsKvQueryList = new ArrayList<>(tsKvQueryList); finalTsKvQueryList = new ArrayList<>(tsKvQueryList);
finalTsKvQueryList.addAll(cmd.getKeys().stream().map(key -> new BaseReadTsKvQuery( finalTsKvQueryList.addAll(keys.stream().map(key -> {
key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.getInterval(), 1, cmd.getAgg() var query = new BaseReadTsKvQuery(
)).collect(Collectors.toList())); key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.getInterval(), 1, cmd.getAgg());
queriesKeys.put(query.getId(), query.getKey());
return query;
}
).collect(Collectors.toList()));
} else { } else {
finalTsKvQueryList = tsKvQueryList; finalTsKvQueryList = tsKvQueryList;
} }
Map<EntityData, ListenableFuture<List<TsKvEntry>>> fetchResultMap = new HashMap<>(); Map<EntityData, ListenableFuture<List<ReadTsKvQueryResult>>> fetchResultMap = new HashMap<>();
ctx.getData().getData().forEach(entityData -> fetchResultMap.put(entityData, List<EntityData> entityDataList = ctx.getData().getData();
tsService.findAll(ctx.getTenantId(), entityData.getEntityId(), finalTsKvQueryList))); entityDataList.forEach(entityData -> fetchResultMap.put(entityData,
tsService.findAllByQueries(ctx.getTenantId(), entityData.getEntityId(), finalTsKvQueryList)));
return Futures.transform(Futures.allAsList(fetchResultMap.values()), f -> { return Futures.transform(Futures.allAsList(fetchResultMap.values()), f -> {
// Map that holds last ts for each key for each entity.
Map<EntityData, Map<String, Long>> lastTsEntityMap = new HashMap<>();
fetchResultMap.forEach((entityData, future) -> { fetchResultMap.forEach((entityData, future) -> {
Map<String, List<TsValue>> keyData = new LinkedHashMap<>();
cmd.getKeys().forEach(key -> keyData.put(key, new ArrayList<>()));
try { try {
List<TsKvEntry> entityTsData = future.get(); Map<String, Long> lastTsMap = new HashMap<>();
if (entityTsData != null) { lastTsEntityMap.put(entityData, lastTsMap);
entityTsData.forEach(entry -> keyData.get(entry.getKey()).add(new TsValue(entry.getTs(), entry.getValueAsString())));
List<ReadTsKvQueryResult> queryResults = future.get();
if (queryResults != null) {
for (ReadTsKvQueryResult queryResult : queryResults) {
String queryKey = queriesKeys.get(queryResult.getQueryId());
entityData.getTimeseries().put(queryKey, queryResult.toTsValues());
lastTsMap.put(queryKey, queryResult.getLastEntryTs());
}
} }
keyData.forEach((k, v) -> entityData.getTimeseries().put(k, v.toArray(new TsValue[v.size()]))); // Populate with empty values if no data found.
keys.forEach(key -> {
if (!entityData.getTimeseries().containsKey(key)) {
entityData.getTimeseries().put(key, new TsValue[0]);
}
});
if (cmd.isFetchLatestPreviousPoint()) { if (cmd.isFetchLatestPreviousPoint()) {
entityData.getTimeseries().values().forEach(dataArray -> { entityData.getTimeseries().values().forEach(dataArray -> Arrays.sort(dataArray, (o1, o2) -> Long.compare(o2.getTs(), o1.getTs())));
Arrays.sort(dataArray, (o1, o2) -> Long.compare(o2.getTs(), o1.getTs()));
});
} }
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
log.warn("[{}][{}][{}] Failed to fetch historical data", ctx.getSessionId(), ctx.getCmdId(), entityData.getEntityId(), e); log.warn("[{}][{}][{}] Failed to fetch historical data", ctx.getSessionId(), ctx.getCmdId(), entityData.getEntityId(), e);
@ -459,13 +588,13 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
ctx.setInitialDataSent(true); ctx.setInitialDataSent(true);
} else { } else {
update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription()); update = new EntityDataUpdate(ctx.getCmdId(), null, entityDataList, ctx.getMaxEntitiesPerDataSubscription());
} }
if (subscribe) { if (subscribe) {
ctx.createTimeseriesSubscriptions(keys.stream().map(key -> new EntityKey(EntityKeyType.TIME_SERIES, key)).collect(Collectors.toList()), cmd.getStartTs(), cmd.getEndTs()); ctx.createTimeSeriesSubscriptions(lastTsEntityMap, cmd.getStartTs(), cmd.getEndTs());
} }
ctx.sendWsMsg(update); ctx.sendWsMsg(update);
ctx.getData().getData().forEach(ed -> ed.getTimeseries().clear()); entityDataList.forEach(ed -> ed.getTimeseries().clear());
} finally { } finally {
ctx.getWsLock().unlock(); ctx.getWsLock().unlock();
} }
@ -533,11 +662,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
ctx.getWsLock().lock(); ctx.getWsLock().lock();
try { try {
ctx.createLatestValuesSubscriptions(latestCmd.getKeys()); ctx.createLatestValuesSubscriptions(latestCmd.getKeys());
if (!ctx.isInitialDataSent()) { checkAndSendInitialData(ctx);
EntityDataUpdate update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
ctx.sendWsMsg(update);
ctx.setInitialDataSent(true);
}
} finally { } finally {
ctx.getWsLock().unlock(); ctx.getWsLock().unlock();
} }

29
application/src/main/java/org/thingsboard/server/service/subscription/ReadTsKvQueryInfo.java

@ -0,0 +1,29 @@
/**
* Copyright © 2016-2022 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.service.subscription;
import lombok.Data;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.service.telemetry.cmd.v2.AggKey;
@Data
public class ReadTsKvQueryInfo {
private final AggKey key;
private final ReadTsKvQuery query;
private final boolean previous;
}

25
application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java

@ -86,7 +86,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
} else { } else {
oldDataMap = Collections.emptyMap(); oldDataMap = Collections.emptyMap();
} }
Map<EntityId, EntityData> newDataMap = newData.getData().stream().collect(Collectors.toMap(EntityData::getEntityId, Function.identity(), (a,b)-> a)); Map<EntityId, EntityData> newDataMap = newData.getData().stream().collect(Collectors.toMap(EntityData::getEntityId, Function.identity(), (a, b) -> a));
if (oldDataMap.size() == newDataMap.size() && oldDataMap.keySet().equals(newDataMap.keySet())) { if (oldDataMap.size() == newDataMap.size() && oldDataMap.keySet().equals(newDataMap.keySet())) {
log.trace("[{}][{}] No updates to entity data found", sessionRef.getSessionId(), cmdId); log.trace("[{}][{}] No updates to entity data found", sessionRef.getSessionId(), cmdId);
} else { } else {
@ -122,8 +122,17 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
createSubscriptions(keys, true, 0, 0); createSubscriptions(keys, true, 0, 0);
} }
public void createTimeseriesSubscriptions(List<EntityKey> keys, long startTs, long endTs) { public void createTimeSeriesSubscriptions(Map<EntityData, Map<String, Long>> entityKeyStates, long startTs, long endTs) {
createSubscriptions(keys, false, startTs, endTs); createTimeSeriesSubscriptions(entityKeyStates, startTs, endTs, false);
}
public void createTimeSeriesSubscriptions(Map<EntityData, Map<String, Long>> entityKeyStates, long startTs, long endTs, boolean resultToLatestValues) {
entityKeyStates.forEach((entityData, keyStates) -> {
int subIdx = sessionRef.getSessionSubIdSeq().incrementAndGet();
subToEntityIdMap.put(subIdx, entityData.getEntityId());
localSubscriptionService.addSubscription(
createTsSub(entityData, subIdx, false, startTs, endTs, keyStates, resultToLatestValues));
});
} }
private void createSubscriptions(List<EntityKey> keys, boolean latestValues, long startTs, long endTs) { private void createSubscriptions(List<EntityKey> keys, boolean latestValues, long startTs, long endTs) {
@ -191,6 +200,14 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
keyStates.put(k, ts); keyStates.put(k, ts);
}); });
} }
return createTsSub(entityData, subIdx, latestValues, startTs, endTs, keyStates);
}
private TbTimeseriesSubscription createTsSub(EntityData entityData, int subIdx, boolean latestValues, long startTs, long endTs, Map<String, Long> keyStates) {
return createTsSub(entityData, subIdx, latestValues, startTs, endTs, keyStates, latestValues);
}
private TbTimeseriesSubscription createTsSub(EntityData entityData, int subIdx, boolean latestValues, long startTs, long endTs, Map<String, Long> keyStates, boolean resultToLatestValues) {
log.trace("[{}][{}][{}] Creating time-series subscription for [{}] with keys: {}", serviceId, cmdId, subIdx, entityData.getEntityId(), keyStates); log.trace("[{}][{}][{}] Creating time-series subscription for [{}] with keys: {}", serviceId, cmdId, subIdx, entityData.getEntityId(), keyStates);
return TbTimeseriesSubscription.builder() return TbTimeseriesSubscription.builder()
.serviceId(serviceId) .serviceId(serviceId)
@ -198,7 +215,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
.subscriptionId(subIdx) .subscriptionId(subIdx)
.tenantId(sessionRef.getSecurityCtx().getTenantId()) .tenantId(sessionRef.getSecurityCtx().getTenantId())
.entityId(entityData.getEntityId()) .entityId(entityData.getEntityId())
.updateConsumer((sessionId, subscriptionUpdate) -> sendWsMsg(sessionId, subscriptionUpdate, EntityKeyType.TIME_SERIES, latestValues)) .updateConsumer((sessionId, subscriptionUpdate) -> sendWsMsg(sessionId, subscriptionUpdate, EntityKeyType.TIME_SERIES, resultToLatestValues))
.allKeys(false) .allKeys(false)
.keyStates(keyStates) .keyStates(keyStates)
.latestValues(latestValues) .latestValues(latestValues)

2
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java

@ -20,7 +20,6 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import lombok.Data; import lombok.Data;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
@ -29,6 +28,7 @@ import org.thingsboard.common.util.DonAsynchron;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;

4
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java

@ -26,11 +26,11 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.CloseStatus;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
@ -716,7 +716,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
"Cmd id is negative value!"); "Cmd id is negative value!");
sendWsMsg(sessionRef, update); sendWsMsg(sessionRef, update);
return false; return false;
} else if (cmd.getQuery() == null && cmd.getLatestCmd() == null && cmd.getHistoryCmd() == null && cmd.getTsCmd() == null) { } else if (cmd.getQuery() == null && !cmd.hasAnyCmd()) {
TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST,
"Query is empty!"); "Query is empty!");
sendWsMsg(sessionRef, update); sendWsMsg(sessionRef, update);

8
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java → application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggHistoryCmd.java

@ -13,15 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; package org.thingsboard.server.service.telemetry.cmd.v2;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@Data @Data
public class LwM2MBootstrapServersConfiguration { public class AggHistoryCmd {
List<LwM2MBootstrapServerCredential> bootstrap; private List<AggKey> keys;
private long startTs;
private long endTs;
} }

32
application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggKey.java

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2022 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.service.telemetry.cmd.v2;
import lombok.Data;
import org.thingsboard.server.common.data.kv.Aggregation;
@Data
public class AggKey {
private int id;
private String key;
private Aggregation agg;
private Long previousStartTs;
private Long previousEndTs;
private Boolean previousValueOnly;
}

29
application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/AggTimeSeriesCmd.java

@ -0,0 +1,29 @@
/**
* Copyright © 2016-2022 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.service.telemetry.cmd.v2;
import lombok.Data;
import java.util.List;
@Data
public class AggTimeSeriesCmd {
private List<AggKey> keys;
private long startTs;
private long timeWindow;
}

21
application/src/main/java/org/thingsboard/server/service/telemetry/cmd/v2/EntityDataCmd.java

@ -16,6 +16,7 @@
package org.thingsboard.server.service.telemetry.cmd.v2; package org.thingsboard.server.service.telemetry.cmd.v2;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter; import lombok.Getter;
import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityDataQuery;
@ -30,17 +31,35 @@ public class EntityDataCmd extends DataCmd {
private final LatestValueCmd latestCmd; private final LatestValueCmd latestCmd;
@Getter @Getter
private final TimeSeriesCmd tsCmd; private final TimeSeriesCmd tsCmd;
@Getter
private final AggHistoryCmd aggHistoryCmd;
@Getter
private final AggTimeSeriesCmd aggTsCmd;
public EntityDataCmd(int cmdId, EntityDataQuery query, EntityHistoryCmd historyCmd, LatestValueCmd latestCmd, TimeSeriesCmd tsCmd) {
this(cmdId, query, historyCmd, latestCmd, tsCmd, null, null);
}
@JsonCreator @JsonCreator
public EntityDataCmd(@JsonProperty("cmdId") int cmdId, public EntityDataCmd(@JsonProperty("cmdId") int cmdId,
@JsonProperty("query") EntityDataQuery query, @JsonProperty("query") EntityDataQuery query,
@JsonProperty("historyCmd") EntityHistoryCmd historyCmd, @JsonProperty("historyCmd") EntityHistoryCmd historyCmd,
@JsonProperty("latestCmd") LatestValueCmd latestCmd, @JsonProperty("latestCmd") LatestValueCmd latestCmd,
@JsonProperty("tsCmd") TimeSeriesCmd tsCmd) { @JsonProperty("tsCmd") TimeSeriesCmd tsCmd,
@JsonProperty("aggHistoryCmd") AggHistoryCmd aggHistoryCmd,
@JsonProperty("aggTsCmd") AggTimeSeriesCmd aggTsCmd) {
super(cmdId); super(cmdId);
this.query = query; this.query = query;
this.historyCmd = historyCmd; this.historyCmd = historyCmd;
this.latestCmd = latestCmd; this.latestCmd = latestCmd;
this.tsCmd = tsCmd; this.tsCmd = tsCmd;
this.aggHistoryCmd = aggHistoryCmd;
this.aggTsCmd = aggTsCmd;
} }
@JsonIgnore
public boolean hasAnyCmd() {
return historyCmd != null || latestCmd != null || tsCmd != null || aggHistoryCmd != null || aggTsCmd != null;
}
} }

16
application/src/main/resources/thingsboard.yml

@ -39,7 +39,7 @@ server:
key_password: "${SSL_PEM_KEY_PASSWORD:server_key_password}" key_password: "${SSL_PEM_KEY_PASSWORD:server_key_password}"
# Keystore server credentials # Keystore server credentials
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${SSL_KEY_STORE_TYPE:PKCS12}" type: "${SSL_KEY_STORE_TYPE:PKCS12}"
# Path to the key store that holds the SSL certificate # Path to the key store that holds the SSL certificate
store_file: "${SSL_KEY_STORE:classpath:keystore/keystore.p12}" store_file: "${SSL_KEY_STORE:classpath:keystore/keystore.p12}"
@ -148,7 +148,7 @@ ui:
# Help parameters # Help parameters
help: help:
# Base url for UI help assets # Base url for UI help assets
base-url: "${UI_HELP_BASE_URL:https://raw.githubusercontent.com/thingsboard/thingsboard-ui-help/release-3.4}" base-url: "${UI_HELP_BASE_URL:https://raw.githubusercontent.com/thingsboard/thingsboard-ui-help/release-3.4.1}"
database: database:
ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records
@ -260,7 +260,7 @@ sql:
stats_print_interval_ms: "${SQL_EVENTS_BATCH_STATS_PRINT_MS:10000}" stats_print_interval_ms: "${SQL_EVENTS_BATCH_STATS_PRINT_MS:10000}"
batch_threads: "${SQL_EVENTS_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution batch_threads: "${SQL_EVENTS_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution
partition_size: "${SQL_EVENTS_REGULAR_PARTITION_SIZE_HOURS:168}" # Number of hours to partition the events. The current value corresponds to one week. partition_size: "${SQL_EVENTS_REGULAR_PARTITION_SIZE_HOURS:168}" # Number of hours to partition the events. The current value corresponds to one week.
debug_partition_size: "${SQL_EVENTS_REGULAR_PARTITION_SIZE_HOURS:1}" # Number of hours to partition the debug events. The current value corresponds to one hour. debug_partition_size: "${SQL_EVENTS_DEBUG_PARTITION_SIZE_HOURS:1}" # Number of hours to partition the debug events. The current value corresponds to one hour.
edge_events: edge_events:
batch_size: "${SQL_EDGE_EVENTS_BATCH_SIZE:1000}" batch_size: "${SQL_EDGE_EVENTS_BATCH_SIZE:1000}"
batch_max_delay: "${SQL_EDGE_EVENTS_BATCH_MAX_DELAY_MS:100}" batch_max_delay: "${SQL_EDGE_EVENTS_BATCH_MAX_DELAY_MS:100}"
@ -685,7 +685,7 @@ transport:
key_password: "${MQTT_SSL_PEM_KEY_PASSWORD:server_key_password}" key_password: "${MQTT_SSL_PEM_KEY_PASSWORD:server_key_password}"
# Keystore server credentials # Keystore server credentials
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${MQTT_SSL_KEY_STORE_TYPE:JKS}" type: "${MQTT_SSL_KEY_STORE_TYPE:JKS}"
# Path to the key store that holds the SSL certificate # Path to the key store that holds the SSL certificate
store_file: "${MQTT_SSL_KEY_STORE:mqttserver.jks}" store_file: "${MQTT_SSL_KEY_STORE:mqttserver.jks}"
@ -728,7 +728,7 @@ transport:
key_password: "${COAP_DTLS_PEM_KEY_PASSWORD:server_key_password}" key_password: "${COAP_DTLS_PEM_KEY_PASSWORD:server_key_password}"
# Keystore server credentials # Keystore server credentials
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${COAP_DTLS_KEY_STORE_TYPE:JKS}" type: "${COAP_DTLS_KEY_STORE_TYPE:JKS}"
# Path to the key store that holds the SSL certificate # Path to the key store that holds the SSL certificate
store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}" store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}"
@ -770,7 +770,7 @@ transport:
key_password: "${LWM2M_SERVER_PEM_KEY_PASSWORD:server_key_password}" key_password: "${LWM2M_SERVER_PEM_KEY_PASSWORD:server_key_password}"
# Keystore server credentials # Keystore server credentials
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${LWM2M_SERVER_KEY_STORE_TYPE:JKS}" type: "${LWM2M_SERVER_KEY_STORE_TYPE:JKS}"
# Path to the key store that holds the SSL certificate # Path to the key store that holds the SSL certificate
store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}" store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}"
@ -806,7 +806,7 @@ transport:
key_password: "${LWM2M_BS_PEM_KEY_PASSWORD:server_key_password}" key_password: "${LWM2M_BS_PEM_KEY_PASSWORD:server_key_password}"
# Keystore server credentials # Keystore server credentials
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${LWM2M_BS_KEY_STORE_TYPE:JKS}" type: "${LWM2M_BS_KEY_STORE_TYPE:JKS}"
# Path to the key store that holds the SSL certificate # Path to the key store that holds the SSL certificate
store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}" store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}"
@ -829,7 +829,7 @@ transport:
cert_file: "${LWM2M_TRUST_PEM_CERT:lwm2mtruststorechain.pem}" cert_file: "${LWM2M_TRUST_PEM_CERT:lwm2mtruststorechain.pem}"
# Keystore with trust certificates # Keystore with trust certificates
keystore: keystore:
# Type of the key store # Type of the key store (JKS or PKCS12)
type: "${LWM2M_TRUST_KEY_STORE_TYPE:JKS}" type: "${LWM2M_TRUST_KEY_STORE_TYPE:JKS}"
# Path to the key store that holds the X509 certificates # Path to the key store that holds the X509 certificates
store_file: "${LWM2M_TRUST_KEY_STORE:lwm2mtruststorechain.jks}" store_file: "${LWM2M_TRUST_KEY_STORE:lwm2mtruststorechain.jks}"

67
application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java

@ -26,9 +26,8 @@ import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hibernate.exception.ConstraintViolationException;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -36,6 +35,7 @@ import org.junit.Rule;
import org.junit.rules.TestRule; import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher; import org.junit.rules.TestWatcher;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.mockito.BDDMockito;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -56,6 +56,7 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
@ -68,28 +69,33 @@ import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadCo
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration; import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.service.mail.TestMailService; import org.thingsboard.server.service.mail.TestMailService;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest; import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest;
import org.thingsboard.server.service.security.auth.rest.LoginRequest; import org.thingsboard.server.service.security.auth.rest.LoginRequest;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
@ -658,7 +664,11 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
} }
protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception {
byte[] content = result.andReturn().getResponse().getContentAsByteArray(); return readResponse(result.andReturn(), type);
}
protected <T> T readResponse(MvcResult result, TypeReference<T> type) throws Exception {
byte[] content = result.getResponse().getContentAsByteArray();
return mapper.readerFor(type).readValue(content); return mapper.readerFor(type).readValue(content);
} }
@ -686,8 +696,8 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
edge.setTenantId(tenantId); edge.setTenantId(tenantId);
edge.setName(name); edge.setName(name);
edge.setType(type); edge.setType(type);
edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); edge.setSecret(StringUtils.randomAlphanumeric(20));
edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); edge.setRoutingKey(StringUtils.randomAlphanumeric(20));
return edge; return edge;
} }
@ -701,4 +711,49 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
return Futures.allAsList(futures); return Futures.allAsList(futures);
} }
protected void testEntityDaoWithRelationsOk(EntityId entityIdFrom, EntityId entityTo, String urlDelete) throws Exception {
createEntityRelation(entityIdFrom, entityTo, "TEST_TYPE");
assertThat(findRelationsByTo(entityTo)).hasSize(1);
doDelete(urlDelete).andExpect(status().isOk());
assertThat(findRelationsByTo(entityTo)).hasSize(0);
}
protected <T> void testEntityDaoWithRelationsTransactionalException(Dao<T> dao, EntityId entityIdFrom, EntityId entityTo,
String urlDelete) throws Exception {
entityDaoRemoveByIdWithException (dao);
createEntityRelation(entityIdFrom, entityTo, "TEST_TRANSACTIONAL_TYPE");
assertThat(findRelationsByTo(entityTo)).hasSize(1);
doDelete(urlDelete)
.andExpect(status().isInternalServerError());
assertThat(findRelationsByTo(entityTo)).hasSize(1);
}
protected <T> void entityDaoRemoveByIdWithException (Dao<T> dao) throws Exception {
BDDMockito.willThrow(new ConstraintViolationException("mock message", new SQLException(), "MOCK_CONSTRAINT"))
.given(dao).removeById(any(), any());
}
protected <T> void afterTestEntityDaoRemoveByIdWithException (Dao<T> dao) throws Exception {
BDDMockito.willCallRealMethod().given(dao).removeById(any(), any());
}
protected void createEntityRelation(EntityId entityIdFrom, EntityId entityIdTo, String typeRelation) throws Exception {
EntityRelation relation = new EntityRelation(entityIdFrom, entityIdTo, typeRelation);
doPost("/api/relation", relation);
}
protected List<EntityRelation> findRelationsByTo(EntityId entityId) throws Exception {
String url = String.format("/api/relations?toId=%s&toType=%s", entityId.getId(), entityId.getEntityType().name());
MvcResult mvcResult = doGet(url).andReturn();
switch (mvcResult.getResponse().getStatus()) {
case 200: return readResponse(mvcResult, new TypeReference<>() {});
case 404: return Collections.emptyList();
}
throw new AssertionError("Unexpected status " + mvcResult.getResponse().getStatus());
}
} }

25
application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java

@ -23,6 +23,7 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
@ -31,7 +32,9 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.dao.alarm.AlarmDao;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -46,6 +49,10 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest {
protected Device customerDevice; protected Device customerDevice;
@SpyBean
private AlarmDao alarmDao;
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
loginTenantAdmin(); loginTenantAdmin();
@ -64,6 +71,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest {
@After @After
public void teardown() throws Exception { public void teardown() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (alarmDao);
deleteDifferentTenant(); deleteDifferentTenant();
} }
@ -421,6 +431,21 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest {
Assert.assertTrue("Created alarm doesn't match the found one!", equals); Assert.assertTrue("Created alarm doesn't match the found one!", equals);
} }
@Test
public void testDeleteAlarmWithDeleteRelationsOk() throws Exception {
loginCustomerUser();
AlarmId alarmId = createAlarm("Alarm for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(customerDevice.getId(), alarmId, "/api/alarm/" + alarmId);
}
@Test
public void testDeleteAlarmExceptionWithRelationsTransactional() throws Exception {
loginCustomerUser();
AlarmId alarmId = createAlarm("Alarm for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(alarmDao, customerDevice.getId(), alarmId, "/api/alarm/" + alarmId);
}
private Alarm createAlarm(String type) throws Exception { private Alarm createAlarm(String type) throws Exception {
Alarm alarm = Alarm.builder() Alarm alarm = Alarm.builder()
.tenantId(tenantId) .tenantId(tenantId)

51
application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java

@ -17,24 +17,27 @@ package org.thingsboard.server.controller;
import com.datastax.oss.driver.api.core.uuid.Uuids; import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.asset.AssetDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService; import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService;
@ -54,6 +57,9 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private AssetDao assetDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -77,6 +83,8 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (assetDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -117,7 +125,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
@Test @Test
public void testSaveAssetWithViolationOfLengthValidation() throws Exception { public void testSaveAssetWithViolationOfLengthValidation() throws Exception {
Asset asset = new Asset(); Asset asset = new Asset();
asset.setName(RandomStringUtils.randomAlphabetic(300)); asset.setName(StringUtils.randomAlphabetic(300));
asset.setType("default"); asset.setType("default");
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -132,7 +140,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
asset.setName("Normal name"); asset.setName("Normal name");
asset.setType(RandomStringUtils.randomAlphabetic(300)); asset.setType(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("type"); msgError = msgErrorFieldLength("type");
doPost("/api/asset", asset) doPost("/api/asset", asset)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -143,7 +151,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
asset.setType("default"); asset.setType("default");
asset.setLabel(RandomStringUtils.randomAlphabetic(300)); asset.setLabel(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("label"); msgError = msgErrorFieldLength("label");
doPost("/api/asset", asset) doPost("/api/asset", asset)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -471,7 +479,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsTitle1 = new ArrayList<>(); List<Asset> assetsTitle1 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -482,7 +490,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsTitle2 = new ArrayList<>(); List<Asset> assetsTitle2 = new ArrayList<>();
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -557,7 +565,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsType1 = new ArrayList<>(); List<Asset> assetsType1 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -569,7 +577,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsType2 = new ArrayList<>(); List<Asset> assetsType2 = new ArrayList<>();
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -684,7 +692,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsTitle1 = new ArrayList<>(); List<Asset> assetsTitle1 = new ArrayList<>();
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -697,7 +705,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsTitle2 = new ArrayList<>(); List<Asset> assetsTitle2 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -779,7 +787,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsType1 = new ArrayList<>(); List<Asset> assetsType1 = new ArrayList<>();
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -793,7 +801,7 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
List<Asset> assetsType2 = new ArrayList<>(); List<Asset> assetsType2 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
asset.setName(name); asset.setName(name);
@ -905,4 +913,23 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
@Test
public void testDeleteAssetWithDeleteRelationsOk() throws Exception {
AssetId assetId = createAsset("Asset for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), assetId, "/api/asset/" + assetId);
}
@Test
public void testDeleteAssetExceptionWithRelationsTransactional() throws Exception {
AssetId assetId = createAsset("Asset for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(assetDao, savedTenant.getId(), assetId, "/api/asset/" + assetId);
}
private Asset createAsset(String name) {
Asset asset = new Asset();
asset.setName(name);
asset.setType("default");
return doPost("/api/asset", asset, Asset.class);
}
} }

43
application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java

@ -20,14 +20,15 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -36,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList; import java.util.ArrayList;
@ -55,6 +57,9 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private CustomerDao customerDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass()));
@ -82,6 +87,8 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (customerDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -122,7 +129,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
@Test @Test
public void testSaveCustomerWithViolationOfValidation() throws Exception { public void testSaveCustomerWithViolationOfValidation() throws Exception {
Customer customer = new Customer(); Customer customer = new Customer();
customer.setTitle(RandomStringUtils.randomAlphabetic(300)); customer.setTitle(StringUtils.randomAlphabetic(300));
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -137,7 +144,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
customer.setTitle("Normal title"); customer.setTitle("Normal title");
customer.setCity(RandomStringUtils.randomAlphabetic(300)); customer.setCity(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("city"); msgError = msgErrorFieldLength("city");
doPost("/api/customer", customer) doPost("/api/customer", customer)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -148,7 +155,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
customer.setCity("Normal city"); customer.setCity("Normal city");
customer.setCountry(RandomStringUtils.randomAlphabetic(300)); customer.setCountry(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("country"); msgError = msgErrorFieldLength("country");
doPost("/api/customer", customer) doPost("/api/customer", customer)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -159,7 +166,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
customer.setCountry("Ukraine"); customer.setCountry("Ukraine");
customer.setPhone(RandomStringUtils.randomAlphabetic(300)); customer.setPhone(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("phone"); msgError = msgErrorFieldLength("phone");
doPost("/api/customer", customer) doPost("/api/customer", customer)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -170,7 +177,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
customer.setPhone("+3892555554512"); customer.setPhone("+3892555554512");
customer.setState(RandomStringUtils.randomAlphabetic(300)); customer.setState(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("state"); msgError = msgErrorFieldLength("state");
doPost("/api/customer", customer) doPost("/api/customer", customer)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -181,7 +188,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
customer.setState("Normal state"); customer.setState("Normal state");
customer.setZip(RandomStringUtils.randomAlphabetic(300)); customer.setZip(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("zip or postal code"); msgError = msgErrorFieldLength("zip or postal code");
doPost("/api/customer", customer) doPost("/api/customer", customer)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -339,7 +346,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Customer customer = new Customer(); Customer customer = new Customer();
customer.setTenantId(tenantId); customer.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String title = title1 + suffix; String title = title1 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
customer.setTitle(title); customer.setTitle(title);
@ -353,7 +360,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
for (int i = 0; i < 175; i++) { for (int i = 0; i < 175; i++) {
Customer customer = new Customer(); Customer customer = new Customer();
customer.setTenantId(tenantId); customer.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String title = title2 + suffix; String title = title2 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
customer.setTitle(title); customer.setTitle(title);
@ -402,4 +409,22 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
Assert.assertFalse(pageData.hasNext()); Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
@Test
public void testDeleteCustomerWithDeleteRelationsOk() throws Exception {
CustomerId customerId = createCustomer("Customer for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), customerId, "/api/customer/" + customerId);
}
@Test
public void testDeleteCustomerExceptionWithRelationsTransactional() throws Exception {
CustomerId customerId = createCustomer("Customer for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(customerDao, savedTenant.getId(), customerId, "/api/customer/" + customerId);
}
private Customer createCustomer(String title) {
Customer customer = new Customer();
customer.setTitle(title);
return doPost("/api/customer", customer, Customer.class);
}
} }

64
application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java

@ -17,23 +17,26 @@ package org.thingsboard.server.controller;
import com.datastax.oss.driver.api.core.uuid.Uuids; import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.dashboard.DashboardDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList; import java.util.ArrayList;
@ -50,6 +53,9 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private DashboardDao dashboardDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -73,45 +79,16 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (dashboardDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@Test
public void testSaveDashboard() throws Exception {
Dashboard dashboard = new Dashboard();
dashboard.setTitle("My dashboard");
Mockito.reset(tbClusterService, auditLogService);
Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDashboard, savedDashboard.getId(), savedDashboard.getId(), savedTenant.getId(),
tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED);
Assert.assertNotNull(savedDashboard);
Assert.assertNotNull(savedDashboard.getId());
Assert.assertTrue(savedDashboard.getCreatedTime() > 0);
Assert.assertEquals(savedTenant.getId(), savedDashboard.getTenantId());
Assert.assertEquals(dashboard.getTitle(), savedDashboard.getTitle());
savedDashboard.setTitle("My new dashboard");
Mockito.reset(tbClusterService, auditLogService);
doPost("/api/dashboard", savedDashboard, Dashboard.class);
testNotifyEntityAllOneTime(savedDashboard, savedDashboard.getId(), savedDashboard.getId(), savedTenant.getId(),
tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED);
Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
Assert.assertEquals(foundDashboard.getTitle(), savedDashboard.getTitle());
}
@Test @Test
public void testSaveDashboardInfoWithViolationOfValidation() throws Exception { public void testSaveDashboardInfoWithViolationOfValidation() throws Exception {
Dashboard dashboard = new Dashboard(); Dashboard dashboard = new Dashboard();
dashboard.setTitle(RandomStringUtils.randomAlphabetic(300)); dashboard.setTitle(StringUtils.randomAlphabetic(300));
String msgError = msgErrorFieldLength("title"); String msgError = msgErrorFieldLength("title");
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -335,7 +312,7 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
int cntEntity = 134; int cntEntity = 134;
for (int i = 0; i < cntEntity; i++) { for (int i = 0; i < cntEntity; i++) {
Dashboard dashboard = new Dashboard(); Dashboard dashboard = new Dashboard();
String suffix = RandomStringUtils.randomAlphanumeric((int) (Math.random() * 15)); String suffix = StringUtils.randomAlphanumeric((int) (Math.random() * 15));
String title = title1 + suffix; String title = title1 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
dashboard.setTitle(title); dashboard.setTitle(title);
@ -346,7 +323,7 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
for (int i = 0; i < 112; i++) { for (int i = 0; i < 112; i++) {
Dashboard dashboard = new Dashboard(); Dashboard dashboard = new Dashboard();
String suffix = RandomStringUtils.randomAlphanumeric((int) (Math.random() * 15)); String suffix = StringUtils.randomAlphanumeric((int) (Math.random() * 15));
String title = title2 + suffix; String title = title2 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
dashboard.setTitle(title); dashboard.setTitle(title);
@ -495,4 +472,21 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
@Test
public void testDeleteDashboardWithDeleteRelationsOk() throws Exception {
DashboardId dashboardId = createDashboard("Dashboard for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), dashboardId, "/api/dashboard/" + dashboardId);
}
@Test
public void testDeleteDashboardExceptionWithRelationsTransactional() throws Exception {
DashboardId dashboardId = createDashboard("Dashboard for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(dashboardDao, savedTenant.getId(), dashboardId, "/api/dashboard/" + dashboardId);
}
private Dashboard createDashboard(String title) {
Dashboard dashboard = new Dashboard();
dashboard.setTitle(title);
return doPost("/api/dashboard", dashboard, Dashboard.class);
}
} }

50
application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java

@ -21,7 +21,6 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -35,6 +34,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.dao.device.DeviceDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
@ -82,6 +83,10 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
@SpyBean @SpyBean
private GatewayNotificationsService gatewayNotificationsService; private GatewayNotificationsService gatewayNotificationsService;
@SpyBean
private DeviceDao deviceDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass()));
@ -109,6 +114,8 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (deviceDao);
doDelete("/api/tenant/" + savedTenant.getId().getId()) doDelete("/api/tenant/" + savedTenant.getId().getId())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -164,7 +171,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
@Test @Test
public void saveDeviceWithViolationOfValidation() throws Exception { public void saveDeviceWithViolationOfValidation() throws Exception {
Device device = new Device(); Device device = new Device();
device.setName(RandomStringUtils.randomAlphabetic(300)); device.setName(StringUtils.randomAlphabetic(300));
device.setType("default"); device.setType("default");
Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService);
@ -181,7 +188,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
device.setTenantId(savedTenant.getId()); device.setTenantId(savedTenant.getId());
msgError = msgErrorFieldLength("type"); msgError = msgErrorFieldLength("type");
device.setType(RandomStringUtils.randomAlphabetic(300)); device.setType(StringUtils.randomAlphabetic(300));
doPost("/api/device", device) doPost("/api/device", device)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -193,7 +200,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
msgError = msgErrorFieldLength("label"); msgError = msgErrorFieldLength("label");
device.setType("Normal type"); device.setType("Normal type");
device.setLabel(RandomStringUtils.randomAlphabetic(300)); device.setLabel(StringUtils.randomAlphabetic(300));
doPost("/api/device", device) doPost("/api/device", device)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -709,7 +716,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(143); futures = new ArrayList<>(143);
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -723,7 +730,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(75); futures = new ArrayList<>(75);
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -783,7 +790,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(143); futures = new ArrayList<>(143);
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -801,7 +808,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(75); futures = new ArrayList<>(75);
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -920,7 +927,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(125); futures = new ArrayList<>(125);
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -936,7 +943,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(143); futures = new ArrayList<>(143);
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -1003,7 +1010,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(125); futures = new ArrayList<>(125);
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -1023,7 +1030,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
futures = new ArrayList<>(143); futures = new ArrayList<>(143);
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
Device device = new Device(); Device device = new Device();
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name); device.setName(name);
@ -1203,4 +1210,23 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
protected void testNotificationDeleteGatewayNever() { protected void testNotificationDeleteGatewayNever() {
Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class)); Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class));
} }
@Test
public void testDeleteDashboardWithDeleteRelationsOk() throws Exception {
DeviceId deviceId = createDevice("Device for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), deviceId, "/api/device/" + deviceId);
}
@Test
public void testDeleteDeviceExceptionWithRelationsTransactional() throws Exception {
DeviceId deviceId = createDevice("Device for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(deviceDao, savedTenant.getId(), deviceId, "/api/device/" + deviceId);
}
private Device createDevice(String name) {
Device device = new Device();
device.setName(name);
device.setType("default");
return doPost("/api/device", device, Device.class);
}
} }

28
application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java

@ -22,12 +22,12 @@ import com.google.protobuf.DynamicMessage;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat; import com.google.protobuf.util.JsonFormat;
import com.squareup.wire.schema.internal.parser.ProtoFileElement; import com.squareup.wire.schema.internal.parser.ProtoFileElement;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -46,10 +47,12 @@ import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadCon
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.device.DeviceProfileDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList; import java.util.ArrayList;
@ -74,6 +77,9 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private DeviceProfileDao deviceProfileDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -97,6 +103,8 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (deviceProfileDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -138,7 +146,7 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
DeviceProfile createDeviceProfile = this.createDeviceProfile(RandomStringUtils.randomAlphabetic(300)); DeviceProfile createDeviceProfile = this.createDeviceProfile(StringUtils.randomAlphabetic(300));
doPost("/api/deviceProfile", createDeviceProfile) doPost("/api/deviceProfile", createDeviceProfile)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -1125,4 +1133,20 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
return JsonFormat.printer().includingDefaultValueFields().print(dynamicMessage); return JsonFormat.printer().includingDefaultValueFields().print(dynamicMessage);
} }
@Test
public void testDeleteDeviceProfileWithDeleteRelationsOk() throws Exception {
DeviceProfileId deviceProfileId = savedDeviceProfile("DeviceProfile for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), deviceProfileId, "/api/deviceProfile/" + deviceProfileId);
}
@Test
public void testDeleteDeviceProfileExceptionWithRelationsTransactional() throws Exception {
DeviceProfileId deviceProfileId = savedDeviceProfile("DeviceProfile for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(deviceProfileDao, savedTenant.getId(), deviceProfileId, "/api/deviceProfile/" + deviceProfileId);
}
private DeviceProfile savedDeviceProfile(String name) {
DeviceProfile deviceProfile = createDeviceProfile(name);
return doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
}
} }

48
application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java

@ -17,26 +17,29 @@ package org.thingsboard.server.controller;
import com.datastax.oss.driver.api.core.uuid.Uuids; import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.edge.EdgeDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.edge.imitator.EdgeImitator; import org.thingsboard.server.edge.imitator.EdgeImitator;
@ -72,6 +75,9 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
private TenantId tenantId; private TenantId tenantId;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private EdgeDao edgeDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -96,6 +102,8 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException (edgeDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -133,7 +141,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
@Test @Test
public void testSaveEdgeWithViolationOfLengthValidation() throws Exception { public void testSaveEdgeWithViolationOfLengthValidation() throws Exception {
Edge edge = constructEdge(RandomStringUtils.randomAlphabetic(300), "default"); Edge edge = constructEdge(StringUtils.randomAlphabetic(300), "default");
String msgError = msgErrorFieldLength("name"); String msgError = msgErrorFieldLength("name");
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -148,7 +156,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
msgError = msgErrorFieldLength("type"); msgError = msgErrorFieldLength("type");
edge.setName("normal name"); edge.setName("normal name");
edge.setType(RandomStringUtils.randomAlphabetic(300)); edge.setType(StringUtils.randomAlphabetic(300));
doPost("/api/edge", edge) doPost("/api/edge", edge)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -159,7 +167,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
msgError = msgErrorFieldLength("label"); msgError = msgErrorFieldLength("label");
edge.setType("normal type"); edge.setType("normal type");
edge.setLabel(RandomStringUtils.randomAlphabetic(300)); edge.setLabel(StringUtils.randomAlphabetic(300));
doPost("/api/edge", edge) doPost("/api/edge", edge)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -389,7 +397,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String title1 = "Edge title 1"; String title1 = "Edge title 1";
List<Edge> edgesTitle1 = new ArrayList<>(); List<Edge> edgesTitle1 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, "default"); Edge edge = constructEdge(name, "default");
@ -398,7 +406,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String title2 = "Edge title 2"; String title2 = "Edge title 2";
List<Edge> edgesTitle2 = new ArrayList<>(); List<Edge> edgesTitle2 = new ArrayList<>();
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, "default"); Edge edge = constructEdge(name, "default");
@ -471,7 +479,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String type1 = "typeA"; String type1 = "typeA";
List<Edge> edgesType1 = new ArrayList<>(); List<Edge> edgesType1 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, type1); Edge edge = constructEdge(name, type1);
@ -481,7 +489,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String type2 = "typeB"; String type2 = "typeB";
List<Edge> edgesType2 = new ArrayList<>(); List<Edge> edgesType2 = new ArrayList<>();
for (int i = 0; i < 75; i++) { for (int i = 0; i < 75; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, type2); Edge edge = constructEdge(name, type2);
@ -600,7 +608,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String title1 = "Edge title 1"; String title1 = "Edge title 1";
List<Edge> edgesTitle1 = new ArrayList<>(); List<Edge> edgesTitle1 = new ArrayList<>();
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, "default"); Edge edge = constructEdge(name, "default");
@ -611,7 +619,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String title2 = "Edge title 2"; String title2 = "Edge title 2";
List<Edge> edgesTitle2 = new ArrayList<>(); List<Edge> edgesTitle2 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, "default"); Edge edge = constructEdge(name, "default");
@ -698,7 +706,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String type1 = "typeC"; String type1 = "typeC";
List<Edge> edgesType1 = new ArrayList<>(); List<Edge> edgesType1 = new ArrayList<>();
for (int i = 0; i < 125; i++) { for (int i = 0; i < 125; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title1 + suffix; String name = title1 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, type1); Edge edge = constructEdge(name, type1);
@ -710,7 +718,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
String type2 = "typeD"; String type2 = "typeD";
List<Edge> edgesType2 = new ArrayList<>(); List<Edge> edgesType2 = new ArrayList<>();
for (int i = 0; i < 143; i++) { for (int i = 0; i < 143; i++) {
String suffix = RandomStringUtils.randomAlphanumeric(15); String suffix = StringUtils.randomAlphanumeric(15);
String name = title2 + suffix; String name = title2 + suffix;
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
Edge edge = constructEdge(name, type2); Edge edge = constructEdge(name, type2);
@ -837,4 +845,20 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@Test
public void testDeleteEdgeWithDeleteRelationsOk() throws Exception {
EdgeId edgeId = savedEdge("Edge for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), edgeId, "/api/edge/" + edgeId);
}
@Test
public void testDeleteEdgeExceptionWithRelationsTransactional() throws Exception {
EdgeId edgeId = savedEdge("Edge for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(edgeDao, savedTenant.getId(), edgeId, "/api/edge/" + edgeId);
}
private Edge savedEdge(String name) {
Edge edge = constructEdge(name, "default");
return doPost("/api/edge", edge, Edge.class);
}
} }

29
application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java

@ -22,7 +22,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
@ -33,6 +32,7 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
@ -40,11 +40,13 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.EntityViewInfo; import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.objects.AttributesEntityView; import org.thingsboard.server.common.data.objects.AttributesEntityView;
import org.thingsboard.server.common.data.objects.TelemetryEntityView; import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
@ -54,6 +56,7 @@ import org.thingsboard.server.common.data.query.EntityKey;
import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.query.EntityKeyType;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.entityview.EntityViewDao;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
@ -93,6 +96,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
List<ListenableFuture<ResultActions>> deleteFutures = new ArrayList<>(); List<ListenableFuture<ResultActions>> deleteFutures = new ArrayList<>();
ListeningExecutorService executor; ListeningExecutorService executor;
@SpyBean
private EntityViewDao entityViewDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass()));
@ -114,6 +120,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
@After @After
public void afterTest() throws Exception { public void afterTest() throws Exception {
afterTestEntityDaoRemoveByIdWithException (entityViewDao);
executor.shutdownNow(); executor.shutdownNow();
} }
@ -170,7 +179,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
@Test @Test
public void testSaveEntityViewWithViolationOfValidation() throws Exception { public void testSaveEntityViewWithViolationOfValidation() throws Exception {
EntityView entityView = createEntityView(RandomStringUtils.randomAlphabetic(300), 0, 0); EntityView entityView = createEntityView(StringUtils.randomAlphabetic(300), 0, 0);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -186,7 +195,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
entityView.setName("Normal name"); entityView.setName("Normal name");
msgError = msgErrorFieldLength("type"); msgError = msgErrorFieldLength("type");
entityView.setType(RandomStringUtils.randomAlphabetic(300)); entityView.setType(StringUtils.randomAlphabetic(300));
doPost("/api/entityView", entityView) doPost("/api/entityView", entityView)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -722,7 +731,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
}); });
viewNameFutures.add(Futures.transform(customerFuture, customerId -> { viewNameFutures.add(Futures.transform(customerFuture, customerId -> {
String fullName = partOfName + ' ' + RandomStringUtils.randomAlphanumeric(15); String fullName = partOfName + ' ' + StringUtils.randomAlphanumeric(15);
fullName = even ? fullName.toLowerCase() : fullName.toUpperCase(); fullName = even ? fullName.toLowerCase() : fullName.toUpperCase();
EntityView view = getNewSavedEntityView(fullName); EntityView view = getNewSavedEntityView(fullName);
view.setCustomerId(customerId); view.setCustomerId(customerId);
@ -786,4 +795,16 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
@Test
public void testDeleteEntityViewWithDeleteRelationsOk() throws Exception {
EntityViewId entityViewId = getNewSavedEntityView("EntityView for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(tenantId, entityViewId, "/api/entityView/" + entityViewId);
}
@Test
public void testDeleteEntityViewExceptionWithRelationsTransactional() throws Exception {
EntityViewId entityViewId = getNewSavedEntityView("EntityView for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(entityViewDao, tenantId, entityViewId, "/api/entityView/" + entityViewId);
}
} }

8
application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java

@ -16,7 +16,6 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -30,6 +29,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackage;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -137,7 +137,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE); firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(RandomStringUtils.randomAlphabetic(300)); firmwareInfo.setTitle(StringUtils.randomAlphabetic(300));
firmwareInfo.setVersion(VERSION); firmwareInfo.setVersion(VERSION);
firmwareInfo.setUsesUrl(false); firmwareInfo.setUsesUrl(false);
String msgError = msgErrorFieldLength("title"); String msgError = msgErrorFieldLength("title");
@ -154,7 +154,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
ActionType.ADDED, new DataValidationException(msgError)); ActionType.ADDED, new DataValidationException(msgError));
firmwareInfo.setTitle(TITLE); firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(RandomStringUtils.randomAlphabetic(300)); firmwareInfo.setVersion(StringUtils.randomAlphabetic(300));
msgError = msgErrorFieldLength("version"); msgError = msgErrorFieldLength("version");
doPost("/api/otaPackage", firmwareInfo) doPost("/api/otaPackage", firmwareInfo)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -168,7 +168,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
firmwareInfo.setVersion(VERSION); firmwareInfo.setVersion(VERSION);
firmwareInfo.setUsesUrl(true); firmwareInfo.setUsesUrl(true);
msgError = msgErrorFieldLength("url"); msgError = msgErrorFieldLength("url");
firmwareInfo.setUrl(RandomStringUtils.randomAlphabetic(300)); firmwareInfo.setUrl(StringUtils.randomAlphabetic(300));
doPost("/api/otaPackage", firmwareInfo) doPost("/api/otaPackage", firmwareInfo)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));

29
application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java

@ -16,22 +16,25 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.rule.RuleChainDao;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -47,6 +50,9 @@ public abstract class BaseRuleChainControllerTest extends AbstractControllerTest
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@SpyBean
private RuleChainDao ruleChainDao;
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -70,6 +76,8 @@ public abstract class BaseRuleChainControllerTest extends AbstractControllerTest
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException(ruleChainDao);
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@ -107,7 +115,7 @@ public abstract class BaseRuleChainControllerTest extends AbstractControllerTest
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
RuleChain ruleChain = new RuleChain(); RuleChain ruleChain = new RuleChain();
ruleChain.setName(RandomStringUtils.randomAlphabetic(300)); ruleChain.setName(StringUtils.randomAlphabetic(300));
String msgError = msgErrorFieldLength("name"); String msgError = msgErrorFieldLength("name");
doPost("/api/ruleChain", ruleChain) doPost("/api/ruleChain", ruleChain)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
@ -223,4 +231,21 @@ public abstract class BaseRuleChainControllerTest extends AbstractControllerTest
Assert.assertEquals(1, pageData.getTotalElements()); Assert.assertEquals(1, pageData.getTotalElements());
} }
@Test
public void testDeleteRuleChainWithDeleteRelationsOk() throws Exception {
RuleChainId ruleChainId = createRuleChain("RuleChain for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), ruleChainId, "/api/ruleChain/" + ruleChainId);
}
@Test
public void testDeleteRuleChainExceptionWithRelationsTransactional() throws Exception {
RuleChainId ruleChainId = createRuleChain("RuleChain for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(ruleChainDao, savedTenant.getId(), ruleChainId, "/api/ruleChain/" + ruleChainId);
}
private RuleChain createRuleChain(String name) {
RuleChain ruleChain = new RuleChain();
ruleChain.setName(name);
return doPost("/api/ruleChain", ruleChain, RuleChain.class);
}
} }

4
application/src/test/java/org/thingsboard/server/controller/BaseTbResourceControllerTest.java

@ -16,13 +16,13 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
@ -118,7 +118,7 @@ public abstract class BaseTbResourceControllerTest extends AbstractControllerTes
public void saveResourceInfoWithViolationOfLengthValidation() throws Exception { public void saveResourceInfoWithViolationOfLengthValidation() throws Exception {
TbResource resource = new TbResource(); TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS); resource.setResourceType(ResourceType.JKS);
resource.setTitle(RandomStringUtils.randomAlphabetic(300)); resource.setTitle(StringUtils.randomAlphabetic(300));
resource.setFileName(DEFAULT_FILE_NAME); resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data"); resource.setData("Test Data");

8
application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java

@ -21,7 +21,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -31,6 +30,7 @@ import org.mockito.Mockito;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
@ -120,7 +120,7 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
public void testSaveTenantWithViolationOfValidation() throws Exception { public void testSaveTenantWithViolationOfValidation() throws Exception {
loginSysAdmin(); loginSysAdmin();
Tenant tenant = new Tenant(); Tenant tenant = new Tenant();
tenant.setTitle(RandomStringUtils.randomAlphanumeric(300)); tenant.setTitle(StringUtils.randomAlphanumeric(300));
Mockito.reset(tbClusterService); Mockito.reset(tbClusterService);
@ -259,7 +259,7 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
List<ListenableFuture<Tenant>> createFutures = new ArrayList<>(134); List<ListenableFuture<Tenant>> createFutures = new ArrayList<>(134);
for (int i = 0; i < 134; i++) { for (int i = 0; i < 134; i++) {
Tenant tenant = new Tenant(); Tenant tenant = new Tenant();
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String title = title1 + suffix; String title = title1 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
tenant.setTitle(title); tenant.setTitle(title);
@ -274,7 +274,7 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
createFutures = new ArrayList<>(127); createFutures = new ArrayList<>(127);
for (int i = 0; i < 127; i++) { for (int i = 0; i < 127; i++) {
Tenant tenant = new Tenant(); Tenant tenant = new Tenant();
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String title = title2 + suffix; String title = title2 + suffix;
title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase(); title = i % 2 == 0 ? title.toLowerCase() : title.toUpperCase();
tenant.setTitle(title); tenant.setTitle(title);

4
application/src/test/java/org/thingsboard/server/controller/BaseTenantProfileControllerTest.java

@ -16,12 +16,12 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.thingsboard.server.common.data.EntityInfo; import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.TenantProfileId;
@ -84,7 +84,7 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController
Mockito.reset(tbClusterService); Mockito.reset(tbClusterService);
TenantProfile tenantProfile = this.createTenantProfile(RandomStringUtils.randomAlphabetic(300)); TenantProfile tenantProfile = this.createTenantProfile(StringUtils.randomAlphabetic(300));
doPost("/api/tenantProfile", tenantProfile) doPost("/api/tenantProfile", tenantProfile)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgErrorFieldLength("name")))); .andExpect(statusReason(containsString(msgErrorFieldLength("name"))));

53
application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java

@ -18,21 +18,25 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.RandomStringUtils; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.user.UserDao;
import org.thingsboard.server.service.mail.TestMailService; import org.thingsboard.server.service.mail.TestMailService;
import java.util.ArrayList; import java.util.ArrayList;
@ -53,6 +57,16 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
private CustomerId customerNUULId = (CustomerId) createEntityId_NULL_UUID(new Customer()); private CustomerId customerNUULId = (CustomerId) createEntityId_NULL_UUID(new Customer());
@SpyBean
private UserDao userDao;
@After
public void afterTest() throws Exception {
loginSysAdmin();
afterTestEntityDaoRemoveByIdWithException(userDao);
}
@Test @Test
public void testSaveUser() throws Exception { public void testSaveUser() throws Exception {
loginSysAdmin(); loginSysAdmin();
@ -131,7 +145,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
user.setAuthority(Authority.TENANT_ADMIN); user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId); user.setTenantId(tenantId);
user.setEmail(email); user.setEmail(email);
user.setFirstName(RandomStringUtils.randomAlphabetic(300)); user.setFirstName(StringUtils.randomAlphabetic(300));
user.setLastName("Downs"); user.setLastName("Downs");
String msgError = msgErrorFieldLength("first name"); String msgError = msgErrorFieldLength("first name");
doPost("/api/user", user) doPost("/api/user", user)
@ -145,7 +159,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
user.setFirstName("Normal name"); user.setFirstName("Normal name");
msgError = msgErrorFieldLength("last name"); msgError = msgErrorFieldLength("last name");
user.setLastName(RandomStringUtils.randomAlphabetic(300)); user.setLastName(StringUtils.randomAlphabetic(300));
doPost("/api/user", user) doPost("/api/user", user)
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
@ -440,7 +454,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
User user = new User(); User user = new User();
user.setAuthority(Authority.TENANT_ADMIN); user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId); user.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email1 + suffix + "@thingsboard.org"; String email = email1 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email); user.setEmail(email);
@ -454,7 +468,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
User user = new User(); User user = new User();
user.setAuthority(Authority.TENANT_ADMIN); user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId); user.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email2 + suffix + "@thingsboard.org"; String email = email2 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email); user.setEmail(email);
@ -605,7 +619,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
User user = new User(); User user = new User();
user.setAuthority(Authority.CUSTOMER_USER); user.setAuthority(Authority.CUSTOMER_USER);
user.setCustomerId(customerId); user.setCustomerId(customerId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email1 + suffix + "@thingsboard.org"; String email = email1 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email); user.setEmail(email);
@ -619,7 +633,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
User user = new User(); User user = new User();
user.setAuthority(Authority.CUSTOMER_USER); user.setAuthority(Authority.CUSTOMER_USER);
user.setCustomerId(customerId); user.setCustomerId(customerId);
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email2 + suffix + "@thingsboard.org"; String email = email2 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email); user.setEmail(email);
@ -688,4 +702,29 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
doDelete("/api/customer/" + customerId.getId().toString()) doDelete("/api/customer/" + customerId.getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@Test
public void testDeleteUserWithDeleteRelationsOk() throws Exception {
UserId userId = createUser().getId();
testEntityDaoWithRelationsOk(tenantId, userId, "/api/user/" + userId);
}
@Test
public void testDeleteUserExceptionWithRelationsTransactional() throws Exception {
UserId userId = createUser().getId();
testEntityDaoWithRelationsTransactionalException(userDao, tenantId, userId, "/api/user/" + userId);
}
private User createUser() throws Exception {
loginSysAdmin();
String email = "tenant2@thingsboard.org";
User user = new User();
user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId);
user.setEmail(email);
user.setFirstName("Joe");
user.setLastName("Downs");
return doPost("/api/user", user, User.class);
}
} }

4
application/src/test/java/org/thingsboard/server/controller/BaseWidgetsBundleControllerTest.java

@ -16,13 +16,13 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -109,7 +109,7 @@ public abstract class BaseWidgetsBundleControllerTest extends AbstractController
@Test @Test
public void testSaveWidgetBundleWithViolationOfLengthValidation() throws Exception { public void testSaveWidgetBundleWithViolationOfLengthValidation() throws Exception {
WidgetsBundle widgetsBundle = new WidgetsBundle(); WidgetsBundle widgetsBundle = new WidgetsBundle();
widgetsBundle.setTitle(RandomStringUtils.randomAlphabetic(300)); widgetsBundle.setTitle(StringUtils.randomAlphabetic(300));
Mockito.reset(tbClusterService); Mockito.reset(tbClusterService);

9
application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java

@ -17,8 +17,6 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jboss.aerogear.security.otp.Totp; import org.jboss.aerogear.security.otp.Totp;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -28,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionStatus; import org.thingsboard.server.common.data.audit.ActionStatus;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
@ -178,7 +177,7 @@ public abstract class TwoFactorAuthTest extends AbstractControllerTest {
logInWithPreVerificationToken(username, password); logInWithPreVerificationToken(username, password);
Stream.generate(() -> RandomStringUtils.randomNumeric(6)) Stream.generate(() -> StringUtils.randomNumeric(6))
.limit(9) .limit(9)
.forEach(incorrectVerificationCode -> { .forEach(incorrectVerificationCode -> {
try { try {
@ -190,11 +189,11 @@ public abstract class TwoFactorAuthTest extends AbstractControllerTest {
} }
}); });
String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + RandomStringUtils.randomNumeric(6)) String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + StringUtils.randomNumeric(6))
.andExpect(status().isUnauthorized())); .andExpect(status().isUnauthorized()));
assertThat(errorMessage).containsIgnoringCase("account was locked due to exceeded 2fa verification attempts"); assertThat(errorMessage).containsIgnoringCase("account was locked due to exceeded 2fa verification attempts");
errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + RandomStringUtils.randomNumeric(6)) errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + StringUtils.randomNumeric(6))
.andExpect(status().isUnauthorized())); .andExpect(status().isUnauthorized()));
assertThat(errorMessage).containsIgnoringCase("user is disabled"); assertThat(errorMessage).containsIgnoringCase("user is disabled");
} }

318
application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java

@ -26,7 +26,6 @@ import com.google.protobuf.AbstractMessage;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite; import com.google.protobuf.MessageLite;
import org.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -44,10 +43,12 @@ import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
@ -56,17 +57,32 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration;
import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration;
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.AlarmCondition; import org.thingsboard.server.common.data.device.profile.AlarmCondition;
import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter;
import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey;
import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType;
import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.AlarmRule;
import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration;
import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration;
import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec;
import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration;
import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@ -77,6 +93,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.DataType;
import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
@ -99,6 +116,9 @@ import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.transport.snmp.SnmpMapping;
import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig;
import org.thingsboard.server.common.data.transport.snmp.config.impl.TelemetryQueryingSnmpCommunicationConfig;
import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
@ -139,9 +159,13 @@ import org.thingsboard.server.gen.edge.v1.UserUpdateMsg;
import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg;
import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.transport.AbstractTransportIntegrationTest;
import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -172,6 +196,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
@Autowired @Autowired
private EdgeEventService edgeEventService; private EdgeEventService edgeEventService;
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
@Autowired @Autowired
private TbClusterService clusterService; private TbClusterService clusterService;
@ -201,12 +228,36 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
installation(); installation();
edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret());
edgeImitator.expectMessageAmount(14); edgeImitator.expectMessageAmount(15);
edgeImitator.connect(); edgeImitator.connect();
requestEdgeRuleChainMetadata();
verifyEdgeConnectionAndInitialData(); verifyEdgeConnectionAndInitialData();
} }
private void requestEdgeRuleChainMetadata() throws Exception {
RuleChainId rootRuleChainId = getEdgeRootRuleChainId();
RuleChainMetadataRequestMsg.Builder builder = RuleChainMetadataRequestMsg.newBuilder()
.setRuleChainIdMSB(rootRuleChainId.getId().getMostSignificantBits())
.setRuleChainIdLSB(rootRuleChainId.getId().getLeastSignificantBits());
testAutoGeneratedCodeByProtobuf(builder);
UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder()
.addRuleChainMetadataRequestMsg(builder.build());
edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build());
}
private RuleChainId getEdgeRootRuleChainId() throws Exception {
List<RuleChain> edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?",
new TypeReference<PageData<RuleChain>>() {}, new PageLink(100)).getData();
for (RuleChain edgeRuleChain : edgeRuleChains) {
if (edgeRuleChain.isRoot()) {
return edgeRuleChain.getId();
}
}
throw new RuntimeException("Root rule chain not found");
}
@After @After
public void afterTest() throws Exception { public void afterTest() throws Exception {
try { try {
@ -222,10 +273,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
private void installation() throws Exception { private void installation() throws Exception {
edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class);
MqttDeviceProfileTransportConfiguration transportConfiguration = new MqttDeviceProfileTransportConfiguration(); thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME,
transportConfiguration.setTransportPayloadTypeConfiguration(new JsonTransportPayloadConfiguration()); createMqttDeviceProfileTransportConfiguration(new JsonTransportPayloadConfiguration(), false));
thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME, transportConfiguration);
extendDeviceProfileData(thermostatDeviceProfile); extendDeviceProfileData(thermostatDeviceProfile);
thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class); thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class);
@ -281,7 +330,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get();
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType());
UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB());
Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); Device device = doGet("/api/device/" + deviceUUID, Device.class);
Assert.assertNotNull(device); Assert.assertNotNull(device);
List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData(); new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData();
@ -295,7 +344,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get();
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB());
DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID, DeviceProfile.class);
Assert.assertNotNull(deviceProfile); Assert.assertNotNull(deviceProfile);
Assert.assertNotNull(deviceProfile.getProfileData()); Assert.assertNotNull(deviceProfile.getProfileData());
Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); Assert.assertNotNull(deviceProfile.getProfileData().getAlarms());
@ -321,7 +370,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get();
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType());
UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB());
RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID, RuleChain.class);
Assert.assertNotNull(ruleChain); Assert.assertNotNull(ruleChain);
List<RuleChain> edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?", 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();
@ -329,6 +378,13 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg);
Optional<RuleChainMetadataUpdateMsg> ruleChainMetadataUpdateOpt = edgeImitator.findMessageByType(RuleChainMetadataUpdateMsg.class);
Assert.assertTrue(ruleChainMetadataUpdateOpt.isPresent());
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = ruleChainMetadataUpdateOpt.get();
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainMetadataUpdateMsg.getMsgType());
Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdMSB());
Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB());
validateAdminSettings(); validateAdminSettings();
} }
@ -408,6 +464,226 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits());
} }
@Test
public void testDeviceProfiles_snmp() throws Exception {
DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("SNMP", createSnmpDeviceProfileTransportConfiguration());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg);
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits());
Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits());
Assert.assertEquals(DeviceTransportType.SNMP.name(), deviceProfileUpdateMsg.getTransportType());
Optional<DeviceProfileData> deviceProfileDataOpt =
dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray());
Assert.assertTrue(deviceProfileDataOpt.isPresent());
DeviceProfileData deviceProfileData = deviceProfileDataOpt.get();
Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof SnmpDeviceProfileTransportConfiguration);
SnmpDeviceProfileTransportConfiguration transportConfiguration =
(SnmpDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration();
Assert.assertEquals(Integer.valueOf(1000), transportConfiguration.getTimeoutMs());
Assert.assertEquals(Integer.valueOf(3), transportConfiguration.getRetries());
Assert.assertFalse(transportConfiguration.getCommunicationConfigs().isEmpty());
SnmpCommunicationConfig communicationConfig = transportConfiguration.getCommunicationConfigs().get(0);
Assert.assertTrue(communicationConfig instanceof TelemetryQueryingSnmpCommunicationConfig);
TelemetryQueryingSnmpCommunicationConfig snmpCommunicationConfig =
(TelemetryQueryingSnmpCommunicationConfig) communicationConfig;
Assert.assertEquals(Long.valueOf(500L), snmpCommunicationConfig.getQueryingFrequencyMs());
Assert.assertFalse(snmpCommunicationConfig.getMappings().isEmpty());
SnmpMapping snmpMapping = snmpCommunicationConfig.getMappings().get(0);
Assert.assertEquals("temperature", snmpMapping.getKey());
Assert.assertEquals("1.3.3.5.6.7.8.9.1", snmpMapping.getOid());
Assert.assertEquals(DataType.DOUBLE, snmpMapping.getDataType());
removeDeviceProfileAndDoBasicAssert(deviceProfile);
}
@Test
public void testDeviceProfiles_lwm2m() throws Exception {
DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("LWM2M", createLwm2mDeviceProfileTransportConfiguration());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg);
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits());
Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits());
Assert.assertEquals(DeviceTransportType.LWM2M.name(), deviceProfileUpdateMsg.getTransportType());
Optional<DeviceProfileData> deviceProfileDataOpt =
dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray());
Assert.assertTrue(deviceProfileDataOpt.isPresent());
DeviceProfileData deviceProfileData = deviceProfileDataOpt.get();
Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof Lwm2mDeviceProfileTransportConfiguration);
Lwm2mDeviceProfileTransportConfiguration transportConfiguration =
(Lwm2mDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration();
OtherConfiguration clientLwM2mSettings = transportConfiguration.getClientLwM2mSettings();
Assert.assertEquals(PowerMode.DRX, clientLwM2mSettings.getPowerMode());
Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getFwUpdateStrategy());
Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getSwUpdateStrategy());
Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getClientOnlyObserveAfterConnect());
Assert.assertTrue(transportConfiguration.isBootstrapServerUpdateEnable());
Assert.assertFalse(transportConfiguration.getBootstrap().isEmpty());
LwM2MBootstrapServerCredential lwM2MBootstrapServerCredential = transportConfiguration.getBootstrap().get(0);
Assert.assertTrue(lwM2MBootstrapServerCredential instanceof NoSecLwM2MBootstrapServerCredential);
NoSecLwM2MBootstrapServerCredential noSecLwM2MBootstrapServerCredential = (NoSecLwM2MBootstrapServerCredential) lwM2MBootstrapServerCredential;
Assert.assertEquals("PUBLIC_KEY", noSecLwM2MBootstrapServerCredential.getServerPublicKey());
Assert.assertEquals(Integer.valueOf(123), noSecLwM2MBootstrapServerCredential.getShortServerId());
Assert.assertTrue(noSecLwM2MBootstrapServerCredential.isBootstrapServerIs());
Assert.assertEquals("localhost", noSecLwM2MBootstrapServerCredential.getHost());
Assert.assertEquals(Integer.valueOf(5687), noSecLwM2MBootstrapServerCredential.getPort());
TelemetryMappingConfiguration observeAttr = transportConfiguration.getObserveAttr();
Assert.assertEquals("batteryLevel", observeAttr.getKeyName().get("/3_1.0/0/9"));
Assert.assertTrue(observeAttr.getObserve().isEmpty());
Assert.assertTrue(observeAttr.getAttribute().isEmpty());
Assert.assertFalse(observeAttr.getTelemetry().isEmpty());
Assert.assertTrue(observeAttr.getTelemetry().contains("/3_1.0/0/9"));
Assert.assertTrue(observeAttr.getAttributeLwm2m().isEmpty());
removeDeviceProfileAndDoBasicAssert(deviceProfile);
}
@Test
public void testDeviceProfiles_coap() throws Exception {
DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("COAP", createCoapDeviceProfileTransportConfiguration());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg);
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits());
Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits());
Assert.assertEquals(DeviceTransportType.COAP.name(), deviceProfileUpdateMsg.getTransportType());
Optional<DeviceProfileData> deviceProfileDataOpt =
dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray());
Assert.assertTrue(deviceProfileDataOpt.isPresent());
DeviceProfileData deviceProfileData = deviceProfileDataOpt.get();
Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof CoapDeviceProfileTransportConfiguration);
CoapDeviceProfileTransportConfiguration transportConfiguration =
(CoapDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration();
PowerSavingConfiguration clientSettings = transportConfiguration.getClientSettings();
Assert.assertEquals(PowerMode.DRX, clientSettings.getPowerMode());
Assert.assertEquals(Long.valueOf(1L), clientSettings.getEdrxCycle());
Assert.assertEquals(Long.valueOf(1L), clientSettings.getPsmActivityTimer());
Assert.assertEquals(Long.valueOf(1L), clientSettings.getPagingTransmissionWindow());
Assert.assertTrue(transportConfiguration.getCoapDeviceTypeConfiguration() instanceof DefaultCoapDeviceTypeConfiguration);
DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration =
(DefaultCoapDeviceTypeConfiguration) transportConfiguration.getCoapDeviceTypeConfiguration();
Assert.assertTrue(coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration() instanceof ProtoTransportPayloadConfiguration);
ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration =
(ProtoTransportPayloadConfiguration) coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration();
Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema());
Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema());
Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcResponseProtoSchema());
Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema());
removeDeviceProfileAndDoBasicAssert(deviceProfile);
}
private DeviceProfile createDeviceProfileAndDoBasicAssert(String deviceProfileName, DeviceProfileTransportConfiguration deviceProfileTransportConfiguration) throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile(deviceProfileName, deviceProfileTransportConfiguration);
extendDeviceProfileData(deviceProfile);
edgeImitator.expectMessageAmount(1);
deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
Assert.assertTrue(edgeImitator.waitForMessages());
return deviceProfile;
}
private void removeDeviceProfileAndDoBasicAssert(DeviceProfile deviceProfile) throws Exception {
edgeImitator.expectMessageAmount(1);
doDelete("/api/deviceProfile/" + deviceProfile.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg);
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits());
Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits());
}
private SnmpDeviceProfileTransportConfiguration createSnmpDeviceProfileTransportConfiguration() {
SnmpDeviceProfileTransportConfiguration transportConfiguration = new SnmpDeviceProfileTransportConfiguration();
List<SnmpCommunicationConfig> communicationConfigs = new ArrayList<>();
TelemetryQueryingSnmpCommunicationConfig communicationConfig = new TelemetryQueryingSnmpCommunicationConfig();
communicationConfig.setQueryingFrequencyMs(500L);
List<SnmpMapping> mappings = new ArrayList<>();
mappings.add(new SnmpMapping("1.3.3.5.6.7.8.9.1", "temperature", DataType.DOUBLE));
communicationConfig.setMappings(mappings);
communicationConfigs.add(communicationConfig);
transportConfiguration.setCommunicationConfigs(communicationConfigs);
transportConfiguration.setTimeoutMs(1000);
transportConfiguration.setRetries(3);
return transportConfiguration;
}
private Lwm2mDeviceProfileTransportConfiguration createLwm2mDeviceProfileTransportConfiguration() {
Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration();
OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(AbstractLwM2MIntegrationTest.CLIENT_LWM2M_SETTINGS, OtherConfiguration.class);
transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings);
transportConfiguration.setBootstrapServerUpdateEnable(true);
TelemetryMappingConfiguration observeAttrConfiguration =
JacksonUtil.fromString(AbstractLwM2MIntegrationTest.OBSERVE_ATTRIBUTES_WITH_PARAMS, TelemetryMappingConfiguration.class);
transportConfiguration.setObserveAttr(observeAttrConfiguration);
List<LwM2MBootstrapServerCredential> bootstrap = new ArrayList<>();
AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential();
bootstrapServerCredential.setServerPublicKey("PUBLIC_KEY");
bootstrapServerCredential.setShortServerId(123);
bootstrapServerCredential.setBootstrapServerIs(true);
bootstrapServerCredential.setHost("localhost");
bootstrapServerCredential.setPort(5687);
bootstrap.add(bootstrapServerCredential);
transportConfiguration.setBootstrap(bootstrap);
return transportConfiguration;
}
private CoapDeviceProfileTransportConfiguration createCoapDeviceProfileTransportConfiguration() {
CoapDeviceProfileTransportConfiguration transportConfiguration = new CoapDeviceProfileTransportConfiguration();
PowerSavingConfiguration clientSettings = new PowerSavingConfiguration();
clientSettings.setPowerMode(PowerMode.DRX);
clientSettings.setEdrxCycle(1L);
clientSettings.setPsmActivityTimer(1L);
clientSettings.setPagingTransmissionWindow(1L);
transportConfiguration.setClientSettings(clientSettings);
DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = new DefaultCoapDeviceTypeConfiguration();
ProtoTransportPayloadConfiguration transportPayloadTypeConfiguration = new ProtoTransportPayloadConfiguration();
transportPayloadTypeConfiguration.setDeviceTelemetryProtoSchema(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA);
transportPayloadTypeConfiguration.setDeviceAttributesProtoSchema(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA);
transportPayloadTypeConfiguration.setDeviceRpcResponseProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA);
transportPayloadTypeConfiguration.setDeviceRpcRequestProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA);
coapDeviceTypeConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration);
transportConfiguration.setCoapDeviceTypeConfiguration(coapDeviceTypeConfiguration);
return transportConfiguration;
}
@Test @Test
public void testDevices() throws Exception { public void testDevices() throws Exception {
// 1 // 1
@ -1233,7 +1509,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
@Test @Test
public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception { public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception {
String deviceOnCloudName = RandomStringUtils.randomAlphanumeric(15); String deviceOnCloudName = StringUtils.randomAlphanumeric(15);
Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default"); Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default");
UUID uuid = Uuids.timeBased(); UUID uuid = Uuids.timeBased();
@ -1878,8 +2154,16 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
Device savedDevice = saveDevice(RandomStringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName()); Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName());
savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId());
DeviceData deviceData = new DeviceData();
deviceData.setConfiguration(new DefaultDeviceConfiguration());
MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration();
transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat");
deviceData.setTransportConfiguration(transportConfiguration);
savedDevice.setDeviceData(deviceData);
savedDevice = doPost("/api/device", savedDevice, Device.class); savedDevice = doPost("/api/device", savedDevice, Device.class);
// wait until device UPDATED event is sent to edge notification service // wait until device UPDATED event is sent to edge notification service
@ -1899,6 +2183,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType());
Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB());
Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB());
Optional<DeviceData> deviceDataOpt =
dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray());
Assert.assertTrue(deviceDataOpt.isPresent());
deviceData = deviceDataOpt.get();
Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration);
MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration =
(MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration();
Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic"));
return savedDevice; return savedDevice;
} }
@ -1942,7 +2234,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE); firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle("Firmware Edge " + RandomStringUtils.randomAlphanumeric(3)); firmwareInfo.setTitle("Firmware Edge " + StringUtils.randomAlphanumeric(3));
firmwareInfo.setVersion("v1.0"); firmwareInfo.setVersion("v1.0");
firmwareInfo.setTag("My firmware #1 v1.0"); firmwareInfo.setTag("My firmware #1 v1.0");
firmwareInfo.setUsesUrl(true); firmwareInfo.setUsesUrl(true);

7
application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java

@ -15,28 +15,23 @@
*/ */
package org.thingsboard.server.service.sms.smpp; package org.thingsboard.server.service.sms.smpp;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.api.Assertions;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.smpp.Session; import org.smpp.Session;
import org.smpp.pdu.SubmitSMResp; import org.smpp.pdu.SubmitSMResp;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration; import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.net.UnknownHostException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;

8
application/src/test/java/org/thingsboard/server/transport/AbstractTransportIntegrationTest.java

@ -33,7 +33,7 @@ public abstract class AbstractTransportIntegrationTest extends AbstractControlle
protected static final AtomicInteger atomicInteger = new AtomicInteger(2); protected static final AtomicInteger atomicInteger = new AtomicInteger(2);
protected static final String DEVICE_TELEMETRY_PROTO_SCHEMA = "syntax =\"proto3\";\n" + public static final String DEVICE_TELEMETRY_PROTO_SCHEMA = "syntax =\"proto3\";\n" +
"\n" + "\n" +
"package test;\n" + "package test;\n" +
"\n" + "\n" +
@ -54,7 +54,7 @@ public abstract class AbstractTransportIntegrationTest extends AbstractControlle
" }\n" + " }\n" +
"}"; "}";
protected static final String DEVICE_ATTRIBUTES_PROTO_SCHEMA = "syntax =\"proto3\";\n" + public static final String DEVICE_ATTRIBUTES_PROTO_SCHEMA = "syntax =\"proto3\";\n" +
"\n" + "\n" +
"package test;\n" + "package test;\n" +
"\n" + "\n" +
@ -75,14 +75,14 @@ public abstract class AbstractTransportIntegrationTest extends AbstractControlle
" }\n" + " }\n" +
"}"; "}";
protected static final String DEVICE_RPC_RESPONSE_PROTO_SCHEMA = "syntax =\"proto3\";\n" + public static final String DEVICE_RPC_RESPONSE_PROTO_SCHEMA = "syntax =\"proto3\";\n" +
"package rpc;\n" + "package rpc;\n" +
"\n" + "\n" +
"message RpcResponseMsg {\n" + "message RpcResponseMsg {\n" +
" optional string payload = 1;\n" + " optional string payload = 1;\n" +
"}"; "}";
protected static final String DEVICE_RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" + public static final String DEVICE_RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" +
"package rpc;\n" + "package rpc;\n" +
"\n" + "\n" +
"message RpcRequestMsg {\n" + "message RpcRequestMsg {\n" +

2
application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java

@ -22,13 +22,13 @@ import com.google.protobuf.DynamicMessage;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.squareup.wire.schema.internal.parser.ProtoFileElement; import com.squareup.wire.schema.internal.parser.ProtoFileElement;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.californium.core.CoapHandler; import org.eclipse.californium.core.CoapHandler;
import org.eclipse.californium.core.CoapObserveRelation; import org.eclipse.californium.core.CoapObserveRelation;
import org.eclipse.californium.core.CoapResponse; import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.CoAP; import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration;
import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration;

4
application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java

@ -144,7 +144,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractControllerTes
" \"attributeLwm2m\": {}\n" + " \"attributeLwm2m\": {}\n" +
" }"; " }";
protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS = public static final String OBSERVE_ATTRIBUTES_WITH_PARAMS =
" {\n" + " {\n" +
" \"keyName\": {\n" + " \"keyName\": {\n" +
@ -159,7 +159,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractControllerTes
" \"attributeLwm2m\": {}\n" + " \"attributeLwm2m\": {}\n" +
" }"; " }";
protected final String CLIENT_LWM2M_SETTINGS = public static final String CLIENT_LWM2M_SETTINGS =
" {\n" + " {\n" +
" \"edrxCycle\": null,\n" + " \"edrxCycle\": null,\n" +
" \"powerMode\": \"DRX\",\n" + " \"powerMode\": \"DRX\",\n" +

7
application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java

@ -17,19 +17,14 @@ package org.thingsboard.server.transport.mqtt;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration;
import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration;

8
application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java

@ -16,12 +16,12 @@
package org.thingsboard.server.transport.mqtt.credentials; package org.thingsboard.server.transport.mqtt.credentials;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.paho.client.mqttv3.MqttSecurityException; import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
@ -102,8 +102,8 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest {
mqttTestClient4.connectAndWait(USER_NAME2, PASSWORD); mqttTestClient4.connectAndWait(USER_NAME2, PASSWORD);
// Also correct. Random clientId and password, but matches access token // Also correct. Random clientId and password, but matches access token
MqttTestClient mqttTestClient5 = new MqttTestClient(RandomStringUtils.randomAlphanumeric(10)); MqttTestClient mqttTestClient5 = new MqttTestClient(StringUtils.randomAlphanumeric(10));
mqttTestClient5.connectAndWait(USER_NAME2, RandomStringUtils.randomAlphanumeric(10)); mqttTestClient5.connectAndWait(USER_NAME2, StringUtils.randomAlphanumeric(10));
testTelemetryIsDelivered(accessTokenDevice, mqttTestClient1); testTelemetryIsDelivered(accessTokenDevice, mqttTestClient1);
testTelemetryIsDelivered(clientIdDevice, mqttTestClient2); testTelemetryIsDelivered(clientIdDevice, mqttTestClient2);
@ -131,7 +131,7 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest {
} }
private void testTelemetryIsDelivered(Device device, MqttTestClient client, boolean ok) throws Exception { private void testTelemetryIsDelivered(Device device, MqttTestClient client, boolean ok) throws Exception {
String randomKey = RandomStringUtils.randomAlphanumeric(10); String randomKey = StringUtils.randomAlphanumeric(10);
List<String> expectedKeys = Arrays.asList(randomKey); List<String> expectedKeys = Arrays.asList(randomKey);
client.publishAndWait(DEVICE_TELEMETRY_TOPIC, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes()); client.publishAndWait(DEVICE_TELEMETRY_TOPIC, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes());

2
application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java

@ -25,12 +25,12 @@ import com.nimbusds.jose.util.StandardCharset;
import com.squareup.wire.schema.internal.parser.ProtoFileElement; import com.squareup.wire.schema.internal.parser.ProtoFileElement;
import io.netty.handler.codec.mqtt.MqttQoS; import io.netty.handler.codec.mqtt.MqttQoS;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;

2
common/actor/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/cache/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java

@ -15,7 +15,7 @@
*/ */
package org.thingsboard.server.cache; package org.thingsboard.server.cache;
import org.apache.commons.lang3.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

2
common/cluster-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/coap-server/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java

@ -27,7 +27,7 @@ import org.eclipse.californium.scandium.dtls.HandshakeException;
import org.eclipse.californium.scandium.dtls.HandshakeResultHandler; import org.eclipse.californium.scandium.dtls.HandshakeResultHandler;
import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier;
import org.eclipse.californium.scandium.util.ServerNames; import org.eclipse.californium.scandium.util.ServerNames;
import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.msg.EncryptionUtil;

2
common/dao-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java

@ -23,7 +23,7 @@ import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBui
import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric;
import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

3
common/dao-api/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java

@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult;
import org.thingsboard.server.common.data.kv.TsKvLatestRemovingResult; import org.thingsboard.server.common.data.kv.TsKvLatestRemovingResult;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
@ -32,6 +33,8 @@ import java.util.List;
*/ */
public interface TimeseriesService { public interface TimeseriesService {
ListenableFuture<List<ReadTsKvQueryResult>> findAllByQueries(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries);
ListenableFuture<List<TsKvEntry>> findAll(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries); ListenableFuture<List<TsKvEntry>> findAll(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries);
ListenableFuture<List<TsKvEntry>> findLatest(TenantId tenantId, EntityId entityId, Collection<String> keys); ListenableFuture<List<TsKvEntry>> findLatest(TenantId tenantId, EntityId entityId, Collection<String> keys);

2
common/data/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>3.4.1-SNAPSHOT</version> <version>3.4.2-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save