Browse Source

merge with master

pull/10977/head
YevhenBondarenko 2 years ago
parent
commit
dfd417b530
  1. 2
      application/src/main/data/json/system/widget_types/unread_notifications.json
  2. 2
      application/src/main/data/json/system/widget_types/update_server_string_attribute.json
  3. 2
      application/src/main/data/json/system/widget_types/update_shared_string_attribute.json
  4. 2
      application/src/main/data/json/system/widget_types/update_string_timeseries.json
  5. 8
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
  6. 2
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  7. 4
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  8. 3
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java
  9. 4
      application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java
  10. 10
      application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
  11. 78
      application/src/main/java/org/thingsboard/server/config/RequestSizeFilter.java
  12. 4
      application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
  13. 4
      application/src/main/java/org/thingsboard/server/config/WebConfig.java
  14. 3
      application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java
  15. 3
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  16. 3
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  17. 5
      application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
  18. 3
      application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
  19. 4
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  20. 2
      application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
  21. 3
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  22. 5
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  23. 5
      application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
  24. 3
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  25. 3
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  26. 3
      application/src/main/java/org/thingsboard/server/controller/EventController.java
  27. 3
      application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java
  28. 2
      application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java
  29. 4
      application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java
  30. 237
      application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java
  31. 2
      application/src/main/java/org/thingsboard/server/controller/TbResourceController.java
  32. 1
      application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java
  33. 1
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  34. 2
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  35. 2
      application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
  36. 10
      application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
  37. 2
      application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java
  38. 2
      application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java
  39. 3
      application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java
  40. 1
      application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java
  41. 1
      application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java
  42. 1
      application/src/main/java/org/thingsboard/server/service/entitiy/tenant/DefaultTbTenantService.java
  43. 3
      application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java
  44. 3
      application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java
  45. 2
      application/src/main/java/org/thingsboard/server/service/entitiy/widgets/type/DefaultWidgetTypeService.java
  46. 4
      application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java
  47. 4
      application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsUnassignTaskProcessor.java
  48. 2
      application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AttributesDeletionTaskProcessor.java
  49. 2
      application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EventsDeletionTaskProcessor.java
  50. 2
      application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java
  51. 6
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  52. 2
      application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java
  53. 5
      application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java
  54. 2
      application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java
  55. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java
  56. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java
  57. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java
  58. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java
  59. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java
  60. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java
  61. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java
  62. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java
  63. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java
  64. 2
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java
  65. 6
      application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java
  66. 1
      application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
  67. 57
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  68. 13
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  69. 8
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java
  70. 17
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java
  71. 4
      application/src/main/java/org/thingsboard/server/service/rpc/TbCoreDeviceRpcService.java
  72. 100
      application/src/main/java/org/thingsboard/server/service/ruleengine/DefaultRuleEngineCallService.java
  73. 31
      application/src/main/java/org/thingsboard/server/service/ruleengine/RuleEngineCallService.java
  74. 6
      application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
  75. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java
  76. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java
  77. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java
  78. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
  79. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java
  80. 4
      application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java
  81. 1
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java
  82. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java
  83. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java
  84. 6
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java
  85. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java
  86. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/GithubOAuth2ClientMapper.java
  87. 5
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java
  88. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java
  89. 6
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java
  90. 6
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java
  91. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetails.java
  92. 3
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetailsSource.java
  93. 6
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java
  94. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java
  95. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java
  96. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java
  97. 2
      application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
  98. 4
      application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
  99. 3
      application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java
  100. 5
      application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java

2
application/src/main/data/json/system/widget_types/unread_notifications.json

@ -17,7 +17,7 @@
"settingsDirective": "tb-unread-notification-widget-settings",
"hasBasicMode": true,
"basicModeDirective": "tb-unread-notification-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0\",\"settings\":{\"cardHtml\":\"<div class='card'>HTML code here</div>\",\"cardCss\":\".card {\\n font-weight: bold;\\n font-size: 32px;\\n color: #999;\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\",\"maxNotificationDisplay\":6,\"showCounter\":true,\"counterValueFont\":{\"family\":\"Roboto\",\"size\":14,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"600\",\"lineHeight\":\"\"},\"counterValueColor\":\"#fff\",\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}},\"enableViewAll\":true,\"enableFilter\":true,\"enableMarkAsRead\":true},\"title\":\"Unread notification\",\"dropShadow\":true,\"configMode\":\"basic\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"#000000\",\"showTitleIcon\":true,\"iconSize\":\"22px\",\"titleIcon\":\"notifications\",\"iconColor\":\"#000000\",\"actions\":{},\"enableFullscreen\":false,\"borderRadius\":\"4px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\"}"
"defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0\",\"settings\":{\"cardHtml\":\"<div class='card'>HTML code here</div>\",\"cardCss\":\".card {\\n font-weight: bold;\\n font-size: 32px;\\n color: #999;\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\",\"maxNotificationDisplay\":6,\"showCounter\":true,\"counterValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"600\",\"lineHeight\":\"\"},\"counterValueColor\":\"#fff\",\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}},\"enableViewAll\":true,\"enableFilter\":true,\"enableMarkAsRead\":true},\"title\":\"Unread notification\",\"dropShadow\":true,\"configMode\":\"basic\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"#000000\",\"showTitleIcon\":true,\"iconSize\":\"22px\",\"titleIcon\":\"notifications\",\"iconColor\":\"#000000\",\"actions\":{},\"enableFullscreen\":false,\"borderRadius\":\"4px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\"}"
},
"tags": null
}

2
application/src/main/data/json/system/widget_types/update_server_string_attribute.json

File diff suppressed because one or more lines are too long

2
application/src/main/data/json/system/widget_types/update_shared_string_attribute.json

