Added singleton mode validation and tests

This commit is contained in:
YevhenBondarenko 2023-04-21 18:30:47 +02:00
parent e342ce1b3e
commit 8d2f6eb856
3 changed files with 86 additions and 5 deletions

View File

@ -183,8 +183,8 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
}
private boolean isMyNode() {
return systemContext.getDiscoveryService().isMonolith()
|| !ruleNode.isSingletonMode()
return !ruleNode.isSingletonMode()
|| systemContext.getDiscoveryService().isMonolith()
|| defaultCtx.isLocalEntity(ruleNode.getId());
}

View File

@ -0,0 +1,66 @@
/**
* 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.service;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.validator.RuleChainDataValidator;
public class RuleChainDataValidatorTest {
@Test
public void testSingletonSupport() {
String node = "org.thingsboard.rule.engine.mqtt.TbMqttNode";
RuleNode ruleNode = createRuleNode(node, false);
RuleChainDataValidator.validateRuleNode(ruleNode);
ruleNode.setSingletonMode(true);
RuleChainDataValidator.validateRuleNode(ruleNode);
}
@Test
public void testSingletonNotSupport() {
String node = "org.thingsboard.rule.engine.flow.TbAckNode";
RuleNode ruleNode = createRuleNode(node, false);
RuleChainDataValidator.validateRuleNode(ruleNode);
ruleNode.setSingletonMode(true);
Assertions.assertThrows(DataValidationException.class,
() -> RuleChainDataValidator.validateRuleNode(ruleNode),
String.format("Singleton mode not supported for [%s].", ruleNode.getType()));
}
@Test
public void testSingletonOnly() {
String node = "org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode";
RuleNode ruleNode = createRuleNode(node, true);
RuleChainDataValidator.validateRuleNode(ruleNode);
ruleNode.setSingletonMode(false);
Assertions.assertThrows(DataValidationException.class,
() -> RuleChainDataValidator.validateRuleNode(ruleNode),
String.format("Supported only singleton mode for [%s].", ruleNode.getType()));
}
private RuleNode createRuleNode(String type, boolean singletonMode) {
RuleNode ruleNode = new RuleNode();
ruleNode.setName("test node");
ruleNode.setType(type);
ruleNode.setSingletonMode(singletonMode);
ruleNode.setConfiguration(JacksonUtil.newObjectNode());
return ruleNode;
}
}

View File

@ -25,19 +25,18 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentSingletonSupport;
import org.thingsboard.server.common.data.rule.NodeConnectionInfo;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.util.ReflectionUtils;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.rule.RuleChainDao;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.ConstraintValidator;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantService;
import java.util.HashMap;
@ -62,7 +61,7 @@ public class RuleChainDataValidator extends DataValidator<RuleChain> {
@Override
protected void validateCreate(TenantId tenantId, RuleChain data) {
validateNumberOfEntitiesPerTenant(tenantId, EntityType.RULE_CHAIN);
validateNumberOfEntitiesPerTenant(tenantId, EntityType.RULE_CHAIN);
}
@Override
@ -114,6 +113,22 @@ public class RuleChainDataValidator extends DataValidator<RuleChain> {
return;
}
ConstraintValidator.validateFields(nodeConfig, errorPrefix);
ComponentSingletonSupport nodeConfigType = null;
try {
nodeConfigType = ReflectionUtils.getAnnotationProperty(ruleNode.getType(),
"org.thingsboard.rule.engine.api.RuleNode", "singleton");
} catch (Exception e) {
log.warn("Failed to validate singleton mode: {}", ExceptionUtils.getRootCauseMessage(e));
return;
}
if (ComponentSingletonSupport.NOT_SUPPORTED.equals(nodeConfigType) && ruleNode.isSingletonMode()) {
throw new DataValidationException(String.format("Singleton mode not supported for [%s].", ruleNode.getType()));
}
if (ComponentSingletonSupport.ONLY_SINGLETON.equals(nodeConfigType) && !ruleNode.isSingletonMode()) {
throw new DataValidationException(String.format("Supported only singleton mode for [%s].", ruleNode.getType()));
}
}
private static void validateCircles(List<NodeConnectionInfo> connectionInfos) {