added tests for check relation presence node & test for TbMsgType and ActionType & refactoring

This commit is contained in:
ShvaykaD 2023-06-30 13:35:03 +03:00
parent f01b2d6595
commit 8beb81cf8d
22 changed files with 498 additions and 69 deletions

View File

@ -273,7 +273,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
TbMsg msg = TbMsg.newMsg(ENTITY_CREATED.name(), device.getId(), device.getCustomerId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode));
sendToRuleEngine(device.getTenantId(), msg, null);
} catch (JsonProcessingException | IllegalArgumentException e) {
log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), ENTITY_CREATED, e);
log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), ENTITY_CREATED.name(), e);
}
}

View File

@ -63,6 +63,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg;
import java.util.UUID;
import static org.thingsboard.server.common.data.msg.TbMsgType.ENTITY_CREATED;
import static org.thingsboard.server.common.data.msg.TbMsgType.TO_SERVER_RPC_REQUEST;
@Component
@Slf4j
@ -218,7 +219,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
ObjectNode data = JacksonUtil.newObjectNode();
data.put("method", deviceRpcCallMsg.getRequestMsg().getMethod());
data.put("params", deviceRpcCallMsg.getRequestMsg().getParams());
TbMsg tbMsg = TbMsg.newMsg(TbMsgType.TO_SERVER_RPC_REQUEST.name(), deviceId, null, metaData,
TbMsg tbMsg = TbMsg.newMsg(TO_SERVER_RPC_REQUEST.name(), deviceId, null, metaData,
TbMsgDataType.JSON, JacksonUtil.OBJECT_MAPPER.writeValueAsString(data));
tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() {
@Override

View File

@ -42,7 +42,7 @@ public enum TbMsgType {
ALARM(null),
ALARM_ACK("Alarm Acknowledged"),
ALARM_CLEAR("Alarm Cleared"),
ALARM_DELETE("Alarm Deleted"),
ALARM_DELETE(null),
ALARM_ASSIGNED("Alarm Assigned"),
ALARM_UNASSIGNED("Alarm Unassigned"),
COMMENT_CREATED("Comment Created"),
@ -78,7 +78,7 @@ public enum TbMsgType {
this.ruleNodeConnection = ruleNodeConnection;
}
public static String getRuleNodeConnection(String msgType) {
public static String getRuleNodeConnectionOrElseOther(String msgType) {
if (msgType == null) {
return TbNodeConnectionType.OTHER;
} else {

View File

@ -0,0 +1,63 @@
/**
* Copyright © 2016-2023 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.common.data.audit;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.common.data.audit.ActionType.ACTIVATED;
import static org.thingsboard.server.common.data.audit.ActionType.ATTRIBUTES_READ;
import static org.thingsboard.server.common.data.audit.ActionType.CREDENTIALS_READ;
import static org.thingsboard.server.common.data.audit.ActionType.CREDENTIALS_UPDATED;
import static org.thingsboard.server.common.data.audit.ActionType.DELETED_COMMENT;
import static org.thingsboard.server.common.data.audit.ActionType.LOCKOUT;
import static org.thingsboard.server.common.data.audit.ActionType.LOGIN;
import static org.thingsboard.server.common.data.audit.ActionType.LOGOUT;
import static org.thingsboard.server.common.data.audit.ActionType.RPC_CALL;
import static org.thingsboard.server.common.data.audit.ActionType.SMS_SENT;
import static org.thingsboard.server.common.data.audit.ActionType.SUSPENDED;
class ActionTypeTest {
private static final List<ActionType> typesWithNullRuleEngineMsgType = List.of(
RPC_CALL,
CREDENTIALS_UPDATED,
ACTIVATED,
SUSPENDED,
CREDENTIALS_READ,
ATTRIBUTES_READ,
LOGIN,
LOGOUT,
LOCKOUT,
DELETED_COMMENT,
SMS_SENT
);
// backward-compatibility tests
@Test
void getRuleEngineMsgTypeTest() {
var types = ActionType.values();
for (var type : types) {
if (typesWithNullRuleEngineMsgType.contains(type)) {
assertThat(type.getRuleEngineMsgType()).isEmpty();
}
}
}
}

View File

@ -0,0 +1,70 @@
/**
* Copyright © 2016-2023 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.common.data.msg;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.common.data.msg.TbMsgType.ALARM;
import static org.thingsboard.server.common.data.msg.TbMsgType.ALARM_DELETE;
import static org.thingsboard.server.common.data.msg.TbMsgType.ENTITY_ASSIGNED_TO_EDGE;
import static org.thingsboard.server.common.data.msg.TbMsgType.ENTITY_UNASSIGNED_FROM_EDGE;
import static org.thingsboard.server.common.data.msg.TbMsgType.PROVISION_FAILURE;
import static org.thingsboard.server.common.data.msg.TbMsgType.PROVISION_SUCCESS;
class TbMsgTypeTest {
private static final List<TbMsgType> typesWithNullRuleNodeConnection = List.of(
ALARM,
ALARM_DELETE,
ENTITY_ASSIGNED_TO_EDGE,
ENTITY_UNASSIGNED_FROM_EDGE,
PROVISION_FAILURE,
PROVISION_SUCCESS
);
// backward-compatibility tests
@Test
void getRuleNodeConnectionsTest() {
var tbMsgTypes = TbMsgType.values();
for (var type : tbMsgTypes) {
if (typesWithNullRuleNodeConnection.contains(type)) {
assertThat(type.getRuleNodeConnection()).isNull();
}
}
}
@Test
void getRuleNodeConnectionOrElseOtherTest() {
assertThat(TbMsgType.getRuleNodeConnectionOrElseOther(null))
.isEqualTo(TbNodeConnectionType.OTHER);
var tbMsgTypes = TbMsgType.values();
for (var type : tbMsgTypes) {
if (typesWithNullRuleNodeConnection.contains(type)) {
assertThat(TbMsgType.getRuleNodeConnectionOrElseOther(type.name()))
.isEqualTo(TbNodeConnectionType.OTHER);
} else {
assertThat(TbMsgType.getRuleNodeConnectionOrElseOther(type.name())).isNotNull()
.isNotEqualTo(TbNodeConnectionType.OTHER);
}
}
}
}

View File

@ -22,6 +22,7 @@ import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
@ -62,6 +63,9 @@ public class TbCheckRelationNode implements TbNode {
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbCheckRelationNodeConfiguration.class);
if (config.isCheckForSingleEntity()) {
if (StringUtils.isEmpty(config.getEntityType()) || StringUtils.isEmpty(config.getEntityId())) {
throw new TbNodeException("Entity should be specified!");
}
this.singleEntityId = EntityIdFactory.getByTypeAndId(config.getEntityType(), config.getEntityId());
ctx.checkTenantEntity(singleEntityId);
}
@ -90,9 +94,9 @@ public class TbCheckRelationNode implements TbNode {
}
private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) {
ListenableFuture<List<EntityRelation>> relationListFuture = EntitySearchDirection.FROM.name().equals(config.getDirection()) ? ctx.getRelationService()
.findByToAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON) : ctx.getRelationService()
.findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON);
ListenableFuture<List<EntityRelation>> relationListFuture = EntitySearchDirection.FROM.name().equals(config.getDirection()) ?
ctx.getRelationService().findByToAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON) :
ctx.getRelationService().findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON);
return Futures.transformAsync(relationListFuture, this::isEmptyList, ctx.getDbCallbackExecutor());
}

View File

@ -50,7 +50,7 @@ public class TbMsgTypeSwitchNode implements TbNode {
@Override
public void onMsg(TbContext ctx, TbMsg msg) {
ctx.tellNext(msg, TbMsgType.getRuleNodeConnection(msg.getType()));
ctx.tellNext(msg, TbMsgType.getRuleNodeConnectionOrElseOther(msg.getType()));
}
}

View File

@ -50,34 +50,33 @@ import static org.thingsboard.server.common.data.msg.TbMsgType.POST_ATTRIBUTES_R
class TbAssetTypeSwitchNodeTest {
TenantId tenantId;
AssetId assetId;
AssetId assetIdDeleted;
AssetProfile assetProfile;
TbContext ctx;
TbAssetTypeSwitchNode node;
EmptyNodeConfiguration config;
TbMsgCallback callback;
RuleEngineAssetProfileCache assetProfileCache;
private static final TbMsgMetaData EMPTY_METADATA = new TbMsgMetaData();
private static final String EMPTY_DATA = "{}";
private AssetId assetId;
private AssetId assetIdDeleted;
private TbContext ctx;
private TbAssetTypeSwitchNode node;
private TbMsgCallback callback;
@BeforeEach
void setUp() throws TbNodeException {
tenantId = new TenantId(UUID.randomUUID());
TenantId tenantId = new TenantId(UUID.randomUUID());
assetId = new AssetId(UUID.randomUUID());
assetIdDeleted = new AssetId(UUID.randomUUID());
assetProfile = new AssetProfile();
AssetProfile assetProfile = new AssetProfile();
assetProfile.setTenantId(tenantId);
assetProfile.setName("TestAssetProfile");
//node
config = new EmptyNodeConfiguration();
EmptyNodeConfiguration config = new EmptyNodeConfiguration();
node = new TbAssetTypeSwitchNode();
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
//init mock
ctx = mock(TbContext.class);
assetProfileCache = mock(RuleEngineAssetProfileCache.class);
RuleEngineAssetProfileCache assetProfileCache = mock(RuleEngineAssetProfileCache.class);
callback = mock(TbMsgCallback.class);
when(ctx.getTenantId()).thenReturn(tenantId);
@ -122,7 +121,7 @@ class TbAssetTypeSwitchNodeTest {
}
private TbMsg getTbMsg(EntityId entityId) {
return TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), entityId, new TbMsgMetaData(), "{}", callback);
return TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), entityId, EMPTY_METADATA, EMPTY_DATA, callback);
}
}

View File

@ -29,7 +29,6 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.common.msg.TbMsg;
@ -53,14 +52,15 @@ class TbCheckAlarmStatusNodeTest {
private static final DeviceId DEVICE_ID = new DeviceId(UUID.randomUUID());
private static final AlarmId ALARM_ID = new AlarmId(UUID.randomUUID());
private static final TestDbCallbackExecutor DB_EXECUTOR = new TestDbCallbackExecutor();
private static final TbMsgMetaData EMPTY_METADATA = new TbMsgMetaData();
private static TbCheckAlarmStatusNode node;
private TbCheckAlarmStatusNode node;
private static TbContext ctx;
private static RuleEngineAlarmService alarmService;
private TbContext ctx;
private RuleEngineAlarmService alarmService;
@BeforeEach
public void setUp() throws TbNodeException {
void setUp() throws TbNodeException {
var config = new TbCheckAlarmStatusNodeConfig().defaultConfiguration();
ctx = mock(TbContext.class);
@ -88,7 +88,7 @@ class TbCheckAlarmStatusNodeTest {
alarm.setType("General Alarm");
String msgData = JacksonUtil.toString(alarm);
TbMsg msg = getTbMsg(DEVICE_ID, msgData);
TbMsg msg = getTbMsg(msgData);
when(alarmService.findAlarmByIdAsync(TENANT_ID, ALARM_ID)).thenReturn(Futures.immediateFuture(alarm));
@ -114,7 +114,7 @@ class TbCheckAlarmStatusNodeTest {
alarm.setCleared(true);
String msgData = JacksonUtil.toString(alarm);
TbMsg msg = getTbMsg(DEVICE_ID, msgData);
TbMsg msg = getTbMsg(msgData);
when(alarmService.findAlarmByIdAsync(TENANT_ID, ALARM_ID)).thenReturn(Futures.immediateFuture(alarm));
@ -140,7 +140,7 @@ class TbCheckAlarmStatusNodeTest {
alarm.setCleared(true);
String msgData = JacksonUtil.toString(alarm);
TbMsg msg = getTbMsg(DEVICE_ID, msgData);
TbMsg msg = getTbMsg(msgData);
when(alarmService.findAlarmByIdAsync(TENANT_ID, ALARM_ID)).thenReturn(Futures.immediateFuture(null));
@ -159,8 +159,8 @@ class TbCheckAlarmStatusNodeTest {
assertThat(value).isInstanceOf(TbNodeException.class).hasMessage("No such alarm found.");
}
private TbMsg getTbMsg(EntityId entityId, String msgData) {
return TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), entityId, new TbMsgMetaData(), msgData);
private TbMsg getTbMsg(String msgData) {
return TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), DEVICE_ID, EMPTY_METADATA, msgData);
}
}

View File

@ -50,9 +50,9 @@ class TbCheckMessageNodeTest {
private static final String EMPTY_DATA = "{}";
private static final TbMsg EMPTY_POST_ATTRIBUTES_MSG = TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), DEVICE_ID, EMPTY_METADATA, EMPTY_DATA);
private static TbCheckMessageNode node;
private TbCheckMessageNode node;
private static TbContext ctx;
private TbContext ctx;
@BeforeEach
void setUp() {

View File

@ -0,0 +1,297 @@
/**
* Copyright © 2016-2023 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.rule.engine.filter;
import com.google.common.util.concurrent.Futures;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.TestDbCallbackExecutor;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.relation.RelationService;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.thingsboard.server.common.data.msg.TbMsgType.POST_ATTRIBUTES_REQUEST;
class TbCheckRelationNodeTest {
private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID());
private static final DeviceId DEVICE_ID = new DeviceId(UUID.randomUUID());
private static final TestDbCallbackExecutor DB_EXECUTOR = new TestDbCallbackExecutor();
private static final TbMsgMetaData EMPTY_METADATA = new TbMsgMetaData();
private static final String EMPTY_DATA = "{}";
private static final TbMsg EMPTY_POST_ATTRIBUTES_MSG = TbMsg.newMsg(POST_ATTRIBUTES_REQUEST.name(), DEVICE_ID, EMPTY_METADATA, EMPTY_DATA);
private TbCheckRelationNode node;
private TbContext ctx;
private RelationService relationService;
@BeforeEach
void setUp() {
ctx = mock(TbContext.class);
relationService = mock(RelationService.class);
when(ctx.getTenantId()).thenReturn(TENANT_ID);
when(ctx.getRelationService()).thenReturn(relationService);
when(ctx.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR);
node = new TbCheckRelationNode();
}
@AfterEach
void tearDown() {
node.destroy();
}
@Test
void givenDefaultConfig_whenInit_then_throwException() {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
// WHEN
var exception = assertThrows(TbNodeException.class, () -> node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config))));
// THEN
assertThat(exception.getMessage()).isEqualTo("Entity should be specified!");
}
@Test
void givenCustomConfigWithCheckRelationToSpecificEntity_whenOnMsg_then_True() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
AssetId assetId = new AssetId(UUID.randomUUID());
config.setEntityType(assetId.getEntityType().name());
config.setEntityId(assetId.getId().toString());
when(relationService.checkRelationAsync(TENANT_ID, assetId, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(true));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.TRUE));
verify(ctx, never()).tellFailure(any(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfigWithCheckRelationToSpecificEntity_whenOnMsg_then_False() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
AssetId assetId = new AssetId(UUID.randomUUID());
config.setEntityType(assetId.getEntityType().name());
config.setEntityId(assetId.getId().toString());
when(relationService.checkRelationAsync(TENANT_ID, assetId, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(false));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.FALSE));
verify(ctx, never()).tellFailure(any(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfigWithCheckRelationToSpecificEntityAndDirectionTo_whenOnMsg_then_True() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
AssetId assetId = new AssetId(UUID.randomUUID());
config.setEntityType(assetId.getEntityType().name());
config.setEntityId(assetId.getId().toString());
config.setDirection(EntitySearchDirection.TO.name());
when(relationService.checkRelationAsync(TENANT_ID, DEVICE_ID, assetId, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(true));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.TRUE));
verify(ctx, never()).tellFailure(any(), any());
verify(relationService, never()).findByFromAndTypeAsync(any(), any(), anyString(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfigWithCheckRelationToSpecificEntityAndDirectionTo_whenOnMsg_then_False() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
AssetId assetId = new AssetId(UUID.randomUUID());
config.setEntityType(assetId.getEntityType().name());
config.setEntityId(assetId.getId().toString());
config.setDirection(EntitySearchDirection.TO.name());
when(relationService.checkRelationAsync(TENANT_ID, DEVICE_ID, assetId, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(false));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.FALSE));
verify(ctx, never()).tellFailure(any(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfig_whenOnMsg_then_True() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
config.setCheckForSingleEntity(false);
var entityRelation = new EntityRelation();
entityRelation.setTo(DEVICE_ID);
entityRelation.setFrom(new AssetId(UUID.randomUUID()));
entityRelation.setType(EntityRelation.CONTAINS_TYPE);
entityRelation.setTypeGroup(RelationTypeGroup.COMMON);
when(relationService.findByToAndTypeAsync(TENANT_ID, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(List.of(entityRelation)));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.TRUE));
verify(ctx, never()).tellFailure(any(), any());
verify(relationService, never()).findByFromAndTypeAsync(any(), any(), anyString(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfig_whenOnMsg_then_False() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
config.setCheckForSingleEntity(false);
when(relationService.findByToAndTypeAsync(TENANT_ID, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(Collections.emptyList()));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.FALSE));
verify(ctx, never()).tellFailure(any(), any());
verify(relationService, never()).findByFromAndTypeAsync(any(), any(), anyString(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfigDirectionTo_whenOnMsg_then_True() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
config.setCheckForSingleEntity(false);
config.setDirection(EntitySearchDirection.TO.name());
var entityRelation = new EntityRelation();
entityRelation.setFrom(new AssetId(UUID.randomUUID()));
entityRelation.setTo(DEVICE_ID);
entityRelation.setType(EntityRelation.CONTAINS_TYPE);
entityRelation.setTypeGroup(RelationTypeGroup.COMMON);
when(relationService.findByFromAndTypeAsync(TENANT_ID, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(List.of(entityRelation)));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.TRUE));
verify(ctx, never()).tellFailure(any(), any());
verify(relationService, never()).findByToAndTypeAsync(any(), any(), anyString(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
@Test
void givenCustomConfigDirectionTo_whenOnMsg_then_False() throws TbNodeException {
// GIVEN
var config = new TbCheckRelationNodeConfiguration().defaultConfiguration();
config.setCheckForSingleEntity(false);
config.setDirection(EntitySearchDirection.TO.name());
when(relationService.findByFromAndTypeAsync(TENANT_ID, DEVICE_ID, config.getRelationType(), RelationTypeGroup.COMMON)).thenReturn(Futures.immediateFuture(Collections.emptyList()));
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
// WHEN
node.onMsg(ctx, EMPTY_POST_ATTRIBUTES_MSG);
// THEN
ArgumentCaptor<TbMsg> newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
verify(ctx, times(1)).tellNext(newMsgCaptor.capture(), eq(TbNodeConnectionType.FALSE));
verify(ctx, never()).tellFailure(any(), any());
verify(relationService, never()).findByToAndTypeAsync(any(), any(), anyString(), any());
TbMsg newMsg = newMsgCaptor.getValue();
assertThat(newMsg).isNotNull();
assertThat(newMsg).isSameAs(EMPTY_POST_ATTRIBUTES_MSG);
}
}

View File

@ -50,34 +50,30 @@ import static org.thingsboard.server.common.data.msg.TbMsgType.POST_ATTRIBUTES_R
class TbDeviceTypeSwitchNodeTest {
TenantId tenantId;
DeviceId deviceId;
DeviceId deviceIdDeleted;
DeviceProfile deviceProfile;
TbContext ctx;
TbDeviceTypeSwitchNode node;
EmptyNodeConfiguration config;
TbMsgCallback callback;
RuleEngineDeviceProfileCache deviceProfileCache;
private DeviceId deviceId;
private DeviceId deviceIdDeleted;
private TbContext ctx;
private TbDeviceTypeSwitchNode node;
private TbMsgCallback callback;
@BeforeEach
void setUp() throws TbNodeException {
tenantId = new TenantId(UUID.randomUUID());
TenantId tenantId = new TenantId(UUID.randomUUID());
deviceId = new DeviceId(UUID.randomUUID());
deviceIdDeleted = new DeviceId(UUID.randomUUID());
deviceProfile = new DeviceProfile();
DeviceProfile deviceProfile = new DeviceProfile();
deviceProfile.setTenantId(tenantId);
deviceProfile.setName("TestDeviceProfile");
//node
config = new EmptyNodeConfiguration();
EmptyNodeConfiguration config = new EmptyNodeConfiguration();
node = new TbDeviceTypeSwitchNode();
node.init(ctx, new TbNodeConfiguration(JacksonUtil.valueToTree(config)));
//init mock
ctx = mock(TbContext.class);
deviceProfileCache = mock(RuleEngineDeviceProfileCache.class);
RuleEngineDeviceProfileCache deviceProfileCache = mock(RuleEngineDeviceProfileCache.class);
callback = mock(TbMsgCallback.class);
when(ctx.getTenantId()).thenReturn(tenantId);

View File

@ -53,8 +53,8 @@ public class TbJsFilterNodeTest {
@Mock
private ScriptEngine scriptEngine;
private RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
private RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased());
private final RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
private final RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased());
@Test
public void falseEvaluationDoNotSendMsg() throws TbNodeException {

View File

@ -47,8 +47,8 @@ public class TbJsSwitchNodeTest {
@Mock
private ScriptEngine scriptEngine;
private RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
private RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased());
private final RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
private final RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased());
@Test
public void multipleRoutesAreAllowed() throws TbNodeException {

View File

@ -43,9 +43,9 @@ class TbMsgTypeSwitchNodeTest {
private static final TbMsgMetaData EMPTY_METADATA = new TbMsgMetaData();
private static final String EMPTY_DATA = "{}";
private static TbMsgTypeSwitchNode node;
private TbMsgTypeSwitchNode node;
private static TbContext ctx;
private TbContext ctx;
@BeforeEach
void setUp() {
@ -84,9 +84,8 @@ class TbMsgTypeSwitchNodeTest {
assertThat(msg).isNotNull();
assertThat(msg.getType()).isNotNull();
assertThat(msg).isSameAs(tbMsgList.get(i));
// todo add additional validation that types like ALARM or PROVISION returns OTHER for backward-compatibility.
assertThat(resultNodeConnections.get(i))
.isEqualTo(TbMsgType.getRuleNodeConnection(msg.getType()));
.isEqualTo(TbMsgType.getRuleNodeConnectionOrElseOther(msg.getType()));
}
}

View File

@ -45,9 +45,9 @@ class TbOriginatorTypeSwitchNodeTest {
private static final TbMsgMetaData EMPTY_METADATA = new TbMsgMetaData();
private static final String EMPTY_DATA = "{}";
private static TbOriginatorTypeSwitchNode node;
private TbOriginatorTypeSwitchNode node;
private static TbContext ctx;
private TbContext ctx;
@BeforeEach
void setUp() {

View File

@ -208,7 +208,7 @@ public class TbGetCustomerAttributeNodeTest {
public void givenMsgDataIsNotAnJsonObjectAndFetchToData_whenOnMsg_thenException() {
// GIVEN
node.fetchTo = FetchTo.DATA;
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
// WHEN
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg));
@ -223,7 +223,7 @@ public class TbGetCustomerAttributeNodeTest {
// GIVEN
var userId = new UserId(UUID.randomUUID());
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), userId, new TbMsgMetaData(), "{}");
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), userId, new TbMsgMetaData(), "{}");
when(ctxMock.getTenantId()).thenReturn(TENANT_ID);
@ -467,7 +467,7 @@ public class TbGetCustomerAttributeNodeTest {
var msgData = "{\"temp\":42,\"humidity\":77,\"messageBodyPattern1\":\"targetKey2\",\"messageBodyPattern2\":\"sourceKey3\"}";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), originator, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), originator, msgMetaData, msgData);
}
@RequiredArgsConstructor

View File

@ -456,7 +456,7 @@ public class TbGetCustomerDetailsNodeTest {
var msgData = "{\"dataKey1\":123,\"dataKey2\":\"dataValue2\"}";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), originator, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), originator, msgMetaData, msgData);
}
private void mockFindCustomer() {

View File

@ -162,7 +162,7 @@ public class TbGetOriginatorFieldsNodeTest {
node.fetchTo = FetchTo.DATA;
var msgMetaData = new TbMsgMetaData();
var msgData = "{\"temp\":42,\"humidity\":77}";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
when(ctxMock.getDeviceService()).thenReturn(deviceServiceMock);
when(ctxMock.getTenantId()).thenReturn(DUMMY_TENANT_ID);
@ -205,7 +205,7 @@ public class TbGetOriginatorFieldsNodeTest {
"testKey1", "testValue1",
"testKey2", "123"));
var msgData = "[\"value1\",\"value2\"]";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
when(ctxMock.getDeviceService()).thenReturn(deviceServiceMock);
when(ctxMock.getTenantId()).thenReturn(DUMMY_TENANT_ID);
@ -253,7 +253,7 @@ public class TbGetOriginatorFieldsNodeTest {
"testKey1", "testValue1",
"testKey2", "123"));
var msgData = "[\"value1\",\"value2\"]";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
when(ctxMock.getDeviceService()).thenReturn(deviceServiceMock);
when(ctxMock.getTenantId()).thenReturn(DUMMY_TENANT_ID);
@ -311,7 +311,7 @@ public class TbGetOriginatorFieldsNodeTest {
"testKey1", "testValue1",
"testKey2", "123"));
var msgData = "[\"value1\",\"value2\"]";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), new DashboardId(UUID.randomUUID()), msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), new DashboardId(UUID.randomUUID()), msgMetaData, msgData);
when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR);

View File

@ -222,7 +222,7 @@ public class TbGetRelatedAttributeNodeTest {
public void givenMsgDataIsNotAnJsonObjectAndFetchToData_whenOnMsg_thenException() {
// GIVEN
node.fetchTo = FetchTo.DATA;
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
// WHEN
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg));

View File

@ -188,7 +188,7 @@ public class TbGetTenantAttributeNodeTest {
public void givenMsgDataIsNotAnJsonObjectAndFetchToData_whenOnMsg_thenException() {
// GIVEN
node.fetchTo = FetchTo.DATA;
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, new TbMsgMetaData(), "[]");
// WHEN
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg));
@ -396,7 +396,7 @@ public class TbGetTenantAttributeNodeTest {
var msgData = "{\"temp\":42,\"humidity\":77,\"messageBodyPattern1\":\"targetKey2\",\"messageBodyPattern2\":\"sourceKey3\"}";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), originator, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), originator, msgMetaData, msgData);
}
@RequiredArgsConstructor

View File

@ -287,7 +287,7 @@ public class TbGetTenantDetailsNodeTest {
var msgData = "{\"dataKey1\":123,\"dataKey2\":\"dataValue2\"}";
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.getRuleNodeConnection(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
msg = TbMsg.newMsg(POST_TELEMETRY_REQUEST.name(), DUMMY_DEVICE_ORIGINATOR, msgMetaData, msgData);
}
private void mockFindTenant() {