From 29d3efa205f2a3963c19cf55acd81dbce2f19652 Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Tue, 22 Nov 2022 14:33:52 +0200 Subject: [PATCH 1/6] add options send notifications --- .../rule/engine/telemetry/TbMsgAttributesNode.java | 9 +++++++-- .../telemetry/TbMsgAttributesNodeConfiguration.java | 2 ++ .../rule/engine/telemetry/TbMsgDeleteAttributes.java | 9 ++++++++- .../telemetry/TbMsgDeleteAttributesConfiguration.java | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index b810774832..27b6acca2e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.telemetry; +import com.google.common.util.concurrent.FutureCallback; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.StringUtils; @@ -65,11 +66,15 @@ public class TbMsgAttributesNode implements TbNode { return; } String src = msg.getData(); - List attributes = new ArrayList<>(JsonConverter.convertToAttributes(new JsonParser().parse(src))); + List attributes = new ArrayList<>(JsonConverter.convertToAttributes(JsonParser.parseString(src))); if (attributes.isEmpty()) { ctx.tellSuccess(msg); return; } + FutureCallback callback = new TelemetryNodeCallback(ctx, msg); + if (config.isSendAttributesUpdatedNotification()) { + callback = new AttributesUpdateNodeCallback(ctx, msg, config.getScope(), attributes); + } String notifyDeviceStr = msg.getMetaData().getValue("notifyDevice"); ctx.getTelemetryService().saveAndNotify( ctx.getTenantId(), @@ -77,7 +82,7 @@ public class TbMsgAttributesNode implements TbNode { config.getScope(), attributes, config.getNotifyDevice() || StringUtils.isEmpty(notifyDeviceStr) || Boolean.parseBoolean(notifyDeviceStr), - new AttributesUpdateNodeCallback(ctx, msg, config.getScope(), attributes) + callback ); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeConfiguration.java index 1586048b81..93b8d63b47 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeConfiguration.java @@ -25,12 +25,14 @@ public class TbMsgAttributesNodeConfiguration implements NodeConfiguration keys; + private boolean sendAttributesDeletedNotification; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeleteAttributesConfiguration.class); this.scope = config.getScope(); this.keys = config.getKeys(); + this.sendAttributesDeletedNotification = config.isSendAttributesDeletedNotification(); } @Override @@ -67,7 +70,11 @@ public class TbMsgDeleteAttributes implements TbNode { if (keysToDelete.isEmpty()) { ctx.tellSuccess(msg); } else { - ctx.getTelemetryService().deleteAndNotify(ctx.getTenantId(), msg.getOriginator(), scope, keysToDelete, new AttributesDeleteNodeCallback(ctx, msg, scope, keysToDelete)); + FutureCallback callback = new TelemetryNodeCallback(ctx, msg); + if (sendAttributesDeletedNotification) { + callback = new AttributesDeleteNodeCallback(ctx, msg, scope, keysToDelete); + } + ctx.getTelemetryService().deleteAndNotify(ctx.getTenantId(), msg.getOriginator(), scope, keysToDelete, callback); } } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesConfiguration.java index 03bef2a4e6..a33bcda3f2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesConfiguration.java @@ -27,12 +27,14 @@ public class TbMsgDeleteAttributesConfiguration implements NodeConfiguration keys; + private boolean sendAttributesDeletedNotification; @Override public TbMsgDeleteAttributesConfiguration defaultConfiguration() { TbMsgDeleteAttributesConfiguration configuration = new TbMsgDeleteAttributesConfiguration(); configuration.setScope(DataConstants.SERVER_SCOPE); configuration.setKeys(Collections.emptyList()); + configuration.setSendAttributesDeletedNotification(false); return configuration; } } From e77c939b676935a699f790dca451cf61ac933fab Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Tue, 22 Nov 2022 14:58:46 +0200 Subject: [PATCH 2/6] refactor code, update logic callback --- .../engine/telemetry/TbMsgAttributesNode.java | 8 +++----- .../engine/telemetry/TbMsgDeleteAttributes.java | 16 +++++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 27b6acca2e..b87af7b9d1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -71,10 +71,6 @@ public class TbMsgAttributesNode implements TbNode { ctx.tellSuccess(msg); return; } - FutureCallback callback = new TelemetryNodeCallback(ctx, msg); - if (config.isSendAttributesUpdatedNotification()) { - callback = new AttributesUpdateNodeCallback(ctx, msg, config.getScope(), attributes); - } String notifyDeviceStr = msg.getMetaData().getValue("notifyDevice"); ctx.getTelemetryService().saveAndNotify( ctx.getTenantId(), @@ -82,7 +78,9 @@ public class TbMsgAttributesNode implements TbNode { config.getScope(), attributes, config.getNotifyDevice() || StringUtils.isEmpty(notifyDeviceStr) || Boolean.parseBoolean(notifyDeviceStr), - callback + config.isSendAttributesUpdatedNotification() ? + new AttributesUpdateNodeCallback(ctx, msg, config.getScope(), attributes) : + new TelemetryNodeCallback(ctx, msg) ); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java index d8dcac9311..d51d36cadb 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java @@ -50,14 +50,12 @@ public class TbMsgDeleteAttributes implements TbNode { private TbMsgDeleteAttributesConfiguration config; private String scope; private List keys; - private boolean sendAttributesDeletedNotification; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeleteAttributesConfiguration.class); this.scope = config.getScope(); this.keys = config.getKeys(); - this.sendAttributesDeletedNotification = config.isSendAttributesDeletedNotification(); } @Override @@ -70,11 +68,15 @@ public class TbMsgDeleteAttributes implements TbNode { if (keysToDelete.isEmpty()) { ctx.tellSuccess(msg); } else { - FutureCallback callback = new TelemetryNodeCallback(ctx, msg); - if (sendAttributesDeletedNotification) { - callback = new AttributesDeleteNodeCallback(ctx, msg, scope, keysToDelete); - } - ctx.getTelemetryService().deleteAndNotify(ctx.getTenantId(), msg.getOriginator(), scope, keysToDelete, callback); + ctx.getTelemetryService().deleteAndNotify( + ctx.getTenantId(), + msg.getOriginator(), + scope, + keysToDelete, + config.isSendAttributesDeletedNotification() ? + new AttributesDeleteNodeCallback(ctx, msg, scope, keysToDelete) : + new TelemetryNodeCallback(ctx, msg) + ); } } } From c6ffdb41af4b19e95abb318d0479150e9a6c0b6a Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Tue, 22 Nov 2022 15:07:00 +0200 Subject: [PATCH 3/6] delete imports --- .../thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java | 1 - .../thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java | 1 - 2 files changed, 2 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index b87af7b9d1..37471ca872 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.telemetry; -import com.google.common.util.concurrent.FutureCallback; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.StringUtils; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java index d51d36cadb..aad7616470 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributes.java @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.telemetry; -import com.google.common.util.concurrent.FutureCallback; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; From c0dcd5e462269c2d4c0ccaeff32a4b6356151b71 Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Tue, 22 Nov 2022 16:30:57 +0200 Subject: [PATCH 4/6] update tests --- .../telemetry/TbMsgDeleteAttributesTest.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesTest.java index 8972a3aa1f..a329f890af 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesTest.java @@ -99,7 +99,19 @@ public class TbMsgDeleteAttributesTest { } @Test - void givenMsg_whenOnMsg_thenVerifyOutput() throws Exception { + void givenMsg_whenOnMsg_thenVerifyOutput_NoSendAttributesDeletedNotification() throws Exception { + onMsg_thenVerifyOutput(false); + } + + @Test + void givenMsg_whenOnMsg_thenVerifyOutput_SendAttributesDeletedNotification() throws Exception { + config.setSendAttributesDeletedNotification(true); + nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config)); + node.init(ctx, nodeConfiguration); + onMsg_thenVerifyOutput(true); + } + + void onMsg_thenVerifyOutput(boolean sendAttributesDeletedNotification) throws Exception { final Map mdMap = Map.of( "TestAttribute_1", "temperature", "city", "NY" @@ -114,11 +126,12 @@ public class TbMsgDeleteAttributesTest { ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); - verify(ctx, times(1)).enqueue(any(), successCaptor.capture(), failureCaptor.capture()); - successCaptor.getValue().run(); + if (sendAttributesDeletedNotification) { + verify(ctx, times(1)).enqueue(any(), successCaptor.capture(), failureCaptor.capture()); + successCaptor.getValue().run(); + verify(ctx, times(1)).attributesDeletedActionMsg(any(), any(), anyString(), anyList()); + } verify(ctx, times(1)).tellSuccess(newMsgCaptor.capture()); - - verify(ctx, times(1)).attributesDeletedActionMsg(any(), any(), anyString(), anyList()); verify(ctx, never()).tellFailure(any(), any()); verify(telemetryService, times(1)).deleteAndNotify(any(), any(), anyString(), anyList(), any()); } From a542b7d593c17a44ce3f128b2c554aa6c0728117 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 24 Nov 2022 11:34:24 +0200 Subject: [PATCH 5/6] added client scope validation for sending notification --- .../rule/engine/telemetry/TbMsgAttributesNode.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 37471ca872..08730a40f3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.telemetry; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -49,6 +50,8 @@ import java.util.List; public class TbMsgAttributesNode implements TbNode { private TbMsgAttributesNodeConfiguration config; + private String scope; + private boolean sendAttributesUpdateNotification; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { @@ -56,6 +59,10 @@ public class TbMsgAttributesNode implements TbNode { if (config.getNotifyDevice() == null) { config.setNotifyDevice(true); } + this.scope = config.getScope(); + this.sendAttributesUpdateNotification = config.isSendAttributesUpdatedNotification() + && !DataConstants.CLIENT_SCOPE.equals(scope); + } @Override @@ -74,10 +81,10 @@ public class TbMsgAttributesNode implements TbNode { ctx.getTelemetryService().saveAndNotify( ctx.getTenantId(), msg.getOriginator(), - config.getScope(), + scope, attributes, config.getNotifyDevice() || StringUtils.isEmpty(notifyDeviceStr) || Boolean.parseBoolean(notifyDeviceStr), - config.isSendAttributesUpdatedNotification() ? + sendAttributesUpdateNotification ? new AttributesUpdateNodeCallback(ctx, msg, config.getScope(), attributes) : new TelemetryNodeCallback(ctx, msg) ); From 1a8a02cfa4cea7739f2f48d883419229d5d342a5 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 24 Nov 2022 13:10:25 +0200 Subject: [PATCH 6/6] updated save attributes node decription --- .../rule/engine/telemetry/TbMsgAttributesNode.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 08730a40f3..f0ff5c061e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -41,8 +41,10 @@ import java.util.List; configClazz = TbMsgAttributesNodeConfiguration.class, nodeDescription = "Saves attributes data", nodeDetails = "Saves entity attributes based on configurable scope parameter. Expects messages with 'POST_ATTRIBUTES_REQUEST' message type. " + - "If upsert(update/insert) operation is completed successfully, rule node will send the \"Attributes Updated\" " + - "event to the root chain of the message originator and send the incoming message via Success chain, otherwise, Failure chain is used.", + "Rule node allows user to enable/disable sending attributes updated notifications for SHARED_SCOPE and SERVER_SCOPE attributes updates. " + + "If upsert(update/insert) operation is completed successfully rule node will send the incoming message via Success chain, otherwise, Failure chain is used. " + + "Additionally if checkbox Send attributes updated notification is set to true, rule node will send the \"Attributes Updated\" " + + "event to the root chain of the message originator.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeAttributesConfig", icon = "file_upload"