File diff suppressed because one or more lines are too long

2
application/src/main/data/json/system/widget_types/update_string_timeseries.json

File diff suppressed because one or more lines are too long

8
application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java

@ -16,9 +16,6 @@
package org.thingsboard.server.actors.device;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorException;
@ -26,10 +23,13 @@ import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponseActorMsg;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
@Slf4j

2
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -74,6 +74,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.DeviceSessionsCacheE
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseReason;
import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
@ -90,7 +91,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCre
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
import org.thingsboard.server.gen.transport.TransportProtos.UplinkNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseReason;
import org.thingsboard.server.service.rpc.RpcSubmitStrategy;
import org.thingsboard.server.service.state.DefaultDeviceStateService;
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;

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

@ -106,10 +106,8 @@ import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider;
import org.thingsboard.server.queue.common.SimpleTbQueueCallback;
import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider;
import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.script.RuleNodeTbelScriptEngine;

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

@ -50,6 +50,9 @@ public abstract class RuleEngineComponentActor<T extends EntityId, P extends Com
}
private void processNotificationRule(ComponentLifecycleEvent event, Throwable e) {
if (processor == null) {
return;
}
systemContext.getNotificationRuleProcessor().process(RuleEngineComponentLifecycleEventTrigger.builder()
.tenantId(tenantId)
.ruleChainId(getRuleChainId())

4
application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java

@ -15,6 +15,8 @@
*/
package org.thingsboard.server.actors.service;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -36,8 +38,6 @@ import org.thingsboard.server.queue.discovery.TbApplicationEventListener;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.queue.util.AfterStartUp;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.config;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
@ -22,18 +26,14 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j

78
application/src/main/java/org/thingsboard/server/config/RequestSizeFilter.java

@ -0,0 +1,78 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.config;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import org.thingsboard.server.common.msg.tools.MaxPayloadSizeExceededException;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import java.io.IOException;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class RequestSizeFilter extends OncePerRequestFilter {
private final List<String> urls = List.of("/api/plugins/rpc/**", "/api/rpc/**");
private final AntPathMatcher pathMatcher = new AntPathMatcher();
private final ThingsboardErrorResponseHandler errorResponseHandler;
@Value("${transport.http.max_payload_size:65536}")
private int maxPayloadSize;
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request.getContentLength() > maxPayloadSize) {
if (log.isDebugEnabled()) {
log.debug("Too large payload size. Url: {}, client ip: {}, content length: {}", request.getRequestURL(),
request.getRemoteAddr(), request.getContentLength());
}
errorResponseHandler.handle(new MaxPayloadSizeExceededException(), response);
return;
}
chain.doFilter(request, response);
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
for (String url : urls) {
if (pathMatcher.match(url, request.getRequestURI())) {
return false;
}
}
return true;
}
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return false;
}
@Override
protected boolean shouldNotFilterErrorDispatch() {
return false;
}
}

4
application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java

