Refactored due to common use of debug mode configuration

This commit is contained in:
YevhenBondarenko 2024-11-13 13:56:46 +01:00
parent cf377b0083
commit f54e1882bf
15 changed files with 108 additions and 72 deletions

View File

@ -577,9 +577,9 @@ public class ActorSystemContext {
@Getter @Getter
private boolean externalNodeForceAck; private boolean externalNodeForceAck;
@Value("${actors.rule.node.max_debug_mode_duration:60}") @Value("${debug_mode.max_duration:60}")
@Getter @Getter
private int maxRuleNodeDebugModeDurationMinutes; private int maxDebugModeDurationMinutes;
@Value("${state.rule.node.deviceState.rateLimit:1:1,30:60,60:3600}") @Value("${state.rule.node.deviceState.rateLimit:1:1,30:60,60:3600}")
@Getter @Getter

View File

@ -64,7 +64,7 @@ import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.rule.RuleNodeDebugUtil; import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.server.common.data.rule.RuleNodeState; import org.thingsboard.server.common.data.rule.RuleNodeState;
import org.thingsboard.server.common.data.script.ScriptLanguage; import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
@ -1002,9 +1002,9 @@ public class DefaultTbContext implements TbContext {
private void persistDebugOutput(TbMsg msg, Set<String> relationTypes, Throwable error, String failureMessage) { private void persistDebugOutput(TbMsg msg, Set<String> relationTypes, Throwable error, String failureMessage) {
RuleNode ruleNode = nodeCtx.getSelf(); RuleNode ruleNode = nodeCtx.getSelf();
if (RuleNodeDebugUtil.isDebugAllAvailable(ruleNode)) { if (DebugModeUtil.isDebugAllAvailable(ruleNode)) {
relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(getTenantId(), ruleNode.getId(), msg, relationType, error, failureMessage)); relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(getTenantId(), ruleNode.getId(), msg, relationType, error, failureMessage));
} else if (RuleNodeDebugUtil.isDebugFailuresAvailable(ruleNode, relationTypes)) { } else if (DebugModeUtil.isDebugFailuresAvailable(ruleNode, relationTypes)) {
mainCtx.persistDebugOutput(getTenantId(), ruleNode.getId(), msg, TbNodeConnectionType.FAILURE, error, failureMessage); mainCtx.persistDebugOutput(getTenantId(), ruleNode.getId(), msg, TbNodeConnectionType.FAILURE, error, failureMessage);
} }
} }

View File

@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.rule.RuleNodeDebugUtil; import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.plugin.RuleNodeUpdatedMsg; import org.thingsboard.server.common.msg.plugin.RuleNodeUpdatedMsg;
@ -256,7 +256,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
var originatorNodeId = envelope.getTargetRuleNodeId(); var originatorNodeId = envelope.getTargetRuleNodeId();
RuleNodeCtx ruleNodeCtx = nodeActors.get(originatorNodeId); RuleNodeCtx ruleNodeCtx = nodeActors.get(originatorNodeId);
if (ruleNodeCtx != null) { if (ruleNodeCtx != null) {
if (RuleNodeDebugUtil.isDebugAvailable(ruleNodeCtx.getSelf(), envelope.getRelationType())) { if (DebugModeUtil.isDebugAvailable(ruleNodeCtx.getSelf(), envelope.getRelationType())) {
systemContext.persistDebugOutput(tenantId, originatorNodeId, tbMsg, envelope.getRelationType()); systemContext.persistDebugOutput(tenantId, originatorNodeId, tbMsg, envelope.getRelationType());
} }
} }

View File

