diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
index 6a806e7bc1..fc541ce4e4 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
@@ -16,9 +16,7 @@
package org.thingsboard.rule.engine.action;
import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
@@ -31,18 +29,21 @@ import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.msg.TbMsg;
-@Slf4j
+import static com.google.common.util.concurrent.Futures.immediateFuture;
+import static com.google.common.util.concurrent.Futures.transform;
+import static com.google.common.util.concurrent.Futures.transformAsync;
+
@RuleNode(
type = ComponentType.ACTION,
name = "clear alarm", relationTypes = {"Cleared", "False"},
configClazz = TbClearAlarmNodeConfiguration.class,
nodeDescription = "Clear Alarm",
- nodeDetails =
- "Details - JS function that creates JSON object based on incoming message. This object will be added into Alarm.details field.\n" +
- "Node output:\n" +
- "If alarm was not cleared, original message is returned. Otherwise new Message returned with type 'ALARM', Alarm object in 'msg' property and 'metadata' will contains 'isClearedAlarm' property. " +
- "Message payload can be accessed via msg property. For example 'temperature = ' + msg.temperature ;. " +
- "Message metadata can be accessed via metadata property. For example 'name = ' + metadata.customerName;.",
+ nodeDetails = """
+ Details - JS function that creates JSON object based on incoming message. This object will be added into Alarm.details field.
+ Node output:
+ If alarm was not cleared, original message is returned. Otherwise new Message returned with type 'ALARM', Alarm object in 'msg' property and 'metadata' will contains 'isClearedAlarm' property.
+ Message payload can be accessed via msg property. For example 'temperature = ' + msg.temperature ;.
+ Message metadata can be accessed via metadata property. For example 'name = ' + metadata.customerName;.""",
configDirective = "tbActionNodeClearAlarmConfig",
icon = "notifications_off"
)
@@ -55,22 +56,26 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode processAlarm(TbContext ctx, TbMsg msg) {
- String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg);
- Alarm alarm;
- if (msg.getOriginator().getEntityType().equals(EntityType.ALARM)) {
- alarm = ctx.getAlarmService().findAlarmById(ctx.getTenantId(), new AlarmId(msg.getOriginator().getId()));
+ String alarmType = TbNodeUtils.processPattern(config.getAlarmType(), msg);
+
+ ListenableFuture alarmFuture;
+ if (msg.getOriginator().getEntityType() == EntityType.ALARM) {
+ alarmFuture = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), new AlarmId(msg.getOriginator().getId()));
} else {
- alarm = ctx.getAlarmService().findLatestActiveByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType);
+ alarmFuture = ctx.getAlarmService().findLatestActiveByOriginatorAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), alarmType);
}
- if (alarm != null && !alarm.getStatus().isCleared()) {
- return clearAlarm(ctx, msg, alarm);
- }
- return Futures.immediateFuture(new TbAlarmResult(false, false, false, null));
+
+ return transformAsync(alarmFuture, alarm -> {
+ if (alarm != null && !alarm.getStatus().isCleared()) {
+ return clearAlarmAsync(ctx, msg, alarm);
+ }
+ return immediateFuture(new TbAlarmResult(false, false, false, null));
+ }, ctx.getDbCallbackExecutor());
}
- private ListenableFuture clearAlarm(TbContext ctx, TbMsg msg, Alarm alarm) {
+ private ListenableFuture clearAlarmAsync(TbContext ctx, TbMsg msg, Alarm alarm) {
ListenableFuture asyncDetails = buildAlarmDetails(msg, alarm.getDetails());
- return Futures.transform(asyncDetails, details -> {
+ return transform(asyncDetails, details -> {
AlarmApiCallResult result = ctx.getAlarmService().clearAlarm(ctx.getTenantId(), alarm.getId(), System.currentTimeMillis(), details);
if (result.isSuccessful()) {
return new TbAlarmResult(false, false, result.isCleared(), result.getAlarm());
@@ -79,4 +84,5 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode