committed by
GitHub
91 changed files with 552 additions and 1650 deletions
@ -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); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
@ -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<RuleNodeProto> nodesList, |
|||
String expectedConfiguration) { |
|||
Optional<RuleNodeProto> 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<RuleNode> nodes, List<NodeConnectionInfo> connections) { |
|||
RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); |
|||
ruleChainMetaData.setRuleChainId(ruleChainId); |
|||
ruleChainMetaData.setFirstNodeIndex(firstNodeIndex); |
|||
ruleChainMetaData.setNodes(nodes); |
|||
ruleChainMetaData.setConnections(connections); |
|||
ruleChainMetaData.setRuleChainConnections(null); |
|||
return ruleChainMetaData; |
|||
} |
|||
|
|||
private List<NodeConnectionInfo> createConnections() { |
|||
List<NodeConnectionInfo> 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<RuleNode> createRuleNodes(RuleChainId ruleChainId) { |
|||
List<RuleNode> 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<NodeConnectionInfo> createConnectionsInDifferentOrder() { |
|||
List<NodeConnectionInfo> 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<RuleNode> createRuleNodesInDifferentOrder(RuleChainId ruleChainId) { |
|||
List<RuleNode> 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}")); |
|||
} |
|||
} |
|||
@ -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<Device> deviceValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<DeviceProfile> deviceProfileValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<Asset> assetValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<AssetProfile> assetProfileValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<Dashboard> dashboardValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<EntityView> entityViewValidator; |
|||
|
|||
@MockBean |
|||
protected DataValidator<TbResource> 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<Arguments> 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()) |
|||
); |
|||
} |
|||
|
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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()); |
|||
} |
|||
|
|||
} |
|||
@ -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; |
|||
} |
|||
|
|||
} |
|||
@ -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<EdgeId> pageData; |
|||
|
|||
public RelatedEdgesCacheValue(PageData<EdgeId> pageData) { |
|||
this.pageData = pageData; |
|||
} |
|||
|
|||
} |
|||
@ -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<RelatedEdgesCacheKey, RelatedEdgesCacheValue> { |
|||
|
|||
public RelatedEdgesCaffeineCache(CacheManager cacheManager) { |
|||
super(cacheManager, CacheConstants.RELATED_EDGES_CACHE); |
|||
} |
|||
|
|||
} |
|||
@ -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; |
|||
|
|||
} |
|||
@ -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<RelatedEdgesCacheKey, RelatedEdgesCacheValue> { |
|||
|
|||
public RelatedEdgesRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { |
|||
super(CacheConstants.RELATED_EDGES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(RelatedEdgesCacheValue.class)); |
|||
} |
|||
|
|||
} |
|||
@ -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<EdgeId> findEdgeIdsByEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink); |
|||
|
|||
void publishRelatedEdgeIdsEvictEvent(TenantId tenantId, EntityId entityId); |
|||
|
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
/** |
|||
* 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.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.event.TransactionalEventListener; |
|||
import org.thingsboard.server.cache.edge.RelatedEdgesCacheKey; |
|||
import org.thingsboard.server.cache.edge.RelatedEdgesCacheValue; |
|||
import org.thingsboard.server.cache.edge.RelatedEdgesEvictEvent; |
|||
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; |
|||
import org.thingsboard.server.dao.entity.AbstractCachedEntityService; |
|||
|
|||
@Service |
|||
public class BaseRelatedEdgesService extends AbstractCachedEntityService<RelatedEdgesCacheKey, RelatedEdgesCacheValue, RelatedEdgesEvictEvent> 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<EdgeId> 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)); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue