Browse Source

Refactoring to support TB-Rule-Engine service

pull/2560/head
Andrii Shvaika 7 years ago
parent
commit
6fe25a2ee2
  1. 26
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 23
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  3. 2
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java
  4. 2
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java
  5. 1
      application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
  6. 5
      application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java
  7. 14
      application/src/main/java/org/thingsboard/server/controller/AdminController.java
  8. 2
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  9. 2
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  10. 2
      application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
  11. 2
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  12. 3
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  13. 2
      application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
  14. 2
      application/src/main/java/org/thingsboard/server/controller/CustomerController.java
  15. 3
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  16. 2
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  17. 4
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  18. 2
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  19. 2
      application/src/main/java/org/thingsboard/server/controller/EventController.java
  20. 3
      application/src/main/java/org/thingsboard/server/controller/RpcController.java
  21. 2
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  22. 2
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  23. 2
      application/src/main/java/org/thingsboard/server/controller/TenantController.java
  24. 2
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  25. 2
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  26. 2
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  27. 3
      application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
  28. 155
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  29. 154
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java
  30. 150
      application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java
  31. 5
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java
  32. 7
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java
  33. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationProvider.java
  34. 1
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java
  35. 1
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java
  36. 13
      application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java
  37. 1
      application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
  38. 2
      application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java
  39. 1
      application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
  40. 1
      application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
  41. 2
      application/src/main/java/org/thingsboard/server/service/session/DefaultDeviceSessionCacheService.java
  42. 18
      application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java
  43. 2
      application/src/main/java/org/thingsboard/server/service/state/DeviceStateService.java
  44. 2
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java
  45. 2
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java
  46. 47
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java
  47. 2
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java
  48. 10
      application/src/main/java/org/thingsboard/server/service/transaction/BaseRuleChainTransactionService.java
  49. 3
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTbCoreToTransportService.java
  50. 2
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  51. 9
      application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java
  52. 2
      application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java
  53. 11
      application/src/main/resources/thingsboard.yml
  54. 2
      common/message/src/main/java/org/thingsboard/server/common/msg/queue/ServiceKey.java
  55. 2
      common/message/src/main/java/org/thingsboard/server/common/msg/queue/TopicPartitionInfo.java
  56. 6
      common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueProvider.java
  57. 6
      common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueProvider.java
  58. 6
      common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueProvider.java
  59. 8
      common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProvider.java
  60. 15
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbCoreComponent.java
  61. 19
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbKafkaQueue.java
  62. 19
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithComponent.java
  63. 22
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithOrCoreComponent.java
  64. 22
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithOrRuleEngineComponent.java
  65. 22
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbRuleEngineComponent.java
  66. 16
      common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
  67. 9
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java
  68. 8
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/session/DeviceAwareSessionContext.java

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

@ -70,7 +70,6 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService;
import org.thingsboard.server.service.executors.SharedEventLoopGroupService;
@ -125,10 +124,6 @@ public class ActorSystemContext {
@Getter
private DataDecodingEncodingService encodingService;
@Autowired
@Getter
private DeviceAuthService deviceAuthService;
@Autowired
@Getter
private DeviceService deviceService;
@ -212,10 +207,6 @@ public class ActorSystemContext {
@Getter
private MailExecutorService mailExecutor;
@Autowired
@Getter
private ClusterRpcCallbackExecutorService clusterRpcCallbackExecutor;
@Autowired
@Getter
private DbCallbackExecutorService dbCallbackExecutor;
@ -232,37 +223,34 @@ public class ActorSystemContext {
@Getter
private MailService mailService;
@Autowired
//TODO: separate context for TbCore and TbRuleEngine
@Autowired(required = false)
@Getter
private DeviceStateService deviceStateService;
@Autowired
@Autowired(required = false)
@Getter
private DeviceSessionCacheService deviceSessionCacheService;
@Lazy
@Autowired
@Autowired(required = false)
@Getter
private TbCoreToTransportService tbCoreToTransportService;
/**
* The following Service will be null if we operate in tb-core mode
*/
@Lazy
@Getter
@Autowired(required = false)
@Getter
private TbRuleEngineDeviceRpcService tbRuleEngineDeviceRpcService;
/**
* The following Service will be null if we operate in tb-rule-engine mode
*/
@Lazy
@Getter
@Autowired(required = false)
@Getter
private TbCoreDeviceRpcService tbCoreDeviceRpcService;
@Lazy
@Autowired
@Autowired(required = false)
@Getter
private RuleChainTransactionService ruleChainTransactionService;

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

@ -212,8 +212,6 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
}
void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) {
//TODO 2.5
boolean reportDeviceActivity = true;
TransportToDeviceActorMsg msg = wrapper.getMsg();
TbMsgCallback callback = wrapper.getCallback();
if (msg.hasSessionEvent()) {
@ -225,37 +223,18 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
if (msg.hasSubscribeToRPC()) {
processSubscriptionCommands(context, msg.getSessionInfo(), msg.getSubscribeToRPC());
}
// if (msg.hasPostAttributes()) {
// handlePostAttributesRequest(context, msg.getSessionInfo(), msg.getPostAttributes());
// reportDeviceActivity = true;
// }
// if (msg.hasPostTelemetry()) {
// handlePostTelemetryRequest(context, msg.getSessionInfo(), msg.getPostTelemetry());
// reportDeviceActivity = true;
// }
if (msg.hasGetAttributes()) {
handleGetAttributesRequest(context, msg.getSessionInfo(), msg.getGetAttributes());
}
if (msg.hasToDeviceRPCCallResponse()) {
processRpcResponses(context, msg.getSessionInfo(), msg.getToDeviceRPCCallResponse());
}
// if (msg.hasToServerRPCCallRequest()) {
// handleClientSideRPCRequest(context, msg.getSessionInfo(), msg.getToServerRPCCallRequest());
// reportDeviceActivity = true;
// }
if (msg.hasSubscriptionInfo()) {
handleSessionActivity(context, msg.getSessionInfo(), msg.getSubscriptionInfo());
}
if (reportDeviceActivity) {
reportLogicalDeviceActivity();
}
callback.onSuccess();
}
private void reportLogicalDeviceActivity() {
systemContext.getDeviceStateService().onDeviceActivity(deviceId);
}
private void reportSessionOpen() {
systemContext.getDeviceStateService().onDeviceConnect(deviceId);
}
@ -469,6 +448,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
if (sessions.size() == 1) {
reportSessionOpen();
}
systemContext.getDeviceStateService().onDeviceActivity(deviceId, System.currentTimeMillis());
dumpSessions();
} else if (msg.getEvent() == SessionEvent.CLOSED) {
log.debug("[{}] Canceling subscriptions for closed session [{}]", deviceId, sessionId);
@ -496,6 +476,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
if (subscriptionInfo.getRpcSubscription()) {
rpcSubscriptions.putIfAbsent(sessionId, sessionMD.getSessionInfo());
}
systemContext.getDeviceStateService().onDeviceActivity(deviceId, subscriptionInfo.getLastActivityTime());
dumpSessions();
}

2
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java

@ -53,7 +53,7 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
processor.onRuleChainToRuleChainMsg((RuleChainToRuleChainMsg) msg);
break;
case PARTITION_CHANGE_MSG:
onClusterEventMsg((PartitionChangeMsg) msg);
processor.onPartitionChangeMsg((PartitionChangeMsg) msg);
break;
case STATS_PERSIST_TICK_MSG:
onStatsPersistTick(id);

2
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java

@ -53,6 +53,8 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa
case STATS_PERSIST_TICK_MSG:
onStatsPersistTick(id);
break;
case PARTITION_CHANGE_MSG:
break;
default:
return false;
}

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