@ -124,6 +124,9 @@ public class ThingsboardSecurityConfiguration {
@Autowired
private RateLimitProcessingFilter rateLimitProcessingFilter;
@Autowired
private RequestSizeFilter requestSizeFilter;
@Bean
protected FilterRegistrationBean<ShallowEtagHeaderFilter> buildEtagFilter() throws Exception {
ShallowEtagHeaderFilter etagFilter = new ShallowEtagHeaderFilter();
@ -225,6 +228,7 @@ public class ThingsboardSecurityConfiguration {
.addFilterBefore(buildRestPublicLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildRefreshTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(requestSizeFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class);
if (oauth2Configuration != null) {
http.oauth2Login(login -> login

4
application/src/main/java/org/thingsboard/server/config/WebConfig.java

@ -15,12 +15,12 @@
*/
package org.thingsboard.server.config;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thingsboard.server.utils.MiscUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller

3
application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java

@ -16,11 +16,8 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

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

@ -17,12 +17,9 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

3
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -18,13 +18,10 @@ package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

5
application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java

@ -16,13 +16,10 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -40,8 +37,8 @@ import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService;
import org.thingsboard.server.service.security.model.SecurityUser;

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

@ -16,10 +16,7 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

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

@ -141,6 +141,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.action.EntityActionService;
@ -314,6 +315,9 @@ public abstract class BaseController {
@Autowired
protected ExportableEntitiesService entitiesService;
@Autowired
protected TbServiceInfoProvider serviceInfoProvider;
@Value("${server.log_controller_error_stack_trace}")
@Getter
private boolean logControllerErrorStackTrace;

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

@ -1712,4 +1712,6 @@ public class ControllerConstants {
MARKDOWN_CODE_BLOCK_START +
"[{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}]" +
MARKDOWN_CODE_BLOCK_END ;
protected static final String SECURITY_WRITE_CHECK = " Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).";
}

3
application/src/main/java/org/thingsboard/server/controller/DashboardController.java

@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -51,8 +50,8 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.dashboard.TbDashboardService;
import org.thingsboard.server.service.security.model.SecurityUser;

5
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -21,14 +21,12 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@ -79,7 +77,6 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

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

@ -16,14 +16,11 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -42,8 +39,8 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.device.profile.TbDeviceProfileService;

3
application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java

@ -16,11 +16,8 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

3
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -17,13 +17,10 @@ package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

3
application/src/main/java/org/thingsboard/server/controller/EventController.java

@ -16,12 +16,9 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

3
application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java

@ -16,12 +16,9 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

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

@ -18,7 +18,6 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
@ -52,7 +51,6 @@ import org.thingsboard.server.service.security.permission.Resource;
import java.io.IOException;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_DESCRIPTION;

4
application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java

@ -46,10 +46,10 @@ import org.thingsboard.server.common.data.rpc.Rpc;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.exception.ToErrorResponseEntity;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.service.security.permission.Operation;
import java.util.UUID;
@ -118,6 +118,7 @@ public class RpcV2Controller extends AbstractRpcController {
@ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC request was sent to the device."),
@ApiResponse(responseCode = "400", description = "Invalid structure of the request."),
@ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(responseCode = "413", description = "Request payload is too large"),
@ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."),
})
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -136,6 +137,7 @@ public class RpcV2Controller extends AbstractRpcController {
@ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC response received."),
@ApiResponse(responseCode = "400", description = "Invalid structure of the request."),
@ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(responseCode = "413", description = "Request payload is too large"),
@ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."),
})
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")

237
application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java

@ -0,0 +1,237 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.FutureCallback;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.annotation.Nullable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.exception.ToErrorResponseEntity;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.ruleengine.RuleEngineCallService;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
@RestController
@TbCoreComponent
@RequestMapping(TbUrlConstants.RULE_ENGINE_URL_PREFIX)
@Slf4j
public class RuleEngineController extends BaseController {
public static final int DEFAULT_TIMEOUT = 10000;
private static final String MSG_DESCRIPTION_PREFIX = "Creates the Message with type 'REST_API_REQUEST' and payload taken from the request body. ";
private static final String MSG_DESCRIPTION = "This method allows you to extend the regular platform API with the power of Rule Engine. You may use default and custom rule nodes to handle the message. " +
"The generated message contains two important metadata fields:\n\n" +
" * **'serviceId'** to identify the platform server that received the request;\n" +
" * **'requestUUID'** to identify the request and route possible response from the Rule Engine;\n\n" +
"Use **'rest call reply'** rule node to push the reply from rule engine back as a REST API call response. ";
@Autowired
private RuleEngineCallService ruleEngineCallService;
@Autowired
private AccessValidator accessValidator;
@ApiOperation(value = "Push user message to the rule engine (handleRuleEngineRequest)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses current User Id ( the one which credentials is used to perform the request) as the Rule Engine message originator. " +
MSG_DESCRIPTION +
"The default timeout of the request processing is 10 seconds."
+ "\n\n" + ControllerConstants.SECURITY_WRITE_CHECK)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseBody
public DeferredResult<ResponseEntity> handleRuleEngineRequest(
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
return handleRuleEngineRequest(null, null, null, DEFAULT_TIMEOUT, requestBody);
}
@ApiOperation(value = "Push entity message to the rule engine (handleRuleEngineRequest)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
"The default timeout of the request processing is 10 seconds."
+ "\n\n" + ControllerConstants.SECURITY_WRITE_CHECK)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}", method = RequestMethod.POST)
@ResponseBody
public DeferredResult<ResponseEntity> handleRuleEngineRequest(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("entityId") String entityIdStr,
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
return handleRuleEngineRequest(entityType, entityIdStr, null, DEFAULT_TIMEOUT, requestBody);
}
@ApiOperation(value = "Push entity message with timeout to the rule engine (handleRuleEngineRequest)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
"The platform expects the timeout value in milliseconds."
+ "\n\n" + ControllerConstants.SECURITY_WRITE_CHECK)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}/{timeout}", method = RequestMethod.POST)
@ResponseBody
public DeferredResult<ResponseEntity> handleRuleEngineRequest(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("entityId") String entityIdStr,
@Parameter(description = "Timeout to process the request in milliseconds", required = true)
@PathVariable("timeout") int timeout,
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
return handleRuleEngineRequest(entityType, entityIdStr, null, timeout, requestBody);
}
@ApiOperation(value = "Push entity message with timeout and specified queue to the rule engine (handleRuleEngineRequest)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
"If request sent for Device/Device Profile or Asset/Asset Profile entity, specified queue will be used instead of the queue selected in the device or asset profile. " +
"The platform expects the timeout value in milliseconds."
+ "\n\n" + ControllerConstants.SECURITY_WRITE_CHECK)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}/{queueName}/{timeout}", method = RequestMethod.POST)
@ResponseBody
public DeferredResult<ResponseEntity> handleRuleEngineRequest(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("entityId") String entityIdStr,
@Parameter(description = "Queue name to process the request in the rule engine", required = true)
@PathVariable("queueName") String queueName,
@Parameter(description = "Timeout to process the request in milliseconds", required = true)
@PathVariable("timeout") int timeout,
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
try {
SecurityUser currentUser = getCurrentUser();
EntityId entityId;
if (StringUtils.isEmpty(entityType) || StringUtils.isEmpty(entityIdStr)) {
entityId = currentUser.getId();
} else {
entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
}
//Check that this is a valid JSON
JacksonUtil.toJsonNode(requestBody);
final DeferredResult<ResponseEntity> response = new DeferredResult<>();
accessValidator.validate(currentUser, Operation.WRITE, entityId, new HttpValidationCallback(response, new FutureCallback<DeferredResult<ResponseEntity>>() {
@Override
public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) {
long expTime = System.currentTimeMillis() + timeout;
HashMap<String, String> metaData = new HashMap<>();
UUID requestId = UUID.randomUUID();
metaData.put("serviceId", serviceInfoProvider.getServiceId());
metaData.put("requestUUID", requestId.toString());
metaData.put("expirationTime", Long.toString(expTime));
TbMsg msg = TbMsg.newMsg(queueName, TbMsgType.REST_API_REQUEST, entityId, currentUser.getCustomerId(), new TbMsgMetaData(metaData), requestBody);
ruleEngineCallService.processRestApiCallToRuleEngine(currentUser.getTenantId(), requestId, msg, queueName != null,
reply -> reply(new LocalRequestMetaData(msg, currentUser, result), reply));
}
@Override
public void onFailure(Throwable e) {
ResponseEntity entity;
if (e instanceof ToErrorResponseEntity) {
entity = ((ToErrorResponseEntity) e).toErrorResponseEntity();
} else {
entity = new ResponseEntity(HttpStatus.UNAUTHORIZED);
}
logRuleEngineCall(currentUser, entityId, requestBody, null, e);
response.setResult(entity);
}
}));
return response;
} catch (IllegalArgumentException iae) {
throw new ThingsboardException("Invalid request body", iae, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
}
private void reply(LocalRequestMetaData rpcRequest, TbMsg response) {
DeferredResult<ResponseEntity> responseWriter = rpcRequest.responseWriter();
if (response == null) {
logRuleEngineCall(rpcRequest, null, new TimeoutException("Processing timeout detected!"));
responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT));
} else {
String responseData = response.getData();
if (!StringUtils.isEmpty(responseData)) {
try {
logRuleEngineCall(rpcRequest, response, null);
responseWriter.setResult(new ResponseEntity<>(JacksonUtil.toJsonNode(responseData), HttpStatus.OK));
} catch (IllegalArgumentException e) {
log.debug("Failed to decode device response: {}", responseData, e);
logRuleEngineCall(rpcRequest, response, e);
responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE));
}
} else {
logRuleEngineCall(rpcRequest, response, null);
responseWriter.setResult(new ResponseEntity<>(HttpStatus.OK));
}
}
}
private void logRuleEngineCall(LocalRequestMetaData rpcRequest, TbMsg response, Throwable e) {
logRuleEngineCall(rpcRequest.user(), rpcRequest.request().getOriginator(), rpcRequest.request().getData(), response, e);
}
private void logRuleEngineCall(SecurityUser user, EntityId entityId, String request, TbMsg response, Throwable e) {
auditLogService.logEntityAction(
user.getTenantId(),
user.getCustomerId(),
user.getId(),
user.getName(),
entityId,
null,
ActionType.REST_API_RULE_ENGINE_CALL,
BaseController.toException(e),
request,
response != null ? response.getData() : "");
}
private record LocalRequestMetaData(TbMsg request, SecurityUser user, DeferredResult<ResponseEntity> responseWriter) {}
}

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

