diff --git a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java index 0809afb4b5..3d3bf2bbbb 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java @@ -35,6 +35,7 @@ import org.thingsboard.server.actors.stats.StatsActor; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; import org.thingsboard.server.queue.discovery.TbApplicationEventListener; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; +import org.thingsboard.server.queue.util.AfterStartUp; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -113,8 +114,7 @@ public class DefaultActorService extends TbApplicationEventListener debugPerTenantLimits = actorContext.getDebugPerTenantLimits(); - DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null); - if (debugTbRateLimits != null) { - debugPerTenantLimits.remove(tenantId, debugTbRateLimits); - } - } - - RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); - RuleChainUpdateResult result = ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData); - checkNotNull(result.isSuccess() ? true : null); - - List updatedRuleChains; - if (updateRelated && result.isSuccess()) { - updatedRuleChains = tbRuleChainService.updateRelatedRuleChains(tenantId, ruleChainMetaData.getRuleChainId(), result); - } else { - updatedRuleChains = Collections.emptyList(); - } - - RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); - - if (RuleChainType.CORE.equals(ruleChain.getType())) { - tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); - updatedRuleChains.forEach(updatedRuleChain -> { - tbClusterService.broadcastEntityStateChangeEvent(updatedRuleChain.getTenantId(), updatedRuleChain.getId(), ComponentLifecycleEvent.UPDATED); - }); + TenantId tenantId = getTenantId(); + if (debugPerTenantEnabled) { + ConcurrentMap debugPerTenantLimits = actorContext.getDebugPerTenantLimits(); + DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null); + if (debugTbRateLimits != null) { + debugPerTenantLimits.remove(tenantId, debugTbRateLimits); } - - logEntityAction(ruleChain.getId(), ruleChain, null, ActionType.UPDATED, null, ruleChainMetaData); - for (RuleChain updatedRuleChain : updatedRuleChains) { - RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId())); - logEntityAction(updatedRuleChain.getId(), updatedRuleChain, null, ActionType.UPDATED, null, updatedRuleChainMetaData); - } - - if (RuleChainType.EDGE.equals(ruleChain.getType())) { - sendEntityNotificationMsg(ruleChain.getTenantId(), ruleChain.getId(), EdgeEventActionType.UPDATED); - updatedRuleChains.forEach(updatedRuleChain -> { - sendEntityNotificationMsg(updatedRuleChain.getTenantId(), updatedRuleChain.getId(), EdgeEventActionType.UPDATED); - }); - } - - return savedRuleChainMetaData; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.RULE_CHAIN), null, - null, ActionType.UPDATED, e, ruleChainMetaData); - - throw handleException(e); } - } + RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); + return tbRuleChainService.saveRuleChainMetaData(tenantId, ruleChain, ruleChainMetaData, updateRelated, + getCurrentUser()); + } @ApiOperation(value = "Get Rule Chains (getRuleChains)", notes = "Returns a page of Rule Chains owned by tenant. " + RULE_CHAIN_DESCRIPTION + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH) @@ -454,46 +335,11 @@ public class RuleChainController extends BaseController { @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.DELETE); - - List referencingRuleNodes = ruleChainService.getReferencingRuleChainNodes(getTenantId(), ruleChainId); - - Set referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet()); - List relatedEdgeIds = null; - if (RuleChainType.EDGE.equals(ruleChain.getType())) { - relatedEdgeIds = findRelatedEdgeIds(getTenantId(), ruleChainId); - } - - ruleChainService.deleteRuleChainById(getTenantId(), ruleChainId); - - referencingRuleChainIds.remove(ruleChain.getId()); - - if (RuleChainType.CORE.equals(ruleChain.getType())) { - referencingRuleChainIds.forEach(referencingRuleChainId -> - tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED)); - - tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED); - } - - logEntityAction(ruleChainId, ruleChain, - null, - ActionType.DELETED, null, strRuleChainId); - - if (RuleChainType.EDGE.equals(ruleChain.getType())) { - sendDeleteNotificationMsg(ruleChain.getTenantId(), ruleChain.getId(), relatedEdgeIds); - } - - } catch (Exception e) { - logEntityAction(emptyId(EntityType.RULE_CHAIN), - null, - null, - ActionType.DELETED, e, strRuleChainId); - throw handleException(e); - } - } + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.DELETE); + tbRuleChainService.delete(ruleChain, getCurrentUser()); + } @ApiOperation(value = "Get latest input message (getLatestRuleNodeDebugInput)", notes = "Gets the input message from the debug events for specified Rule Chain Id. " + @@ -679,31 +525,14 @@ public class RuleChainController extends BaseController { @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter("edgeId", strEdgeId); checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); - Edge edge = checkEdgeId(edgeId, Operation.WRITE); - - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - checkRuleChain(ruleChainId, Operation.READ); - - RuleChain savedRuleChain = checkNotNull(ruleChainService.assignRuleChainToEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId)); - - logEntityAction(ruleChainId, savedRuleChain, - null, - ActionType.ASSIGNED_TO_EDGE, null, strRuleChainId, strEdgeId, edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); + Edge edge = checkEdgeId(edgeId, Operation.WRITE); - return savedRuleChain; - } catch (Exception e) { + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.READ); - logEntityAction(emptyId(EntityType.RULE_CHAIN), null, - null, - ActionType.ASSIGNED_TO_EDGE, e, strRuleChainId, strEdgeId); - - throw handleException(e); - } - } + return tbRuleChainService.assignRuleChainToEdge(getTenantId(), ruleChain, edge, getCurrentUser()); + } @ApiOperation(value = "Unassign rule chain from edge (unassignRuleChainFromEdge)", notes = "Clears assignment of the rule chain to the edge. " + @@ -719,30 +548,13 @@ public class RuleChainController extends BaseController { @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter("edgeId", strEdgeId); checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); - Edge edge = checkEdgeId(edgeId, Operation.WRITE); - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.READ); - - RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId, false)); - - logEntityAction(ruleChainId, ruleChain, - null, - ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, strEdgeId, edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); + Edge edge = checkEdgeId(edgeId, Operation.WRITE); + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.READ); - return savedRuleChain; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.RULE_CHAIN), null, - null, - ActionType.UNASSIGNED_FROM_EDGE, e, strRuleChainId, strEdgeId); - - throw handleException(e); - } - } + return tbRuleChainService.unassignRuleChainFromEdge(getTenantId(), ruleChain, edge, getCurrentUser()); + } @ApiOperation(value = "Get Edge Rule Chains (getEdgeRuleChains)", notes = "Returns a page of Rule Chains assigned to the specified edge. " + RULE_CHAIN_DESCRIPTION + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH) @@ -783,18 +595,9 @@ public class RuleChainController extends BaseController { public RuleChain setEdgeTemplateRootRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); - ruleChainService.setEdgeTemplateRootRuleChain(getTenantId(), ruleChainId); - return ruleChain; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.RULE_CHAIN), - null, - null, - ActionType.UPDATED, e, strRuleChainId); - throw handleException(e); - } + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); + return tbRuleChainService.setEdgeTemplateRootRuleChain(getTenantId(), ruleChain, getCurrentUser()); } @ApiOperation(value = "Set Auto Assign To Edge Rule Chain (setAutoAssignToEdgeRuleChain)", @@ -806,19 +609,10 @@ public class RuleChainController extends BaseController { public RuleChain setAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); - ruleChainService.setAutoAssignToEdgeRuleChain(getTenantId(), ruleChainId); - return ruleChain; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.RULE_CHAIN), - null, - null, - ActionType.UPDATED, e, strRuleChainId); - throw handleException(e); - } - } + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); + return tbRuleChainService.setAutoAssignToEdgeRuleChain(getTenantId(), ruleChain, getCurrentUser()); + } @ApiOperation(value = "Unset Auto Assign To Edge Rule Chain (unsetAutoAssignToEdgeRuleChain)", notes = "Removes the rule chain from the list of rule chains that are going to be automatically assigned for any new edge that will be created. " + @@ -829,19 +623,11 @@ public class RuleChainController extends BaseController { public RuleChain unsetAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); - try { - RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); - ruleChainService.unsetAutoAssignToEdgeRuleChain(getTenantId(), ruleChainId); - return ruleChain; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.RULE_CHAIN), - null, - null, - ActionType.UPDATED, e, strRuleChainId); - throw handleException(e); - } - } + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); + + return tbRuleChainService.unsetAutoAssignToEdgeRuleChain(getTenantId(), ruleChain, getCurrentUser()); + } // TODO: @voba refactor this - add new config to edge rule chain to set it as auto-assign @ApiOperation(value = "Get Auto Assign To Edge Rule Chains (getAutoAssignToEdgeRuleChains)", @@ -863,5 +649,4 @@ public class RuleChainController extends BaseController { throw handleException(e); } } - } diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 24373f54a4..120449c137 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpHeaders; @@ -30,10 +31,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.lwm2m.LwM2mObject; @@ -41,6 +40,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.resource.TbResourceService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -68,8 +68,11 @@ import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LI @RestController @TbCoreComponent @RequestMapping("/api") +@RequiredArgsConstructor public class TbResourceController extends BaseController { + private final TbResourceService tbResourceService; + public static final String RESOURCE_ID = "resourceId"; @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @@ -144,20 +147,9 @@ public class TbResourceController extends BaseController { @ResponseBody public TbResource saveResource(@ApiParam(value = "A JSON value representing the Resource.") @RequestBody TbResource resource) throws ThingsboardException { - boolean created = resource.getId() == null; - try { - resource.setTenantId(getTenantId()); - checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); - TbResource savedResource = checkNotNull(resourceService.saveResource(resource)); - tbClusterService.onResourceChange(savedResource, null); - logEntityAction(savedResource.getId(), savedResource, - null, created ? ActionType.ADDED : ActionType.UPDATED, null); - return savedResource; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.TB_RESOURCE), resource, - null, created ? ActionType.ADDED : ActionType.UPDATED, e); - throw handleException(e); - } + resource.setTenantId(getTenantId()); + checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); + return tbResourceService.save(resource, getCurrentUser()); } @ApiOperation(value = "Get Resource Infos (getResources)", @@ -242,16 +234,8 @@ public class TbResourceController extends BaseController { public void deleteResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable("resourceId") String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); - try { - TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); - TbResource tbResource = checkResourceId(resourceId, Operation.DELETE); - resourceService.deleteResource(getTenantId(), resourceId); - tbClusterService.onResourceDeleted(tbResource, null); - logEntityAction(resourceId, tbResource, null, ActionType.DELETED, null, strResourceId); - } catch (Exception e) { - logEntityAction(emptyId(EntityType.TB_RESOURCE), null, null, ActionType.DELETED, e, strResourceId); - throw handleException(e); - } + TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); + TbResource tbResource = checkResourceId(resourceId, Operation.DELETE); + tbResourceService.delete(tbResource, getCurrentUser()); } - } \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 250f5392b5..d6fda64d31 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -33,14 +33,10 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.rule.engine.api.MailService; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; @@ -50,6 +46,7 @@ import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; import org.thingsboard.server.common.data.security.model.JwtToken; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.user.TbUserService; import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository; import org.thingsboard.server.service.security.model.JwtTokenPair; import org.thingsboard.server.service.security.model.SecurityUser; @@ -60,7 +57,6 @@ import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.system.SystemSecurityService; import javax.servlet.http.HttpServletRequest; -import java.util.List; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; @@ -102,6 +98,7 @@ public class UserController extends BaseController { private final RefreshTokenRepository refreshTokenRepository; private final SystemSecurityService systemSecurityService; private final ApplicationEventPublisher eventPublisher; + private final TbUserService tbUserService; @ApiOperation(value = "Get User (getUserById)", notes = "Fetch the User object based on the provided User Id. " + @@ -188,47 +185,12 @@ public class UserController extends BaseController { @RequestBody User user, @ApiParam(value = "Send activation email (or use activation link)", defaultValue = "true") @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { - try { - - if (Authority.TENANT_ADMIN.equals(getCurrentUser().getAuthority())) { - user.setTenantId(getCurrentUser().getTenantId()); - } - - checkEntity(user.getId(), user, Resource.USER); - - boolean sendEmail = user.getId() == null && sendActivationMail; - User savedUser = checkNotNull(userService.saveUser(user)); - if (sendEmail) { - SecurityUser authUser = getCurrentUser(); - UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), savedUser.getId()); - String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request); - String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, - userCredentials.getActivateToken()); - String email = savedUser.getEmail(); - try { - mailService.sendActivationEmail(activateUrl, email); - } catch (ThingsboardException e) { - userService.deleteUser(authUser.getTenantId(), savedUser.getId()); - throw e; - } - } - - logEntityAction(savedUser.getId(), savedUser, - savedUser.getCustomerId(), - user.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); - - sendEntityNotificationMsg(getTenantId(), savedUser.getId(), - user.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); - - return savedUser; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.USER), user, - null, user.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); - - throw handleException(e); + if (Authority.TENANT_ADMIN.equals(getCurrentUser().getAuthority())) { + user.setTenantId(getCurrentUser().getTenantId()); } - } + checkEntity(user.getId(), user, Resource.USER); + return tbUserService.save(getTenantId(), getCurrentUser().getCustomerId(), user, sendActivationMail, request, getCurrentUser()); + } @ApiOperation(value = "Send or re-send the activation email", notes = "Force send the activation email to the user. Useful to resend the email if user has accidentally deleted it. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @@ -298,31 +260,12 @@ public class UserController extends BaseController { @ApiParam(value = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); - try { - UserId userId = new UserId(toUUID(strUserId)); - User user = checkUserId(userId, Operation.DELETE); - - if (user.getAuthority() == Authority.SYS_ADMIN && getCurrentUser().getId().equals(userId)) { - throw new ThingsboardException("Sysadmin is not allowed to delete himself", ThingsboardErrorCode.PERMISSION_DENIED); - } - - List relatedEdgeIds = findRelatedEdgeIds(getTenantId(), userId); - - userService.deleteUser(getCurrentUser().getTenantId(), userId); - - logEntityAction(userId, user, - user.getCustomerId(), - ActionType.DELETED, null, strUserId); - - sendDeleteNotificationMsg(getTenantId(), userId, relatedEdgeIds); - - } catch (Exception e) { - logEntityAction(emptyId(EntityType.USER), - null, - null, - ActionType.DELETED, e, strUserId); - throw handleException(e); + UserId userId = new UserId(toUUID(strUserId)); + User user = checkUserId(userId, Operation.DELETE); + if (user.getAuthority() == Authority.SYS_ADMIN && getCurrentUser().getId().equals(userId)) { + throw new ThingsboardException("Sysadmin is not allowed to delete himself", ThingsboardErrorCode.PERMISSION_DENIED); } + tbUserService.delete(getTenantId(), getCurrentUser().getCustomerId(), user, getCurrentUser()); } @ApiOperation(value = "Get Users (getUsers)", diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 7ec3e2e9aa..4a69b203ed 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -27,7 +28,6 @@ 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.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.widgetsBundle.TbWidgetsBundleService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -57,8 +58,11 @@ import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDL @RestController @TbCoreComponent @RequestMapping("/api") +@RequiredArgsConstructor public class WidgetsBundleController extends BaseController { + private final TbWidgetsBundleService tbWidgetsBundleService; + private static final String WIDGET_BUNDLE_DESCRIPTION = "Widget Bundle represents a group(bundle) of widgets. Widgets are grouped into bundle by type or use case. "; @ApiOperation(value = "Get Widget Bundle (getWidgetsBundleById)", @@ -93,7 +97,7 @@ public class WidgetsBundleController extends BaseController { public WidgetsBundle saveWidgetsBundle( @ApiParam(value = "A JSON value representing the Widget Bundle.", required = true) @RequestBody WidgetsBundle widgetsBundle) throws ThingsboardException { - try { + if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { widgetsBundle.setTenantId(TenantId.SYS_TENANT_ID); } else { @@ -101,15 +105,8 @@ public class WidgetsBundleController extends BaseController { } checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); - WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); - - sendEntityNotificationMsg(getTenantId(), savedWidgetsBundle.getId(), - widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); - return checkNotNull(savedWidgetsBundle); - } catch (Exception e) { - throw handleException(e); - } + return tbWidgetsBundleService.save(widgetsBundle, getCurrentUser()); } @ApiOperation(value = "Delete widgets bundle (deleteWidgetsBundle)", @@ -121,16 +118,9 @@ public class WidgetsBundleController extends BaseController { @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { checkParameter("widgetsBundleId", strWidgetsBundleId); - try { - WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); - checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); - widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); - - sendEntityNotificationMsg(getTenantId(), widgetsBundleId, EdgeEventActionType.DELETED); - - } catch (Exception e) { - throw handleException(e); - } + WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); + WidgetsBundle widgetsBundle = checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); + tbWidgetsBundleService.delete(widgetsBundle, getCurrentUser()); } @ApiOperation(value = "Get Widget Bundles (getWidgetsBundles)", diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 5ed8f588e2..40e15c7b0e 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -220,6 +220,7 @@ public class ThingsboardInstallService { case "3.3.4": log.info("Upgrading ThingsBoard from version 3.3.4 to 3.4.0 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.3.4"); + dataUpdateService.updateData("3.3.4"); log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java index 0d9e6793e8..395ebdeaac 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java @@ -53,15 +53,21 @@ import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TenantService; +import org.thingsboard.server.dao.user.UserService; +import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.edge.EdgeNotificationService; import org.thingsboard.server.service.executors.DbCallbackExecutorService; +import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.ota.OtaPackageStateService; +import org.thingsboard.server.service.resource.TbResourceService; +import org.thingsboard.server.service.rule.TbRuleChainService; import org.thingsboard.server.service.security.permission.AccessControlService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; @@ -111,6 +117,8 @@ public abstract class AbstractTbEntityService { @Autowired protected RuleChainService ruleChainService; @Autowired + protected TbRuleChainService tbRuleChainService; + @Autowired protected EdgeNotificationService edgeNotificationService; @Autowired protected QueueService queueService; @@ -132,6 +140,16 @@ public abstract class AbstractTbEntityService { protected OtaPackageStateService otaPackageStateService; @Autowired protected RelationService relationService; + @Autowired + protected OtaPackageService otaPackageService; + @Autowired + protected InstallScripts installScripts; + @Autowired + protected UserService userService; + @Autowired + protected TbResourceService resourceService; + @Autowired + protected WidgetsBundleService widgetsBundleService; protected ListenableFuture removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) { ListenableFuture> alarmsFuture = diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 3799dc4093..4ec70fd115 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -36,9 +36,12 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; @@ -78,14 +81,29 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } public void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, - CustomerId customerId, ActionType actionType, + CustomerId customerId, List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo) { - logEntityAction(tenantId, originatorId, alarm, customerId, actionType, user, additionalInfo); + logEntityAction(tenantId, originatorId, alarm, customerId, ActionType.DELETED, user, additionalInfo); sendAlarmDeleteNotificationMsg(tenantId, alarm, relatedEdgeIds, body); } + @Override + public void notifyDeleteRuleChain(TenantId tenantId, RuleChain ruleChain, + List relatedEdgeIds, SecurityUser user) { + RuleChainId ruleChainId = ruleChain.getId(); + logEntityAction(tenantId, ruleChainId, ruleChain, null, ActionType.DELETED, user, null, ruleChainId.toString()); + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + sendDeleteNotificationMsg(tenantId, ruleChainId, relatedEdgeIds, null); + } + } + + @Override + public void notifySendMsgToEdgeService(TenantId tenantId, I entityId, EdgeEventActionType edgeEventActionType) { + sendEntityNotificationMsg(tenantId, entityId, edgeEventActionType); + } + @Override public void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, CustomerId customerId, E entity, @@ -104,10 +122,9 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS public void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId, CustomerId customerId, EdgeId edgeId, E entity, ActionType actionType, - EdgeEventActionType edgeActionType, SecurityUser user, Object... additionalInfo) { logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); - sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, entityId, edgeActionType); + sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, entityId, edgeTypeByActionType(actionType)); } @Override @@ -207,10 +224,10 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS @Override public void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId, I entityId, E entity, SecurityUser user, - ActionType actionType, Exception e, + ActionType actionType, boolean sendNotifyMsgToEdge, Exception e, Object... additionalInfo) { notifyEntity(tenantId, entityId, entity, customerId, actionType, user, e, additionalInfo); - if (e == null) { + if (sendNotifyMsgToEdge) { sendEntityNotificationMsg(tenantId, entityId, edgeTypeByActionType(actionType)); } } @@ -333,6 +350,10 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS return EdgeEventActionType.RELATION_ADD_OR_UPDATE; case RELATION_DELETED: return EdgeEventActionType.RELATION_DELETED; + case ASSIGNED_TO_EDGE: + return EdgeEventActionType.ASSIGNED_TO_EDGE; + case UNASSIGNED_FROM_EDGE: + return EdgeEventActionType.UNASSIGNED_FROM_EDGE; default: return null; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 97d9b0ca58..c1131761dc 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.service.security.model.SecurityUser; @@ -50,10 +51,14 @@ public interface TbNotificationEntityService { SecurityUser user, Object... additionalInfo); void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, - CustomerId customerId, ActionType actionType, - List relatedEdgeIds, + CustomerId customerId, List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo); + void notifyDeleteRuleChain(TenantId tenantId, RuleChain ruleChain, + List relatedEdgeIds, SecurityUser user); + + void notifySendMsgToEdgeService(TenantId tenantId, I entityId, EdgeEventActionType edgeEventActionType); + void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, CustomerId customerId, E entity, ActionType actionType, @@ -64,7 +69,6 @@ public interface TbNotificationEntityService { void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId, CustomerId customerId, EdgeId edgeId, E entity, ActionType actionType, - EdgeEventActionType edgeActionType, SecurityUser user, Object... additionalInfo); void notifyCreateOruUpdateTenant(Tenant tenant, ComponentLifecycleEvent event); @@ -91,7 +95,7 @@ public interface TbNotificationEntityService { void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId, I entityId, E entity, SecurityUser user, - ActionType actionType, Exception e, + ActionType actionType, boolean sendNotifyMsgToEdge, Exception e, Object... additionalInfo); void notifyCreateOrUpdateOrDeleteRelation(TenantId tenantId, CustomerId customerId, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index f00bd06de3..4930f54a5d 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -81,7 +81,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb try { List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm, alarm.getOriginator(), user.getCustomerId(), - ActionType.DELETED, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); + relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index 4be68b75f9..492464f147 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -135,7 +135,7 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb try { Asset savedAsset = checkNotNull(assetService.assignAssetToEdge(tenantId, assetId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, savedAsset.getCustomerId(), - edgeId, savedAsset, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, assetId.toString(), edgeId.toString(), edge.getName()); + edgeId, savedAsset, actionType, user, assetId.toString(), edgeId.toString(), edge.getName()); return savedAsset; } catch (Exception e) { @@ -154,7 +154,7 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(tenantId, assetId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, asset.getCustomerId(), - edgeId, asset, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, assetId.toString(), edgeId.toString(), edge.getName()); + edgeId, asset, actionType, user, assetId.toString(), edgeId.toString(), edge.getName()); return savedAsset; } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index 838e32f427..d35cb06a85 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -17,7 +17,6 @@ package org.thingsboard.server.service.entitiy.customer; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; -import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; @@ -37,8 +36,6 @@ import java.util.List; @AllArgsConstructor public class DefaultTbCustomerService extends AbstractTbEntityService implements TbCustomerService { - private final TbClusterService tbClusterService; - @Override public Customer save(Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index 141963e2e3..f7110c4da7 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -226,7 +226,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement try { Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(tenantId, dashboardId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, user.getCustomerId(), - edgeId, savedDashboard, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, dashboardId.toString(), + edgeId, savedDashboard, actionType, user, dashboardId.toString(), edgeId.toString(), edge.getName()); return savedDashboard; } catch (Exception e) { @@ -246,7 +246,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement Dashboard savedDevice = checkNotNull(dashboardService.unassignDashboardFromEdge(tenantId, dashboardId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, user.getCustomerId(), - edgeId, dashboard, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, dashboardId.toString(), + edgeId, dashboard, actionType, user, dashboardId.toString(), edgeId.toString(), edge.getName()); return savedDevice; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java index 08e3a6f4cd..d74610a462 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java @@ -248,7 +248,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T try { Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, savedDevice.getCustomerId(), - edgeId, savedDevice, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); + edgeId, savedDevice, actionType, user, deviceId.toString(), edgeId.toString(), edge.getName()); return savedDevice; } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, @@ -267,7 +267,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, device.getCustomerId(), - edgeId, device, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); + edgeId, device, actionType, user, deviceId.toString(), edgeId.toString(), edge.getName()); return savedDevice; } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/deviceProfile/DefaultTbDeviceProfileService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/deviceProfile/DefaultTbDeviceProfileService.java index 1c2b3bf79c..ca73b0cb83 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/deviceProfile/DefaultTbDeviceProfileService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/deviceProfile/DefaultTbDeviceProfileService.java @@ -61,11 +61,10 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); - notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedDeviceProfile.getId(), savedDeviceProfile, user, actionType, null); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedDeviceProfile.getId(), savedDeviceProfile, user, actionType, true, null); return savedDeviceProfile; } catch (Exception e) { - notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, null, - actionType, user, e); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, user, actionType, false, e); throw handleException(e); } } @@ -79,9 +78,9 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple tbClusterService.onDeviceProfileDelete(deviceProfile, null); tbClusterService.broadcastEntityStateChangeEvent(tenantId, deviceProfileId, ComponentLifecycleEvent.DELETED); - notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, deviceProfileId, deviceProfile, user, ActionType.DELETED, null, deviceProfileId.toString()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, deviceProfileId, deviceProfile, user, ActionType.DELETED, true, null, deviceProfileId.toString()); } catch (Exception e) { - notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.DEVICE_PROFILE), null, user, ActionType.DELETED, e, deviceProfileId.toString()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.DEVICE_PROFILE), null, user, ActionType.DELETED, false, e, deviceProfileId.toString()); throw handleException(e); } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityView/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityView/DefaultTbEntityViewService.java index 7816330825..878c6d32bb 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityView/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityView/DefaultTbEntityViewService.java @@ -112,7 +112,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, entityViewId); entityViewService.deleteEntityView(tenantId, entityViewId); - notificationEntityService.notifyDeleteEntity(tenantId, entityViewId, entityView, user != null ? user.getCustomerId() : null, ActionType.DELETED, + notificationEntityService.notifyDeleteEntity(tenantId, entityViewId, entityView, entityView.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, entityViewId.toString()); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ENTITY_VIEW), null, null, @@ -162,7 +162,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToEdge(tenantId, entityViewId, edgeId)); try { notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, entityViewId, customerId, - edgeId, savedEntityView, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, savedEntityView.getEntityId().toString(), + edgeId, savedEntityView, actionType, user, savedEntityView.getEntityId().toString(), edgeId.toString(), edge.getName()); return savedEntityView; } catch (Exception e) { @@ -181,7 +181,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen try { EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(tenantId, entityViewId, edgeId)); notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, entityViewId, customerId, - edgeId, entityView, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, entityViewId.toString(), + edgeId, entityView, actionType, user, entityViewId.toString(), edgeId.toString(), edge.getName()); return savedEntityView; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/DefaultTbOtaPackageService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/DefaultTbOtaPackageService.java new file mode 100644 index 0000000000..555041ed8f --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/DefaultTbOtaPackageService.java @@ -0,0 +1,107 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.otaPackageController; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.StringUtils; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.OtaPackageId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; + +import java.nio.ByteBuffer; + +@Service +@TbCoreComponent +@AllArgsConstructor +@Slf4j +public class DefaultTbOtaPackageService extends AbstractTbEntityService implements TbOtaPackageService { + @Override + public OtaPackageInfo save(SaveOtaPackageInfoRequest saveOtaPackageInfoRequest, SecurityUser user) throws ThingsboardException { + TenantId tenantId = saveOtaPackageInfoRequest.getTenantId(); + ActionType actionType = saveOtaPackageInfoRequest.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + try { + OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(new OtaPackageInfo(saveOtaPackageInfoRequest), saveOtaPackageInfoRequest.isUsesUrl()); + notificationEntityService.notifyEntity(tenantId, savedOtaPackageInfo.getId(), savedOtaPackageInfo, null, + actionType, user, null); + return savedOtaPackageInfo; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.OTA_PACKAGE), saveOtaPackageInfoRequest, null, + actionType, user, e); + throw handleException(e); + } + } + + @Override + public void delete(OtaPackageInfo otaPackageInfo, SecurityUser user) throws ThingsboardException { + TenantId tenantId = otaPackageInfo.getTenantId(); + OtaPackageId otaPackageId = otaPackageInfo.getId(); + try { + otaPackageService.deleteOtaPackage(tenantId, otaPackageId); + notificationEntityService.notifyEntity(tenantId, otaPackageId, otaPackageInfo, null, + ActionType.DELETED, user, null, otaPackageInfo.getId().toString()); + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.OTA_PACKAGE), null, null, + ActionType.DELETED, user, e, otaPackageInfo.getId().toString()); + throw handleException(e); + } + } + + @Override + public OtaPackageInfo saveOtaPackageData(OtaPackageInfo otaPackageInfo, String checksum, ChecksumAlgorithm checksumAlgorithm, + byte[] data, String filename, String contentType, SecurityUser user) throws ThingsboardException { + TenantId tenantId = otaPackageInfo.getTenantId(); + OtaPackageId otaPackageId = otaPackageInfo.getId(); + try { + if (StringUtils.isEmpty(checksum)) { + checksum = otaPackageService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(data)); + } + OtaPackage otaPackage = new OtaPackage(otaPackageId); + otaPackage.setCreatedTime(otaPackageInfo.getCreatedTime()); + otaPackage.setTenantId(tenantId); + otaPackage.setDeviceProfileId(otaPackageInfo.getDeviceProfileId()); + otaPackage.setType(otaPackageInfo.getType()); + otaPackage.setTitle(otaPackageInfo.getTitle()); + otaPackage.setVersion(otaPackageInfo.getVersion()); + otaPackage.setTag(otaPackageInfo.getTag()); + otaPackage.setAdditionalInfo(otaPackageInfo.getAdditionalInfo()); + otaPackage.setChecksumAlgorithm(checksumAlgorithm); + otaPackage.setChecksum(checksum); + otaPackage.setFileName(filename); + otaPackage.setContentType(contentType); + otaPackage.setData(ByteBuffer.wrap(data)); + otaPackage.setDataSize((long) data.length); + OtaPackageInfo savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage); + notificationEntityService.notifyEntity(tenantId, savedOtaPackage.getId(), savedOtaPackage, null, + ActionType.UPDATED, user, null); + return savedOtaPackage; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.OTA_PACKAGE), null, null, + ActionType.UPDATED, user, e, otaPackageId.toString()); + throw handleException(e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/TbOtaPackageService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/TbOtaPackageService.java new file mode 100644 index 0000000000..7a7d0e79f7 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/otaPackageController/TbOtaPackageService.java @@ -0,0 +1,32 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.otaPackageController; + +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.service.security.model.SecurityUser; + +public interface TbOtaPackageService { + + OtaPackageInfo save(SaveOtaPackageInfoRequest saveOtaPackageInfoRequest, SecurityUser user) throws ThingsboardException; + + void delete(OtaPackageInfo otaPackageInfo, SecurityUser user) throws ThingsboardException; + + OtaPackageInfo saveOtaPackageData(OtaPackageInfo otaPackageInfo, String checksum, ChecksumAlgorithm checksumAlgorithm, + byte[] data, String filename, String contentType, SecurityUser securityUser) throws ThingsboardException; +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java new file mode 100644 index 0000000000..592496e6f8 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java @@ -0,0 +1,95 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.user; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.thingsboard.rule.engine.api.MailService; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.security.UserCredentials; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; +import org.thingsboard.server.service.security.system.SystemSecurityService; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +import static org.thingsboard.server.controller.UserController.ACTIVATE_URL_PATTERN; + +@Service +@TbCoreComponent +@AllArgsConstructor +@Slf4j +public class DefaultUserService extends AbstractTbEntityService implements TbUserService { + + private final MailService mailService; + private final SystemSecurityService systemSecurityService; + + @Override + public User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, + HttpServletRequest request, SecurityUser user) throws ThingsboardException { + ActionType actionType = tbUser.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + try { + boolean sendEmail = tbUser.getId() == null && sendActivationMail; + User savedUser = checkNotNull(userService.saveUser(tbUser)); + if (sendEmail) { + UserCredentials userCredentials = userService.findUserCredentialsByUserId(tenantId, savedUser.getId()); + String baseUrl = systemSecurityService.getBaseUrl(tenantId, customerId, request); + String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, + userCredentials.getActivateToken()); + String email = savedUser.getEmail(); + try { + mailService.sendActivationEmail(activateUrl, email); + } catch (ThingsboardException e) { + userService.deleteUser(tenantId, savedUser.getId()); + throw e; + } + } + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, savedUser.getId(), + savedUser, user, actionType, true, null); + return savedUser; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.USER), + tbUser, user, actionType, false, e); + throw handleException(e); + } + } + + @Override + public void delete(TenantId tenantId, CustomerId customerId, User tbUser, SecurityUser user) throws ThingsboardException { + UserId userId = tbUser.getId(); + try { + List relatedEdgeIds = findRelatedEdgeIds(tenantId, userId); + + userService.deleteUser(tenantId, userId); + notificationEntityService.notifyDeleteEntity(tenantId, userId, tbUser, customerId, + ActionType.DELETED, relatedEdgeIds, user, userId.toString()); + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.USER), + null, user, ActionType.DELETED, false, e, userId.toString()); + throw handleException(e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java new file mode 100644 index 0000000000..177aad17cc --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java @@ -0,0 +1,30 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.user; + +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.service.security.model.SecurityUser; + +import javax.servlet.http.HttpServletRequest; + +public interface TbUserService { + User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, HttpServletRequest request, SecurityUser user) throws ThingsboardException; + + void delete (TenantId tenantId, CustomerId customerId, User tbUser, SecurityUser user) throws ThingsboardException; +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/DefaultWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/DefaultWidgetsBundleService.java new file mode 100644 index 0000000000..f3d8dfc138 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/DefaultWidgetsBundleService.java @@ -0,0 +1,53 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.widgetsBundle; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; + +@Service +@TbCoreComponent +@AllArgsConstructor +public class DefaultWidgetsBundleService extends AbstractTbEntityService implements TbWidgetsBundleService{ + @Override + public WidgetsBundle save(WidgetsBundle widgetsBundle, SecurityUser user) throws ThingsboardException { + try { + WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); + notificationEntityService.notifySendMsgToEdgeService(widgetsBundle.getTenantId(), savedWidgetsBundle.getId(), + widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); + return savedWidgetsBundle; + } catch (Exception e) { + throw handleException(e); + } + } + + @Override + public void delete(WidgetsBundle widgetsBundle, SecurityUser user) throws ThingsboardException { + try { + widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId()); + notificationEntityService.notifySendMsgToEdgeService(widgetsBundle.getTenantId(), widgetsBundle.getId(), + EdgeEventActionType.DELETED); + } catch (Exception e) { + throw handleException(e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/TbWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/TbWidgetsBundleService.java new file mode 100644 index 0000000000..7672db1a71 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgetsBundle/TbWidgetsBundleService.java @@ -0,0 +1,22 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.widgetsBundle; + +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.service.entitiy.SimpleTbEntityService; + +public interface TbWidgetsBundleService extends SimpleTbEntityService { +} diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index d22660969d..cece3377b0 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -611,67 +611,76 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Override public void createQueues() { - Queue mainQueue = new Queue(); - mainQueue.setTenantId(TenantId.SYS_TENANT_ID); - mainQueue.setName("Main"); - mainQueue.setTopic("tb_rule_engine.main"); - mainQueue.setPollInterval(25); - mainQueue.setPartitions(10); - mainQueue.setConsumerPerPartition(true); - mainQueue.setPackProcessingTimeout(2000); - SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); - mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); - mainQueueSubmitStrategy.setBatchSize(1000); - mainQueue.setSubmitStrategy(mainQueueSubmitStrategy); - ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); - mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); - mainQueueProcessingStrategy.setRetries(3); - mainQueueProcessingStrategy.setFailurePercentage(0); - mainQueueProcessingStrategy.setPauseBetweenRetries(3); - mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); - mainQueue.setProcessingStrategy(mainQueueProcessingStrategy); - queueService.saveQueue(mainQueue); - - Queue highPriorityQueue = new Queue(); - highPriorityQueue.setTenantId(TenantId.SYS_TENANT_ID); - highPriorityQueue.setName("HighPriority"); - highPriorityQueue.setTopic("tb_rule_engine.hp"); - highPriorityQueue.setPollInterval(25); - highPriorityQueue.setPartitions(10); - highPriorityQueue.setConsumerPerPartition(true); - highPriorityQueue.setPackProcessingTimeout(2000); - SubmitStrategy highPriorityQueueSubmitStrategy = new SubmitStrategy(); - highPriorityQueueSubmitStrategy.setType(SubmitStrategyType.BURST); - highPriorityQueueSubmitStrategy.setBatchSize(100); - highPriorityQueue.setSubmitStrategy(highPriorityQueueSubmitStrategy); - ProcessingStrategy highPriorityQueueProcessingStrategy = new ProcessingStrategy(); - highPriorityQueueProcessingStrategy.setType(ProcessingStrategyType.RETRY_FAILED_AND_TIMED_OUT); - highPriorityQueueProcessingStrategy.setRetries(0); - highPriorityQueueProcessingStrategy.setFailurePercentage(0); - highPriorityQueueProcessingStrategy.setPauseBetweenRetries(5); - highPriorityQueueProcessingStrategy.setMaxPauseBetweenRetries(5); - highPriorityQueue.setProcessingStrategy(highPriorityQueueProcessingStrategy); - queueService.saveQueue(highPriorityQueue); - - Queue sequentialByOriginatorQueue = new Queue(); - sequentialByOriginatorQueue.setTenantId(TenantId.SYS_TENANT_ID); - sequentialByOriginatorQueue.setName("SequentialByOriginator"); - sequentialByOriginatorQueue.setTopic("tb_rule_engine.sq"); - sequentialByOriginatorQueue.setPollInterval(25); - sequentialByOriginatorQueue.setPartitions(10); - sequentialByOriginatorQueue.setPackProcessingTimeout(2000); - sequentialByOriginatorQueue.setConsumerPerPartition(true); - SubmitStrategy sequentialByOriginatorQueueSubmitStrategy = new SubmitStrategy(); - sequentialByOriginatorQueueSubmitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); - sequentialByOriginatorQueueSubmitStrategy.setBatchSize(100); - sequentialByOriginatorQueue.setSubmitStrategy(sequentialByOriginatorQueueSubmitStrategy); - ProcessingStrategy sequentialByOriginatorQueueProcessingStrategy = new ProcessingStrategy(); - sequentialByOriginatorQueueProcessingStrategy.setType(ProcessingStrategyType.RETRY_FAILED_AND_TIMED_OUT); - sequentialByOriginatorQueueProcessingStrategy.setRetries(3); - sequentialByOriginatorQueueProcessingStrategy.setFailurePercentage(0); - sequentialByOriginatorQueueProcessingStrategy.setPauseBetweenRetries(5); - sequentialByOriginatorQueueProcessingStrategy.setMaxPauseBetweenRetries(5); - sequentialByOriginatorQueue.setProcessingStrategy(sequentialByOriginatorQueueProcessingStrategy); - queueService.saveQueue(sequentialByOriginatorQueue); + Queue mainQueue = queueService.findQueueByTenantIdAndName(TenantId.SYS_TENANT_ID, "Main"); + if (mainQueue == null) { + mainQueue = new Queue(); + mainQueue.setTenantId(TenantId.SYS_TENANT_ID); + mainQueue.setName("Main"); + mainQueue.setTopic("tb_rule_engine.main"); + mainQueue.setPollInterval(25); + mainQueue.setPartitions(10); + mainQueue.setConsumerPerPartition(true); + mainQueue.setPackProcessingTimeout(2000); + SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); + mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + mainQueueSubmitStrategy.setBatchSize(1000); + mainQueue.setSubmitStrategy(mainQueueSubmitStrategy); + ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); + mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); + mainQueueProcessingStrategy.setRetries(3); + mainQueueProcessingStrategy.setFailurePercentage(0); + mainQueueProcessingStrategy.setPauseBetweenRetries(3); + mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); + mainQueue.setProcessingStrategy(mainQueueProcessingStrategy); + queueService.saveQueue(mainQueue); + } + + Queue highPriorityQueue = queueService.findQueueByTenantIdAndName(TenantId.SYS_TENANT_ID, "HighPriority"); + if (highPriorityQueue == null) { + highPriorityQueue = new Queue(); + highPriorityQueue.setTenantId(TenantId.SYS_TENANT_ID); + highPriorityQueue.setName("HighPriority"); + highPriorityQueue.setTopic("tb_rule_engine.hp"); + highPriorityQueue.setPollInterval(25); + highPriorityQueue.setPartitions(10); + highPriorityQueue.setConsumerPerPartition(true); + highPriorityQueue.setPackProcessingTimeout(2000); + SubmitStrategy highPriorityQueueSubmitStrategy = new SubmitStrategy(); + highPriorityQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + highPriorityQueueSubmitStrategy.setBatchSize(100); + highPriorityQueue.setSubmitStrategy(highPriorityQueueSubmitStrategy); + ProcessingStrategy highPriorityQueueProcessingStrategy = new ProcessingStrategy(); + highPriorityQueueProcessingStrategy.setType(ProcessingStrategyType.RETRY_FAILED_AND_TIMED_OUT); + highPriorityQueueProcessingStrategy.setRetries(0); + highPriorityQueueProcessingStrategy.setFailurePercentage(0); + highPriorityQueueProcessingStrategy.setPauseBetweenRetries(5); + highPriorityQueueProcessingStrategy.setMaxPauseBetweenRetries(5); + highPriorityQueue.setProcessingStrategy(highPriorityQueueProcessingStrategy); + queueService.saveQueue(highPriorityQueue); + } + + Queue sequentialByOriginatorQueue = queueService.findQueueByTenantIdAndName(TenantId.SYS_TENANT_ID, "SequentialByOriginator"); + if (sequentialByOriginatorQueue == null) { + sequentialByOriginatorQueue = new Queue(); + sequentialByOriginatorQueue.setTenantId(TenantId.SYS_TENANT_ID); + sequentialByOriginatorQueue.setName("SequentialByOriginator"); + sequentialByOriginatorQueue.setTopic("tb_rule_engine.sq"); + sequentialByOriginatorQueue.setPollInterval(25); + sequentialByOriginatorQueue.setPartitions(10); + sequentialByOriginatorQueue.setPackProcessingTimeout(2000); + sequentialByOriginatorQueue.setConsumerPerPartition(true); + SubmitStrategy sequentialByOriginatorQueueSubmitStrategy = new SubmitStrategy(); + sequentialByOriginatorQueueSubmitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); + sequentialByOriginatorQueueSubmitStrategy.setBatchSize(100); + sequentialByOriginatorQueue.setSubmitStrategy(sequentialByOriginatorQueueSubmitStrategy); + ProcessingStrategy sequentialByOriginatorQueueProcessingStrategy = new ProcessingStrategy(); + sequentialByOriginatorQueueProcessingStrategy.setType(ProcessingStrategyType.RETRY_FAILED_AND_TIMED_OUT); + sequentialByOriginatorQueueProcessingStrategy.setRetries(3); + sequentialByOriginatorQueueProcessingStrategy.setFailurePercentage(0); + sequentialByOriginatorQueueProcessingStrategy.setPauseBetweenRetries(5); + sequentialByOriginatorQueueProcessingStrategy.setMaxPauseBetweenRetries(5); + sequentialByOriginatorQueue.setProcessingStrategy(sequentialByOriginatorQueueProcessingStrategy); + queueService.saveQueue(sequentialByOriginatorQueue); + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index a86adeb578..d0d5f37e00 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -571,73 +571,10 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.4", SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, conn); - log.info("Loading queues..."); - try { - if (!CollectionUtils.isEmpty(queueConfig.getQueues())) { - queueConfig.getQueues().forEach(queueSettings -> { - queueService.saveQueue(queueConfigToQueue(queueSettings)); - }); - } else { - systemDataLoaderService.createQueues(); - } - } catch (Exception e) { - } - log.info("Updating device profiles..."); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.4", "schema_update_device_profile.sql"); loadSql(schemaUpdateFile, conn); - log.info("Updating checkpoint rule nodes..."); - PageLink pageLink = new PageLink(100); - PageData pageData; - do { - pageData = tenantService.findTenants(pageLink); - for (Tenant tenant : pageData.getData()) { - TenantId tenantId = tenant.getId(); - Map queues = - queueService.findQueuesByTenantId(tenantId).stream().collect(Collectors.toMap(Queue::getName, Queue::getId)); - try { - List checkpointNodes = - ruleChainService.findRuleNodesByTenantIdAndType(tenantId, "org.thingsboard.rule.engine.flow.TbCheckpointNode"); - checkpointNodes.forEach(node -> { - ObjectNode configuration = (ObjectNode) node.getConfiguration(); - JsonNode queueNameNode = configuration.remove("queueName"); - if (queueNameNode != null) { - String queueName = queueNameNode.asText(); - configuration.put("queueId", queues.get(queueName).toString()); - ruleChainService.saveRuleNode(tenantId, node); - } - }); - } catch (Exception e) { - } - } - pageLink = pageLink.nextPageLink(); - } while (pageData.hasNext()); - - log.info("Updating tenant profiles..."); - PageLink profilePageLink = new PageLink(100); - PageData profilePageData; - do { - profilePageData = tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, profilePageLink); - - profilePageData.getData().forEach(profile -> { - try { - List queueConfiguration = profile.getProfileData().getQueueConfiguration(); - if (profile.isIsolatedTbRuleEngine() && (queueConfiguration == null || queueConfiguration.isEmpty())) { - TenantProfileQueueConfiguration mainQueueConfig = getMainQueueConfiguration(); - profile.getProfileData().setQueueConfiguration(Collections.singletonList((mainQueueConfig))); - tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, profile); - List isolatedTenants = tenantService.findTenantIdsByTenantProfileId(profile.getId()); - isolatedTenants.forEach(tenantId -> { - queueService.saveQueue(new Queue(tenantId, mainQueueConfig)); - }); - } - } catch (Exception e) { - } - - }); - profilePageLink = profilePageLink.nextPageLink(); - } while (profilePageData.hasNext()); log.info("Updating schema settings..."); conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3004000;"); log.info("Schema updated."); @@ -691,48 +628,4 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService return isOldSchema; } - private Queue queueConfigToQueue(TbRuleEngineQueueConfiguration queueSettings) { - Queue queue = new Queue(); - queue.setTenantId(TenantId.SYS_TENANT_ID); - queue.setName(queueSettings.getName()); - queue.setTopic(queueSettings.getTopic()); - queue.setPollInterval(queueSettings.getPollInterval()); - queue.setPartitions(queueSettings.getPartitions()); - queue.setPackProcessingTimeout(queueSettings.getPackProcessingTimeout()); - SubmitStrategy submitStrategy = new SubmitStrategy(); - submitStrategy.setBatchSize(queueSettings.getSubmitStrategy().getBatchSize()); - submitStrategy.setType(SubmitStrategyType.valueOf(queueSettings.getSubmitStrategy().getType())); - queue.setSubmitStrategy(submitStrategy); - ProcessingStrategy processingStrategy = new ProcessingStrategy(); - processingStrategy.setType(ProcessingStrategyType.valueOf(queueSettings.getProcessingStrategy().getType())); - processingStrategy.setRetries(queueSettings.getProcessingStrategy().getRetries()); - processingStrategy.setFailurePercentage(queueSettings.getProcessingStrategy().getFailurePercentage()); - processingStrategy.setPauseBetweenRetries(queueSettings.getProcessingStrategy().getPauseBetweenRetries()); - processingStrategy.setMaxPauseBetweenRetries(queueSettings.getProcessingStrategy().getMaxPauseBetweenRetries()); - queue.setProcessingStrategy(processingStrategy); - queue.setConsumerPerPartition(queueSettings.isConsumerPerPartition()); - return queue; - } - - private TenantProfileQueueConfiguration getMainQueueConfiguration() { - TenantProfileQueueConfiguration mainQueueConfiguration = new TenantProfileQueueConfiguration(); - mainQueueConfiguration.setName("Main"); - mainQueueConfiguration.setTopic("tb_rule_engine.main"); - mainQueueConfiguration.setPollInterval(25); - mainQueueConfiguration.setPartitions(10); - mainQueueConfiguration.setConsumerPerPartition(true); - mainQueueConfiguration.setPackProcessingTimeout(2000); - SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); - mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); - mainQueueSubmitStrategy.setBatchSize(1000); - mainQueueConfiguration.setSubmitStrategy(mainQueueSubmitStrategy); - ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); - mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); - mainQueueProcessingStrategy.setRetries(3); - mainQueueProcessingStrategy.setFailurePercentage(0); - mainQueueProcessingStrategy.setPauseBetweenRetries(3); - mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); - mainQueueConfiguration.setProcessingStrategy(mainQueueProcessingStrategy); - return mainQueueConfiguration; - } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 93c4bb835e..7b87668319 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @@ -31,14 +32,12 @@ import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNodeConfiguration; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.RuleNodeId; -import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.*; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -47,12 +46,14 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.query.DynamicValue; import org.thingsboard.server.common.data.query.FilterPredicateValue; +import org.thingsboard.server.common.data.queue.*; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.alarm.AlarmDao; import org.thingsboard.server.dao.alarm.AlarmService; @@ -61,16 +62,22 @@ import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; import org.thingsboard.server.dao.model.sql.RelationEntity; import org.thingsboard.server.dao.oauth2.OAuth2Service; +import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.sql.device.DeviceProfileRepository; +import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; +import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; import org.thingsboard.server.service.install.InstallScripts; +import org.thingsboard.server.service.install.SystemDataLoaderService; +import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -115,6 +122,18 @@ public class DefaultDataUpdateService implements DataUpdateService { @Autowired private OAuth2Service oAuth2Service; + @Autowired + private TenantProfileService tenantProfileService; + + @Autowired + private QueueService queueService; + + @Autowired + private TbRuleEngineQueueConfigService queueConfig; + + @Autowired + private SystemDataLoaderService systemDataLoaderService; + @Override public void updateData(String fromVersion) throws Exception { switch (fromVersion) { @@ -141,6 +160,26 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.3.2 to 3.3.3 ..."); updateNestedRuleChains(); break; + case "3.3.4": + log.info("Updating data from version 3.3.4 to 3.4.0 ..."); + log.info("Loading queues..."); + try { + if (!CollectionUtils.isEmpty(queueConfig.getQueues())) { + queueConfig.getQueues().forEach(queueSettings -> { + Queue queue = queueConfigToQueue(queueSettings); + Queue existing = queueService.findQueueByTenantIdAndName(queue.getTenantId(), queue.getName()); + if (existing == null) { + queueService.saveQueue(queue); + } + }); + } else { + systemDataLoaderService.createQueues(); + } + } catch (Exception e) { + } + tenantsProfileQueueConfigurationUpdater.updateEntities(null); + checkPointRuleNodesUpdater.updateEntities(null); + break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } @@ -547,4 +586,133 @@ public class DefaultDataUpdateService implements DataUpdateService { log.warn("CAUTION: Update of Oauth2 parameters from 3.2.2 to 3.3.0 available only in ThingsBoard versions 3.3.0/3.3.1"); } + private final PaginatedUpdater tenantsProfileQueueConfigurationUpdater = + new PaginatedUpdater<>() { + + @Override + protected String getName() { + return "Tenant profiles queue configuration updater"; + } + + @Override + protected boolean forceReportTotal() { + return true; + } + + @Override + protected PageData findEntities(String id, PageLink pageLink) { + return tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, pageLink); + } + + @Override + protected void updateEntity(TenantProfile tenantProfile) { + updateTenantProfileQueueConfiguration(tenantProfile); + } + }; + + private void updateTenantProfileQueueConfiguration(TenantProfile profile) { + try { + List queueConfiguration = profile.getProfileData().getQueueConfiguration(); + if (profile.isIsolatedTbRuleEngine() && (queueConfiguration == null || queueConfiguration.isEmpty())) { + TenantProfileQueueConfiguration mainQueueConfig = getMainQueueConfiguration(); + profile.getProfileData().setQueueConfiguration(Collections.singletonList((mainQueueConfig))); + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, profile); + List isolatedTenants = tenantService.findTenantIdsByTenantProfileId(profile.getId()); + isolatedTenants.forEach(tenantId -> { + queueService.saveQueue(new Queue(tenantId, mainQueueConfig)); + }); + } + } catch (Exception e) { + log.error("Failed to update tenant profile queue configuration name=["+profile.getName()+"], id=["+ profile.getId().getId() +"]", e); + } + } + + private TenantProfileQueueConfiguration getMainQueueConfiguration() { + TenantProfileQueueConfiguration mainQueueConfiguration = new TenantProfileQueueConfiguration(); + mainQueueConfiguration.setName("Main"); + mainQueueConfiguration.setTopic("tb_rule_engine.main"); + mainQueueConfiguration.setPollInterval(25); + mainQueueConfiguration.setPartitions(10); + mainQueueConfiguration.setConsumerPerPartition(true); + mainQueueConfiguration.setPackProcessingTimeout(2000); + SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); + mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + mainQueueSubmitStrategy.setBatchSize(1000); + mainQueueConfiguration.setSubmitStrategy(mainQueueSubmitStrategy); + ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); + mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); + mainQueueProcessingStrategy.setRetries(3); + mainQueueProcessingStrategy.setFailurePercentage(0); + mainQueueProcessingStrategy.setPauseBetweenRetries(3); + mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); + mainQueueConfiguration.setProcessingStrategy(mainQueueProcessingStrategy); + return mainQueueConfiguration; + } + + private Queue queueConfigToQueue(TbRuleEngineQueueConfiguration queueSettings) { + Queue queue = new Queue(); + queue.setTenantId(TenantId.SYS_TENANT_ID); + queue.setName(queueSettings.getName()); + queue.setTopic(queueSettings.getTopic()); + queue.setPollInterval(queueSettings.getPollInterval()); + queue.setPartitions(queueSettings.getPartitions()); + queue.setPackProcessingTimeout(queueSettings.getPackProcessingTimeout()); + SubmitStrategy submitStrategy = new SubmitStrategy(); + submitStrategy.setBatchSize(queueSettings.getSubmitStrategy().getBatchSize()); + submitStrategy.setType(SubmitStrategyType.valueOf(queueSettings.getSubmitStrategy().getType())); + queue.setSubmitStrategy(submitStrategy); + ProcessingStrategy processingStrategy = new ProcessingStrategy(); + processingStrategy.setType(ProcessingStrategyType.valueOf(queueSettings.getProcessingStrategy().getType())); + processingStrategy.setRetries(queueSettings.getProcessingStrategy().getRetries()); + processingStrategy.setFailurePercentage(queueSettings.getProcessingStrategy().getFailurePercentage()); + processingStrategy.setPauseBetweenRetries(queueSettings.getProcessingStrategy().getPauseBetweenRetries()); + processingStrategy.setMaxPauseBetweenRetries(queueSettings.getProcessingStrategy().getMaxPauseBetweenRetries()); + queue.setProcessingStrategy(processingStrategy); + queue.setConsumerPerPartition(queueSettings.isConsumerPerPartition()); + return queue; + } + + private final PaginatedUpdater checkPointRuleNodesUpdater = + new PaginatedUpdater<>() { + + @Override + protected String getName() { + return "Checkpoint rule nodes updater"; + } + + @Override + protected boolean forceReportTotal() { + return true; + } + + @Override + protected PageData findEntities(String id, PageLink pageLink) { + return ruleChainService.findAllRuleNodesByType("org.thingsboard.rule.engine.flow.TbCheckpointNode", pageLink); + } + + @Override + protected void updateEntity(RuleNode ruleNode) { + updateCheckPointRuleNodeConfiguration(ruleNode); + } + }; + + private void updateCheckPointRuleNodeConfiguration(RuleNode node) { + try { + ObjectNode configuration = (ObjectNode) node.getConfiguration(); + JsonNode queueNameNode = configuration.remove("queueName"); + if (queueNameNode != null) { + RuleChain ruleChain = this.ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, node.getRuleChainId()); + TenantId tenantId = ruleChain.getTenantId(); + Map queues = + queueService.findQueuesByTenantId(tenantId).stream().collect(Collectors.toMap(Queue::getName, Queue::getId)); + String queueName = queueNameNode.asText(); + QueueId queueId = queues.get(queueName); + configuration.put("queueId", queueId != null ? queueId.toString() : ""); + ruleChainService.saveRuleNode(tenantId, node); + } + } catch (Exception e) { + log.error("Failed to update checkpoint rule node configuration name=["+node.getName()+"], id=["+ node.getId().getId() +"]", e); + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index bec0dceed3..2ca47d689f 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -61,6 +61,7 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.provider.TbCoreQueueFactory; +import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.edge.EdgeNotificationService; @@ -170,8 +171,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService { - TbResource saveResource(TbResource resource) throws ThingsboardException; + TbResource saveResourceInternal(TbResource resource) throws ThingsboardException; TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey); @@ -51,8 +52,6 @@ public interface TbResourceService { String sortOrder, PageLink pageLink); - void deleteResource(TenantId tenantId, TbResourceId resourceId); - void deleteResourcesByTenantId(TenantId tenantId); long sumDataSizeByTenantId(TenantId tenantId); diff --git a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java index ae247c0e47..ac82f78ccb 100644 --- a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java +++ b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java @@ -22,19 +22,30 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.flow.TbRuleChainOutputNode; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.rule.DefaultRuleChainCreateRequest; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainOutputLabelsUsage; +import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNodeUpdateResult; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; import java.util.Collections; import java.util.Comparator; @@ -50,7 +61,7 @@ import java.util.stream.Collectors; @Service @TbCoreComponent @Slf4j -public class DefaultTbRuleChainService implements TbRuleChainService { +public class DefaultTbRuleChainService extends AbstractTbEntityService implements TbRuleChainService { private final RuleChainService ruleChainService; private final RelationService relationService; @@ -152,6 +163,238 @@ public class DefaultTbRuleChainService implements TbRuleChainService { return ruleChainIds.stream().map(id -> ruleChainService.findRuleChainById(tenantId, id)).collect(Collectors.toList()); } + @Override + public RuleChain save(RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + TenantId tenantId = ruleChain.getTenantId(); + ActionType actionType = ruleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + try { + RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); + + if (RuleChainType.CORE.equals(savedRuleChain.getType())) { + tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), + actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); + } + boolean sendMsgToEdge = RuleChainType.EDGE.equals(savedRuleChain.getType()) && actionType.equals(ActionType.UPDATED); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedRuleChain.getId(), + savedRuleChain, user, actionType, sendMsgToEdge, null); + return savedRuleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + ruleChain, user, actionType, false, e); + throw handleException(e); + } + } + + @Override + public void delete(RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + TenantId tenantId = ruleChain.getTenantId(); + RuleChainId ruleChainId = ruleChain.getId(); + try { + List referencingRuleNodes = ruleChainService.getReferencingRuleChainNodes(tenantId, ruleChainId); + + Set referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet()); + + List relatedEdgeIds = null; + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + relatedEdgeIds = findRelatedEdgeIds(tenantId, ruleChainId); + } + + ruleChainService.deleteRuleChainById(tenantId, ruleChainId); + + referencingRuleChainIds.remove(ruleChain.getId()); + + if (RuleChainType.CORE.equals(ruleChain.getType())) { + referencingRuleChainIds.forEach(referencingRuleChainId -> + tbClusterService.broadcastEntityStateChangeEvent(tenantId, referencingRuleChainId, ComponentLifecycleEvent.UPDATED)); + + tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChain.getId(), ComponentLifecycleEvent.DELETED); + } + + notificationEntityService.notifyDeleteRuleChain(tenantId, ruleChain, relatedEdgeIds, user); + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.DELETED, false, e, ruleChainId.toString()); + throw handleException(e); + } + } + + @Override + public RuleChain saveDefaultByName(TenantId tenantId, DefaultRuleChainCreateRequest request, SecurityUser user) throws ThingsboardException { + try { + RuleChain savedRuleChain = installScripts.createDefaultRuleChain(tenantId, request.getName()); + tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), ComponentLifecycleEvent.CREATED); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedRuleChain.getId(), + savedRuleChain, user, ActionType.ADDED, false, null); + return savedRuleChain; + } catch (Exception e) { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName(request.getName()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + ruleChain, user, ActionType.ADDED, false, e); + throw handleException(e); + } + } + + @Override + public RuleChain setRootRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId); + if (ruleChainService.setRootRuleChain(tenantId, ruleChainId)) { + if (previousRootRuleChain != null) { + RuleChainId previousRootRuleChainId = previousRootRuleChain.getId(); + previousRootRuleChain = ruleChainService.findRuleChainById(tenantId, previousRootRuleChainId); + + tbClusterService.broadcastEntityStateChangeEvent(tenantId, previousRootRuleChainId, + ComponentLifecycleEvent.UPDATED); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, previousRootRuleChainId, + previousRootRuleChain, user, ActionType.UPDATED, false, null); + } + ruleChain = ruleChainService.findRuleChainById(tenantId, ruleChainId); + + tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChainId, + ComponentLifecycleEvent.UPDATED); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, ruleChainId, + ruleChain, user, ActionType.UPDATED, false, null); + } + return ruleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + ruleChain, user, ActionType.UPDATED, false, e, ruleChainId.toString()); + throw handleException(e); + } + } + + @Override + public RuleChainMetaData saveRuleChainMetaData(TenantId tenantId, RuleChain ruleChain, RuleChainMetaData ruleChainMetaData, + boolean updateRelated, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + RuleChainId ruleChainMetaDataId = ruleChainMetaData.getRuleChainId(); + try { + RuleChainUpdateResult result = ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData); + checkNotNull(result.isSuccess() ? true : null); + + List updatedRuleChains; + if (updateRelated && result.isSuccess()) { + updatedRuleChains = tbRuleChainService.updateRelatedRuleChains(tenantId, ruleChainMetaDataId, result); + } else { + updatedRuleChains = Collections.emptyList(); + } + + RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaDataId)); + + if (RuleChainType.CORE.equals(ruleChain.getType())) { + tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChainId, ComponentLifecycleEvent.UPDATED); + updatedRuleChains.forEach(updatedRuleChain -> { + tbClusterService.broadcastEntityStateChangeEvent(tenantId, updatedRuleChain.getId(), ComponentLifecycleEvent.UPDATED); + }); + } + + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, ruleChainId, + ruleChain, user, ActionType.UPDATED, false, null, ruleChainMetaData); + + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + notificationEntityService.notifySendMsgToEdgeService(tenantId, ruleChain.getId(), EdgeEventActionType.UPDATED); + } + + for (RuleChain updatedRuleChain : updatedRuleChains) { + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + notificationEntityService.notifySendMsgToEdgeService(tenantId, updatedRuleChain.getId(), EdgeEventActionType.UPDATED); + } else { + RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId())); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, updatedRuleChain.getId(), + updatedRuleChain, user, ActionType.UPDATED, false, null, updatedRuleChainMetaData); + } + } + return savedRuleChainMetaData; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.ADDED, false, e, ruleChainMetaData); + throw handleException(e); + } + } + + @Override + public RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + RuleChain savedRuleChain = checkNotNull(ruleChainService.assignRuleChainToEdge(tenantId, ruleChainId, edge.getId())); + notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, ruleChainId, + null, edge.getId(), + savedRuleChain, ActionType.ASSIGNED_TO_EDGE, + user, ruleChainId.toString(), edge.getId().toString(), edge.getName()); + return savedRuleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.ASSIGNED_TO_EDGE, false, e, ruleChainId.toString(), edge.getId().toString()); + throw handleException(e); + } + } + + @Override + public RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(tenantId, ruleChainId, edge.getId(), false)); + notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, ruleChainId, + null, edge.getId(), + savedRuleChain, ActionType.UNASSIGNED_FROM_EDGE, + user, ruleChainId.toString(), edge.getId().toString(), edge.getName()); + return savedRuleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.UNASSIGNED_FROM_EDGE, false, e, ruleChainId.toString(), edge.getId().toString()); + throw handleException(e); + } + } + + @Override + public RuleChain setEdgeTemplateRootRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + ruleChainService.setEdgeTemplateRootRuleChain(tenantId, ruleChainId); + + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, ruleChainId, + ruleChain, user, ActionType.UPDATED, false, null); + return ruleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.UPDATED, false, e, ruleChainId.toString()); + throw handleException(e); + } + } + + @Override + public RuleChain setAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + ruleChainService.setAutoAssignToEdgeRuleChain(tenantId, ruleChainId); + + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, ruleChainId, + ruleChain, user, ActionType.UPDATED, false, null); + return ruleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.UPDATED, false, e, ruleChainId.toString()); + throw handleException(e); + } + } + + @Override + public RuleChain unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException { + RuleChainId ruleChainId = ruleChain.getId(); + try { + ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, ruleChainId, + ruleChain, user, ActionType.UPDATED, false, null); + return ruleChain; + } catch (Exception e) { + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, emptyId(EntityType.RULE_CHAIN), + null, user, ActionType.UPDATED, false, e, ruleChainId.toString()); + throw handleException(e); + } + } + public Set updateRelatedRuleChains(TenantId tenantId, RuleChainId ruleChainId, Map labelsMap) { Set updatedRuleChains = new HashSet<>(); List usageList = getOutputLabelUsage(tenantId, ruleChainId); @@ -188,4 +431,5 @@ public class DefaultTbRuleChainService implements TbRuleChainService { private boolean isRuleNode(RuleNode ruleNode, Class clazz) { return ruleNode != null && ruleNode.getType().equals(clazz.getName()); } + } diff --git a/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java b/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java index 78a630416d..dbdba7d4ef 100644 --- a/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java +++ b/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java @@ -15,20 +15,44 @@ */ package org.thingsboard.server.service.rule; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.rule.DefaultRuleChainCreateRequest; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainOutputLabelsUsage; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; +import org.thingsboard.server.service.entitiy.SimpleTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; import java.util.List; import java.util.Set; -public interface TbRuleChainService { +public interface TbRuleChainService extends SimpleTbEntityService { Set getRuleChainOutputLabels(TenantId tenantId, RuleChainId ruleChainId); List getOutputLabelUsage(TenantId tenantId, RuleChainId ruleChainId); List updateRelatedRuleChains(TenantId tenantId, RuleChainId ruleChainId, RuleChainUpdateResult result); + + RuleChain saveDefaultByName(TenantId tenantId, DefaultRuleChainCreateRequest request, SecurityUser user) throws ThingsboardException; + + RuleChain setRootRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException; + + RuleChainMetaData saveRuleChainMetaData(TenantId tenantId, RuleChain ruleChain, RuleChainMetaData ruleChainMetaData, + boolean updateRelated, SecurityUser user) throws ThingsboardException; + + RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, + SecurityUser user) throws ThingsboardException; + RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, + SecurityUser user) throws ThingsboardException; + + RuleChain setEdgeTemplateRootRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException; + + RuleChain setAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException; + + RuleChain unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java index 7510552ffb..323ca2528c 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java @@ -33,6 +33,7 @@ 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.TbCoreQueueFactory; +import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; import javax.annotation.PostConstruct; @@ -91,8 +92,7 @@ public class TbCoreTransportApiService { transportApiTemplate = builder.build(); } - @EventListener(ApplicationReadyEvent.class) - @Order(value = 2) + @AfterStartUp(order = AfterStartUp.REGULAR_SERVICE) public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { log.info("Received application ready event. Starting polling for events."); transportApiTemplate.init(transportApiService); diff --git a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java index 59ede61621..31349ebec4 100644 --- a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java @@ -24,7 +24,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.EntityInfo; -import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; @@ -173,7 +172,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(filename); resource.setData("1"); - return resourceService.saveResource(resource); + return resourceService.saveResourceInternal(resource); } @Test @@ -185,7 +184,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); Assert.assertNotNull(savedResource); Assert.assertNotNull(savedResource.getId()); @@ -197,11 +196,11 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { savedResource.setTitle("My new resource"); - resourceService.saveResource(savedResource); + resourceService.saveResourceInternal(savedResource); TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); Assert.assertEquals(foundResource.getTitle(), savedResource.getTitle()); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } @Test @@ -212,7 +211,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setFileName("test_model.xml"); resource.setData(Base64.getEncoder().encodeToString(LWM2M_TEST_MODEL.getBytes())); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); Assert.assertNotNull(savedResource); Assert.assertNotNull(savedResource.getId()); @@ -222,7 +221,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { Assert.assertEquals("0_1.0", savedResource.getResourceKey()); Assert.assertEquals(resource.getData(), savedResource.getData()); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } @Test @@ -232,11 +231,11 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); Assert.assertEquals(TenantId.SYS_TENANT_ID, savedResource.getTenantId()); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } @Test(expected = DataValidationException.class) @@ -248,7 +247,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); TbResource resource2 = new TbResource(); resource.setTenantId(tenantId); @@ -258,9 +257,9 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setData("Test Data"); try { - resourceService.saveResource(resource2); + resourceService.saveResourceInternal(resource2); } finally { - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } } @@ -271,7 +270,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - resourceService.saveResource(resource); + resourceService.saveResourceInternal(resource); } @Test(expected = DataValidationException.class) @@ -282,7 +281,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - resourceService.saveResource(resource); + resourceService.saveResourceInternal(resource); } @Test @@ -292,12 +291,12 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); Assert.assertNotNull(foundResource); Assert.assertEquals(savedResource, foundResource); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } @Test @@ -308,12 +307,12 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); TbResource foundResource = resourceService.getResource(tenantId, savedResource.getResourceType(), savedResource.getResourceKey()); Assert.assertNotNull(foundResource); Assert.assertEquals(savedResource, foundResource); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); } @Test @@ -323,11 +322,11 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResource savedResource = resourceService.saveResource(resource); + TbResource savedResource = resourceService.saveResourceInternal(resource); TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); Assert.assertNotNull(foundResource); - resourceService.deleteResource(tenantId, savedResource.getId()); + resourceService.delete(savedResource, null); foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); Assert.assertNull(foundResource); } @@ -349,7 +348,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); resource.setData("Test Data"); - resources.add(new TbResourceInfo(resourceService.saveResource(resource))); + resources.add(new TbResourceInfo(resourceService.saveResourceInternal(resource))); } List loadedResources = new ArrayList<>(); @@ -397,7 +396,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); resource.setData("Test Data"); - TbResourceInfo tbResourceInfo = new TbResourceInfo(resourceService.saveResource(resource)); + TbResourceInfo tbResourceInfo = new TbResourceInfo(resourceService.saveResourceInternal(resource)); if (i >= 50) { resources.add(tbResourceInfo); } @@ -410,7 +409,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); resource.setData("Test Data"); - resources.add(new TbResourceInfo(resourceService.saveResource(resource))); + resources.add(new TbResourceInfo(resourceService.saveResourceInternal(resource))); } List loadedResources = new ArrayList<>(); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 1d99534636..3328372f2e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -94,5 +94,7 @@ public interface RuleChainService { List findRuleNodesByTenantIdAndType(TenantId tenantId, String type); + PageData findAllRuleNodesByType(String type, PageLink pageLink); + RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java b/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java index 50201ef3fc..e38677b2ce 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java @@ -156,9 +156,9 @@ public class DefaultTbQueueRequestTemplate staleRequest, long currentNs) { if (currentNs >= staleRequest.getSubmitTime() + staleRequest.getTimeout()) { - log.warn("Request timeout detected, currentNs [{}], {}, key [{}]", currentNs, staleRequest, key); + log.debug("Request timeout detected, currentNs [{}], {}, key [{}]", currentNs, staleRequest, key); } else { - log.error("Request timeout detected, currentNs [{}], {}, key [{}]", currentNs, staleRequest, key); + log.info("Request timeout detected, currentNs [{}], {}, key [{}]", currentNs, staleRequest, key); } staleRequest.future.setException(new TimeoutException()); } @@ -173,7 +173,7 @@ public class DefaultTbQueueRequestTemplate expectedResponse = pendingRequests.remove(requestId); if (expectedResponse == null) { - log.warn("[{}] Invalid or stale request, response: {}", requestId, String.valueOf(response).replace("\n", " ")); + log.debug("[{}] Invalid or stale request, response: {}", requestId, String.valueOf(response).replace("\n", " ")); } else { expectedResponse.future.set(response); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DummyDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DummyDiscoveryService.java index 6718471abf..d124419135 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DummyDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DummyDiscoveryService.java @@ -22,6 +22,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; +import org.thingsboard.server.queue.util.AfterStartUp; import java.util.Collections; @@ -40,8 +41,7 @@ public class DummyDiscoveryService implements DiscoveryService { this.partitionService = partitionService; } - @EventListener(ApplicationReadyEvent.class) - @Order(value = 1) + @AfterStartUp(order = AfterStartUp.DISCOVERY_SERVICE) public void onApplicationEvent(ApplicationReadyEvent event) { partitionService.recalculatePartitions(serviceInfoProvider.getServiceInfo(), Collections.emptyList()); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java index e7db76bead..8a56a86bcc 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; import org.thingsboard.server.queue.discovery.event.ClusterTopologyChangeEvent; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; +import org.thingsboard.server.queue.util.AfterStartUp; import javax.annotation.PostConstruct; import java.util.ArrayList; @@ -89,10 +90,10 @@ public class HashPartitionService implements PartitionService { @PostConstruct public void init() { this.hashFunction = forName(hashFunctionName); - partitionsInit(); } - private void partitionsInit() { + @AfterStartUp(order = AfterStartUp.QUEUE_INFO_INITIALIZATION) + public void partitionsInit() { QueueKey coreKey = new QueueKey(ServiceType.TB_CORE); partitionSizesMap.put(coreKey, corePartitions); partitionTopicsMap.put(coreKey, coreTopic); @@ -101,6 +102,7 @@ public class HashPartitionService implements PartitionService { String serviceType = serviceInfoProvider.getServiceType(); + if ("tb-transport".equals(serviceType)) { //If transport started earlier than tb-core int getQueuesRetries = 10; @@ -111,7 +113,7 @@ public class HashPartitionService implements PartitionService { queueRoutingInfoList = queueRoutingInfoService.getAllQueuesRoutingInfo(); break; } catch (Exception e) { - log.info("Failed to get queues routing info!"); + log.info("Failed to get queues routing info: {}!", e.getMessage()); getQueuesRetries--; } try { diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java index 8afd4dc768..89eda16cad 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java @@ -41,6 +41,7 @@ import org.springframework.util.Assert; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; +import org.thingsboard.server.queue.util.AfterStartUp; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -115,8 +116,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi .collect(Collectors.toList()); } - @EventListener(ApplicationReadyEvent.class) - @Order(value = 1) + @AfterStartUp(order = AfterStartUp.DISCOVERY_SERVICE) public void onApplicationEvent(ApplicationReadyEvent event) { if (stopped) { log.debug("Ignoring application ready event. Service is stopped."); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java index 60867f314f..11f01cba2b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java @@ -59,9 +59,7 @@ public class DefaultTbApiUsageClient implements TbApiUsageClient { private final EnumMap> stats = new EnumMap<>(ApiUsageRecordKey.class); - @Lazy - @Autowired - private PartitionService partitionService; + private final PartitionService partitionService; private final SchedulerComponent scheduler; private final TbQueueProducerProvider producerProvider; private TbQueueProducer> msgProducer; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/util/AfterStartUp.java b/common/queue/src/main/java/org/thingsboard/server/queue/util/AfterStartUp.java index 19e56e31cb..487e734c33 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/util/AfterStartUp.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/util/AfterStartUp.java @@ -30,6 +30,17 @@ import java.lang.annotation.Target; @EventListener(ApplicationReadyEvent.class) @Order public @interface AfterStartUp { + + int QUEUE_INFO_INITIALIZATION = 1; + int DISCOVERY_SERVICE = 2; + + int ACTOR_SYSTEM = 9; + int REGULAR_SERVICE = 10; + + int BEFORE_TRANSPORT_SERVICE = Integer.MAX_VALUE - 1001; + int TRANSPORT_SERVICE = Integer.MAX_VALUE - 1000; + int AFTER_TRANSPORT_SERVICE = Integer.MAX_VALUE - 999; + @AliasFor(annotation = Order.class, attribute = "value") - int order() default Integer.MAX_VALUE; + int order(); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 9b49030f7e..e4a9a2492f 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -20,15 +20,11 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.californium.scandium.config.DtlsConfig; import org.eclipse.californium.scandium.config.DtlsConnectorConfig; import org.eclipse.californium.scandium.dtls.cipher.CipherSuite; -import org.eclipse.leshan.core.node.LwM2mNode; import org.eclipse.leshan.core.node.codec.DefaultLwM2mDecoder; import org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder; -import org.eclipse.leshan.core.request.SendRequest; import org.eclipse.leshan.server.californium.LeshanServer; import org.eclipse.leshan.server.californium.LeshanServerBuilder; import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; -import org.eclipse.leshan.server.registration.Registration; -import org.eclipse.leshan.server.send.SendListener; import org.springframework.stereotype.Component; import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.common.data.DataConstants; @@ -44,7 +40,6 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import javax.annotation.PreDestroy; import java.security.cert.X509Certificate; -import java.util.Map; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CURVES_ONLY; @@ -76,7 +71,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { private LeshanServer server; - @AfterStartUp(order = Integer.MAX_VALUE - 1) + @AfterStartUp(order = AfterStartUp.AFTER_TRANSPORT_SERVICE) public void init() { this.server = getLhServer(); /* diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index 260dcd7ab1..c25c2d3c9a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -84,7 +84,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { private final Map lwM2mClientsByRegistrationId = new ConcurrentHashMap<>(); private final Map profiles = new ConcurrentHashMap<>(); - @AfterStartUp(order = Integer.MAX_VALUE - 1) + @AfterStartUp(order = AfterStartUp.BEFORE_TRANSPORT_SERVICE) public void init() { String nodeId = context.getNodeId(); Set fetchedClients = clientStore.getAll(); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java index 4432a0c83c..2634672a3b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java @@ -69,7 +69,7 @@ public class LwM2MModelConfigServiceImpl implements LwM2MModelConfigService { private ConcurrentMap currentModelConfigs; - @AfterStartUp(order = Integer.MAX_VALUE - 1) + @AfterStartUp(order = AfterStartUp.BEFORE_TRANSPORT_SERVICE) private void init() { List models = modelStore.getAll(); log.debug("Fetched model configs: {}", models); diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java index 42190974b9..1dd46dc7cd 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java @@ -73,7 +73,7 @@ public class SnmpTransportContext extends TransportContext { private final Map sessions = new ConcurrentHashMap<>(); private final Collection allSnmpDevicesIds = new ConcurrentLinkedDeque<>(); - @AfterStartUp(order = Integer.MAX_VALUE) + @AfterStartUp(order = AfterStartUp.AFTER_TRANSPORT_SERVICE) public void fetchDevicesAndEstablishSessions() { log.info("Initializing SNMP devices sessions"); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 5b29d3c3ff..9f6ddc87a4 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -157,13 +157,10 @@ public class DefaultTransportService implements TransportService { @Autowired @Lazy private TbApiUsageClient apiUsageClient; - @Autowired - @Lazy - private PartitionService partitionService; - private final Map statsMap = new LinkedHashMap<>(); private final Gson gson = new Gson(); + private final PartitionService partitionService; private final TbTransportQueueFactory queueProvider; private final TbQueueProducerProvider producerProvider; @@ -197,7 +194,8 @@ public class DefaultTransportService implements TransportService { private volatile boolean stopped = false; - public DefaultTransportService(TbServiceInfoProvider serviceInfoProvider, + public DefaultTransportService(PartitionService partitionService, + TbServiceInfoProvider serviceInfoProvider, TbTransportQueueFactory queueProvider, TbQueueProducerProvider producerProvider, NotificationsTopicService notificationsTopicService, @@ -207,6 +205,7 @@ public class DefaultTransportService implements TransportService { TransportRateLimitService rateLimitService, DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, TransportResourceCache transportResourceCache, ApplicationEventPublisher eventPublisher) { + this.partitionService = partitionService; this.serviceInfoProvider = serviceInfoProvider; this.queueProvider = queueProvider; this.producerProvider = producerProvider; @@ -240,7 +239,7 @@ public class DefaultTransportService implements TransportService { mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); } - @AfterStartUp + @AfterStartUp(order = AfterStartUp.TRANSPORT_SERVICE) private void start() { mainConsumerExecutor.execute(() -> { while (!stopped) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportQueueRoutingInfoService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportQueueRoutingInfoService.java index ae1b6934c3..95fcef99f3 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportQueueRoutingInfoService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportQueueRoutingInfoService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.transport.service; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -33,9 +34,11 @@ import java.util.stream.Collectors; @ConditionalOnExpression("'${service.type:null}'=='tb-transport'") public class TransportQueueRoutingInfoService implements QueueRoutingInfoService { - @Lazy - @Autowired - private TransportService transportService; + private final TransportService transportService; + + public TransportQueueRoutingInfoService(@Lazy TransportService transportService) { + this.transportService = transportService; + } @Override public List getAllQueuesRoutingInfo() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 166d142baf..4be7227214 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -68,8 +68,7 @@ import java.util.Set; import java.util.stream.Collectors; import static org.thingsboard.server.common.data.DataConstants.TENANT; -import static org.thingsboard.server.dao.service.Validator.validateId; -import static org.thingsboard.server.dao.service.Validator.validateString; +import static org.thingsboard.server.dao.service.Validator.*; /** * Created by igor on 3/12/18. @@ -676,6 +675,14 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return ruleNodeDao.findRuleNodesByTenantIdAndType(tenantId, type, ""); } + @Override + public PageData findAllRuleNodesByType(String type, PageLink pageLink) { + log.trace("Executing findAllRuleNodesByType, type {}, pageLink {}", type, pageLink); + validateString(type, "Incorrect type of the rule node"); + validatePageLink(pageLink); + return ruleNodeDao.findAllRuleNodesByType(type, pageLink); + } + @Override public RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode) { return ruleNodeDao.save(tenantId, ruleNode); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java index 3984622d89..b4f087b98a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java @@ -16,6 +16,8 @@ package org.thingsboard.server.dao.rule; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.dao.Dao; @@ -27,4 +29,6 @@ import java.util.List; public interface RuleNodeDao extends Dao { List findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String search); + + PageData findAllRuleNodesByType(String type, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java index a499e68da8..a0f84758c6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java @@ -20,6 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.RuleNodeEntity; @@ -27,6 +29,7 @@ import org.thingsboard.server.dao.rule.RuleNodeDao; import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; import java.util.List; +import java.util.Objects; import java.util.UUID; @Slf4j @@ -50,4 +53,14 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String search) { return DaoUtil.convertDataList(ruleNodeRepository.findRuleNodesByTenantIdAndType(tenantId.getId(), type, search)); } + + @Override + public PageData findAllRuleNodesByType(String type, PageLink pageLink) { + return DaoUtil.toPageData(ruleNodeRepository + .findAllRuleNodesByType( + type, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java index b11923a50f..f584ff2b02 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.dao.sql.rule; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -32,4 +34,9 @@ public interface RuleNodeRepository extends JpaRepository @Param("ruleType") String ruleType, @Param("searchText") String searchText); + @Query("SELECT r FROM RuleNodeEntity r WHERE r.type = :ruleType AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ") + Page findAllRuleNodesByType(@Param("ruleType") String ruleType, + @Param("searchText") String searchText, + Pageable pageable); + }