@ -40,6 +40,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.thingsboard.server.dao.audit.AuditLogLevelFilter;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.auth.jwt.JwtAuthenticationProvider;
import org.thingsboard.server.service.security.auth.jwt.JwtTokenAuthenticationProcessingFilter;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenAuthenticationProvider;

5
application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java

@ -32,11 +32,13 @@ import org.springframework.web.socket.server.support.HttpSessionHandshakeInterce
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.controller.plugin.TbWebSocketHandler;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.Map;
@Configuration
@TbMonolithOrCoreComponent
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
@ -62,7 +64,8 @@ public class WebSocketConfiguration implements WebSocketConfigurer {
SecurityUser user = null;
try {
user = getCurrentUser();
} catch (ThingsboardException ex) {}
} catch (ThingsboardException ex) {
}
if (user == null) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return false;

14
application/src/main/java/org/thingsboard/server/controller/AdminController.java

@ -25,23 +25,25 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.UpdateMessage;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.common.data.security.model.SecuritySettings;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import org.thingsboard.server.service.update.UpdateService;
import org.thingsboard.server.common.data.UpdateMessage;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api/admin")
public class AdminController extends BaseController {
@Autowired
private MailService mailService;
@Autowired
private AdminSettingsService adminSettingsService;
@ -65,7 +67,7 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/settings", method = RequestMethod.POST)
@ResponseBody
@ResponseBody
public AdminSettings saveAdminSettings(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
try {
accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
@ -111,8 +113,8 @@ public class AdminController extends BaseController {
accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
adminSettings = checkNotNull(adminSettings);
if (adminSettings.getKey().equals("mail")) {
String email = getCurrentUser().getEmail();
mailService.sendTestMail(adminSettings.getJsonValue(), email);
String email = getCurrentUser().getEmail();
mailService.sendTestMail(adminSettings.getJsonValue(), email);
}
} catch (Exception e) {
throw handleException(e);

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

@ -41,10 +41,12 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class AlarmController extends BaseController {

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

@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -51,6 +52,7 @@ import java.util.List;
import java.util.stream.Collectors;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class AssetController extends BaseController {

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

@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import java.util.Arrays;
import java.util.List;
@ -39,6 +40,7 @@ import java.util.UUID;
import java.util.stream.Collectors;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class AuditLogController extends BaseController {

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

@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
import org.thingsboard.server.common.data.security.model.SecuritySettings;
@ -56,6 +57,7 @@ import java.net.URI;
import java.net.URISyntaxException;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
@Slf4j
public class AuthController extends BaseController {

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

@ -92,6 +92,8 @@ 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.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.queue.util.TbMonolithOrRuleEngineComponent;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.queue.TbClusterService;
import org.thingsboard.server.service.security.model.SecurityUser;
@ -112,6 +114,7 @@ import java.util.UUID;
import static org.thingsboard.server.dao.service.Validator.validateId;
@Slf4j
@TbMonolithOrCoreComponent
public abstract class BaseController {
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";

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

@ -25,12 +25,14 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class ComponentDescriptorController extends BaseController {

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

@ -36,10 +36,12 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class CustomerController extends BaseController {

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

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.controller;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
@ -41,6 +40,7 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -48,6 +48,7 @@ import java.util.HashSet;
import java.util.Set;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class DashboardController extends BaseController {

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

@ -51,6 +51,7 @@ import org.thingsboard.server.dao.device.claim.ClaimResponse;
import org.thingsboard.server.dao.device.claim.ClaimResult;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -62,6 +63,7 @@ import java.util.List;
import java.util.stream.Collectors;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class DeviceController extends BaseController {

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

@ -24,23 +24,23 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.alarm.Alarm;
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.id.UUIDBased;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationInfo;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import java.util.List;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class EntityRelationController extends BaseController {

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

@ -47,6 +47,7 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -64,6 +65,7 @@ import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
* Created by Victor Basanets on 8/28/2017.
*/
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
@Slf4j
public class EntityViewController extends BaseController {

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

@ -31,9 +31,11 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class EventController extends BaseController {

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

@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.FutureCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
@ -43,6 +42,7 @@ import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.rpc.RpcRequest;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.LocalRequestMetaData;
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
@ -60,6 +60,7 @@ import java.util.UUID;
* Created by ashvayka on 22.03.18.
*/
@RestController
@TbMonolithOrCoreComponent
@RequestMapping(TbUrlConstants.RPC_URL_PREFIX)
@Slf4j
public class RpcController extends BaseController {

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

@ -55,6 +55,7 @@ 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.dao.event.EventService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.script.JsInvokeService;
import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.security.permission.Operation;
@ -68,6 +69,7 @@ import java.util.stream.Collectors;
@Slf4j
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class RuleChainController extends BaseController {

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

@ -70,6 +70,7 @@ import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
@ -97,6 +98,7 @@ import java.util.stream.Collectors;
* Created by ashvayka on 22.03.18.
*/
@RestController
@TbMonolithOrCoreComponent
@RequestMapping(TbUrlConstants.TELEMETRY_URL_PREFIX)
@Slf4j
public class TelemetryController extends BaseController {

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

@ -34,11 +34,13 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.install.InstallScripts;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
@Slf4j
public class TenantController extends BaseController {

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

@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal;
@ -55,6 +56,7 @@ import org.thingsboard.server.service.security.permission.Resource;
import javax.servlet.http.HttpServletRequest;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class UserController extends BaseController {

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

@ -31,12 +31,14 @@ import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.List;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class WidgetTypeController extends BaseController {

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

@ -33,12 +33,14 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.List;
@RestController
@TbMonolithOrCoreComponent
@RequestMapping("/api")
public class WidgetsBundleController extends BaseController {

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

@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.msg.tools.TbRateLimits;
import org.thingsboard.server.config.WebSocketConfiguration;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal;
import org.thingsboard.server.service.telemetry.SessionEvent;
@ -52,6 +53,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class TbWebSocketHandler extends TextWebSocketHandler implements TelemetryWebSocketMsgEndpoint {
@ -63,7 +65,6 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
@Value("${server.ws.send_timeout:5000}")
private long sendTimeout;
@Value("${server.ws.limits.max_sessions_per_tenant:0}")
private int maxSessionsPerTenant;
@Value("${server.ws.limits.max_sessions_per_customer:0}")

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

@ -18,26 +18,29 @@ package org.thingsboard.server.service.queue;
import akka.actor.ActorRef;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.gen.transport.TransportProtos.*;
import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionMgrMsgProto;
import org.thingsboard.server.gen.transport.TransportProtos.TbAttributeUpdateProto;
import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseProto;
import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.queue.processing.AbstractConsumerService;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
import org.thingsboard.server.service.state.DeviceStateService;
@ -47,7 +50,6 @@ import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -55,15 +57,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCoreMsg, ToCoreNotificationMsg> implements TbCoreConsumerService {
@Value("${queue.core.poll_interval}")
private long pollDuration;
@ -72,56 +73,33 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
@Value("${queue.core.stats.enabled:false}")
private boolean statsEnabled;
private final ActorSystemContext actorContext;
private final DeviceStateService stateService;
private final TbLocalSubscriptionService localSubscriptionService;
private final SubscriptionManagerService subscriptionManagerService;
private final DataDecodingEncodingService encodingService;
private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> mainConsumer;
private final TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> nfConsumer;
private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
private volatile ExecutorService mainConsumerExecutor;
private volatile ExecutorService notificationsConsumerExecutor;
private volatile boolean stopped = false;
public DefaultTbCoreConsumerService(TbCoreQueueProvider tbCoreQueueProvider, ActorSystemContext actorContext,
DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService,
SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService,
TbCoreDeviceRpcService tbCoreDeviceRpcService) {
this.mainConsumer = tbCoreQueueProvider.getToCoreMsgConsumer();
this.nfConsumer = tbCoreQueueProvider.getToCoreNotificationsMsgConsumer();
this.actorContext = actorContext;
super(actorContext, encodingService,
tbCoreQueueProvider.getToCoreMsgConsumer(), tbCoreQueueProvider.getToCoreNotificationsMsgConsumer());
this.stateService = stateService;
this.localSubscriptionService = localSubscriptionService;
this.subscriptionManagerService = subscriptionManagerService;
this.encodingService = encodingService;
this.tbCoreDeviceRpcService = tbCoreDeviceRpcService;
}
@PostConstruct
public void init() {
this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-consumer"));
this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-notifications-consumer"));
super.init("tb-core-consumer", "tb-core-notifications-consumer");
}
@Override
public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
if (partitionChangeEvent.getServiceKey().getServiceType() == ServiceType.TB_CORE) {
log.info("Subscribing to partitions: {}", partitionChangeEvent.getPartitions());
this.mainConsumer.subscribe(partitionChangeEvent.getPartitions());
}
}
@EventListener(ApplicationReadyEvent.class)
public void onApplicationEvent(ApplicationReadyEvent event) {
log.info("Subscribing to notifications: {}", mainConsumer.getTopic());
this.nfConsumer.subscribe();
launchNotificationsConsumer();
launchMainConsumer();
}
private void launchMainConsumer() {
protected void launchMainConsumer() {
log.info("Launching main consumer");
mainConsumerExecutor.execute(() -> {
while (!stopped) {
try {
@ -134,6 +112,7 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> failedMap = new ConcurrentHashMap<>();
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
pendingMap.forEach((id, msg) -> {
log.info("[{}] Creating main callback for message: {}", id, msg.getValue());
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
try {
ToCoreMsg toCoreMsg = msg.getValue();
@ -177,57 +156,38 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
});
}
private void launchNotificationsConsumer() {
notificationsConsumerExecutor.execute(() -> {
while (!stopped) {
try {
List<TbProtoQueueMsg<ToCoreNotificationMsg>> msgs = nfConsumer.poll(pollDuration);
if (msgs.isEmpty()) {
continue;
}
ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreNotificationMsg>> pendingMap = msgs.stream().collect(
Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreNotificationMsg>> failedMap = new ConcurrentHashMap<>();
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
pendingMap.forEach((id, msg) -> {
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
try {
ToCoreNotificationMsg toCoreMsg = msg.getValue();
if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) {
log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg());
forwardToLocalSubMgrService(toCoreMsg.getToLocalSubscriptionServiceMsg(), callback);
} else if (toCoreMsg.hasFromDeviceRpcResponse()) {
log.trace("[{}] Forwarding message to RPC service {}", id, toCoreMsg.getFromDeviceRpcResponse());
forwardToCoreRpcService(toCoreMsg.getFromDeviceRpcResponse(), callback);
} else if (toCoreMsg.getComponentLifecycleMsg() != null && !toCoreMsg.getComponentLifecycleMsg().isEmpty()) {
Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getComponentLifecycleMsg().toByteArray());
if (actorMsg.isPresent()) {
log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
}
callback.onSuccess();
}
} catch (Throwable e) {
log.warn("[{}] Failed to process notification: {}", id, msg, e);
callback.onFailure(e);
}
});
if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process notification: {}", id, msg.getValue()));
failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process notification: {}", id, msg.getValue()));
}
nfConsumer.commit();
} catch (Exception e) {
log.warn("Failed to obtain notifications from queue.", e);
try {
Thread.sleep(pollDuration);
} catch (InterruptedException e2) {
log.trace("Failed to wait until the server has capacity to handle new notifications", e2);
}
}
@Override
protected ServiceType getServiceType() {
return ServiceType.TB_CORE;
}
@Override
protected long getNotificationPollDuration() {
return pollDuration;
}
@Override
protected long getNotificationPackProcessingTimeout() {
return packProcessingTimeout;
}
@Override
protected void handleNotification(UUID id, TbProtoQueueMsg<ToCoreNotificationMsg> msg, TbMsgCallback callback) throws Exception {
ToCoreNotificationMsg toCoreMsg = msg.getValue();
if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) {
log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg());
forwardToLocalSubMgrService(toCoreMsg.getToLocalSubscriptionServiceMsg(), callback);
} else if (toCoreMsg.hasFromDeviceRpcResponse()) {
log.trace("[{}] Forwarding message to RPC service {}", id, toCoreMsg.getFromDeviceRpcResponse());
forwardToCoreRpcService(toCoreMsg.getFromDeviceRpcResponse(), callback);
} else if (toCoreMsg.getComponentLifecycleMsg() != null && !toCoreMsg.getComponentLifecycleMsg().isEmpty()) {
Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getComponentLifecycleMsg().toByteArray());
if (actorMsg.isPresent()) {
log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
}
log.info("Tb Core Notifications Consumer stopped.");
});
callback.onSuccess();
}
}
private void forwardToCoreRpcService(FromDeviceRPCResponseProto proto, TbMsgCallback callback) {
@ -245,23 +205,6 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
}
}
@PreDestroy
public void destroy() {
stopped = true;
if (mainConsumer != null) {
mainConsumer.unsubscribe();
}
if (nfConsumer != null) {
nfConsumer.unsubscribe();
}
if (mainConsumerExecutor != null) {
mainConsumerExecutor.shutdownNow();
}
if (notificationsConsumerExecutor != null) {
notificationsConsumerExecutor.shutdownNow();
}
}
private void forwardToLocalSubMgrService(LocalSubscriptionServiceMsgProto msg, TbMsgCallback callback) {
if (msg.hasSubUpdate()) {
localSubscriptionService.onSubscriptionUpdate(msg.getSubUpdate().getSessionId(), TbSubscriptionUtils.fromProto(msg.getSubUpdate()), callback);

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

@ -19,49 +19,42 @@ import akka.actor.ActorRef;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.transport.TransportProtos.*;
import org.thingsboard.server.queue.provider.TbRuleEngineQueueProvider;
import org.thingsboard.server.queue.util.TbMonolithOrRuleEngineComponent;
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.queue.processing.AbstractConsumerService;
import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingDecision;
import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult;
import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategy;
import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategyFactory;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-rule-engine'")
@TbMonolithOrRuleEngineComponent
@Slf4j
public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerService {
public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<ToRuleEngineMsg, ToRuleEngineNotificationMsg> implements TbRuleEngineConsumerService {
@Value("${queue.rule_engine.poll_interval}")
private long pollDuration;
@ -70,96 +63,24 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
@Value("${queue.rule_engine.stats.enabled:false}")
private boolean statsEnabled;
private final ActorSystemContext actorContext;
private final TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> mainConsumer;
private final TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> nfConsumer;
private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
private final TbRuleEngineProcessingStrategyFactory factory;
private final DataDecodingEncodingService encodingService;
private volatile ExecutorService mainConsumerExecutor;
private volatile ExecutorService notificationsConsumerExecutor;
private volatile boolean stopped = false;
public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbRuleEngineQueueProvider tbRuleEngineQueueProvider, ActorSystemContext actorContext,
DataDecodingEncodingService encodingService) {
public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbRuleEngineQueueProvider tbRuleEngineQueueProvider,
ActorSystemContext actorContext, DataDecodingEncodingService encodingService) {
super(actorContext, encodingService,
tbRuleEngineQueueProvider.getToRuleEngineMsgConsumer(), tbRuleEngineQueueProvider.getToRuleEngineNotificationsMsgConsumer());
this.factory = factory;
this.mainConsumer = tbRuleEngineQueueProvider.getToRuleEngineMsgConsumer();
this.nfConsumer = tbRuleEngineQueueProvider.getToRuleEngineNotificationsMsgConsumer();
this.actorContext = actorContext;
this.encodingService = encodingService;
}
@PostConstruct
public void init() {
this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-rule-engine-consumer"));
this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-rule-engine-notifications-consumer"));
super.init("tb-rule-engine-consumer", "tb-rule-engine-notifications-consumer");
this.factory.newInstance();
}
@Override
public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
if (partitionChangeEvent.getServiceKey().getServiceType() == ServiceType.TB_RULE_ENGINE) {
log.info("Subscribing to partitions: {}", partitionChangeEvent.getPartitions());
this.mainConsumer.subscribe(partitionChangeEvent.getPartitions());
}
}
@EventListener(ApplicationReadyEvent.class)
public void onApplicationEvent(ApplicationReadyEvent event) {
this.nfConsumer.subscribe();
launchNotificationsConsumer();
launchMainConsumer();
}
private void launchNotificationsConsumer() {
notificationsConsumerExecutor.execute(() -> {
while (!stopped) {
try {
List<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> msgs = nfConsumer.poll(pollDuration);
if (msgs.isEmpty()) {
continue;
}
ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineNotificationMsg>> pendingMap = msgs.stream().collect(
Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineNotificationMsg>> failedMap = new ConcurrentHashMap<>();
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
pendingMap.forEach((id, msg) -> {
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
try {
ToRuleEngineNotificationMsg toRuleEngineMsg = msg.getValue();
if (toRuleEngineMsg.getComponentLifecycleMsg() != null && !toRuleEngineMsg.getComponentLifecycleMsg().isEmpty()) {
Optional<TbActorMsg> actorMsg = encodingService.decode(toRuleEngineMsg.getComponentLifecycleMsg().toByteArray());
if (actorMsg.isPresent()) {
log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
}
callback.onSuccess();
} else {
callback.onSuccess();
}
} catch (Throwable e) {
log.warn("[{}] Failed to process message: {}", id, msg, e);
callback.onFailure(e);
}
});
if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process message: {}", id, msg.getValue()));
failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process message: {}", id, msg.getValue()));
}
nfConsumer.commit();
} catch (Exception e) {
log.warn("Failed to process messages from queue.", e);
try {
Thread.sleep(pollDuration);
} catch (InterruptedException e2) {
log.trace("Failed to wait until the server has capacity to handle new requests", e2);
}
}
}
});
}
private void launchMainConsumer() {
protected void launchMainConsumer() {
mainConsumerExecutor.execute(() -> {
while (!stopped) {
try {
@ -184,6 +105,7 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
allMap.forEach((id, msg) -> {
log.info("[{}] Creating main callback for message: {}", id, msg.getValue());
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, allMap, successMap, failedMap);
try {
ToRuleEngineMsg toRuleEngineMsg = msg.getValue();
@ -217,6 +139,36 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
});
}
@Override
protected ServiceType getServiceType() {
return ServiceType.TB_RULE_ENGINE;
}
@Override
protected long getNotificationPollDuration() {
return pollDuration;
}
@Override
protected long getNotificationPackProcessingTimeout() {
return packProcessingTimeout;
}
@Override
protected void handleNotification(UUID id, TbProtoQueueMsg<ToRuleEngineNotificationMsg> msg, TbMsgCallback callback) throws Exception {
ToRuleEngineNotificationMsg nfMsg = msg.getValue();
if (nfMsg.getComponentLifecycleMsg() != null && !nfMsg.getComponentLifecycleMsg().isEmpty()) {
Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray());
if (actorMsg.isPresent()) {
log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
}
callback.onSuccess();
} else {
callback.onSuccess();
}
}
private void forwardToRuleEngineActor(TenantId tenantId, ByteString tbMsgData, TbMsgCallback callback) {
TbMsg tbMsg = TbMsg.fromBytes(tbMsgData.toByteArray(), callback);
actorContext.getAppActor().tell(new QueueToRuleEngineMsg(tenantId, tbMsg), ActorRef.noSender());
@ -233,20 +185,4 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
}
}
@PreDestroy
public void destroy() {
stopped = true;
if (mainConsumer != null) {
mainConsumer.unsubscribe();
}
if (nfConsumer != null) {
nfConsumer.unsubscribe();
}
if (mainConsumerExecutor != null) {
mainConsumerExecutor.shutdownNow();
}
if (notificationsConsumerExecutor != null) {
notificationsConsumerExecutor.shutdownNow();
}
}
}

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

@ -0,0 +1,150 @@
/**
* Copyright © 2016-2020 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.queue.processing;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.queue.MsgPackCallback;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
public abstract class AbstractConsumerService<T extends com.google.protobuf.GeneratedMessageV3, N extends com.google.protobuf.GeneratedMessageV3> implements ApplicationListener<PartitionChangeEvent> {
protected volatile ExecutorService mainConsumerExecutor;
private volatile ExecutorService notificationsConsumerExecutor;
protected volatile boolean stopped = false;
protected final ActorSystemContext actorContext;
protected final DataDecodingEncodingService encodingService;
protected final TbQueueConsumer<TbProtoQueueMsg<T>> mainConsumer;
protected final TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer;
public AbstractConsumerService(ActorSystemContext actorContext, DataDecodingEncodingService encodingService, TbQueueConsumer<TbProtoQueueMsg<T>> mainConsumer, TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer) {
this.actorContext = actorContext;
this.encodingService = encodingService;
this.mainConsumer = mainConsumer;
this.nfConsumer = nfConsumer;
}
public void init(String mainConsumerThreadName, String nfConsumerThreadName) {
this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(mainConsumerThreadName));
this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(nfConsumerThreadName));
}
@Override
public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
if (partitionChangeEvent.getServiceKey().getServiceType() == getServiceType()) {
log.info("Subscribing to partitions: {}", partitionChangeEvent.getPartitions());
this.mainConsumer.subscribe(partitionChangeEvent.getPartitions());
}
}
@EventListener(ApplicationReadyEvent.class)
public void onApplicationEvent(ApplicationReadyEvent event) {
log.info("Subscribing to notifications: {}", nfConsumer.getTopic());
this.nfConsumer.subscribe();
launchNotificationsConsumer();
launchMainConsumer();
}
protected abstract ServiceType getServiceType();
protected abstract void launchMainConsumer();
protected abstract long getNotificationPollDuration();
protected abstract long getNotificationPackProcessingTimeout();
protected void launchNotificationsConsumer() {
notificationsConsumerExecutor.execute(() -> {
while (!stopped) {
try {
List<TbProtoQueueMsg<N>> msgs = nfConsumer.poll(getNotificationPollDuration());
if (msgs.isEmpty()) {
continue;
}
ConcurrentMap<UUID, TbProtoQueueMsg<N>> pendingMap = msgs.stream().collect(
Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
ConcurrentMap<UUID, TbProtoQueueMsg<N>> failedMap = new ConcurrentHashMap<>();
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
pendingMap.forEach((id, msg) -> {
log.info("[{}] Creating notification callback for message: {}", id, msg.getValue());
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
try {
handleNotification(id, msg, callback);
} catch (Throwable e) {
log.warn("[{}] Failed to process notification: {}", id, msg, e);
callback.onFailure(e);
}
});
if (!processingTimeoutLatch.await(getNotificationPackProcessingTimeout(), TimeUnit.MILLISECONDS)) {
pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process notification: {}", id, msg.getValue()));
failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process notification: {}", id, msg.getValue()));
}
nfConsumer.commit();
} catch (Exception e) {
log.warn("Failed to obtain notifications from queue.", e);
try {
Thread.sleep(getNotificationPollDuration());
} catch (InterruptedException e2) {
log.trace("Failed to wait until the server has capacity to handle new notifications", e2);
}
}
}
log.info("Tb Core Notifications Consumer stopped.");
});
}
protected abstract void handleNotification(UUID id, TbProtoQueueMsg<N> msg, TbMsgCallback callback) throws Exception;
@PreDestroy
public void destroy() {
stopped = true;
if (mainConsumer != null) {
mainConsumer.unsubscribe();
}
if (nfConsumer != null) {
nfConsumer.unsubscribe();
}
if (mainConsumerExecutor != null) {
mainConsumerExecutor.shutdownNow();
}
if (notificationsConsumerExecutor != null) {
notificationsConsumerExecutor.shutdownNow();
}
}
}

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

@ -36,6 +36,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.queue.TbClusterService;
import javax.annotation.PostConstruct;
@ -54,7 +55,7 @@ import java.util.function.Consumer;
*/
@Service
@Slf4j
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
@TbMonolithOrCoreComponent
public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
private static final ObjectMapper json = new ObjectMapper();
@ -79,7 +80,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
this.actorContext = actorContext;
}
@Autowired
@Autowired(required = false)
public void setTbRuleEngineRpcService(Optional<TbRuleEngineDeviceRpcService> tbRuleEngineRpcService) {
this.tbRuleEngineRpcService = tbRuleEngineRpcService;
}

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

@ -17,8 +17,6 @@ package org.thingsboard.server.service.rpc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.RpcError;
@ -31,6 +29,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.TbMonolithOrRuleEngineComponent;
import org.thingsboard.server.service.queue.TbClusterService;
import javax.annotation.PostConstruct;
@ -45,7 +44,7 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@Service
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-rule-engine'")
@TbMonolithOrRuleEngineComponent
@Slf4j
public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcService {
@ -67,7 +66,7 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi
this.serviceInfoProvider = serviceInfoProvider;
}
@Autowired
@Autowired(required = false)
public void setTbCoreRpcService(Optional<TbCoreDeviceRpcService> tbCoreRpcService) {
this.tbCoreRpcService = tbCoreRpcService;
}

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

@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal;
import org.thingsboard.server.service.security.system.SystemSecurityService;
@ -46,6 +47,7 @@ import ua_parser.Client;
import java.util.UUID;
@Component
@Slf4j
public class RestAuthenticationProvider implements AuthenticationProvider {

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

@ -20,6 +20,7 @@ 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 org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

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

@ -23,6 +23,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.token.JwtToken;

13
application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java

@ -24,16 +24,21 @@ import org.thingsboard.server.common.transport.auth.DeviceAuthResult;
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultDeviceAuthService implements DeviceAuthService {
@Autowired
DeviceService deviceService;
private final DeviceService deviceService;
@Autowired
DeviceCredentialsService deviceCredentialsService;
private final DeviceCredentialsService deviceCredentialsService;
public DefaultDeviceAuthService(DeviceService deviceService, DeviceCredentialsService deviceCredentialsService) {
this.deviceService = deviceService;
this.deviceCredentialsService = deviceCredentialsService;
}
@Override
public DeviceAuthResult process(DeviceCredentialsFilter credentialsFilter) {

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

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.config.JwtSettings;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal;

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

@ -15,11 +15,9 @@
*/
package org.thingsboard.server.service.security.permission;
import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.service.security.model.SecurityUser;
public interface AccessControlService {

1
application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.*;

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

@ -46,6 +46,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.user.UserServiceImpl;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;
import org.thingsboard.server.common.data.security.model.SecuritySettings;
import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;

2
application/src/main/java/org/thingsboard/server/service/session/DefaultDeviceSessionCacheService.java

@ -21,6 +21,7 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.gen.transport.TransportProtos.DeviceSessionsCacheEntry;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import java.util.Collections;
import java.util.UUID;
@ -31,6 +32,7 @@ import static org.thingsboard.server.common.data.CacheConstants.SESSIONS_CACHE;
* Created by ashvayka on 29.10.18.
*/
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultDeviceSessionCacheService implements DeviceSessionCacheService {

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

@ -60,6 +60,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.annotation.Nullable;
@ -89,6 +90,7 @@ import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE;
* Created by ashvayka on 01.05.18.
*/
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultDeviceStateService implements DeviceStateService {
@ -109,7 +111,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
private final TimeseriesService tsService;
private final TbQueueProducerProvider producerProvider;
private final PartitionService partitionService;
private final TelemetrySubscriptionService tsSubService;
private TelemetrySubscriptionService tsSubService;
@Value("${state.defaultInactivityTimeoutInSec}")
@Getter
@ -137,13 +140,17 @@ public class DefaultDeviceStateService implements DeviceStateService {
public DefaultDeviceStateService(TenantService tenantService, DeviceService deviceService,
AttributesService attributesService, TimeseriesService tsService,
TbQueueProducerProvider producerProvider, PartitionService partitionService, TelemetrySubscriptionService tsSubService) {
TbQueueProducerProvider producerProvider, PartitionService partitionService) {
this.tenantService = tenantService;
this.deviceService = deviceService;
this.attributesService = attributesService;
this.tsService = tsService;
this.producerProvider = producerProvider;
this.partitionService = partitionService;
}
@Autowired
public void setTsSubService(TelemetrySubscriptionService tsSubService) {
this.tsSubService = tsSubService;
}
@ -188,9 +195,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
}
@Override
public void onDeviceActivity(DeviceId deviceId) {
deviceLastReportedActivity.put(deviceId, System.currentTimeMillis());
long lastReportedActivity = deviceLastReportedActivity.getOrDefault(deviceId, 0L);
public void onDeviceActivity(DeviceId deviceId, long lastReportedActivity) {
deviceLastReportedActivity.put(deviceId, lastReportedActivity);
long lastSavedActivity = deviceLastSavedActivity.getOrDefault(deviceId, 0L);
if (lastReportedActivity > 0 && lastReportedActivity > lastSavedActivity) {
DeviceStateData stateData = getOrFetchDeviceStateData(deviceId);
@ -494,7 +500,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
try {
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, stateData.getDeviceId(), stateData.getMetaData().copy(), TbMsgDataType.JSON
, json.writeValueAsString(state)
, null, null, null);
, null, null, TbMsgCallback.EMPTY);
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, stateData.getTenantId(), stateData.getDeviceId());
TransportProtos.ToRuleEngineMsg msg = TransportProtos.ToRuleEngineMsg.newBuilder()
.setTenantIdMSB(stateData.getTenantId().getId().getMostSignificantBits())

2
application/src/main/java/org/thingsboard/server/service/state/DeviceStateService.java

@ -35,7 +35,7 @@ public interface DeviceStateService extends ApplicationListener<PartitionChangeE
void onDeviceConnect(DeviceId deviceId);
void onDeviceActivity(DeviceId deviceId);
void onDeviceActivity(DeviceId deviceId, long lastReportedActivityTime);
void onDeviceDisconnect(DeviceId deviceId);

2
application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java

@ -48,6 +48,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
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.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.queue.TbClusterService;
import org.thingsboard.server.service.state.DefaultDeviceStateService;
import org.thingsboard.server.service.state.DeviceStateService;
@ -70,6 +71,7 @@ import java.util.function.Function;
import java.util.function.Predicate;
@Slf4j
@TbMonolithOrCoreComponent
@Service
public class DefaultSubscriptionManagerService implements SubscriptionManagerService {

2
application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java

@ -37,6 +37,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketService;
import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
@ -52,6 +53,7 @@ import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Slf4j
@TbMonolithOrCoreComponent
@Service
public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionService {

47
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java

@ -51,6 +51,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
@ -66,26 +67,32 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
private final Set<TopicPartitionInfo> currentPartitions = ConcurrentHashMap.newKeySet();
@Autowired
private AttributesService attrService;
@Autowired
private TimeseriesService tsService;
@Autowired
private TbQueueProducerProvider producerProvider;
@Autowired
private PartitionService partitionService;
@Autowired
private SubscriptionManagerService subscriptionManagerService;
private final AttributesService attrService;
private final TimeseriesService tsService;
private final TbQueueProducerProvider producerProvider;
private final PartitionService partitionService;
private Optional<SubscriptionManagerService> subscriptionManagerService;
private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> toCoreProducer;
private ExecutorService tsCallBackExecutor;
private ExecutorService wsCallBackExecutor;
public DefaultTelemetrySubscriptionService(AttributesService attrService,
TimeseriesService tsService,
TbQueueProducerProvider producerProvider,
PartitionService partitionService) {
this.attrService = attrService;
this.tsService = tsService;
this.producerProvider = producerProvider;
this.partitionService = partitionService;
}
@Autowired(required = false)
public void setSubscriptionManagerService(Optional<SubscriptionManagerService> subscriptionManagerService) {
this.subscriptionManagerService = subscriptionManagerService;
}
@PostConstruct
public void initExecutor() {
tsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("ts-service-ts-callback"));
@ -158,7 +165,11 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
private void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) {
subscriptionManagerService.onAttributesUpdate(tenantId, entityId, scope, attributes, TbMsgCallback.EMPTY);
if (subscriptionManagerService.isPresent()) {
subscriptionManagerService.get().onAttributesUpdate(tenantId, entityId, scope, attributes, TbMsgCallback.EMPTY);
} else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!");
}
} else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAttributesUpdateProto(tenantId, entityId, scope, attributes);
toCoreProducer.send(tpi, new TbProtoQueueMsg<>(entityId.getId(), toCoreMsg), null);
@ -168,7 +179,11 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
private void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) {
subscriptionManagerService.onTimeSeriesUpdate(tenantId, entityId, ts, TbMsgCallback.EMPTY);
if (subscriptionManagerService.isPresent()) {
subscriptionManagerService.get().onTimeSeriesUpdate(tenantId, entityId, ts, TbMsgCallback.EMPTY);
} else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!");
}
} else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toTimeseriesUpdateProto(tenantId, entityId, ts);
toCoreProducer.send(tpi, new TbProtoQueueMsg<>(entityId.getId(), toCoreMsg), null);

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

@ -43,6 +43,7 @@ import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.dao.util.TenantRateLimitException;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.ValidationCallback;
import org.thingsboard.server.service.security.ValidationResult;
@ -83,6 +84,7 @@ import java.util.stream.Collectors;
* Created by ashvayka on 27.03.18.
*/
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultTelemetryWebSocketService implements TelemetryWebSocketService {

10
application/src/main/java/org/thingsboard/server/service/transaction/BaseRuleChainTransactionService.java

@ -24,6 +24,8 @@ import org.thingsboard.rule.engine.api.RuleChainTransactionService;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.queue.util.TbMonolithOrRuleEngineComponent;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import javax.annotation.PostConstruct;
@ -44,11 +46,11 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@Service
@TbMonolithOrRuleEngineComponent
@Slf4j
public class BaseRuleChainTransactionService implements RuleChainTransactionService {
@Autowired
private DbCallbackExecutorService callbackExecutor;
private final DbCallbackExecutorService callbackExecutor;
@Value("${actors.rule.transaction.queue_size}")
private int finalQueueSize;
@ -61,6 +63,10 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ
private ExecutorService timeoutExecutor;
public BaseRuleChainTransactionService(DbCallbackExecutorService callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@PostConstruct
public void init() {
timeoutExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("rule-chain-transaction"));

3
application/src/main/java/org/thingsboard/server/service/transport/DefaultTbCoreToTransportService.java

@ -27,6 +27,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos.DeviceActorToTransportMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import java.util.UUID;
import java.util.function.Consumer;
@ -35,7 +36,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
@Slf4j
@Service
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
@TbMonolithOrCoreComponent
public class DefaultTbCoreToTransportService implements TbCoreToTransportService {
private final TbQueueProducer<TbProtoQueueMsg<ToTransportMsg>> tbTransportProducer;

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

@ -41,6 +41,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponse
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.state.DeviceStateService;
@ -52,6 +53,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
@Slf4j
@Service
@TbMonolithOrCoreComponent
public class DefaultTransportApiService implements TransportApiService {
private static final ObjectMapper mapper = new ObjectMapper();

9
application/src/main/java/org/thingsboard/server/service/transport/RemoteTransportApiService.java → application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java

@ -28,6 +28,8 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -38,9 +40,8 @@ import java.util.concurrent.*;
*/
@Slf4j
@Service
//TODO 2.5: This Confitional annotation should be removed, and Service renamed to something meaningful
//@ConditionalOnProperty(prefix = "transport", value = "type", havingValue = "remote")
public class RemoteTransportApiService {
@TbMonolithOrCoreComponent
public class TbCoreTransportApiService {
private final TbCoreQueueProvider tbCoreQueueProvider;
private final TransportApiService transportApiService;
@ -58,7 +59,7 @@ public class RemoteTransportApiService {
private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>,
TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate;
public RemoteTransportApiService(TbCoreQueueProvider tbCoreQueueProvider, TransportApiService transportApiService) {
public TbCoreTransportApiService(TbCoreQueueProvider tbCoreQueueProvider, TransportApiService transportApiService) {
this.tbCoreQueueProvider = tbCoreQueueProvider;
this.transportApiService = transportApiService;
}

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

@ -24,6 +24,7 @@ import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.UpdateMessage;
import org.thingsboard.server.queue.util.TbMonolithOrCoreComponent;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -38,6 +39,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@Service
@TbMonolithOrCoreComponent
@Slf4j
public class DefaultUpdateService implements UpdateService {

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

@ -205,8 +205,6 @@ sql:
# Actor system parameters
actors:
cluster:
grpc_callback_thread_pool_size: "${ACTORS_CLUSTER_GRPC_CALLBACK_THREAD_POOL_SIZE:10}"
tenant:
create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}"
session:
@ -370,7 +368,7 @@ spring:
username: "${SPRING_DATASOURCE_USERNAME:postgres}"
password: "${SPRING_DATASOURCE_PASSWORD:postgres}"
hikari:
maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:50}"
maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:5}"
# Audit log parameters
audit-log:
@ -540,8 +538,6 @@ queue:
response_poll_interval: "${TB_QUEUE_TRANSPORT_RESPONSE_POLL_INTERVAL_MS:25}"
core:
topic: "${TB_QUEUE_CORE_TOPIC:tb.core}"
# For high priority notifications that require minimum latency and processing time
notifications_topic: "${TB_QUEUE_CORE_NOTIFICATIONS_TOPIC:tb.rule-engine.notifications}"
poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack_processing_timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:60000}"
@ -550,8 +546,6 @@ queue:
print_interval_ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"
rule_engine:
topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine}"
# For high priority notifications that require minimum latency and processing time
notifications_topic: "${TB_QUEUE_RULE_ENGINE_NOTIFICATIONS_TOPIC:tb.rule-engine.notifications}"
poll_interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:10}"
pack_processing_timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}"
@ -573,4 +567,5 @@ service:
type: "${TB_SERVICE_TYPE:monolith}" # monolith or tb-core or tb-rule-engine or tb-transport
# Unique id for this service (autogenerated if empty)
id: "${TB_SERVICE_ID:}"
tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id.
tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id.

2
common/message/src/main/java/org/thingsboard/server/common/msg/queue/ServiceKey.java

@ -16,10 +16,12 @@
package org.thingsboard.server.common.msg.queue;
import lombok.Getter;
import lombok.ToString;
import org.thingsboard.server.common.data.id.TenantId;
import java.util.Objects;
@ToString
public class ServiceKey {
@Getter
private final ServiceType serviceType;

2
common/message/src/main/java/org/thingsboard/server/common/msg/queue/TopicPartitionInfo.java

@ -17,11 +17,13 @@ package org.thingsboard.server.common.msg.queue;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import org.thingsboard.server.common.data.id.TenantId;
import java.util.Objects;
import java.util.Optional;
@ToString
public class TopicPartitionInfo {
private final String topic;

6
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueProvider.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.queue.provider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -37,9 +36,12 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
import org.thingsboard.server.queue.kafka.TbKafkaSettings;
import org.thingsboard.server.queue.util.TbKafkaQueue;
import org.thingsboard.server.queue.util.TbMonolithComponent;
@Component
@ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='monolith'")
@TbMonolithComponent
@TbKafkaQueue
public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEngineQueueProvider {
private final PartitionService partitionService;

6
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueProvider.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.queue.provider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -37,9 +36,12 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
import org.thingsboard.server.queue.kafka.TbKafkaSettings;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.queue.util.TbKafkaQueue;
@Component
@ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='tb-core'")
@TbCoreComponent
@TbKafkaQueue
public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
private final PartitionService partitionService;

6
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueProvider.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.queue.provider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -35,9 +34,12 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
import org.thingsboard.server.queue.kafka.TbKafkaSettings;
import org.thingsboard.server.queue.util.TbKafkaQueue;
import org.thingsboard.server.queue.util.TbRuleEngineComponent;
@Component
@ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='tb-rule-engine'")
@TbKafkaQueue
@TbRuleEngineComponent
public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider {
private final PartitionService partitionService;

8
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProvider.java

@ -15,7 +15,7 @@
*/
package org.thingsboard.server.queue.provider;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.*;
import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
@ -50,7 +50,7 @@ public interface TbCoreQueueProvider {
*
* @return
*/
TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer();
TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer();
/**
* Used to push messages to other instances of TB Core Service
@ -64,7 +64,7 @@ public interface TbCoreQueueProvider {
*
* @return
*/
TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer();
TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer();
/**
* Used to consume messages by TB Core Service
@ -78,7 +78,7 @@ public interface TbCoreQueueProvider {
*
* @return
*/
TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer();
TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer();
/**
* Used to consume Transport API Calls

15
application/src/main/java/org/thingsboard/server/service/transport/ToTransportMsgEncoder.java → common/queue/src/main/java/org/thingsboard/server/queue/util/TbCoreComponent.java

@ -13,17 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.transport;
package org.thingsboard.server.queue.util;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
import org.thingsboard.server.queue.kafka.TbKafkaEncoder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
/**
* Created by ashvayka on 05.10.18.
*/
public class ToTransportMsgEncoder implements TbKafkaEncoder<ToTransportMsg> {
@Override
public byte[] encode(ToTransportMsg value) {
return value.toByteArray();
}
@ConditionalOnExpression("'${service.type:null}'=='tb-core'")
public @interface TbCoreComponent {
}

19
application/src/main/java/org/thingsboard/server/service/transport/ToRuleEngineMsgDecoder.java → common/queue/src/main/java/org/thingsboard/server/queue/util/TbKafkaQueue.java

@ -13,21 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.transport;
package org.thingsboard.server.queue.util;
import org.thingsboard.server.queue.TbQueueMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.queue.kafka.TbKafkaDecoder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import java.io.IOException;
/**
* Created by ashvayka on 05.10.18.
*/
public class ToRuleEngineMsgDecoder implements TbKafkaDecoder<ToRuleEngineMsg> {
@Override
public ToRuleEngineMsg decode(TbQueueMsg msg) throws IOException {
return ToRuleEngineMsg.parseFrom(msg.getData());
}
@ConditionalOnExpression("'${queue.type:null}'=='kafka'")
public @interface TbKafkaQueue {
}

19
application/src/main/java/org/thingsboard/server/service/executors/ClusterRpcCallbackExecutorService.java → common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithComponent.java

@ -13,21 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.executors;
package org.thingsboard.server.queue.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.AbstractListeningExecutor;
@Component
public class ClusterRpcCallbackExecutorService extends AbstractListeningExecutor {
@Value("${actors.cluster.grpc_callback_thread_pool_size}")
private int grpcCallbackExecutorThreadPoolSize;
@Override
protected int getThreadPollSize() {
return grpcCallbackExecutorThreadPoolSize;
}
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("'${service.type:null}'=='monolith'")
public @interface TbMonolithComponent {
}

22
common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithOrCoreComponent.java

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.queue.util;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
public @interface TbMonolithOrCoreComponent {
}

22
common/queue/src/main/java/org/thingsboard/server/queue/util/TbMonolithOrRuleEngineComponent.java

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.queue.util;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-rule-engine'")
public @interface TbMonolithOrRuleEngineComponent {
}

22
common/queue/src/main/java/org/thingsboard/server/queue/util/TbRuleEngineComponent.java

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.queue.util;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("'${service.type:null}'=='tb-rule-engine'")
public @interface TbRuleEngineComponent {
}

16
common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java

@ -410,13 +410,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
private void processDisconnect(ChannelHandlerContext ctx) {
ctx.close();
log.info("[{}] Client disconnected!", sessionId);
if (deviceSessionCtx.isConnected()) {
transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.CLOSED), null);
transportService.deregisterSession(sessionInfo);
if (gatewaySessionHandler != null) {
gatewaySessionHandler.onGatewayDisconnect();
}
}
doDisconnect();
}
private MqttConnAckMessage createMqttConnAckMsg(MqttConnectReturnCode returnCode) {
@ -485,9 +479,17 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
doDisconnect();
}
private void doDisconnect() {
if (deviceSessionCtx.isConnected()) {
transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.CLOSED), null);
transportService.deregisterSession(sessionInfo);
if (gatewaySessionHandler != null) {
gatewaySessionHandler.onGatewayDisconnect();
}
deviceSessionCtx.setDisconnected();
}
}

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

@ -45,6 +45,7 @@ import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.provider.TbTransportQueueProvider;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -92,6 +93,7 @@ public class DefaultTransportService implements TransportService {
private final Gson gson = new Gson();
private final TbTransportQueueProvider queueProvider;
private final TbQueueProducerProvider producerProvider;
private final PartitionService partitionService;
protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate;
@ -110,8 +112,9 @@ public class DefaultTransportService implements TransportService {
private ExecutorService mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer"));
private volatile boolean stopped = false;
public DefaultTransportService(TbTransportQueueProvider queueProvider, PartitionService partitionService) {
public DefaultTransportService(TbTransportQueueProvider queueProvider, TbQueueProducerProvider producerProvider, PartitionService partitionService) {
this.queueProvider = queueProvider;
this.producerProvider = producerProvider;
this.partitionService = partitionService;
}
@ -126,8 +129,8 @@ public class DefaultTransportService implements TransportService {
this.transportCallbackExecutor = Executors.newWorkStealingPool(20);
this.schedulerExecutor.scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS);
transportApiRequestTemplate = queueProvider.getTransportApiRequestTemplate();
ruleEngineMsgProducer = queueProvider.getRuleEngineMsgProducer();
tbCoreMsgProducer = queueProvider.getTbCoreMsgProducer();
ruleEngineMsgProducer = producerProvider.getRuleEngineMsgProducer();
tbCoreMsgProducer = producerProvider.getTbCoreMsgProducer();
transportNotificationsConsumer = queueProvider.getTransportNotificationsConsumer();
transportNotificationsConsumer.subscribe();
transportApiRequestTemplate.init();

8
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/session/DeviceAwareSessionContext.java

@ -35,6 +35,7 @@ public abstract class DeviceAwareSessionContext implements SessionContext {
private volatile DeviceId deviceId;
@Getter
private volatile DeviceInfoProto deviceInfo;
private volatile boolean connected;
public DeviceId getDeviceId() {
return deviceId;
@ -42,10 +43,15 @@ public abstract class DeviceAwareSessionContext implements SessionContext {
public void setDeviceInfo(DeviceInfoProto deviceInfo) {
this.deviceInfo = deviceInfo;
this.connected = true;
this.deviceId = new DeviceId(new UUID(deviceInfo.getDeviceIdMSB(), deviceInfo.getDeviceIdLSB()));
}
public boolean isConnected() {
return deviceInfo != null;
return connected;
}
public void setDisconnected() {
this.connected = false;
}
}

Loading…
Cancel
Save