@ -17,9 +17,7 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

1
application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java

@ -22,4 +22,5 @@ public class TbUrlConstants {
public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry";
public static final String RPC_V1_URL_PREFIX = "/api/plugins/rpc";
public static final String RPC_V2_URL_PREFIX = "/api/rpc";
public static final String RULE_ENGINE_URL_PREFIX = "/api/rule-engine/";
}

1
application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java

@ -19,7 +19,6 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;

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

@ -36,8 +36,8 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.widgets.bundle.TbWidgetsBundleService;
import org.thingsboard.server.service.security.permission.Operation;

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

@ -39,6 +39,7 @@ import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.NativeWebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.id.CustomerId;
@ -48,7 +49,6 @@ import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.config.WebSocketConfiguration;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.auth.jwt.JwtAuthenticationProvider;
import org.thingsboard.server.service.security.exception.JwtExpiredTokenException;

10
application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java

@ -46,6 +46,7 @@ import org.springframework.web.util.WebUtils;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.msg.tools.MaxPayloadSizeExceededException;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.exception.JwtExpiredTokenException;
@ -146,6 +147,8 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
handleAccessDeniedException(response);
} else if (exception instanceof AuthenticationException) {
handleAuthenticationException((AuthenticationException) exception, response);
} else if (exception instanceof MaxPayloadSizeExceededException) {
handleMaxPayloadSizeExceededException(response, (MaxPayloadSizeExceededException) exception);
} else {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(exception.getMessage(),
@ -184,6 +187,13 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS));
}
private void handleMaxPayloadSizeExceededException(HttpServletResponse response, MaxPayloadSizeExceededException exception) throws IOException {
response.setStatus(HttpStatus.PAYLOAD_TOO_LARGE.value());
JacksonUtil.writeValue(response.getWriter(),
ThingsboardErrorResponse.of(exception.getMessage(),
ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.PAYLOAD_TOO_LARGE));
}
private void handleSubscriptionException(ThingsboardException subscriptionException, HttpServletResponse response) throws IOException {
response.setStatus(HttpStatus.FORBIDDEN.value());
JacksonUtil.writeValue(response.getWriter(),

2
application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.service.component;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -41,7 +42,6 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.component.ComponentDescriptorService;
import jakarta.annotation.PostConstruct;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;

2
application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java

@ -19,9 +19,7 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

3
application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.EntityAlarm;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
@ -194,7 +195,7 @@ public class EdgeEventSourcingListener {
}
break;
case ALARM:
if (entity instanceof AlarmApiCallResult || entity instanceof Alarm) {
if (entity instanceof AlarmApiCallResult || entity instanceof Alarm || entity instanceof EntityAlarm) {
return false;
}
break;

1
application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java

@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
@Service

1
application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java

@ -30,7 +30,6 @@ import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;

1
application/src/main/java/org/thingsboard/server/service/entitiy/tenant/DefaultTbTenantService.java

@ -17,7 +17,6 @@ package org.thingsboard.server.service.entitiy.tenant;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId;

3
application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.service.entitiy.user;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -32,8 +33,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import jakarta.servlet.http.HttpServletRequest;
import static org.thingsboard.server.controller.UserController.ACTIVATE_URL_PATTERN;
@Service

3
application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java

@ -15,13 +15,12 @@
*/
package org.thingsboard.server.service.entitiy.user;
import jakarta.servlet.http.HttpServletRequest;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import jakarta.servlet.http.HttpServletRequest;
public interface TbUserService {
User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, HttpServletRequest request, User user) throws ThingsboardException;

2
application/src/main/java/org/thingsboard/server/service/entitiy/widgets/type/DefaultWidgetTypeService.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.entitiy.widgets.type;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
@ -25,7 +24,6 @@ import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;

4
application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java

@ -17,11 +17,11 @@ package org.thingsboard.server.service.executors;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.Getter;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.concurrent.TimeUnit;
@Component

4
application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsUnassignTaskProcessor.java

@ -18,10 +18,10 @@ package org.thingsboard.server.service.housekeeper.processor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.housekeeper.AlarmsUnassignHousekeeperTask;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType;
import org.thingsboard.server.common.data.housekeeper.AlarmsUnassignHousekeeperTask;
import org.thingsboard.server.service.entitiy.alarm.TbAlarmService;
import java.util.List;

2
application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AttributesDeletionTaskProcessor.java

@ -18,9 +18,9 @@ package org.thingsboard.server.service.housekeeper.processor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTask;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType;
import org.thingsboard.server.dao.attributes.AttributesService;
@Component
@RequiredArgsConstructor

2
application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EventsDeletionTaskProcessor.java

@ -17,9 +17,9 @@ package org.thingsboard.server.service.housekeeper.processor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTask;
import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType;
import org.thingsboard.server.dao.event.EventService;
@Component
@RequiredArgsConstructor

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

@ -24,8 +24,8 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.dao.cassandra.CassandraCluster;
import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry;
import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey;
import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry;
import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository;
import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;

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

@ -19,6 +19,9 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.Futures;
import freemarker.template.Configuration;
import freemarker.template.Template;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -53,9 +56,6 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.Locale;

2
application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java

@ -16,12 +16,12 @@
package org.thingsboard.server.service.mail;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import jakarta.annotation.PostConstruct;
import java.io.IOException;
@Service

5
application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java

@ -23,10 +23,11 @@ import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.StringUtils;
@ -34,8 +35,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mail.MailOauth2Provider;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import java.time.Duration;
import java.time.Instant;
import java.util.Properties;

2
application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java

@ -16,6 +16,7 @@
package org.thingsboard.server.service.notification;
import com.google.common.util.concurrent.ListenableFuture;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -40,7 +41,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.executors.NotificationExecutorService;
import org.thingsboard.server.service.partition.AbstractPartitionBasedService;
import jakarta.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collections;
import java.util.HashSet;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java

@ -22,6 +22,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.NotificationRequestId;
@ -41,7 +42,6 @@ import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.dao.notification.NotificationRequestService;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.notification.NotificationDeduplicationService;
import org.thingsboard.server.service.executors.NotificationExecutorService;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java

@ -22,10 +22,10 @@ import org.thingsboard.server.common.data.alarm.AlarmStatusFilter;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.notification.info.AlarmAssignmentNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig.Action;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger;
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java

@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.alarm.AlarmStatusFilter;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.notification.info.AlarmCommentNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmCommentNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger;
import org.thingsboard.server.dao.entity.EntityService;
import static org.apache.commons.collections4.CollectionUtils.isEmpty;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java

@ -19,9 +19,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.notification.info.ApiUsageLimitNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger;
import org.thingsboard.server.dao.tenant.TenantService;
import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java

@ -23,10 +23,10 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.info.DeviceActivityNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@Service

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java

@ -20,9 +20,9 @@ import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.notification.info.EntityActionNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger;
import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java

@ -20,9 +20,9 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.UpdateMessage;
import org.thingsboard.server.common.data.notification.info.NewPlatformVersionNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger;
@Service
@RequiredArgsConstructor

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java

@ -16,9 +16,9 @@
package org.thingsboard.server.service.notification.rule.trigger;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger;
public interface NotificationRuleTriggerProcessor<T extends NotificationRuleTrigger, C extends NotificationRuleTriggerConfig> {

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java

@ -21,10 +21,10 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.info.RateLimitsNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.config.RateLimitsNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.util.CollectionsUtil;
import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger;
import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.tenant.TenantService;

2
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java

@ -23,10 +23,10 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.notification.info.RuleEngineComponentLifecycleEventNotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.queue.discovery.PartitionService;

6
application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java

@ -16,13 +16,13 @@
package org.thingsboard.server.service.ota;
import com.google.common.util.concurrent.FutureCallback;
import jakarta.annotation.Nullable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.server.common.data.AttributeScope;
import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.AttributeScope;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.ota.OtaPackageUtil;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.ota.OtaPackageService;
@ -52,7 +53,6 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory;
import jakarta.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

1
application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java

@ -62,7 +62,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.subscription.TbAttributeSubscriptionScope;
import java.util.ArrayList;
import java.util.Collection;

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

@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.DataConstants;
@ -35,6 +36,7 @@ import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.AssetId;
@ -45,6 +47,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
@ -188,6 +191,14 @@ public class DefaultTbClusterService implements TbClusterService {
toCoreNfs.incrementAndGet();
}
@Override
public void pushNotificationToCore(String targetServiceId, TransportProtos.RestApiCallResponseMsgProto responseMsgProto, TbQueueCallback callback) {
TopicPartitionInfo tpi = topicService.getNotificationsTopic(ServiceType.TB_CORE, targetServiceId);
ToCoreNotificationMsg msg = ToCoreNotificationMsg.newBuilder().setRestApiCallResponseMsg(responseMsgProto).build();
producerProvider.getTbCoreNotificationsMsgProducer().send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), callback);
toCoreNfs.incrementAndGet();
}
@Override
public void pushMsgToRuleEngine(TopicPartitionInfo tpi, UUID msgId, ToRuleEngineMsg msg, TbQueueCallback callback) {
log.trace("PUSHING msg: {} to:{}", msg, tpi);
@ -197,6 +208,11 @@ public class DefaultTbClusterService implements TbClusterService {
@Override
public void pushMsgToRuleEngine(TenantId tenantId, EntityId entityId, TbMsg tbMsg, TbQueueCallback callback) {
pushMsgToRuleEngine(tenantId, entityId, tbMsg, false, callback);
}
@Override
public void pushMsgToRuleEngine(TenantId tenantId, EntityId entityId, TbMsg tbMsg, boolean useQueueFromTbMsg, TbQueueCallback callback) {
if (tenantId == null || tenantId.isNullUid()) {
if (entityId.getEntityType().equals(EntityType.TENANT)) {
tenantId = TenantId.fromUUID(entityId.getId());
@ -205,31 +221,56 @@ public class DefaultTbClusterService implements TbClusterService {
return;
}
} else {
HasRuleEngineProfile ruleEngineProfile = getRuleEngineProfileForEntityOrElseNull(tenantId, entityId);
tbMsg = transformMsg(tbMsg, ruleEngineProfile);
HasRuleEngineProfile ruleEngineProfile = getRuleEngineProfileForEntityOrElseNull(tenantId, entityId, tbMsg);
tbMsg = transformMsg(tbMsg, ruleEngineProfile, useQueueFromTbMsg);
}
ruleEngineProducerService.sendToRuleEngine(producerProvider.getRuleEngineMsgProducer(), tenantId, tbMsg, callback);
toRuleEngineMsgs.incrementAndGet();
}
private HasRuleEngineProfile getRuleEngineProfileForEntityOrElseNull(TenantId tenantId, EntityId entityId) {
HasRuleEngineProfile getRuleEngineProfileForEntityOrElseNull(TenantId tenantId, EntityId entityId, TbMsg tbMsg) {
if (entityId.getEntityType().equals(EntityType.DEVICE)) {
return deviceProfileCache.get(tenantId, new DeviceId(entityId.getId()));
if (TbMsgType.ENTITY_DELETED.equals(tbMsg.getInternalType())) {
try {
Device deletedDevice = JacksonUtil.fromString(tbMsg.getData(), Device.class);
if (deletedDevice == null) {
return null;
}
return deviceProfileCache.get(tenantId, deletedDevice.getDeviceProfileId());
} catch (Exception e) {
log.warn("[{}][{}] Failed to deserialize device: {}", tenantId, entityId, tbMsg, e);
return null;
}
} else {
return deviceProfileCache.get(tenantId, new DeviceId(entityId.getId()));
}
} else if (entityId.getEntityType().equals(EntityType.DEVICE_PROFILE)) {
return deviceProfileCache.get(tenantId, new DeviceProfileId(entityId.getId()));
} else if (entityId.getEntityType().equals(EntityType.ASSET)) {
return assetProfileCache.get(tenantId, new AssetId(entityId.getId()));
if (TbMsgType.ENTITY_DELETED.equals(tbMsg.getInternalType())) {
try {
Asset deletedAsset = JacksonUtil.fromString(tbMsg.getData(), Asset.class);
if (deletedAsset == null) {
return null;
}
return assetProfileCache.get(tenantId, deletedAsset.getAssetProfileId());
} catch (Exception e) {
log.warn("[{}][{}] Failed to deserialize asset: {}", tenantId, entityId, tbMsg, e);
return null;
}
} else {
return assetProfileCache.get(tenantId, new AssetId(entityId.getId()));
}
} else if (entityId.getEntityType().equals(EntityType.ASSET_PROFILE)) {
return assetProfileCache.get(tenantId, new AssetProfileId(entityId.getId()));
}
return null;
}
private TbMsg transformMsg(TbMsg tbMsg, HasRuleEngineProfile ruleEngineProfile) {
private TbMsg transformMsg(TbMsg tbMsg, HasRuleEngineProfile ruleEngineProfile, boolean useQueueFromTbMsg) {
if (ruleEngineProfile != null) {
RuleChainId targetRuleChainId = ruleEngineProfile.getDefaultRuleChainId();
String targetQueueName = ruleEngineProfile.getDefaultQueueName();
String targetQueueName = useQueueFromTbMsg ? tbMsg.getQueueName() : ruleEngineProfile.getDefaultQueueName();
boolean isRuleChainTransform = targetRuleChainId != null && !targetRuleChainId.equals(tbMsg.getRuleChainId());
boolean isQueueTransform = targetQueueName != null && !targetQueueName.equals(tbMsg.getQueueName());

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

@ -96,6 +96,7 @@ import org.thingsboard.server.service.queue.processing.AbstractConsumerService;
import org.thingsboard.server.service.queue.processing.IdMsgPair;
import org.thingsboard.server.service.resource.TbImageService;
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
import org.thingsboard.server.service.ruleengine.RuleEngineCallService;
import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService;
import org.thingsboard.server.service.state.DeviceStateService;
import org.thingsboard.server.service.subscription.SubscriptionManagerService;
@ -149,6 +150,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
private final NotificationRuleProcessor notificationRuleProcessor;
private final TbCoreQueueFactory queueFactory;
private final TbImageService imageService;
private final RuleEngineCallService ruleEngineCallService;
private final TbCoreConsumerStats stats;
private MainQueueConsumerManager<TbProtoQueueMsg<ToCoreMsg>, CoreQueueConfig> mainConsumer;
@ -177,7 +179,8 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
JwtSettingsService jwtSettingsService,
NotificationSchedulerService notificationSchedulerService,
NotificationRuleProcessor notificationRuleProcessor,
TbImageService imageService) {
TbImageService imageService,
RuleEngineCallService ruleEngineCallService) {
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, apiUsageStateService, partitionService,
eventPublisher, jwtSettingsService);
this.stateService = stateService;
@ -192,6 +195,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
this.notificationSchedulerService = notificationSchedulerService;
this.notificationRuleProcessor = notificationRuleProcessor;
this.imageService = imageService;
this.ruleEngineCallService = ruleEngineCallService;
this.queueFactory = tbCoreQueueFactory;
}
@ -377,6 +381,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
} else if (toCoreNotification.hasFromDeviceRpcResponse()) {
log.trace("[{}] Forwarding message to RPC service {}", id, toCoreNotification.getFromDeviceRpcResponse());
forwardToCoreRpcService(toCoreNotification.getFromDeviceRpcResponse(), callback);
} else if (toCoreNotification.hasRestApiCallResponseMsg()) {
log.trace("[{}] Forwarding message to RuleEngineCallService service {}", id, toCoreNotification.getRestApiCallResponseMsg());
forwardToRuleEngineCallService(toCoreNotification.getRestApiCallResponseMsg(), callback);
} else if (toCoreNotification.hasComponentLifecycle()) {
handleComponentLifecycleMsg(id, ProtoUtils.fromProto(toCoreNotification.getComponentLifecycle()));
callback.onSuccess();
@ -738,6 +745,10 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
actorContext.getDbCallbackExecutor());
}
void forwardToRuleEngineCallService(TransportProtos.RestApiCallResponseMsgProto restApiCallResponseMsg, TbCallback callback) {
ruleEngineCallService.onQueueMsg(restApiCallResponseMsg, callback);
}
private void throwNotHandled(Object msg, TbCallback callback) {
log.warn("Message not handled: {}", msg);
callback.onFailure(new RuntimeException("Message not handled!"));

8
application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java

@ -16,6 +16,8 @@
package org.thingsboard.server.service.rpc;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -31,17 +33,15 @@ import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

17
application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java

@ -15,6 +15,8 @@
*/
package org.thingsboard.server.service.rpc;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -27,19 +29,18 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rpc.Rpc;
import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.dao.rpc.RpcService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.TbRuleEngineComponent;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -127,6 +128,16 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi
});
}
@Override
public void sendRestApiCallReply(String serviceId, UUID requestId, TbMsg tbMsg) {
TransportProtos.RestApiCallResponseMsgProto msg = TransportProtos.RestApiCallResponseMsgProto.newBuilder()
.setRequestIdMSB(requestId.getMostSignificantBits())
.setRequestIdLSB(requestId.getLeastSignificantBits())
.setResponse(TbMsg.toByteString(tbMsg))
.build();
clusterService.pushNotificationToCore(serviceId, msg, null);
}
@Override
public Rpc findRpcById(TenantId tenantId, RpcId id) {
return rpcService.findById(tenantId, id);

4
application/src/main/java/org/thingsboard/server/service/rpc/TbCoreDeviceRpcService.java

@ -15,10 +15,10 @@
*/
package org.thingsboard.server.service.rpc;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.function.Consumer;

100
application/src/main/java/org/thingsboard/server/service/ruleengine/DefaultRuleEngineCallService.java

@ -0,0 +1,100 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.ruleengine;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@Service
@Slf4j
public class DefaultRuleEngineCallService implements RuleEngineCallService {
private final TbClusterService clusterService;
private ScheduledExecutorService executor;
private final ConcurrentMap<UUID, Consumer<TbMsg>> requests = new ConcurrentHashMap<>();
public DefaultRuleEngineCallService(TbClusterService clusterService) {
this.clusterService = clusterService;
}
@PostConstruct
public void initExecutor() {
executor = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("re-rest-callback"));
}
@PreDestroy
public void shutdownExecutor() {
if (executor != null) {
executor.shutdownNow();
}
}
@Override
public void processRestApiCallToRuleEngine(TenantId tenantId, UUID requestId, TbMsg request, boolean useQueueFromTbMsg, Consumer<TbMsg> responseConsumer) {
log.trace("[{}] Processing REST API call to rule engine: [{}] for entity: [{}]", tenantId, requestId, request.getOriginator());
requests.put(requestId, responseConsumer);
sendRequestToRuleEngine(tenantId, request, useQueueFromTbMsg);
scheduleTimeout(request, requestId, requests);
}
@Override
public void onQueueMsg(TransportProtos.RestApiCallResponseMsgProto restApiCallResponseMsg, TbCallback callback) {
UUID requestId = new UUID(restApiCallResponseMsg.getRequestIdMSB(), restApiCallResponseMsg.getRequestIdLSB());
Consumer<TbMsg> consumer = requests.remove(requestId);
if (consumer != null) {
consumer.accept(TbMsg.fromBytes(null, restApiCallResponseMsg.getResponse().toByteArray(), TbMsgCallback.EMPTY));
} else {
log.trace("[{}] Unknown or stale rest api call response received", requestId);
}
callback.onSuccess();
}
private void sendRequestToRuleEngine(TenantId tenantId, TbMsg msg, boolean useQueueFromTbMsg) {
clusterService.pushMsgToRuleEngine(tenantId, msg.getOriginator(), msg, useQueueFromTbMsg, null);
}
private void scheduleTimeout(TbMsg request, UUID requestId, ConcurrentMap<UUID, Consumer<TbMsg>> requestsMap) {
long expirationTime = Long.parseLong(request.getMetaData().getValue("expirationTime"));
long timeout = Math.max(0, expirationTime - System.currentTimeMillis());
log.trace("[{}] processing the request: [{}]", this.hashCode(), requestId);
executor.schedule(() -> {
Consumer<TbMsg> consumer = requestsMap.remove(requestId);
if (consumer != null) {
log.trace("[{}] request timeout detected: [{}]", this.hashCode(), requestId);
consumer.accept(null);
}
}, timeout, TimeUnit.MILLISECONDS);
}
}

31
application/src/main/java/org/thingsboard/server/service/ruleengine/RuleEngineCallService.java

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.ruleengine;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.UUID;
import java.util.function.Consumer;
public interface RuleEngineCallService {
void processRestApiCallToRuleEngine(TenantId tenantId, UUID requestId, TbMsg request, boolean useQueueFromTbMsg, Consumer<TbMsg> responseConsumer);
void onQueueMsg(TransportProtos.RestApiCallResponseMsgProto restApiCallResponseMsg, TbCallback callback);
}

6
application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java

@ -19,6 +19,9 @@ import com.google.common.base.Function;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import jakarta.annotation.Nullable;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -81,9 +84,6 @@ import org.thingsboard.server.service.security.permission.AccessControlService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import jakarta.annotation.Nullable;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiConsumer;

8
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.service.security.auth.jwt;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,10 +31,6 @@ import org.thingsboard.server.service.security.auth.JwtAuthenticationToken;
import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor;
import org.thingsboard.server.service.security.model.token.RawAccessJwtToken;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {

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

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.service.security.auth.jwt;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
@ -30,10 +34,6 @@ import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.token.RawAccessJwtToken;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j

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

@ -15,12 +15,12 @@
*/
package org.thingsboard.server.service.security.auth.jwt;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

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

@ -15,13 +15,12 @@
*/
package org.thingsboard.server.service.security.auth.jwt.extractor;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import jakarta.servlet.http.HttpServletRequest;
@Component(value="jwtHeaderTokenExtractor")
public class JwtHeaderTokenExtractor implements TokenExtractor {
public static final String HEADER_PREFIX = "Bearer ";

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

@ -15,13 +15,12 @@
*/
package org.thingsboard.server.service.security.auth.jwt.extractor;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import jakarta.servlet.http.HttpServletRequest;
@Component(value="jwtQueryTokenExtractor")
public class JwtQueryTokenExtractor implements TokenExtractor {

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

@ -20,19 +20,19 @@ import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.LockedException;
import org.springframework.stereotype.Service;
import org.thingsboard.server.cache.limits.RateLimitService;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.limit.LimitedApi;
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.dao.user.UserService;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.cache.limits.RateLimitService;
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.provider.TwoFaProvider;

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

@ -42,7 +42,6 @@ import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantService;

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

@ -16,6 +16,7 @@
package org.thingsboard.server.service.security.auth.oauth2;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Service;
@ -29,7 +30,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

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

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Service;
@ -24,7 +25,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
@Service(value = "basicOAuth2ClientMapper")

6
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java

@ -17,12 +17,12 @@ package org.thingsboard.server.service.security.auth.oauth2;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;

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

@ -16,6 +16,7 @@
package org.thingsboard.server.service.security.auth.oauth2;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
@ -30,8 +31,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
@Service(value = "customOAuth2ClientMapper")
@Slf4j
@TbCoreComponent

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

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
@ -30,7 +31,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Map;
import java.util.Optional;

5
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java

@ -15,14 +15,13 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.stereotype.Component;
import org.thingsboard.server.queue.util.TbCoreComponent;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
@TbCoreComponent
public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {

3
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java

@ -15,12 +15,11 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.thingsboard.server.common.data.oauth2.OAuth2Registration;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
public interface OAuth2ClientMapper {
SecurityUser getOrCreateUserByClientPrincipal(HttpServletRequest request, OAuth2AuthenticationToken token, String providerAccessToken, OAuth2Registration registration);
}

6
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java

@ -15,6 +15,9 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
@ -27,9 +30,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

6
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java

@ -15,6 +15,9 @@
*/
package org.thingsboard.server.service.security.auth.oauth2;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
@ -38,9 +41,6 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

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

@ -15,11 +15,11 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import ua_parser.Client;
import ua_parser.Parser;
import jakarta.servlet.http.HttpServletRequest;
import java.io.Serializable;
@Data

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

@ -15,9 +15,8 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.AuthenticationDetailsSource;
public class RestAuthenticationDetailsSource implements
AuthenticationDetailsSource<HttpServletRequest, RestAuthenticationDetails> {

6
application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java

@ -15,15 +15,15 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component(value = "defaultAuthenticationFailureHandler")

8
application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@ -30,10 +34,6 @@ import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManage
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

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

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationDetailsSource;
@ -31,10 +35,6 @@ import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.UserPrincipal;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j

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

@ -15,6 +15,10 @@
*/
package org.thingsboard.server.service.security.auth.rest;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
@ -30,10 +34,6 @@ import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException;
import org.thingsboard.server.service.security.model.UserPrincipal;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j

2
application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java

@ -19,8 +19,6 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.DashboardId;

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

@ -18,6 +18,8 @@ package org.thingsboard.server.service.security.system;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
@ -61,8 +63,6 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.utils.MiscUtils;
import ua_parser.Client;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

3
application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.service.security.system;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.AuthenticationException;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
@ -27,8 +28,6 @@ import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettin
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.service.security.model.SecurityUser;
import jakarta.servlet.http.HttpServletRequest;
public interface SystemSecurityService {
SecuritySettings getSecuritySettings();

5
application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java

@ -16,6 +16,8 @@
package org.thingsboard.server.service.sms;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NestedRuntimeException;
import org.springframework.stereotype.Service;
@ -35,9 +37,6 @@ import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
@Service
@Slf4j
public class DefaultSmsService implements SmsService {

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

Loading…
Cancel
Save