@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.rule.RuleNodeDebugUtil; import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.RuleNodeException; import org.thingsboard.server.common.msg.queue.RuleNodeException;
@ -131,7 +131,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
if (maxRuleNodeExecutionsPerMessage == 0 || ruleNodeCount < maxRuleNodeExecutionsPerMessage) { if (maxRuleNodeExecutionsPerMessage == 0 || ruleNodeCount < maxRuleNodeExecutionsPerMessage) {
apiUsageClient.report(tenantId, tbMsg.getCustomerId(), ApiUsageRecordKey.RE_EXEC_COUNT); apiUsageClient.report(tenantId, tbMsg.getCustomerId(), ApiUsageRecordKey.RE_EXEC_COUNT);
persistDebugInputIfAllowed(msg.getMsg(), "Self", tenantProfileConfiguration persistDebugInputIfAllowed(msg.getMsg(), "Self", tenantProfileConfiguration
.getMaxRuleNodeDebugModeDurationMinutes(systemContext.getMaxRuleNodeDebugModeDurationMinutes())); .getMaxDebugModeDurationMinutes(systemContext.getMaxDebugModeDurationMinutes()));
try { try {
tbNode.onMsg(defaultCtx, msg.getMsg()); tbNode.onMsg(defaultCtx, msg.getMsg());
} catch (Exception e) { } catch (Exception e) {
@ -155,7 +155,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
if (maxRuleNodeExecutionsPerMessage == 0 || ruleNodeCount < maxRuleNodeExecutionsPerMessage) { if (maxRuleNodeExecutionsPerMessage == 0 || ruleNodeCount < maxRuleNodeExecutionsPerMessage) {
apiUsageClient.report(tenantId, tbMsg.getCustomerId(), ApiUsageRecordKey.RE_EXEC_COUNT); apiUsageClient.report(tenantId, tbMsg.getCustomerId(), ApiUsageRecordKey.RE_EXEC_COUNT);
persistDebugInputIfAllowed(msg.getMsg(), msg.getFromRelationType(), tenantProfileConfiguration persistDebugInputIfAllowed(msg.getMsg(), msg.getFromRelationType(), tenantProfileConfiguration
.getMaxRuleNodeDebugModeDurationMinutes(systemContext.getMaxRuleNodeDebugModeDurationMinutes())); .getMaxDebugModeDurationMinutes(systemContext.getMaxDebugModeDurationMinutes()));
try { try {
tbNode.onMsg(msg.getCtx(), msg.getMsg()); tbNode.onMsg(msg.getCtx(), msg.getMsg());
} catch (Exception e) { } catch (Exception e) {
@ -219,7 +219,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
} }
private void persistDebugInputIfAllowed(TbMsg msg, String fromNodeConnectionType, int debugModeDurationMinutes) { private void persistDebugInputIfAllowed(TbMsg msg, String fromNodeConnectionType, int debugModeDurationMinutes) {
if (RuleNodeDebugUtil.isDebugAllAvailable(ruleNode)) { if (DebugModeUtil.isDebugAllAvailable(ruleNode)) {
systemContext.persistDebugInput(tenantId, entityId, msg, fromNodeConnectionType); systemContext.persistDebugInput(tenantId, entityId, msg, fromNodeConnectionType);
} }
} }

View File

@ -71,8 +71,8 @@ public class SystemInfoController extends BaseController {
@Value("${ui.dashboard.max_datapoints_limit}") @Value("${ui.dashboard.max_datapoints_limit}")
private long maxDatapointsLimit; private long maxDatapointsLimit;
@Value("${actors.rule.node.max_debug_mode_duration:60}") @Value("${debug_mode.max_duration:60}")
private int maxRuleNodeDebugModeDurationMinutes; private int maxDebugModeDurationMinutes;
@Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled:true}") @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled:true}")
@Getter @Getter
@ -153,7 +153,7 @@ public class SystemInfoController extends BaseController {
if (!currentUser.isSystemAdmin()) { if (!currentUser.isSystemAdmin()) {
DefaultTenantProfileConfiguration tenantProfileConfiguration = tenantProfileCache.get(tenantId).getDefaultProfileConfiguration(); DefaultTenantProfileConfiguration tenantProfileConfiguration = tenantProfileCache.get(tenantId).getDefaultProfileConfiguration();
systemParams.setMaxResourceSize(tenantProfileConfiguration.getMaxResourceSize()); systemParams.setMaxResourceSize(tenantProfileConfiguration.getMaxResourceSize());
systemParams.setMaxRuleNodeDebugDurationMinutes(tenantProfileConfiguration.getMaxRuleNodeDebugModeDurationMinutes(maxRuleNodeDebugModeDurationMinutes)); systemParams.setMaxDebugModeDurationMinutes(tenantProfileConfiguration.getMaxDebugModeDurationMinutes(maxDebugModeDurationMinutes));
if (ruleChainDebugPerTenantLimitsEnabled) { if (ruleChainDebugPerTenantLimitsEnabled) {
systemParams.setRuleChainDebugPerTenantLimitsConfiguration(ruleChainDebugPerTenantLimitsConfiguration); systemParams.setRuleChainDebugPerTenantLimitsConfiguration(ruleChainDebugPerTenantLimitsConfiguration);
} }

View File

@ -88,7 +88,7 @@ public class TenantMsgConstructorV1 implements TenantMsgConstructor {
configuration.setMaxTransportDataPoints(0); configuration.setMaxTransportDataPoints(0);
configuration.setRuleEngineExceptionsTtlDays(0); configuration.setRuleEngineExceptionsTtlDays(0);
configuration.setMaxRuleNodeExecutionsPerMessage(0); configuration.setMaxRuleNodeExecutionsPerMessage(0);
configuration.setMaxRuleNodeDebugDurationMinutes(0); configuration.setMaxDebugDurationMinutes(0);
tenantProfileData.setConfiguration(configuration); tenantProfileData.setConfiguration(configuration);
tenantProfile.setProfileData(tenantProfileData); tenantProfile.setProfileData(tenantProfileData);

View File

@ -495,6 +495,11 @@ actors:
# Actors statistic persistence frequency in milliseconds # Actors statistic persistence frequency in milliseconds
persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}" persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}"
debug_mode:
# The maximum allowed duration (in minutes) for the debug mode to be used.
# If a specific value is set in the tenant profile, the minimum between value from profile and this setting will be used.
max_duration: "${DEBUG_MODE_MAX_DURATION_MINUTES:60}"
# Cache settings parameters # Cache settings parameters
cache: cache:
# caffeine or redis(7.2 - latest compatible version) # caffeine or redis(7.2 - latest compatible version)

View File

@ -0,0 +1,33 @@
/**
* 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.common.data;
import io.swagger.v3.oas.annotations.media.Schema;
public interface HasDebugMode {
boolean isDebugFailures();
void setDebugFailures(boolean debugFailures);
boolean isDebugAll();
void setDebugAll(boolean debugAll);
long getDebugAllUntil();
void setDebugAllUntil(long debugAllUntil);
}

View File

@ -32,6 +32,6 @@ public class SystemParams {
long maxDatapointsLimit; long maxDatapointsLimit;
long maxResourceSize; long maxResourceSize;
boolean mobileQrEnabled; boolean mobileQrEnabled;
int maxRuleNodeDebugDurationMinutes; int maxDebugModeDurationMinutes;
String ruleChainDebugPerTenantLimitsConfiguration; String ruleChainDebugPerTenantLimitsConfiguration;
} }

View File

@ -23,6 +23,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo;
import org.thingsboard.server.common.data.HasDebugMode;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
@ -34,7 +35,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Slf4j @Slf4j
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class RuleNode extends BaseDataWithAdditionalInfo<RuleNodeId> implements HasName { public class RuleNode extends BaseDataWithAdditionalInfo<RuleNodeId> implements HasName, HasDebugMode {
private static final long serialVersionUID = -5656679015121235465L; private static final long serialVersionUID = -5656679015121235465L;

View File

@ -1,45 +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.common.data.rule;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import java.util.Set;
public final class RuleNodeDebugUtil {
private RuleNodeDebugUtil() {}
public static boolean isDebugAllAvailable(RuleNode ruleNode) {
return ruleNode.getDebugAllUntil() > System.currentTimeMillis();
}
public static boolean isDebugAvailable(RuleNode ruleNode, String nodeConnection) {
return isDebugAllAvailable(ruleNode) || ruleNode.isDebugFailures() && TbNodeConnectionType.FAILURE.equals(nodeConnection);
}
public static boolean isDebugFailuresAvailable(RuleNode ruleNode, Set<String> nodeConnections) {
return isDebugFailuresAvailable(ruleNode) && nodeConnections.contains(TbNodeConnectionType.FAILURE);
}
public static boolean isDebugFailuresAvailable(RuleNode ruleNode, String nodeConnection) {
return isDebugFailuresAvailable(ruleNode) && TbNodeConnectionType.FAILURE.equals(nodeConnection);
}
public static boolean isDebugFailuresAvailable(RuleNode ruleNode) {
return ruleNode.isDebugFailures() || isDebugAllAvailable(ruleNode);
}
}

View File

@ -95,7 +95,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
@Schema(example = "50") @Schema(example = "50")
private int maxRuleNodeExecutionsPerMessage; private int maxRuleNodeExecutionsPerMessage;
@Schema(example = "15") @Schema(example = "15")
private int maxRuleNodeDebugDurationMinutes; private int maxDebugDurationMinutes;
@Schema(example = "0") @Schema(example = "0")
private long maxEmails; private long maxEmails;
@Schema(example = "true") @Schema(example = "true")
@ -204,10 +204,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
} }
@Override @Override
public int getMaxRuleNodeDebugModeDurationMinutes(int systemMaxRuleNodeDebugModeDurationMinutes) { public int getMaxDebugModeDurationMinutes(int systemMaxDebugModeDurationMinutes) {
if (maxRuleNodeDebugDurationMinutes > 0) { if (maxDebugDurationMinutes > 0) {
return Math.min(systemMaxRuleNodeDebugModeDurationMinutes, maxRuleNodeDebugDurationMinutes); return Math.min(systemMaxDebugModeDurationMinutes, maxDebugDurationMinutes);
} }
return systemMaxRuleNodeDebugModeDurationMinutes; return systemMaxDebugModeDurationMinutes;
} }
} }

View File

@ -52,6 +52,6 @@ public interface TenantProfileConfiguration extends Serializable {
int getMaxRuleNodeExecsPerMessage(); int getMaxRuleNodeExecsPerMessage();
@JsonIgnore @JsonIgnore
int getMaxRuleNodeDebugModeDurationMinutes(int systemMaxRuleNodeDebugModeDurationMinutes); int getMaxDebugModeDurationMinutes(int systemMaxDebugModeDurationMinutes);
} }

View File

@ -0,0 +1,43 @@
/**
* 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.common.util;
import org.thingsboard.server.common.data.HasDebugMode;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import java.util.Set;
public final class DebugModeUtil {
private DebugModeUtil() {
}
public static boolean isDebugAllAvailable(HasDebugMode debugMode) {
return debugMode.getDebugAllUntil() > System.currentTimeMillis();
}
public static boolean isDebugAvailable(HasDebugMode debugMode, String nodeConnection) {
return isDebugAllAvailable(debugMode) || debugMode.isDebugFailures() && TbNodeConnectionType.FAILURE.equals(nodeConnection);
}
public static boolean isDebugFailuresAvailable(HasDebugMode debugMode, Set<String> nodeConnections) {
return isDebugFailuresAvailable(debugMode) && nodeConnections.contains(TbNodeConnectionType.FAILURE);
}
private static boolean isDebugFailuresAvailable(HasDebugMode debugMode) {
return debugMode.isDebugFailures() || isDebugAllAvailable(debugMode);
}
}

View File

@ -68,7 +68,6 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.service.validator.RuleChainDataValidator; import org.thingsboard.server.dao.service.validator.RuleChainDataValidator;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.util.TimeUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -118,8 +117,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Lazy @Lazy
private TbTenantProfileCache tbTenantProfileCache; private TbTenantProfileCache tbTenantProfileCache;
@Value("${actors.rule.node.max_debug_mode_duration:60}") @Value("${debug_mode.max_duration:60}")
private int maxRuleNodeDebugModeDurationMinutes; private int maxDebugModeDurationMinutes;
@Override @Override
@Transactional @Transactional
@ -231,7 +230,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
node.setRuleChainId(ruleChainId); node.setRuleChainId(ruleChainId);
node = ruleNodeUpdater.apply(node); node = ruleNodeUpdater.apply(node);
int debugDuration = tbTenantProfileCache.get(tenantId).getDefaultProfileConfiguration().getMaxRuleNodeDebugModeDurationMinutes(maxRuleNodeDebugModeDurationMinutes); int debugDuration = tbTenantProfileCache.get(tenantId).getDefaultProfileConfiguration().getMaxDebugModeDurationMinutes(maxDebugModeDurationMinutes);
long debugUntil = now + TimeUnit.MINUTES.toMillis(debugDuration); long debugUntil = now + TimeUnit.MINUTES.toMillis(debugDuration);
if (node.isDebugAll()) { if (node.isDebugAll()) {