diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index c37381c585..7fbe040091 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -18,6 +18,7 @@ package org.thingsboard.server.controller.plugin; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.RemovalCause; +import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.websocket.RemoteEndpoint; import jakarta.websocket.SendHandler; @@ -65,7 +66,6 @@ import org.thingsboard.server.service.ws.WsCommandsWrapper; import org.thingsboard.server.service.ws.notification.cmd.NotificationCmdsWrapper; import org.thingsboard.server.service.ws.telemetry.cmd.TelemetryCmdsWrapper; -import javax.annotation.PostConstruct; import java.io.IOException; import java.security.InvalidParameterException; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java index f36f9ee2c3..789320e352 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge; import com.fasterxml.jackson.databind.node.NullNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -49,8 +50,6 @@ import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.user.UserServiceImpl; -import javax.annotation.PostConstruct; - /** * This event listener does not support async event processing because relay on ThreadLocal * Another possible approach is to implement a special annotation and a bunch of classes similar to TransactionalApplicationListener @@ -76,7 +75,7 @@ public class EdgeEventSourcingListener { @PostConstruct public void init() { - log.info("EdgeEventSourcingListener initiated"); + log.debug("EdgeEventSourcingListener initiated"); } @TransactionalEventListener(fallbackExecution = true) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/RelatedEdgesSourcingListener.java b/application/src/main/java/org/thingsboard/server/service/edge/RelatedEdgesSourcingListener.java new file mode 100644 index 0000000000..851f59c3ab --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/RelatedEdgesSourcingListener.java @@ -0,0 +1,80 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.edge; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.dao.edge.RelatedEdgesService; +import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent; +import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +@RequiredArgsConstructor +@Slf4j +public class RelatedEdgesSourcingListener { + + private final RelatedEdgesService relatedEdgesService; + + private ExecutorService executorService; + + @PostConstruct + public void init() { + log.debug("RelatedEdgesSourcingListener initiated"); + executorService = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("related-edges-listener")); + } + + @PreDestroy + public void destroy() { + log.debug("RelatedEdgesSourcingListener destroy"); + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + } + } + + @TransactionalEventListener(fallbackExecution = true) + public void handleEvent(ActionEntityEvent event) { + executorService.submit(() -> { + try { + switch (event.getActionType()) { + case ASSIGNED_TO_EDGE, UNASSIGNED_FROM_EDGE -> + relatedEdgesService.publishRelatedEdgeIdsEvictEvent(event.getTenantId(), event.getEntityId()); + } + } catch (Exception e) { + log.error("[{}] failed to process ActionEntityEvent: {}", event.getTenantId(), event, e); + } + }); + } + + @TransactionalEventListener(fallbackExecution = true) + public void handleEvent(DeleteEntityEvent event) { + executorService.submit(() -> { + try { + relatedEdgesService.publishRelatedEdgeIdsEvictEvent(event.getTenantId(), event.getEntityId()); + } catch (Exception e) { + log.error("[{}] failed to process DeleteEntityEvent: {}", event.getTenantId(), event, e); + } + }); + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index bb1d6383e1..8dee74aac1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -133,14 +133,14 @@ import java.util.UUID; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import static org.thingsboard.server.dao.edge.BaseRelatedEdgesService.RELATED_EDGES_CACHE_ITEMS; + @Slf4j public abstract class BaseEdgeProcessor { protected static final Lock deviceCreationLock = new ReentrantLock(); protected static final Lock assetCreationLock = new ReentrantLock(); - protected static final int DEFAULT_PAGE_SIZE = 100; - @Autowired protected TelemetrySubscriptionService tsSubService; @@ -507,7 +507,7 @@ public abstract class BaseEdgeProcessor { EdgeEventActionType actionType, EdgeId sourceEdgeId) { List> futures = new ArrayList<>(); PageDataIterableByTenantIdEntityId edgeIds = - new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, RELATED_EDGES_CACHE_ITEMS); for (EdgeId relatedEdgeId : edgeIds) { if (!relatedEdgeId.equals(sourceEdgeId)) { futures.add(saveEdgeEvent(tenantId, relatedEdgeId, type, actionType, entityId, null)); @@ -653,7 +653,7 @@ public abstract class BaseEdgeProcessor { private boolean isEntityNotAssignedToEdge(TenantId tenantId, EntityId entityId, EdgeId edgeId) { PageDataIterableByTenantIdEntityId edgeIds = - new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, RELATED_EDGES_CACHE_ITEMS); for (EdgeId edgeId1 : edgeIds) { if (edgeId1.equals(edgeId)) { return false; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java index 22d76dc86e..009c5854cd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java @@ -43,6 +43,8 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import static org.thingsboard.server.dao.edge.BaseRelatedEdgesService.RELATED_EDGES_CACHE_ITEMS; + @Slf4j public abstract class AlarmEdgeProcessor extends BaseAlarmProcessor implements AlarmProcessor { @@ -148,7 +150,7 @@ public abstract class AlarmEdgeProcessor extends BaseAlarmProcessor implements A EdgeEventType edgeEventType) { List> futures = new ArrayList<>(); PageDataIterableByTenantIdEntityId edgeIds = - new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, originatorId, DEFAULT_PAGE_SIZE); + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, originatorId, RELATED_EDGES_CACHE_ITEMS); for (EdgeId relatedEdgeId : edgeIds) { if (!relatedEdgeId.equals(sourceEdgeId)) { futures.add(saveEdgeEvent(tenantId, relatedEdgeId, edgeEventType, actionType, alarmId, body)); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java index 5d264cd83d..3e3c9dfb64 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java @@ -107,6 +107,7 @@ public abstract class AssetEdgeProcessor extends BaseAssetProcessor implements A public DownlinkMsg convertAssetEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion) { AssetId assetId = new AssetId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; + var msgConstructor = (AssetMsgConstructor) assetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion); switch (edgeEvent.getAction()) { case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> { Asset asset = assetService.findAssetById(edgeEvent.getTenantId(), assetId); @@ -120,20 +121,15 @@ public abstract class AssetEdgeProcessor extends BaseAssetProcessor implements A if (UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(msgType)) { AssetProfile assetProfile = assetProfileService.findAssetProfileById(edgeEvent.getTenantId(), asset.getAssetProfileId()); assetProfile = checkIfAssetProfileDefaultFieldsAssignedToEdge(edgeEvent.getTenantId(), edgeId, assetProfile, edgeVersion); - builder.addAssetProfileUpdateMsg(((AssetMsgConstructor) assetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)) - .constructAssetProfileUpdatedMsg(msgType, assetProfile)); + builder.addAssetProfileUpdateMsg(msgConstructor.constructAssetProfileUpdatedMsg(msgType, assetProfile)); } downlinkMsg = builder.build(); } } - case DELETED, UNASSIGNED_FROM_EDGE -> { - AssetUpdateMsg assetUpdateMsg = ((AssetMsgConstructor) - assetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructAssetDeleteMsg(assetId); - downlinkMsg = DownlinkMsg.newBuilder() - .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAssetUpdateMsg(assetUpdateMsg) - .build(); - } + case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) + .addAssetUpdateMsg(msgConstructor.constructAssetDeleteMsg(assetId)) + .build(); } return downlinkMsg; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java index aab35f89d8..f5f25b1c56 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java @@ -100,27 +100,23 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl public DownlinkMsg convertDashboardEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion) { DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; + var msgConstructor = (DashboardMsgConstructor) dashboardMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion); switch (edgeEvent.getAction()) { case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> { Dashboard dashboard = dashboardService.findDashboardById(edgeEvent.getTenantId(), dashboardId); if (dashboard != null) { UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); - DashboardUpdateMsg dashboardUpdateMsg = ((DashboardMsgConstructor) - dashboardMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructDashboardUpdatedMsg(msgType, dashboard); + DashboardUpdateMsg dashboardUpdateMsg = msgConstructor.constructDashboardUpdatedMsg(msgType, dashboard); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addDashboardUpdateMsg(dashboardUpdateMsg) .build(); } } - case DELETED, UNASSIGNED_FROM_EDGE -> { - DashboardUpdateMsg dashboardUpdateMsg = ((DashboardMsgConstructor) - dashboardMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructDashboardDeleteMsg(dashboardId); - downlinkMsg = DownlinkMsg.newBuilder() - .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addDashboardUpdateMsg(dashboardUpdateMsg) - .build(); - } + case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) + .addDashboardUpdateMsg(msgConstructor.constructDashboardDeleteMsg(dashboardId)) + .build(); } return downlinkMsg; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java index a55dd77e01..52f09971ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java @@ -226,9 +226,7 @@ public abstract class DeviceEdgeProcessor extends BaseDeviceProcessor implements Device device = deviceService.findDeviceById(edgeEvent.getTenantId(), deviceId); if (device != null) { UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); - DeviceUpdateMsg deviceUpdateMsg = ((DeviceMsgConstructor) - deviceMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)) - .constructDeviceUpdatedMsg(msgType, device); + DeviceUpdateMsg deviceUpdateMsg = msgConstructor.constructDeviceUpdatedMsg(msgType, device); DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addDeviceUpdateMsg(deviceUpdateMsg); @@ -247,19 +245,17 @@ public abstract class DeviceEdgeProcessor extends BaseDeviceProcessor implements break; case DELETED: case UNASSIGNED_FROM_EDGE: - DeviceUpdateMsg deviceUpdateMsg = msgConstructor.constructDeviceDeleteMsg(deviceId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addDeviceUpdateMsg(deviceUpdateMsg) + .addDeviceUpdateMsg(msgConstructor.constructDeviceDeleteMsg(deviceId)) .build(); break; case CREDENTIALS_UPDATED: DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(edgeEvent.getTenantId(), deviceId); if (deviceCredentials != null) { - DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = msgConstructor.constructDeviceCredentialsUpdatedMsg(deviceCredentials); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsg) + .addDeviceCredentialsUpdateMsg(msgConstructor.constructDeviceCredentialsUpdatedMsg(deviceCredentials)) .build(); } break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/edge/EdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/edge/EdgeProcessor.java index 7bb631b330..f49c4b0a00 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/edge/EdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/edge/EdgeProcessor.java @@ -79,7 +79,7 @@ public class EdgeProcessor extends BaseEdgeProcessor { List> futures = new ArrayList<>(); futures.add(saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, customerId, null)); futures.add(saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.EDGE, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, edgeId, null)); - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageLink pageLink = new PageLink(1000); PageData pageData; do { pageData = userService.findCustomerUsers(tenantId, customerId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java index 70d9d9686f..4ef37f703b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java @@ -104,27 +104,23 @@ public abstract class EntityViewEdgeProcessor extends BaseEntityViewProcessor im public DownlinkMsg convertEntityViewEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion) { EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; + var msgConstructor = (EntityViewMsgConstructor) entityViewMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion); switch (edgeEvent.getAction()) { case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> { EntityView entityView = entityViewService.findEntityViewById(edgeEvent.getTenantId(), entityViewId); if (entityView != null) { UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); - EntityViewUpdateMsg entityViewUpdateMsg = ((EntityViewMsgConstructor) - entityViewMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructEntityViewUpdatedMsg(msgType, entityView); + EntityViewUpdateMsg entityViewUpdateMsg = msgConstructor.constructEntityViewUpdatedMsg(msgType, entityView); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addEntityViewUpdateMsg(entityViewUpdateMsg) .build(); } } - case DELETED, UNASSIGNED_FROM_EDGE -> { - EntityViewUpdateMsg entityViewUpdateMsg = ((EntityViewMsgConstructor) - entityViewMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructEntityViewDeleteMsg(entityViewId); - downlinkMsg = DownlinkMsg.newBuilder() - .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addEntityViewUpdateMsg(entityViewUpdateMsg) - .build(); - } + case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) + .addEntityViewUpdateMsg(msgConstructor.constructEntityViewDeleteMsg(entityViewId)) + .build(); } return downlinkMsg; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java index f63aa8b829..b71493fa39 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java @@ -42,6 +42,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg convertRuleChainEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion) { RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; + var msgConstructor = (RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion); switch (edgeEvent.getAction()) { case ADDED, UPDATED, ASSIGNED_TO_EDGE -> { RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId); @@ -58,9 +59,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { isRoot = edge.getRootRuleChainId().equals(ruleChainId); } UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); - RuleChainUpdateMsg ruleChainUpdateMsg = ((RuleChainMsgConstructor) - ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)) - .constructRuleChainUpdatedMsg(msgType, ruleChain, isRoot); + RuleChainUpdateMsg ruleChainUpdateMsg = msgConstructor.constructRuleChainUpdatedMsg(msgType, ruleChain, isRoot); DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) @@ -78,8 +77,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { } case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addRuleChainUpdateMsg(((RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)) - .constructRuleChainDeleteMsg(ruleChainId)) + .addRuleChainUpdateMsg(msgConstructor.constructRuleChainDeleteMsg(ruleChainId)) .build(); } return downlinkMsg; @@ -89,11 +87,11 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId); DownlinkMsg downlinkMsg = null; + var msgConstructor = (RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion); if (ruleChain != null) { RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(edgeEvent.getTenantId(), ruleChainId); UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = ((RuleChainMsgConstructor) - ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)) + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = msgConstructor .constructRuleChainMetadataUpdatedMsg(edgeEvent.getTenantId(), msgType, ruleChainMetaData, edgeVersion); if (ruleChainMetadataUpdateMsg != null) { downlinkMsg = DownlinkMsg.newBuilder() diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java b/application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java index 4a7c1e1e87..08b1e57651 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.entitiy; import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -53,7 +54,6 @@ import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; import org.thingsboard.server.dao.tenant.TenantService; -import javax.annotation.PostConstruct; import java.util.Set; @Component @@ -66,7 +66,7 @@ public class EntityStateSourcingListener { @PostConstruct public void init() { - log.info("EntityStateSourcingListener initiated"); + log.debug("EntityStateSourcingListener initiated"); } @TransactionalEventListener(fallbackExecution = true) @@ -264,4 +264,5 @@ public class EntityStateSourcingListener { metaData.putValue("assignedFromTenantName", tenant.getName()); return metaData; } + } diff --git a/application/src/main/java/org/thingsboard/server/service/executors/PubSubRuleNodeExecutorProvider.java b/application/src/main/java/org/thingsboard/server/service/executors/PubSubRuleNodeExecutorProvider.java index 8bfe8cf8a5..c8e30ba471 100644 --- a/application/src/main/java/org/thingsboard/server/service/executors/PubSubRuleNodeExecutorProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/executors/PubSubRuleNodeExecutorProvider.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.service.executors; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -22,8 +24,6 @@ import org.thingsboard.common.util.ExecutorProvider; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.queue.util.TbRuleEngineComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperReprocessingService.java b/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperReprocessingService.java index 37a55c99d6..f0a6a58849 100644 --- a/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperReprocessingService.java +++ b/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperReprocessingService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.housekeeper; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.context.annotation.Lazy; @@ -33,7 +34,6 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.PreDestroy; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; diff --git a/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperService.java b/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperService.java index eea92eb75b..933f6fad3e 100644 --- a/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperService.java +++ b/application/src/main/java/org/thingsboard/server/service/housekeeper/HousekeeperService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.housekeeper; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -35,7 +36,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.housekeeper.processor.HousekeeperTaskProcessor; import org.thingsboard.server.service.housekeeper.stats.HousekeeperStatsService; -import javax.annotation.PreDestroy; import java.util.List; import java.util.Map; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java index 5ba86198db..98e85077a4 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.notification; import com.google.common.util.concurrent.ListenableFuture; import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -41,7 +42,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.executors.NotificationExecutorService; import org.thingsboard.server.service.partition.AbstractPartitionBasedService; -import javax.annotation.PreDestroy; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -75,9 +75,7 @@ public class DefaultNotificationSchedulerService extends AbstractPartitionBasedS @Override protected Map>> onAddedPartitions(Set addedPartitions) { - PageDataIterable notificationRequests = new PageDataIterable<>(pageLink -> { - return notificationRequestService.findScheduledNotificationRequests(pageLink); - }, 1000); + PageDataIterable notificationRequests = new PageDataIterable<>(notificationRequestService::findScheduledNotificationRequests, 1000); for (NotificationRequest notificationRequest : notificationRequests) { TopicPartitionInfo requestPartition = partitionService.resolve(ServiceType.TB_CORE, notificationRequest.getTenantId(), notificationRequest.getId()); if (addedPartitions.contains(requestPartition)) { diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionSchedulerComponent.java b/application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionSchedulerComponent.java index 7dcfee932f..680be6929d 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionSchedulerComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionSchedulerComponent.java @@ -15,13 +15,13 @@ */ package org.thingsboard.server.service.subscription; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.Getter; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 8b29af34ed..b7c43391be 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -22,6 +22,8 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -102,8 +104,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.profile.TbDeviceProfileCache; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentMap; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index a0a8ea0c2f..c3a5998b60 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -572,6 +572,9 @@ cache: edges: timeToLiveInMinutes: "${CACHE_SPECS_EDGES_TTL:1440}" # Edges cache TTL maxSize: "${CACHE_SPECS_EDGES_MAX_SIZE:10000}" # 0 means the cache is disabled + relatedEdges: + timeToLiveInMinutes: "${CACHE_SPECS_RELATED_EDGES_TTL:1440}" # Related Edges cache TTL + maxSize: "${CACHE_SPECS_RELATED_EDGES_MAX_SIZE:10000}" # 0 means the cache is disabled repositorySettings: timeToLiveInMinutes: "${CACHE_SPECS_REPOSITORY_SETTINGS_TTL:1440}" # Repository settings cache TTL maxSize: "${CACHE_SPECS_REPOSITORY_SETTINGS_MAX_SIZE:10000}" # 0 means the cache is disabled diff --git a/application/src/test/java/org/thingsboard/server/cache/CaffeineCacheDefaultConfigurationTest.java b/application/src/test/java/org/thingsboard/server/cache/CaffeineCacheDefaultConfigurationTest.java index dac269d16a..d92ccfeacb 100644 --- a/application/src/test/java/org/thingsboard/server/cache/CaffeineCacheDefaultConfigurationTest.java +++ b/application/src/test/java/org/thingsboard/server/cache/CaffeineCacheDefaultConfigurationTest.java @@ -41,10 +41,10 @@ public class CaffeineCacheDefaultConfigurationTest { @Test public void verifyTransactionAwareCacheManagerProxy() { assertThat(cacheSpecsMap.getSpecs()).as("specs").isNotNull(); - cacheSpecsMap.getSpecs().forEach((name, cacheSpecs)->assertThat(cacheSpecs).as("cache %s specs", name).isNotNull()); + cacheSpecsMap.getSpecs().forEach((name, cacheSpecs) -> assertThat(cacheSpecs).as("cache %s specs", name).isNotNull()); SoftAssertions softly = new SoftAssertions(); - cacheSpecsMap.getSpecs().forEach((name, cacheSpecs)->{ + cacheSpecsMap.getSpecs().forEach((name, cacheSpecs) -> { softly.assertThat(name).as("cache name").isNotEmpty(); softly.assertThat(cacheSpecs.getTimeToLiveInMinutes()).as("cache %s time to live", name).isGreaterThan(0); softly.assertThat(cacheSpecs.getMaxSize()).as("cache %s max size", name).isGreaterThan(0); diff --git a/application/src/test/java/org/thingsboard/server/edge/RelationEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/RelationEdgeTest.java index 82b7a09623..68d4df8fc8 100644 --- a/application/src/test/java/org/thingsboard/server/edge/RelationEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/RelationEdgeTest.java @@ -31,8 +31,6 @@ import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UplinkMsg; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @DaoSqlTest public class RelationEdgeTest extends AbstractEdgeTest { diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructorTest.java deleted file mode 100644 index ec43753596..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructorTest.java +++ /dev/null @@ -1,414 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.constructor; - -import com.fasterxml.jackson.databind.JsonNode; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.thingsboard.common.util.JacksonUtil; -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.msg.TbMsgType; -import org.thingsboard.server.common.data.msg.TbNodeConnectionType; -import org.thingsboard.server.common.data.rule.NodeConnectionInfo; -import org.thingsboard.server.common.data.rule.RuleChainMetaData; -import org.thingsboard.server.common.data.rule.RuleNode; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; -import org.thingsboard.server.gen.edge.v1.RuleChainConnectionInfoProto; -import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.v1.RuleNodeProto; -import org.thingsboard.server.gen.edge.v1.UpdateMsgType; -import org.thingsboard.server.service.edge.rpc.constructor.rule.RuleChainMsgConstructorV1; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Slf4j -@ExtendWith(MockitoExtension.class) -public class RuleChainMsgConstructorTest { - - private static final String RPC_CONNECTION_TYPE = "RPC"; - - private RuleChainMsgConstructorV1 ruleChainMsgConstructorV1; - - private TenantId tenantId; - - @BeforeEach - public void setup() { - ruleChainMsgConstructorV1 = new RuleChainMsgConstructorV1(); - tenantId = new TenantId(UUID.randomUUID()); - } - - @Test - public void testConstructRuleChainMetadataUpdatedMsg_V_3_4_0() { - RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID()); - RuleChainMetaData ruleChainMetaData = createRuleChainMetaData( - ruleChainId, 3, createRuleNodes(ruleChainId), createConnections()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = - ruleChainMsgConstructorV1.constructRuleChainMetadataUpdatedMsg( - tenantId, - UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, - ruleChainMetaData, - EdgeVersion.V_3_4_0); - - assetV_3_3_3_and_V_3_4_0(ruleChainMetadataUpdateMsg); - - assertCheckpointRuleNodeConfiguration( - ruleChainMetadataUpdateMsg.getNodesList(), - "{\"queueName\":\"HighPriority\"}"); - } - - @Test - public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_3() { - RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID()); - RuleChainMetaData ruleChainMetaData = createRuleChainMetaData( - ruleChainId, 3, createRuleNodes(ruleChainId), createConnections()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = - ruleChainMsgConstructorV1.constructRuleChainMetadataUpdatedMsg( - tenantId, - UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, - ruleChainMetaData, - EdgeVersion.V_3_3_3); - - assetV_3_3_3_and_V_3_4_0(ruleChainMetadataUpdateMsg); - - assertCheckpointRuleNodeConfiguration( - ruleChainMetadataUpdateMsg.getNodesList(), - "{\"queueName\":\"HighPriority\"}"); - } - - private void assetV_3_3_3_and_V_3_4_0(RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg) { - Assertions.assertEquals(3, ruleChainMetadataUpdateMsg.getFirstNodeIndex(), "First rule node index incorrect!"); - Assertions.assertEquals(12, ruleChainMetadataUpdateMsg.getNodesCount(), "Nodes count incorrect!"); - Assertions.assertEquals(13, ruleChainMetadataUpdateMsg.getConnectionsCount(), "Connections count incorrect!"); - Assertions.assertEquals(0, ruleChainMetadataUpdateMsg.getRuleChainConnectionsCount(), "Rule chain connections count incorrect!"); - - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(3, 6, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(0)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(3, 10, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(1)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(3, 0, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(2)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 11, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(3)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 11, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(4)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 11, TbMsgType.ATTRIBUTES_UPDATED.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(5)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 7, TbMsgType.TO_SERVER_RPC_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(6)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 4, TbMsgType.POST_TELEMETRY_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(7)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 5, TbMsgType.POST_ATTRIBUTES_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(8)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 8, TbNodeConnectionType.OTHER), ruleChainMetadataUpdateMsg.getConnections(9)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 9, TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(10)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(7, 11, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(11)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(10, 9, RPC_CONNECTION_TYPE), ruleChainMetadataUpdateMsg.getConnections(12)); - } - - @Test - public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0() { - RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID()); - RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(ruleChainId, 3, createRuleNodes(ruleChainId), createConnections()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = - ruleChainMsgConstructorV1.constructRuleChainMetadataUpdatedMsg( - tenantId, - UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, - ruleChainMetaData, - EdgeVersion.V_3_3_0); - - Assertions.assertEquals(2, ruleChainMetadataUpdateMsg.getFirstNodeIndex(),"First rule node index incorrect!"); - Assertions.assertEquals(10, ruleChainMetadataUpdateMsg.getNodesCount(), "Nodes count incorrect!"); - Assertions.assertEquals(10, ruleChainMetadataUpdateMsg.getConnectionsCount(),"Connections count incorrect!"); - Assertions.assertEquals(1, ruleChainMetadataUpdateMsg.getRuleChainConnectionsCount(), "Rule chain connections count incorrect!"); - - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(2, 5, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(0)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(3, 9, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(1)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 9, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(2)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 9, TbMsgType.ATTRIBUTES_UPDATED.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(3)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 6, TbMsgType.TO_SERVER_RPC_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(4)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 3, TbMsgType.POST_TELEMETRY_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(5)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 4, TbMsgType.POST_ATTRIBUTES_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(6)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 7, TbNodeConnectionType.OTHER), ruleChainMetadataUpdateMsg.getConnections(7)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 8, TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(8)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 9, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(9)); - - RuleChainConnectionInfoProto ruleChainConnection = ruleChainMetadataUpdateMsg.getRuleChainConnections(0); - Assertions.assertEquals(2, ruleChainConnection.getFromIndex(), "From index incorrect!"); - Assertions.assertEquals(TbNodeConnectionType.SUCCESS, ruleChainConnection.getType(), "Type index incorrect!"); - Assertions.assertEquals("{\"description\":\"\",\"layoutX\":477,\"layoutY\":560,\"ruleChainNodeId\":\"rule-chain-node-UNDEFINED\"}", - ruleChainConnection.getAdditionalInfo(),"Additional info incorrect!"); - Assertions.assertTrue(ruleChainConnection.getTargetRuleChainIdMSB() != 0,"Target rule chain id MSB incorrect!"); - Assertions.assertTrue(ruleChainConnection.getTargetRuleChainIdLSB() != 0,"Target rule chain id LSB incorrect!"); - - assertCheckpointRuleNodeConfiguration( - ruleChainMetadataUpdateMsg.getNodesList(), - "{\"queueName\":\"HighPriority\"}"); - } - - @Test - public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0_inDifferentOrder() { - // same rule chain metadata, but different order of rule nodes - RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID()); - RuleChainMetaData ruleChainMetaData1 = createRuleChainMetaData(ruleChainId, 8, createRuleNodesInDifferentOrder(ruleChainId), createConnectionsInDifferentOrder()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = - ruleChainMsgConstructorV1.constructRuleChainMetadataUpdatedMsg( - tenantId, - UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, - ruleChainMetaData1, - EdgeVersion.V_3_3_0); - - Assertions.assertEquals(7, ruleChainMetadataUpdateMsg.getFirstNodeIndex(), "First rule node index incorrect!"); - Assertions.assertEquals(10, ruleChainMetadataUpdateMsg.getNodesCount(),"Nodes count incorrect!"); - Assertions.assertEquals(10, ruleChainMetadataUpdateMsg.getConnectionsCount(),"Connections count incorrect!"); - Assertions.assertEquals(1, ruleChainMetadataUpdateMsg.getRuleChainConnectionsCount(),"Rule chain connections count incorrect!"); - - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(3, 0, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(0)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 0, TbMsgType.ATTRIBUTES_UPDATED.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(1)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 3, TbMsgType.TO_SERVER_RPC_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(2)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 6, TbMsgType.POST_TELEMETRY_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(3)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 5, TbMsgType.POST_ATTRIBUTES_REQUEST.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(4)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 2, TbNodeConnectionType.OTHER), ruleChainMetadataUpdateMsg.getConnections(5)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(4, 1, TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE.getRuleNodeConnection()), ruleChainMetadataUpdateMsg.getConnections(6)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(5, 0, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(7)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(6, 0, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(8)); - compareNodeConnectionInfoAndProto(createNodeConnectionInfo(7, 4, TbNodeConnectionType.SUCCESS), ruleChainMetadataUpdateMsg.getConnections(9)); - - RuleChainConnectionInfoProto ruleChainConnection = ruleChainMetadataUpdateMsg.getRuleChainConnections(0); - Assertions.assertEquals(7, ruleChainConnection.getFromIndex(),"From index incorrect!"); - Assertions.assertEquals(TbNodeConnectionType.SUCCESS, ruleChainConnection.getType(), "Type index incorrect!"); - Assertions.assertEquals( "{\"description\":\"\",\"layoutX\":477,\"layoutY\":560,\"ruleChainNodeId\":\"rule-chain-node-UNDEFINED\"}", - ruleChainConnection.getAdditionalInfo(), "Additional info incorrect!"); - Assertions.assertTrue(ruleChainConnection.getTargetRuleChainIdMSB() != 0, "Target rule chain id MSB incorrect!"); - Assertions.assertTrue(ruleChainConnection.getTargetRuleChainIdLSB() != 0, "Target rule chain id LSB incorrect!"); - - assertCheckpointRuleNodeConfiguration( - ruleChainMetadataUpdateMsg.getNodesList(), - "{\"queueName\":\"HighPriority\"}"); - } - - private void assertCheckpointRuleNodeConfiguration(List nodesList, - String expectedConfiguration) { - Optional checkpointRuleNodeOpt = nodesList.stream() - .filter(rn -> "org.thingsboard.rule.engine.flow.TbCheckpointNode".equals(rn.getType())) - .findFirst(); - Assertions.assertTrue(checkpointRuleNodeOpt.isPresent()); - RuleNodeProto checkpointRuleNode = checkpointRuleNodeOpt.get(); - Assertions.assertEquals(expectedConfiguration, checkpointRuleNode.getConfiguration()); - } - - private void compareNodeConnectionInfoAndProto(NodeConnectionInfo expected, org.thingsboard.server.gen.edge.v1.NodeConnectionInfoProto actual) { - Assertions.assertEquals(expected.getFromIndex(), actual.getFromIndex()); - Assertions.assertEquals(expected.getToIndex(), actual.getToIndex()); - Assertions.assertEquals(expected.getType(), actual.getType()); - } - - private RuleChainMetaData createRuleChainMetaData(RuleChainId ruleChainId, Integer firstNodeIndex, List nodes, List connections) { - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); - ruleChainMetaData.setRuleChainId(ruleChainId); - ruleChainMetaData.setFirstNodeIndex(firstNodeIndex); - ruleChainMetaData.setNodes(nodes); - ruleChainMetaData.setConnections(connections); - ruleChainMetaData.setRuleChainConnections(null); - return ruleChainMetaData; - } - - private List createConnections() { - List result = new ArrayList<>(); - result.add(createNodeConnectionInfo(3, 6, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(3, 10, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(3, 0, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(4, 11, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(5, 11, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(6, 11, TbMsgType.ATTRIBUTES_UPDATED.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(6, 7, TbMsgType.TO_SERVER_RPC_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(6, 4, TbMsgType.POST_TELEMETRY_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(6, 5, TbMsgType.POST_ATTRIBUTES_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(6, 8, TbNodeConnectionType.OTHER)); - result.add(createNodeConnectionInfo(6, 9, TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(7, 11, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(10, 9, RPC_CONNECTION_TYPE)); - return result; - } - - private NodeConnectionInfo createNodeConnectionInfo(int fromIndex, int toIndex, String type) { - NodeConnectionInfo result = new NodeConnectionInfo(); - result.setFromIndex(fromIndex); - result.setToIndex(toIndex); - result.setType(type); - return result; - } - - private List createRuleNodes(RuleChainId ruleChainId) { - List result = new ArrayList<>(); - result.add(getOutputNode(ruleChainId)); - result.add(getAcknowledgeNode(ruleChainId)); - result.add(getCheckpointNode(ruleChainId)); - result.add(getDeviceProfileNode(ruleChainId)); - result.add(getSaveTimeSeriesNode(ruleChainId)); - result.add(getSaveClientAttributesNode(ruleChainId)); - result.add(getMessageTypeSwitchNode(ruleChainId)); - result.add(getLogRpcFromDeviceNode(ruleChainId)); - result.add(getLogOtherNode(ruleChainId)); - result.add(getRpcCallRequestNode(ruleChainId)); - result.add(getPushToAnalyticsNode(ruleChainId)); - result.add(getPushToCloudNode(ruleChainId)); - return result; - } - - private RuleNode createRuleNode(RuleChainId ruleChainId, String type, String name, JsonNode configuration, JsonNode additionalInfo) { - RuleNode e = new RuleNode(); - e.setRuleChainId(ruleChainId); - e.setType(type); - e.setName(name); - e.setDebugMode(false); - e.setConfiguration(configuration); - e.setAdditionalInfo(additionalInfo); - e.setId(new RuleNodeId(UUID.randomUUID())); - return e; - } - - private List createConnectionsInDifferentOrder() { - List result = new ArrayList<>(); - result.add(createNodeConnectionInfo(0, 2, RPC_CONNECTION_TYPE)); - result.add(createNodeConnectionInfo(4, 1, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(5, 1, TbMsgType.ATTRIBUTES_UPDATED.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(5, 4, TbMsgType.TO_SERVER_RPC_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(5, 7, TbMsgType.POST_TELEMETRY_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(5, 6, TbMsgType.POST_ATTRIBUTES_REQUEST.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(5, 3, TbNodeConnectionType.OTHER)); - result.add(createNodeConnectionInfo(5, 2, TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE.getRuleNodeConnection())); - result.add(createNodeConnectionInfo(6, 1, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(7, 1, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(8, 11, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(8, 5, TbNodeConnectionType.SUCCESS)); - result.add(createNodeConnectionInfo(8, 0, TbNodeConnectionType.SUCCESS)); - return result; - } - - private List createRuleNodesInDifferentOrder(RuleChainId ruleChainId) { - List result = new ArrayList<>(); - result.add(getPushToAnalyticsNode(ruleChainId)); - result.add(getPushToCloudNode(ruleChainId)); - result.add(getRpcCallRequestNode(ruleChainId)); - result.add(getLogOtherNode(ruleChainId)); - result.add(getLogRpcFromDeviceNode(ruleChainId)); - result.add(getMessageTypeSwitchNode(ruleChainId)); - result.add(getSaveClientAttributesNode(ruleChainId)); - result.add(getSaveTimeSeriesNode(ruleChainId)); - result.add(getDeviceProfileNode(ruleChainId)); - result.add(getCheckpointNode(ruleChainId)); - result.add(getAcknowledgeNode(ruleChainId)); - result.add(getOutputNode(ruleChainId)); - return result; - } - - - private RuleNode getOutputNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.flow.TbRuleChainOutputNode", - "Output node", - JacksonUtil.toJsonNode("{\"version\":0}"), - JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":178,\"layoutY\":592}")); - } - - private RuleNode getCheckpointNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.flow.TbCheckpointNode", - "Checkpoint node", - JacksonUtil.toJsonNode("{\"queueName\":\"HighPriority\"}"), - JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":178,\"layoutY\":647}")); - } - - private RuleNode getSaveTimeSeriesNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", - "Save Timeseries", - JacksonUtil.toJsonNode("{\"defaultTTL\":0}"), - JacksonUtil.toJsonNode("{\"layoutX\":823,\"layoutY\":157}")); - } - - private RuleNode getMessageTypeSwitchNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", - "Message Type Switch", - JacksonUtil.toJsonNode("{\"version\":0}"), - JacksonUtil.toJsonNode("{\"layoutX\":347,\"layoutY\":149}")); - } - - private RuleNode getLogOtherNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.action.TbLogNode", - "Log Other", - JacksonUtil.toJsonNode("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"), - JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":378}")); - } - - private RuleNode getPushToCloudNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", - "Push to cloud", - JacksonUtil.toJsonNode("{\"scope\":\"SERVER_SCOPE\"}"), - JacksonUtil.toJsonNode("{\"layoutX\":1129,\"layoutY\":52}")); - } - - private RuleNode getAcknowledgeNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.flow.TbAckNode", - "Acknowledge node", - JacksonUtil.toJsonNode("{\"version\":0}"), - JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":177,\"layoutY\":703}")); - } - - private RuleNode getDeviceProfileNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", - "Device Profile Node", - JacksonUtil.toJsonNode("{\"persistAlarmRulesState\":false,\"fetchAlarmRulesStateOnStart\":false}"), - JacksonUtil.toJsonNode("{\"description\":\"Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \\\"Success\\\" relation type.\",\"layoutX\":187,\"layoutY\":468}")); - } - - private RuleNode getSaveClientAttributesNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode", - "Save Client Attributes", - JacksonUtil.toJsonNode("{\"scope\":\"CLIENT_SCOPE\"}"), - JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":52}")); - } - - private RuleNode getLogRpcFromDeviceNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.action.TbLogNode", - "Log RPC from Device", - JacksonUtil.toJsonNode("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"), - JacksonUtil.toJsonNode("{\"layoutX\":825,\"layoutY\":266}")); - } - - private RuleNode getRpcCallRequestNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", - "RPC Call Request", - JacksonUtil.toJsonNode("{\"timeoutInSeconds\":60}"), - JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":466}")); - } - - private RuleNode getPushToAnalyticsNode(RuleChainId ruleChainId) { - return createRuleNode(ruleChainId, - "org.thingsboard.rule.engine.flow.TbRuleChainInputNode", - "Push to Analytics", - JacksonUtil.toJsonNode("{\"ruleChainId\":\"af588000-6c7c-11ec-bafd-c9a47a5c8d99\"}"), - JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":477,\"layoutY\":560}")); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java deleted file mode 100644 index ac21141b75..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java +++ /dev/null @@ -1,563 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor; - -import org.junit.jupiter.params.provider.Arguments; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.context.annotation.Lazy; -import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.Dashboard; -import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.TbResource; -import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.asset.AssetProfile; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.dao.alarm.AlarmCommentService; -import org.thingsboard.server.dao.alarm.AlarmService; -import org.thingsboard.server.dao.asset.AssetProfileService; -import org.thingsboard.server.dao.asset.AssetService; -import org.thingsboard.server.dao.attributes.AttributesService; -import org.thingsboard.server.dao.customer.CustomerService; -import org.thingsboard.server.dao.dashboard.DashboardService; -import org.thingsboard.server.dao.device.DeviceCredentialsService; -import org.thingsboard.server.dao.device.DeviceProfileService; -import org.thingsboard.server.dao.device.DeviceService; -import org.thingsboard.server.dao.edge.EdgeEventService; -import org.thingsboard.server.dao.edge.EdgeService; -import org.thingsboard.server.dao.edge.EdgeSynchronizationManager; -import org.thingsboard.server.dao.entityview.EntityViewService; -import org.thingsboard.server.dao.notification.NotificationRuleService; -import org.thingsboard.server.dao.notification.NotificationTargetService; -import org.thingsboard.server.dao.notification.NotificationTemplateService; -import org.thingsboard.server.dao.oauth2.OAuth2ClientService; -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.resource.ImageService; -import org.thingsboard.server.dao.resource.ResourceService; -import org.thingsboard.server.dao.rule.RuleChainService; -import org.thingsboard.server.dao.service.DataValidator; -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.dao.user.UserService; -import org.thingsboard.server.dao.widget.WidgetTypeService; -import org.thingsboard.server.dao.widget.WidgetsBundleService; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; -import org.thingsboard.server.queue.discovery.PartitionService; -import org.thingsboard.server.queue.provider.TbQueueProducerProvider; -import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.asset.AssetMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.asset.AssetMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.asset.AssetMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.customer.CustomerMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.customer.CustomerMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.customer.CustomerMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.dashboard.DashboardMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.dashboard.DashboardMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.dashboard.DashboardMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.device.DeviceMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.device.DeviceMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.device.DeviceMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.edge.EdgeMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.notification.NotificationMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.oauth2.OAuth2MsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.queue.QueueMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.queue.QueueMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.queue.QueueMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.relation.RelationMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.relation.RelationMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.relation.RelationMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.resource.ResourceMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.resource.ResourceMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.resource.ResourceMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.rule.RuleChainMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.rule.RuleChainMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.rule.RuleChainMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.settings.AdminSettingsMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.settings.AdminSettingsMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.settings.AdminSettingsMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.telemetry.EntityDataMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.tenant.TenantMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.tenant.TenantMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.tenant.TenantMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.user.UserMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.user.UserMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.user.UserMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.constructor.widget.WidgetMsgConstructorFactory; -import org.thingsboard.server.service.edge.rpc.constructor.widget.WidgetMsgConstructorV1; -import org.thingsboard.server.service.edge.rpc.constructor.widget.WidgetMsgConstructorV2; -import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.asset.AssetEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.asset.AssetEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.asset.AssetEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.asset.profile.AssetProfileEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.asset.profile.AssetProfileEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.dashboard.DashboardEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.dashboard.DashboardEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.dashboard.DashboardEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.device.DeviceEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.device.DeviceEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.device.DeviceEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.device.profile.DeviceProfileEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.device.profile.DeviceProfileEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor; -import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor; -import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorV2; -import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorFactory; -import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV1; -import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV2; -import org.thingsboard.server.service.entitiy.TbLogEntityActionService; -import org.thingsboard.server.service.executors.DbCallbackExecutorService; -import org.thingsboard.server.service.profile.TbAssetProfileCache; -import org.thingsboard.server.service.profile.TbDeviceProfileCache; -import org.thingsboard.server.service.state.DeviceStateService; -import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; - -import java.util.UUID; -import java.util.stream.Stream; - -public abstract class BaseEdgeProcessorTest { - - @MockBean - protected TelemetrySubscriptionService tsSubService; - - @MockBean - protected TbLogEntityActionService logEntityActionService; - - @MockBean - protected RuleChainService ruleChainService; - - @MockBean - protected AlarmService alarmService; - - @MockBean - protected AlarmCommentService alarmCommentService; - - @MockBean - protected DeviceService deviceService; - - @MockBean - protected TbDeviceProfileCache deviceProfileCache; - - @MockBean - protected TbAssetProfileCache assetProfileCache; - - @MockBean - protected DashboardService dashboardService; - - @MockBean - protected AssetService assetService; - - @MockBean - protected EntityViewService entityViewService; - - @MockBean - protected TenantService tenantService; - - @MockBean - protected TenantProfileService tenantProfileService; - - @MockBean - protected EdgeService edgeService; - - @MockBean - protected CustomerService customerService; - - @MockBean - protected UserService userService; - - @MockBean - protected NotificationRuleService notificationRuleService; - - @MockBean - protected NotificationTargetService notificationTargetService; - - @MockBean - protected NotificationTemplateService notificationTemplateService; - - @MockBean - protected DeviceProfileService deviceProfileService; - - @MockBean - protected AssetProfileService assetProfileService; - - @MockBean - protected RelationService relationService; - - @MockBean - protected DeviceCredentialsService deviceCredentialsService; - - @MockBean - protected AttributesService attributesService; - - @MockBean - protected TimeseriesService timeseriesService; - - @MockBean - protected TbClusterService tbClusterService; - - @MockBean - protected DeviceStateService deviceStateService; - - @MockBean - protected EdgeEventService edgeEventService; - - @MockBean - protected WidgetsBundleService widgetsBundleService; - - @MockBean - protected WidgetTypeService widgetTypeService; - - @MockBean - protected OtaPackageService otaPackageService; - - @MockBean - protected QueueService queueService; - - @MockBean - protected PartitionService partitionService; - - @MockBean - protected ResourceService resourceService; - - @MockBean - protected OAuth2ClientService oAuth2ClientService; - - @MockBean - @Lazy - protected TbQueueProducerProvider producerProvider; - - @MockBean - protected DataValidator deviceValidator; - - @MockBean - protected DataValidator deviceProfileValidator; - - @MockBean - protected DataValidator assetValidator; - - @MockBean - protected DataValidator assetProfileValidator; - - @MockBean - protected DataValidator dashboardValidator; - - @MockBean - protected DataValidator entityViewValidator; - - @MockBean - protected DataValidator resourceValidator; - - @MockBean - protected EdgeMsgConstructor edgeMsgConstructor; - - @MockBean - protected EntityDataMsgConstructor entityDataMsgConstructor; - - @MockBean - protected AdminSettingsMsgConstructorV1 adminSettingsMsgConstructorV1; - - @MockBean - protected AdminSettingsMsgConstructorV2 adminSettingsMsgConstructorV2; - - @MockBean - protected AlarmMsgConstructorV1 alarmMsgConstructorV1; - - @MockBean - protected AlarmMsgConstructorV2 alarmMsgConstructorV2; - - @SpyBean - protected AssetMsgConstructorV1 assetMsgConstructorV1; - - @SpyBean - protected AssetMsgConstructorV2 assetMsgConstructorV2; - - @MockBean - protected CustomerMsgConstructorV1 customerMsgConstructorV1; - - @MockBean - protected CustomerMsgConstructorV2 customerMsgConstructorV2; - - @MockBean - protected DashboardMsgConstructorV1 dashboardMsgConstructorV1; - - @MockBean - protected DashboardMsgConstructorV2 dashboardMsgConstructorV2; - - @SpyBean - protected DeviceMsgConstructorV1 deviceMsgConstructorV1; - - @SpyBean - protected DeviceMsgConstructorV2 deviceMsgConstructorV2; - - @MockBean - protected EntityViewMsgConstructorV1 entityViewMsgConstructorV1; - - @MockBean - protected EntityViewMsgConstructorV2 entityViewMsgConstructorV2; - - @MockBean - protected OtaPackageMsgConstructorV1 otaPackageMsgConstructorV1; - - @MockBean - protected OtaPackageMsgConstructorV2 otaPackageMsgConstructorV2; - - @MockBean - protected QueueMsgConstructorV1 queueMsgConstructorV1; - - @MockBean - protected QueueMsgConstructorV2 queueMsgConstructorV2; - - @MockBean - protected RelationMsgConstructorV1 relationMsgConstructorV1; - - @MockBean - protected RelationMsgConstructorV2 relationMsgConstructorV2; - - @MockBean - protected ResourceMsgConstructorV1 resourceMsgConstructorV1; - - @MockBean - protected ResourceMsgConstructorV2 resourceMsgConstructorV2; - - @SpyBean - protected RuleChainMsgConstructorV1 ruleChainMsgConstructorV1; - - @SpyBean - protected RuleChainMsgConstructorV2 ruleChainMsgConstructorV2; - - @MockBean - protected TenantMsgConstructorV1 tenantMsgConstructorV1; - - @MockBean - protected TenantMsgConstructorV2 tenantMsgConstructorV2; - - @MockBean - protected UserMsgConstructorV1 userMsgConstructorV1; - - @MockBean - protected UserMsgConstructorV2 userMsgConstructorV2; - - @MockBean - protected WidgetMsgConstructorV1 widgetMsgConstructorV1; - - @MockBean - protected WidgetMsgConstructorV2 widgetMsgConstructorV2; - - @MockBean - protected NotificationMsgConstructor notificationMsgConstructor; - - @MockBean - protected OAuth2MsgConstructor oAuth2MsgConstructor; - - @MockBean - protected AlarmEdgeProcessorV1 alarmProcessorV1; - - @MockBean - protected AlarmEdgeProcessorV2 alarmProcessorV2; - - @SpyBean - protected AssetEdgeProcessorV1 assetProcessorV1; - - @SpyBean - protected AssetEdgeProcessorV2 assetProcessorV2; - - @SpyBean - protected AssetProfileEdgeProcessorV1 assetProfileProcessorV1; - - @SpyBean - protected AssetProfileEdgeProcessorV2 assetProfileProcessorV2; - - @MockBean - protected DashboardEdgeProcessorV1 dashboardProcessorV1; - - @MockBean - protected DashboardEdgeProcessorV2 dashboardProcessorV2; - - @MockBean - protected ImageService imageService; - - @SpyBean - protected DeviceEdgeProcessorV1 deviceEdgeProcessorV1; - - @SpyBean - protected DeviceEdgeProcessorV2 deviceEdgeProcessorV2; - - @SpyBean - protected DeviceProfileEdgeProcessorV1 deviceProfileProcessorV1; - - @SpyBean - protected DeviceProfileEdgeProcessorV2 deviceProfileProcessorV2; - - @MockBean - protected EntityViewProcessorV1 entityViewProcessorV1; - - @MockBean - protected EntityViewProcessorV2 entityViewProcessorV2; - - @MockBean - protected ResourceEdgeProcessorV1 resourceEdgeProcessorV1; - - @MockBean - protected ResourceEdgeProcessorV2 resourceEdgeProcessorV2; - - @MockBean - protected RelationEdgeProcessorV1 relationEdgeProcessorV1; - - @MockBean - protected RelationEdgeProcessorV2 relationEdgeProcessorV2; - - @MockBean - protected OAuth2EdgeProcessor oAuth2EdgeProcessor; - - @MockBean - protected NotificationEdgeProcessor notificationEdgeProcessor; - - @SpyBean - protected RuleChainMsgConstructorFactory ruleChainMsgConstructorFactory; - - @MockBean - protected AlarmMsgConstructorFactory alarmMsgConstructorFactory; - - @SpyBean - protected DeviceMsgConstructorFactory deviceMsgConstructorFactory; - - @SpyBean - protected AssetMsgConstructorFactory assetMsgConstructorFactory; - - @MockBean - protected DashboardMsgConstructorFactory dashboardMsgConstructorFactory; - - @MockBean - protected EntityViewMsgConstructorFactory entityViewMsgConstructorFactory; - - @MockBean - protected RelationMsgConstructorFactory relationMsgConstructorFactory; - - @MockBean - protected UserMsgConstructorFactory userMsgConstructorFactory; - - @MockBean - protected CustomerMsgConstructorFactory customerMsgConstructorFactory; - - @MockBean - protected TenantMsgConstructorFactory tenantMsgConstructorFactory; - - @MockBean - protected WidgetMsgConstructorFactory widgetBundleMsgConstructorFactory; - - @MockBean - protected AdminSettingsMsgConstructorFactory adminSettingsMsgConstructorFactory; - - @MockBean - protected OtaPackageMsgConstructorFactory otaPackageMsgConstructorFactory; - - @MockBean - protected QueueMsgConstructorFactory queueMsgConstructorFactory; - - @MockBean - protected ResourceMsgConstructorFactory resourceMsgConstructorFactory; - - @MockBean - protected AlarmEdgeProcessorFactory alarmEdgeProcessorFactory; - - @SpyBean - protected AssetEdgeProcessorFactory assetEdgeProcessorFactory; - - @MockBean - protected DashboardEdgeProcessorFactory dashboardEdgeProcessorFactory; - - @SpyBean - protected DeviceEdgeProcessorFactory deviceEdgeProcessorFactory; - - @MockBean - protected EntityViewProcessorFactory entityViewProcessorFactory; - - @MockBean - protected RelationEdgeProcessorFactory relationEdgeProcessorFactory; - - @MockBean - protected ResourceEdgeProcessorFactory resourceEdgeProcessorFactory; - - @MockBean - protected EdgeSynchronizationManager edgeSynchronizationManager; - - @MockBean - protected DbCallbackExecutorService dbCallbackExecutorService; - - protected EdgeId edgeId; - protected TenantId tenantId; - protected EdgeEvent edgeEvent; - - protected DashboardId getDashboardId(long expectedDashboardIdMSB, long expectedDashboardIdLSB) { - DashboardId dashboardId; - if (expectedDashboardIdMSB != 0 && expectedDashboardIdLSB != 0) { - dashboardId = new DashboardId(new UUID(expectedDashboardIdMSB, expectedDashboardIdLSB)); - } else { - dashboardId = new DashboardId(UUID.randomUUID()); - } - return dashboardId; - } - - protected RuleChainId getRuleChainId(long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - RuleChainId ruleChainId; - if (expectedRuleChainIdMSB != 0 && expectedRuleChainIdLSB != 0) { - ruleChainId = new RuleChainId(new UUID(expectedRuleChainIdMSB, expectedRuleChainIdLSB)); - } else { - ruleChainId = new RuleChainId(UUID.randomUUID()); - } - return ruleChainId; - } - - protected static Stream provideParameters() { - UUID dashboardUUID = UUID.randomUUID(); - UUID ruleChainUUID = UUID.randomUUID(); - return Stream.of( - Arguments.of(EdgeVersion.V_3_3_0, 0, 0, 0, 0), - Arguments.of(EdgeVersion.V_3_3_3, 0, 0, 0, 0), - Arguments.of(EdgeVersion.V_3_4_0, 0, 0, 0, 0), - Arguments.of(EdgeVersion.V_3_6_0, - dashboardUUID.getMostSignificantBits(), - dashboardUUID.getLeastSignificantBits(), - ruleChainUUID.getMostSignificantBits(), - ruleChainUUID.getLeastSignificantBits()) - ); - } - -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AbstractAssetProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AbstractAssetProcessorTest.java deleted file mode 100644 index d87cc776cd..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AbstractAssetProcessorTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.asset; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.asset.AssetProfile; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.id.AssetId; -import org.thingsboard.server.common.data.id.AssetProfileId; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessorTest; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.BDDMockito.willReturn; - -public abstract class AbstractAssetProcessorTest extends BaseEdgeProcessorTest { - - - protected AssetId assetId; - protected AssetProfileId assetProfileId; - protected AssetProfile assetProfile; - - @BeforeEach - public void setUp() { - edgeId = new EdgeId(UUID.randomUUID()); - tenantId = new TenantId(UUID.randomUUID()); - assetId = new AssetId(UUID.randomUUID()); - assetProfileId = new AssetProfileId(UUID.randomUUID()); - - assetProfile = new AssetProfile(); - assetProfile.setId(assetProfileId); - assetProfile.setName("AssetProfile"); - assetProfile.setDefault(true); - - Asset asset = new Asset(); - asset.setAssetProfileId(assetProfileId); - asset.setId(assetId); - asset.setName("Asset"); - asset.setType(assetProfile.getName()); - - edgeEvent = new EdgeEvent(); - edgeEvent.setTenantId(tenantId); - edgeEvent.setAction(EdgeEventActionType.ADDED); - - - willReturn(asset).given(assetService).findAssetById(tenantId, assetId); - willReturn(assetProfile).given(assetProfileService).findAssetProfileById(tenantId, assetProfileId); - } - - protected void updateAssetProfileDefaultFields(long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - DashboardId dashboardId = getDashboardId(expectedDashboardIdMSB, expectedDashboardIdLSB); - RuleChainId ruleChainId = getRuleChainId(expectedRuleChainIdMSB, expectedRuleChainIdLSB); - - assetProfile.setDefaultDashboardId(dashboardId); - assetProfile.setDefaultEdgeRuleChainId(ruleChainId); - - } - - protected void verify(DownlinkMsg downlinkMsg, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - AssetProfileUpdateMsg assetProfileUpdateMsg = downlinkMsg.getAssetProfileUpdateMsgList().get(0); - assertNotNull(assetProfileUpdateMsg); - Assertions.assertThat(assetProfileUpdateMsg.getDefaultDashboardIdMSB()).isEqualTo(expectedDashboardIdMSB); - Assertions.assertThat(assetProfileUpdateMsg.getDefaultDashboardIdLSB()).isEqualTo(expectedDashboardIdLSB); - Assertions.assertThat(assetProfileUpdateMsg.getDefaultRuleChainIdMSB()).isEqualTo(expectedRuleChainIdMSB); - Assertions.assertThat(assetProfileUpdateMsg.getDefaultRuleChainIdLSB()).isEqualTo(expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorTest.java deleted file mode 100644 index dab779c326..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.asset; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.context.SpringBootTest; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; - -@SpringBootTest(classes = {AssetEdgeProcessorV1.class}) -class AssetEdgeProcessorTest extends AbstractAssetProcessorTest { - - @ParameterizedTest - @MethodSource("provideParameters") - public void testAssetProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - updateAssetProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - - edgeEvent.setEntityId(assetId.getId()); - - DownlinkMsg downlinkMsg = assetProcessorV1.convertAssetEventToDownlink(edgeEvent, edgeId, edgeVersion); - - verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessorTest.java deleted file mode 100644 index edbab05ccd..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessorTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.asset; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.context.SpringBootTest; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; - -@SpringBootTest(classes = {AssetEdgeProcessorV1.class}) -class AssetProfileEdgeProcessorTest extends AbstractAssetProcessorTest{ - - @ParameterizedTest - @MethodSource("provideParameters") - public void testAssetProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - - updateAssetProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - - edgeEvent.setEntityId(assetProfileId.getId()); - - DownlinkMsg downlinkMsg = assetProfileProcessorV1.convertAssetProfileEventToDownlink(edgeEvent, edgeId, edgeVersion); - - verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/AbstractDeviceProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/AbstractDeviceProcessorTest.java deleted file mode 100644 index 31524e467a..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/AbstractDeviceProcessorTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.device; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.DeviceProfileType; -import org.thingsboard.server.common.data.DeviceTransportType; -import org.thingsboard.server.common.data.device.profile.DeviceProfileData; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.security.DeviceCredentials; -import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessorTest; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.BDDMockito.willReturn; - -public abstract class AbstractDeviceProcessorTest extends BaseEdgeProcessorTest { - - protected DeviceId deviceId; - protected DeviceProfileId deviceProfileId; - protected DeviceProfile deviceProfile; - - @BeforeEach - public void setUp() { - edgeId = new EdgeId(UUID.randomUUID()); - tenantId = new TenantId(UUID.randomUUID()); - deviceId = new DeviceId(UUID.randomUUID()); - deviceProfileId = new DeviceProfileId(UUID.randomUUID()); - - deviceProfile = new DeviceProfile(); - deviceProfile.setId(deviceProfileId); - deviceProfile.setName("DeviceProfile"); - deviceProfile.setDefault(true); - deviceProfile.setType(DeviceProfileType.DEFAULT); - DeviceProfileData deviceProfileData = new DeviceProfileData(); - deviceProfile.setProfileData(deviceProfileData); - deviceProfile.setTransportType(DeviceTransportType.DEFAULT); - - DeviceCredentials deviceCredentials = new DeviceCredentials(); - deviceCredentials.setDeviceId(deviceId); - - Device device = new Device(); - device.setDeviceProfileId(deviceProfileId); - device.setId(deviceId); - device.setName("Device"); - device.setType(deviceProfile.getName()); - - edgeEvent = new EdgeEvent(); - edgeEvent.setTenantId(tenantId); - edgeEvent.setAction(EdgeEventActionType.ADDED); - - willReturn(device).given(deviceService).findDeviceById(tenantId, deviceId); - willReturn(deviceProfile).given(deviceProfileService).findDeviceProfileById(tenantId, deviceProfileId); - willReturn(deviceCredentials).given(deviceCredentialsService).findDeviceCredentialsByDeviceId(tenantId, deviceId); - } - - protected void updateDeviceProfileDefaultFields(long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - DashboardId dashboardId = getDashboardId(expectedDashboardIdMSB, expectedDashboardIdLSB); - RuleChainId ruleChainId = getRuleChainId(expectedRuleChainIdMSB, expectedRuleChainIdLSB); - - deviceProfile.setDefaultDashboardId(dashboardId); - deviceProfile.setDefaultEdgeRuleChainId(ruleChainId); - - } - - protected void verify(DownlinkMsg downlinkMsg, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - DeviceProfileUpdateMsg deviceProfileUpdateMsg = downlinkMsg.getDeviceProfileUpdateMsgList().get(0); - assertNotNull(deviceProfileUpdateMsg); - Assertions.assertThat(deviceProfileUpdateMsg.getDefaultDashboardIdMSB()).isEqualTo(expectedDashboardIdMSB); - Assertions.assertThat(deviceProfileUpdateMsg.getDefaultDashboardIdLSB()).isEqualTo(expectedDashboardIdLSB); - Assertions.assertThat(deviceProfileUpdateMsg.getDefaultRuleChainIdMSB()).isEqualTo(expectedRuleChainIdMSB); - Assertions.assertThat(deviceProfileUpdateMsg.getDefaultRuleChainIdLSB()).isEqualTo(expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorTest.java deleted file mode 100644 index 238a79f9d2..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.device; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.context.SpringBootTest; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; - -@SpringBootTest(classes = {DeviceEdgeProcessorV1.class}) -class DeviceEdgeProcessorTest extends AbstractDeviceProcessorTest { - - @ParameterizedTest - @MethodSource("provideParameters") - public void testDeviceProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - updateDeviceProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - edgeEvent.setEntityId(deviceId.getId()); - - DownlinkMsg downlinkMsg = deviceEdgeProcessorV1.convertDeviceEventToDownlink(edgeEvent, edgeId, edgeVersion); - - verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessorTest.java deleted file mode 100644 index 179f524f6d..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.device; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.context.SpringBootTest; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.gen.edge.v1.EdgeVersion; -import org.thingsboard.server.service.edge.rpc.processor.device.profile.DeviceProfileEdgeProcessorV1; - - -@SpringBootTest(classes = {DeviceProfileEdgeProcessorV1.class}) -class DeviceProfileEdgeProcessorTest extends AbstractDeviceProcessorTest { - - @ParameterizedTest - @MethodSource("provideParameters") - public void testDeviceProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB, - long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) { - updateDeviceProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - - edgeEvent.setEntityId(deviceProfileId.getId()); - - DownlinkMsg downlinkMsg = deviceProfileProcessorV1.convertDeviceProfileEventToDownlink(edgeEvent, edgeId, edgeVersion); - - verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB); - } -} diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/TelemetryEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/TelemetryEdgeProcessorTest.java deleted file mode 100644 index 94714af463..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/TelemetryEdgeProcessorTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.edge.rpc.processor.telemetry; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; -import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.gen.edge.v1.DownlinkMsg; -import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessorTest; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; - -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = {TelemetryEdgeProcessor.class}) -@TestPropertySource(properties = { - "edges.rpc.max_telemetry_message_size=1000" -}) -public class TelemetryEdgeProcessorTest extends BaseEdgeProcessorTest { - - @SpyBean - private TelemetryEdgeProcessor telemetryEdgeProcessor; - - @MockBean - private NotificationRuleProcessor notificationRuleProcessor; - - @Test - public void testConvert_maxSizeLimit() { - Edge edge = new Edge(); - EdgeEvent edgeEvent = new EdgeEvent(); - ObjectNode body = JacksonUtil.newObjectNode(); - body.put("value", StringUtils.randomAlphanumeric(1000)); - edgeEvent.setBody(body); - - DownlinkMsg downlinkMsg = telemetryEdgeProcessor.convertTelemetryEventToDownlink(edge, edgeEvent); - Assert.assertNull(downlinkMsg); - - verify(notificationRuleProcessor, Mockito.times(1)).process(any()); - } - -} diff --git a/application/src/test/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcServiceTest.java b/application/src/test/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcServiceTest.java index 0ed53b9561..2cab5f991a 100644 --- a/application/src/test/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcServiceTest.java @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.gen.transport.TransportProtos; + import java.util.UUID; import static org.mockito.BDDMockito.then; diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceCacheKey.java b/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceCacheKey.java index 895af47a09..ed6258842d 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceCacheKey.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceCacheKey.java @@ -22,6 +22,7 @@ import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -30,6 +31,9 @@ import java.io.Serializable; @Builder public class DeviceCacheKey implements Serializable { + @Serial + private static final long serialVersionUID = 6366389552842340207L; + private final TenantId tenantId; private final DeviceId deviceId; private final String deviceName; @@ -56,4 +60,5 @@ public class DeviceCacheKey implements Serializable { return tenantId + "_" + deviceId; } } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheEvictEvent.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheEvictEvent.java similarity index 91% rename from dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheEvictEvent.java rename to common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheEvictEvent.java index 36487b2422..6d02cbfe5a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheEvictEvent.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheEvictEvent.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.edge; +package org.thingsboard.server.cache.edge; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.id.TenantId; @Data @RequiredArgsConstructor -class EdgeCacheEvictEvent { +public class EdgeCacheEvictEvent { private final TenantId tenantId; private final String newName; diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheKey.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheKey.java similarity index 87% rename from dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheKey.java rename to common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheKey.java index b07dfc32da..9ae0eaf54e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCacheKey.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCacheKey.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.edge; +package org.thingsboard.server.cache.edge; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -21,6 +21,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -29,6 +30,9 @@ import java.io.Serializable; @Builder public class EdgeCacheKey implements Serializable { + @Serial + private static final long serialVersionUID = -2299543993746815287L; + private final TenantId tenantId; private final String name; diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCaffeineCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCaffeineCache.java similarity index 96% rename from dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCaffeineCache.java rename to common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCaffeineCache.java index baba0dfd68..9204ba1848 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeCaffeineCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeCaffeineCache.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.edge; +package org.thingsboard.server.cache.edge; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cache.CacheManager; diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeRedisCache.java similarity index 97% rename from dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java rename to common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeRedisCache.java index f1502e9ad7..7fa8876a69 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/EdgeRedisCache.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.edge; +package org.thingsboard.server.cache.edge; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -32,4 +32,5 @@ public class EdgeRedisCache extends RedisTbTransactionalCache(Edge.class)); } + } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheKey.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheKey.java new file mode 100644 index 0000000000..7fbf24bb40 --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheKey.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache.edge; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +import java.io.Serial; +import java.io.Serializable; + +@Getter +@EqualsAndHashCode +@RequiredArgsConstructor +@Builder +public class RelatedEdgesCacheKey implements Serializable { + + @Serial + private static final long serialVersionUID = 5118170671697650121L; + + private final TenantId tenantId; + private final EntityId entityId; + + @Override + public String toString() { + return tenantId + "_" + entityId; + } + +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheValue.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheValue.java new file mode 100644 index 0000000000..a46b2c5875 --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCacheValue.java @@ -0,0 +1,37 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache.edge; + +import lombok.Data; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.page.PageData; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class RelatedEdgesCacheValue implements Serializable { + + @Serial + private static final long serialVersionUID = -2765080094748518572L; + + private final PageData pageData; + + public RelatedEdgesCacheValue(PageData pageData) { + this.pageData = pageData; + } + +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCaffeineCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCaffeineCache.java new file mode 100644 index 0000000000..e2007e9b09 --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesCaffeineCache.java @@ -0,0 +1,32 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache.edge; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cache.CacheManager; +import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.CaffeineTbTransactionalCache; +import org.thingsboard.server.common.data.CacheConstants; + +@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true) +@Service("RelatedEdgeIdsCache") +public class RelatedEdgesCaffeineCache extends CaffeineTbTransactionalCache { + + public RelatedEdgesCaffeineCache(CacheManager cacheManager) { + super(cacheManager, CacheConstants.RELATED_EDGES_CACHE); + } + +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesEvictEvent.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesEvictEvent.java new file mode 100644 index 0000000000..4b079668ec --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesEvictEvent.java @@ -0,0 +1,30 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache.edge; + +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@RequiredArgsConstructor +public class RelatedEdgesEvictEvent { + + private final TenantId tenantId; + private final EntityId entityId; + +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesRedisCache.java new file mode 100644 index 0000000000..099e3e65bc --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/edge/RelatedEdgesRedisCache.java @@ -0,0 +1,35 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache.edge; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.CacheSpecsMap; +import org.thingsboard.server.cache.RedisTbTransactionalCache; +import org.thingsboard.server.cache.TBRedisCacheConfiguration; +import org.thingsboard.server.cache.TbJsonRedisSerializer; +import org.thingsboard.server.common.data.CacheConstants; + +@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") +@Service("RelatedEdgeIdsCache") +public class RelatedEdgesRedisCache extends RedisTbTransactionalCache { + + public RelatedEdgesRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { + super(CacheConstants.RELATED_EDGES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(RelatedEdgesCacheValue.class)); + } + +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoCacheKey.java b/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoCacheKey.java index 2cf1768751..45de55057f 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoCacheKey.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoCacheKey.java @@ -22,6 +22,7 @@ import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -30,6 +31,9 @@ import java.io.Serializable; @Builder public class ResourceInfoCacheKey implements Serializable { + @Serial + private static final long serialVersionUID = 2100510964692846992L; + private final TenantId tenantId; private final TbResourceId tbResourceId; @@ -37,4 +41,5 @@ public class ResourceInfoCacheKey implements Serializable { public String toString() { return tenantId + "_" + tbResourceId; } + } diff --git a/common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java b/common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java index ec37a5a864..399a27f07e 100644 --- a/common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java +++ b/common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java @@ -34,11 +34,11 @@ import org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.gen.transport.TransportProtos.RestApiCallResponseMsgProto; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToVersionControlServiceMsg; -import org.thingsboard.server.gen.transport.TransportProtos.RestApiCallResponseMsgProto; import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueClusterService; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index 8b7e021484..278232d2f3 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; import java.util.Optional; +import java.util.UUID; public interface EdgeService extends EntityDaoService { @@ -86,6 +87,8 @@ public interface EdgeService extends EntityDaoService { PageData findEdgesByTenantIdAndEntityId(TenantId tenantId, EntityId ruleChainId, PageLink pageLink); + PageData findEdgeIdsByTenantIdAndEntityId(TenantId tenantId, EntityId ruleChainId, PageLink pageLink); + PageData findEdgesByTenantProfileId(TenantProfileId tenantProfileId, PageLink pageLink); List findAllRelatedEdgeIds(TenantId tenantId, EntityId entityId); @@ -95,4 +98,5 @@ public interface EdgeService extends EntityDaoService { String findMissingToRelatedRuleChains(TenantId tenantId, EdgeId edgeId, String tbRuleChainInputNodeClassName); ListenableFuture isEdgeActiveAsync(TenantId tenantId, EdgeId edgeId, String activityState); + } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/RelatedEdgesService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/RelatedEdgesService.java new file mode 100644 index 0000000000..eef5dd9e90 --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/RelatedEdgesService.java @@ -0,0 +1,30 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.edge; + +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; + +public interface RelatedEdgesService { + + PageData findEdgeIdsByEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink); + + void publishRelatedEdgeIdsEvictEvent(TenantId tenantId, EntityId entityId); + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java index 2de57f36ac..adf626a8d0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java @@ -25,6 +25,7 @@ public class CacheConstants { public static final String USER_CACHE = "users"; public static final String ENTITY_VIEW_CACHE = "entityViews"; public static final String EDGE_CACHE = "edges"; + public static final String RELATED_EDGES_CACHE = "relatedEdges"; public static final String CLAIM_DEVICES_CACHE = "claimDevices"; public static final String SECURITY_SETTINGS_CACHE = "securitySettings"; public static final String TENANT_PROFILE_CACHE = "tenantProfiles"; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index b529edeb0c..9641b5e69f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -55,7 +55,7 @@ public class DataConstants { public static final String TB_IMAGE_PREFIX = "tb-image;"; - public static final String[] allScopes() { + public static String[] allScopes() { return new String[]{CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java index 99378dbc7c..9254789527 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.kv; import jakarta.validation.Valid; import lombok.Data; + import java.util.Optional; /** diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java index 82f96ea966..f0fe38996b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java @@ -18,7 +18,6 @@ package org.thingsboard.server.common.data.kv; import jakarta.validation.Valid; import lombok.Data; -import java.util.Objects; import java.util.Optional; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java index 48cf0e6765..d0cc471888 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java @@ -29,7 +29,6 @@ public class PageDataIterableByTenantIdEntityId extends BasePageDataIterable< this.function = function; this.tenantId = tenantId; this.entityId = entityId; - } @Override @@ -40,4 +39,5 @@ public class PageDataIterableByTenantIdEntityId extends BasePageDataIterable< public interface FetchFunction { PageData fetch(TenantId tenantId, EntityId entityId, PageLink link); } + } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java index e03266b3e6..11b7df1958 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.queue.kafka; +import jakarta.annotation.PreDestroy; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -35,7 +36,6 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.TbProperty; import org.thingsboard.server.queue.util.PropertyUtils; -import javax.annotation.PreDestroy; import java.util.Collections; import java.util.List; import java.util.Map; diff --git a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java index 63806f7630..fec6185d90 100644 --- a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java +++ b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.context.ApplicationEventPublisher; import org.springframework.test.util.ReflectionTestUtils; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java index 32e209b2ea..9b52be0f58 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java @@ -22,7 +22,6 @@ import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java index 4945072530..0e5fb94a89 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java @@ -16,10 +16,10 @@ package org.thingsboard.script.api; import com.google.common.util.concurrent.FutureCallback; +import jakarta.annotation.Nullable; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import jakarta.annotation.Nullable; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java index dc83b08af4..c2851dd108 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java @@ -20,6 +20,8 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import delight.nashornsandbox.NashornSandbox; import delight.nashornsandbox.NashornSandboxes; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -31,8 +33,6 @@ import org.thingsboard.script.api.TbScriptException; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.PreDestroy; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java index ac631408ee..df6f5f58c8 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java @@ -22,10 +22,11 @@ import com.google.common.hash.Hashing; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.Getter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.mvel2.CompileException; import org.mvel2.ExecutionContext; import org.mvel2.MVEL; import org.mvel2.ParserContext; @@ -46,8 +47,6 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.PreDestroy; import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.Calendar; diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetCacheKey.java index 15009d67b0..f5b7dedaa3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetCacheKey.java @@ -21,6 +21,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -29,6 +30,7 @@ import java.io.Serializable; @Builder public class AssetCacheKey implements Serializable { + @Serial private static final long serialVersionUID = 4196610233744512673L; private final TenantId tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileCacheKey.java index 18e45d08fb..1e91d43a8f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileCacheKey.java @@ -19,11 +19,13 @@ import lombok.Data; import org.thingsboard.server.common.data.id.AssetProfileId; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Data public class AssetProfileCacheKey implements Serializable { + @Serial private static final long serialVersionUID = 8220455917177676472L; private final TenantId tenantId; @@ -60,4 +62,5 @@ public class AssetProfileCacheKey implements Serializable { return tenantId + "_" + name; } } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java index cabf433425..2cbd444f80 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java @@ -21,12 +21,15 @@ import lombok.Getter; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; +import java.io.Serial; import java.io.Serializable; @EqualsAndHashCode @Getter @AllArgsConstructor public class AttributeCacheKey implements Serializable { + + @Serial private static final long serialVersionUID = 2013369077925351881L; private final AttributeScope scope; @@ -37,4 +40,5 @@ public class AttributeCacheKey implements Serializable { public String toString() { return "{" + entityId + "}" + scope + "_" + key; } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java index 6f49b2a94e..88d6757de3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java @@ -24,7 +24,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.AttributeScope; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index 5c7430ebc8..0cd805ee24 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -304,7 +304,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb if (customer == null) { throw new DataValidationException("Can't unassign dashboards from non-existent customer!"); } - new CustomerDashboardsUnassigner(customer).removeEntities(tenantId, customer); + new CustomerDashboardsRemover(customer).removeEntities(tenantId, customer); } @Override @@ -413,11 +413,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb return EntityType.DASHBOARD; } - private class CustomerDashboardsUnassigner extends PaginatedRemover { + private class CustomerDashboardsRemover extends PaginatedRemover { - private Customer customer; + private final Customer customer; - CustomerDashboardsUnassigner(Customer customer) { + CustomerDashboardsRemover(Customer customer) { this.customer = customer; } @@ -435,7 +435,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb private class CustomerDashboardsUpdater extends PaginatedRemover { - private Customer customer; + private final Customer customer; CustomerDashboardsUpdater(Customer customer) { this.customer = customer; diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java index 6df8f9907e..ad886b6a7c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java @@ -20,11 +20,13 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Data public class DeviceProfileCacheKey implements Serializable { + @Serial private static final long serialVersionUID = 8220455917177676472L; private final TenantId tenantId; @@ -71,4 +73,5 @@ public class DeviceProfileCacheKey implements Serializable { } return tenantId + "_" + name; } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index e6ba0e5e72..afca584a80 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -612,12 +612,12 @@ public class DeviceServiceImpl extends CachedVersionedEntityService implements RelatedEdgesService { + + public static final int RELATED_EDGES_CACHE_ITEMS = 1000; + public static final PageLink FIRST_PAGE = new PageLink(RELATED_EDGES_CACHE_ITEMS); + + @Autowired + @Lazy + private EdgeService edgeService; + + @TransactionalEventListener(classes = RelatedEdgesEvictEvent.class) + @Override + public void handleEvictEvent(RelatedEdgesEvictEvent event) { + cache.evict(new RelatedEdgesCacheKey(event.getTenantId(), event.getEntityId())); + } + + @Override + public PageData findEdgeIdsByEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink) { + if (!pageLink.equals(FIRST_PAGE)) { + return edgeService.findEdgeIdsByTenantIdAndEntityId(tenantId, entityId, pageLink); + } + return cache.getAndPutInTransaction(new RelatedEdgesCacheKey(tenantId, entityId), + () -> new RelatedEdgesCacheValue(edgeService.findEdgeIdsByTenantIdAndEntityId(tenantId, entityId, pageLink)), false).getPageData(); + } + + @Override + public void publishRelatedEdgeIdsEvictEvent(TenantId tenantId, EntityId entityId) { + publishEvictEvent(new RelatedEdgesEvictEvent(tenantId, entityId)); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java index f629a97a7f..be876cb5e0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInfo; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -35,147 +36,40 @@ import java.util.UUID; */ public interface EdgeDao extends Dao { - /** - * Save or update edge object - * - * @param edge the edge object - * @return saved edge object - */ Edge save(TenantId tenantId, Edge edge); - /** - * Find edge info by id. - * - * @param tenantId the tenant id - * @param edgeId the edge id - * @return the edge info object - */ EdgeInfo findEdgeInfoById(TenantId tenantId, UUID edgeId); - /** - * Find edges by tenantId and page link. - * - * @param tenantId the tenantId - * @param pageLink the page link - * @return the list of edge objects - */ PageData findEdgesByTenantId(UUID tenantId, PageLink pageLink); - /** - * Find edges by tenantId, type and page link. - * - * @param tenantId the tenantId - * @param type the type - * @param pageLink the page link - * @return the list of edge objects - */ PageData findEdgesByTenantIdAndType(UUID tenantId, String type, PageLink pageLink); - /** - * Find edges by tenantId and edges Ids. - * - * @param tenantId the tenantId - * @param edgeIds the edge Ids - * @return the list of edge objects - */ ListenableFuture> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List edgeIds); - /** - * Find edges by tenantId, customerId and page link. - * - * @param tenantId the tenantId - * @param customerId the customerId - * @param pageLink the page link - * @return the list of edge objects - */ PageData findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, PageLink pageLink); - /** - * Find edges by tenantId, customerId, type and page link. - * - * @param tenantId the tenantId - * @param customerId the customerId - * @param type the type - * @param pageLink the page link - * @return the list of edge objects - */ PageData findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, PageLink pageLink); - /** - * Find edge infos by tenantId, customerId and page link. - * - * @param tenantId the tenantId - * @param customerId the customerId - * @param pageLink the page link - * @return the list of edge info objects - */ PageData findEdgeInfosByTenantIdAndCustomerId(UUID tenantId, UUID customerId, PageLink pageLink); - /** - * Find edge infos by tenantId, customerId, type and page link. - * - * @param tenantId the tenantId - * @param customerId the customerId - * @param type the type - * @param pageLink the page link - * @return the list of edge info objects - */ PageData findEdgeInfosByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, PageLink pageLink); - /** - * Find edges by tenantId, customerId and edges Ids. - * - * @param tenantId the tenantId - * @param customerId the customerId - * @param edgeIds the edge Ids - * @return the list of edge objects - */ ListenableFuture> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List edgeIds); - /** - * Find edges by tenantId and edge name. - * - * @param tenantId the tenantId - * @param name the edge name - * @return the optional edge object - */ Optional findEdgeByTenantIdAndName(UUID tenantId, String name); - /** - * Find tenants edge types. - * - * @return the list of tenant edge type objects - */ ListenableFuture> findTenantEdgeTypesAsync(UUID tenantId); - /** - * Find edge by routing Key. - * - * @param routingKey the edge routingKey - * @return the optional edge object - */ Optional findByRoutingKey(UUID tenantId, String routingKey); PageData findEdgeInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink); PageData findEdgeInfosByTenantId(UUID tenantId, PageLink pageLink); - /** - * Find edges by tenantId and entityId. - * - * @param tenantId the tenantId - * @param entityId the entityId - * @param entityType the entityType - * @return the list of edge objects - */ PageData findEdgesByTenantIdAndEntityId(UUID tenantId, UUID entityId, EntityType entityType, PageLink pageLink); - /** - * Find edges by tenantProfileId. - * - * @param tenantProfileId the tenantProfileId - * @return the list of edge objects - */ + PageData findEdgeIdsByTenantIdAndEntityId(UUID tenantId, UUID entityId, EntityType entityType, PageLink pageLink); + PageData findEdgesByTenantProfileId(UUID tenantProfileId, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index c03bc0a238..6a9536d8ac 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -32,6 +32,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.cache.edge.EdgeCacheEvictEvent; +import org.thingsboard.server.cache.edge.EdgeCacheKey; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; @@ -82,6 +84,7 @@ import java.util.UUID; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; +import static org.thingsboard.server.dao.edge.BaseRelatedEdgesService.RELATED_EDGES_CACHE_ITEMS; import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; @@ -122,6 +125,10 @@ public class EdgeServiceImpl extends AbstractCachedEntityService INCORRECT_TENANT_ID + id); validateId(customerId, id -> INCORRECT_CUSTOMER_ID + id); - customerEdgeUnassigner.removeEntities(tenantId, customerId); + customerEdgeRemover.removeEntities(tenantId, customerId); } @Override @@ -433,6 +440,14 @@ public class EdgeServiceImpl extends AbstractCachedEntityService findEdgeIdsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink) { + log.trace("Executing findEdgeIdsByTenantIdAndEntityId, tenantId [{}], entityId [{}], pageLink [{}]", tenantId, entityId, pageLink); + Validator.validateId(tenantId, id -> INCORRECT_TENANT_ID + id); + validatePageLink(pageLink); + return edgeDao.findEdgeIdsByTenantIdAndEntityId(tenantId.getId(), entityId.getId(), entityId.getEntityType(), pageLink); + } + @Override public PageData findEdgesByTenantProfileId(TenantProfileId tenantProfileId, PageLink pageLink) { log.trace("Executing findEdgesByTenantProfileId, tenantProfileId [{}], pageLink [{}]", tenantProfileId, pageLink); @@ -441,7 +456,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService tenantEdgesRemover = + private final PaginatedRemover tenantEdgesRemover = new PaginatedRemover<>() { @Override @@ -455,7 +470,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService customerEdgeUnassigner = new PaginatedRemover<>() { + private final PaginatedRemover customerEdgeRemover = new PaginatedRemover<>() { @Override protected PageData findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) { @@ -477,7 +492,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService relatedEdgeIdsIterator = - new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + new PageDataIterableByTenantIdEntityId<>(this::findRelatedEdgeIdsByEntityId, tenantId, entityId, RELATED_EDGES_CACHE_ITEMS); List result = new ArrayList<>(); for (EdgeId edgeId : relatedEdgeIdsIterator) { result.add(edgeId); @@ -497,18 +512,17 @@ public class EdgeServiceImpl extends AbstractCachedEntityService edgeIds = Collections.singletonList(new EdgeId(entityId.getId())); - return new PageData<>(edgeIds, 1, 1, false); + return new PageData<>(List.of(new EdgeId(entityId.getId())), 1, 1, false); case DEVICE: case ASSET: case ENTITY_VIEW: case DASHBOARD: case RULE_CHAIN: - return convertToEdgeIds(findEdgesByTenantIdAndEntityId(tenantId, entityId, pageLink)); + return relatedEdgesService.findEdgeIdsByEntityId(tenantId, entityId, pageLink); case USER: User userById = userService.findUserById(tenantId, new UserId(entityId.getId())); if (userById == null) { - return createEmptyEdgeIdPageData(); + return PageData.emptyPageData(); } if (userById.getCustomerId() == null || userById.getCustomerId().isNullUid()) { return convertToEdgeIds(findEdgesByTenantId(tenantId, pageLink)); @@ -519,17 +533,13 @@ public class EdgeServiceImpl extends AbstractCachedEntityService createEmptyEdgeIdPageData() { - return new PageData<>(new ArrayList<>(), 0, 0, false); - } - private PageData convertToEdgeIds(PageData pageData) { if (pageData == null) { - return createEmptyEdgeIdPageData(); + return PageData.emptyPageData(); } List edgeIds = new ArrayList<>(); if (pageData.getData() != null && !pageData.getData().isEmpty()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/EntityCountCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/entity/EntityCountCacheKey.java index a977e53b31..48df179fa7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/EntityCountCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/EntityCountCacheKey.java @@ -21,6 +21,7 @@ import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -28,6 +29,7 @@ import java.io.Serializable; @RequiredArgsConstructor public class EntityCountCacheKey implements Serializable { + @Serial private static final long serialVersionUID = -1992105662738434178L; private final TenantId tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewCacheKey.java index c5398653a0..59df403165 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewCacheKey.java @@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.TenantId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -29,6 +30,9 @@ import java.io.Serializable; @Builder public class EntityViewCacheKey implements Serializable { + @Serial + private static final long serialVersionUID = 5986277528222738163L; + private final TenantId tenantId; private final String name; private final EntityId entityId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index cbe6883b46..43b5e5cdfb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -157,7 +157,7 @@ public class EntityViewServiceImpl extends CachedVersionedEntityService INCORRECT_TENANT_ID + id); validateId(customerId, id -> INCORRECT_CUSTOMER_ID + id); - customerEntityViewsUnAssigner.removeEntities(tenantId, customerId); + customerEntityViewsRemover.removeEntities(tenantId, customerId); } @Override @@ -450,7 +450,7 @@ public class EntityViewServiceImpl extends CachedVersionedEntityService tenantEntityViewRemover = new PaginatedRemover() { + private final PaginatedRemover tenantEntityViewRemover = new PaginatedRemover<>() { @Override protected PageData findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { return entityViewDao.findEntityViewsByTenantId(id.getId(), pageLink); @@ -462,7 +462,7 @@ public class EntityViewServiceImpl extends CachedVersionedEntityService customerEntityViewsUnAssigner = new PaginatedRemover() { + private final PaginatedRemover customerEntityViewsRemover = new PaginatedRemover<>() { @Override protected PageData findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) { return entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageCacheKey.java index ad0120ba53..e4381a5c36 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageCacheKey.java @@ -21,6 +21,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.thingsboard.server.common.data.id.OtaPackageId; +import java.io.Serial; import java.io.Serializable; @Getter @@ -29,6 +30,9 @@ import java.io.Serializable; @Builder public class OtaPackageCacheKey implements Serializable { + @Serial + private static final long serialVersionUID = 6733960018642945642L; + private final OtaPackageId id; @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java index 2084bb9641..30cf46e41e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import java.io.Serial; import java.io.Serializable; @EqualsAndHashCode @@ -31,6 +32,7 @@ import java.io.Serializable; @Builder public class RelationCacheKey implements Serializable { + @Serial private static final long serialVersionUID = 3911151843961657570L; private final EntityId from; diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java index 2302dd0abf..d668f51dbd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChainType; -import java.util.Collection; import java.util.List; /** @@ -71,4 +70,5 @@ public interface RelationDao { List deleteInboundRelations(TenantId tenantId, EntityId entity, RelationTypeGroup relationTypeGroup); List findRuleNodeToRuleChainRelations(RuleChainType ruleChainType, int limit); + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java index 559214128d..b0c6a47783 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java @@ -120,6 +120,16 @@ public interface EdgeRepository extends JpaRepository { @Param("textSearch") String textSearch, Pageable pageable); + @Query("SELECT ee.id FROM EdgeEntity ee, RelationEntity re WHERE ee.tenantId = :tenantId " + + "AND ee.id = re.fromId AND re.fromType = 'EDGE' AND re.relationTypeGroup = 'EDGE' " + + "AND re.relationType = 'Contains' AND re.toId = :entityId AND re.toType = :entityType " + + "AND (:textSearch IS NULL OR ilike(ee.name, CONCAT('%', :textSearch, '%')) = true)") + Page findIdsByTenantIdAndEntityId(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("entityType") String entityType, + @Param("textSearch") String textSearch, + Pageable pageable); + @Query("SELECT ee FROM EdgeEntity ee, TenantEntity te WHERE ee.tenantId = te.id AND te.tenantProfileId = :tenantProfileId ") Page findByTenantProfileId(@Param("tenantProfileId") UUID tenantProfileId, Pageable pageable); @@ -134,4 +144,5 @@ public interface EdgeRepository extends JpaRepository { List findEdgesByTenantIdAndIdIn(UUID tenantId, List edgeIds); EdgeEntity findByRoutingKey(String routingKey); + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java index e76dfe9764..3c2d64825f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInfo; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -183,6 +184,18 @@ public class JpaEdgeDao extends JpaAbstractDao implements Edge DaoUtil.toPageable(pageLink))); } + @Override + public PageData findEdgeIdsByTenantIdAndEntityId(UUID tenantId, UUID entityId, EntityType entityType, PageLink pageLink) { + log.debug("Try to find edge ids by tenantId [{}], entityId [{}], entityType [{}], pageLink [{}]", tenantId, entityId, entityType, pageLink); + return DaoUtil.pageToPageData( + edgeRepository.findIdsByTenantIdAndEntityId( + tenantId, + entityId, + entityType.name(), + pageLink.getTextSearch(), + DaoUtil.toPageable(pageLink))).mapData(EdgeId::fromUUID); + } + @Override public PageData findEdgesByTenantProfileId(UUID tenantProfileId, PageLink pageLink) { log.debug("Try to find edges by tenantProfileId [{}], pageLink [{}]", tenantProfileId, pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileCacheKey.java index d8637950d2..e467a36243 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileCacheKey.java @@ -18,11 +18,13 @@ package org.thingsboard.server.dao.tenant; import lombok.Data; import org.thingsboard.server.common.data.id.TenantProfileId; +import java.io.Serial; import java.io.Serializable; @Data public class TenantProfileCacheKey implements Serializable { + @Serial private static final long serialVersionUID = 8220455917177676472L; private final TenantProfileId tenantProfileId; @@ -50,4 +52,5 @@ public class TenantProfileCacheKey implements Serializable { return tenantProfileId.toString(); } } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsLatestCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsLatestCacheKey.java index adb572922a..9880f21cc1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsLatestCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsLatestCacheKey.java @@ -18,7 +18,6 @@ package org.thingsboard.server.dao.timeseries; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; -import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import java.io.Serial; @@ -28,6 +27,8 @@ import java.io.Serializable; @Getter @AllArgsConstructor public class TsLatestCacheKey implements Serializable { + + @Serial private static final long serialVersionUID = 2024369077925351881L; private final EntityId entityId; @@ -37,4 +38,5 @@ public class TsLatestCacheKey implements Serializable { public String toString() { return "{" + entityId + "}" + key; } + } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index ea0b6eab8d..7d8018cdd8 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -42,8 +42,8 @@ import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTra import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; -import org.thingsboard.server.common.data.housekeeper.TenantEntitiesDeletionHousekeeperTask; import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; +import org.thingsboard.server.common.data.housekeeper.TenantEntitiesDeletionHousekeeperTask; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; @@ -55,12 +55,12 @@ import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.common.data.oauth2.PlatformType; import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.msg.housekeeper.HousekeeperClient; import org.thingsboard.server.dao.audit.AuditLogLevelFilter; import org.thingsboard.server.dao.audit.AuditLogLevelMask; import org.thingsboard.server.dao.audit.AuditLogLevelProperties; import org.thingsboard.server.dao.entity.EntityDaoService; import org.thingsboard.server.dao.entity.EntityServiceRegistry; -import org.thingsboard.server.common.msg.housekeeper.HousekeeperClient; import org.thingsboard.server.dao.tenant.TenantService; import java.io.IOException; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java index 6c87b0128f..a26f345fb7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java @@ -18,28 +18,19 @@ package org.thingsboard.server.dao.service; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; -import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.ResultSetExtractor; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; -import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest; -import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.CustomerId; @@ -108,7 +99,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java index 7919893d00..edb521d51a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java @@ -30,8 +30,6 @@ import org.thingsboard.server.common.data.queue.QueueStats; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.queue.QueueStatsService; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; diff --git a/dao/src/test/resources/application-test.properties b/dao/src/test/resources/application-test.properties index 06b8069f11..48f7c92b1d 100644 --- a/dao/src/test/resources/application-test.properties +++ b/dao/src/test/resources/application-test.properties @@ -75,6 +75,9 @@ cache.specs.otaPackagesData.maxSize=100000 cache.specs.edges.timeToLiveInMinutes=1440 cache.specs.edges.maxSize=100000 +cache.specs.relatedEdges.timeToLiveInMinutes=1440 +cache.specs.relatedEdges.maxSize=100000 + cache.specs.notificationRules.timeToLiveInMinutes=1440 cache.specs.notificationRules.maxSize=10000 diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index a43c4be9d2..4ae86742a2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -40,6 +40,8 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import static org.thingsboard.server.dao.edge.BaseRelatedEdgesService.RELATED_EDGES_CACHE_ITEMS; + @Slf4j @RuleNode( type = ComponentType.ACTION, @@ -66,8 +68,6 @@ import java.util.UUID; ) public class TbMsgPushToEdgeNode extends AbstractTbMsgPushNode { - static final int DEFAULT_PAGE_SIZE = 100; - @Override EdgeEvent buildEvent(TenantId tenantId, EdgeEventActionType eventAction, UUID entityId, EdgeEventType eventType, JsonNode entityBody) { @@ -122,7 +122,7 @@ public class TbMsgPushToEdgeNode extends AbstractTbMsgPushNode> futures = new ArrayList<>(); PageDataIterableByTenantIdEntityId edgeIds = new PageDataIterableByTenantIdEntityId<>( - ctx.getEdgeService()::findRelatedEdgeIdsByEntityId, ctx.getTenantId(), msg.getOriginator(), DEFAULT_PAGE_SIZE); + ctx.getEdgeService()::findRelatedEdgeIdsByEntityId, ctx.getTenantId(), msg.getOriginator(), RELATED_EDGES_CACHE_ITEMS); for (EdgeId edgeId : edgeIds) { EdgeEvent edgeEvent = buildEvent(msg, ctx); futures.add(notifyEdge(ctx, edgeEvent, edgeId)); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sns/TbSnsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sns/TbSnsNodeTest.java index 09787d3da8..eaa20e7b59 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sns/TbSnsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sns/TbSnsNodeTest.java @@ -50,9 +50,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.mock; import static org.mockito.BDDMockito.never; +import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.verifyNoMoreInteractions; @ExtendWith(MockitoExtension.class) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNodeTest.java index 48f42edb97..e8238ce5af 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNodeTest.java @@ -54,9 +54,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.mock; import static org.mockito.BDDMockito.never; +import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.verifyNoMoreInteractions; @ExtendWith(MockitoExtension.class) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java index cd191c3707..db2a015f28 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java @@ -16,8 +16,8 @@ package org.thingsboard.rule.engine.credentials; import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeTest.java index b8a70991bc..621a1a4ba2 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeTest.java @@ -49,6 +49,7 @@ import java.util.UUID; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; +import static org.thingsboard.server.dao.edge.BaseRelatedEdgesService.RELATED_EDGES_CACHE_ITEMS; @ExtendWith(MockitoExtension.class) public class TbMsgPushToEdgeNodeTest { @@ -82,7 +83,7 @@ public class TbMsgPushToEdgeNodeTest { public void ackMsgInCaseNoEdgeRelated() { Mockito.when(ctx.getTenantId()).thenReturn(tenantId); Mockito.when(ctx.getEdgeService()).thenReturn(edgeService); - Mockito.when(edgeService.findRelatedEdgeIdsByEntityId(tenantId, deviceId, new PageLink(TbMsgPushToEdgeNode.DEFAULT_PAGE_SIZE))).thenReturn(new PageData<>()); + Mockito.when(edgeService.findRelatedEdgeIdsByEntityId(tenantId, deviceId, new PageLink(RELATED_EDGES_CACHE_ITEMS))).thenReturn(new PageData<>()); TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, TbMsg.EMPTY_JSON_OBJECT, null, null); @@ -103,7 +104,7 @@ public class TbMsgPushToEdgeNodeTest { UserId userId = new UserId(UUID.randomUUID()); EdgeId edgeId = new EdgeId(UUID.randomUUID()); PageData edgePageData = new PageData<>(List.of(edgeId), 1, 1, false); - Mockito.when(edgeService.findRelatedEdgeIdsByEntityId(tenantId, userId, new PageLink(TbMsgPushToEdgeNode.DEFAULT_PAGE_SIZE))).thenReturn(edgePageData); + Mockito.when(edgeService.findRelatedEdgeIdsByEntityId(tenantId, userId, new PageLink(RELATED_EDGES_CACHE_ITEMS))).thenReturn(edgePageData); TbMsg msg = TbMsg.newMsg(TbMsgType.ATTRIBUTES_UPDATED, userId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, TbMsg.EMPTY_JSON_OBJECT, null, null); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java index 84bbafe825..fb08dff8e2 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata; import com.google.common.util.concurrent.Futures; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index f4e69b9079..894a538c80 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -35,7 +35,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.asset.Asset; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index 1efc1c1e73..3b6b1eb3c6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -37,7 +37,6 @@ import org.thingsboard.rule.engine.util.TbMsgSource; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.Tenant; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java index 6ecd1b6eb9..e567160b0a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java @@ -15,9 +15,9 @@ */ package org.thingsboard.rule.engine.metadata; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Assertions; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index cb9c913a4e..9f20301b46 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -33,7 +33,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; import org.thingsboard.server.common.data.AttributeScope; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java index 66ab5826b7..b5cf5533b8 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java @@ -53,7 +53,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; import static org.mockito.Mockito.mock;