From cb1b817b49f2e3c187591d1888ae777fac9138e0 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 16 Nov 2023 15:28:24 +0200 Subject: [PATCH] added backward-compatibility test for notifyDevice feature --- .../engine/telemetry/TbMsgAttributesNode.java | 4 +- .../telemetry/TbMsgAttributesNodeTest.java | 77 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) 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 9bbee45477..2ebb0193f9 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 @@ -43,7 +43,9 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; -import static org.thingsboard.server.common.data.DataConstants.*; +import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE; +import static org.thingsboard.server.common.data.DataConstants.NOTIFY_DEVICE_METADATA_KEY; +import static org.thingsboard.server.common.data.DataConstants.SCOPE; import static org.thingsboard.server.common.data.msg.TbMsgType.POST_ATTRIBUTES_REQUEST; @Slf4j diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java index 818c1bb97f..3aeff8df7d 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java @@ -19,8 +19,20 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; +import org.mockito.junit.jupiter.MockitoExtension; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; +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.DataConstants; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; @@ -28,22 +40,38 @@ import org.thingsboard.server.common.data.kv.DoubleDataEntry; import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.util.TbPair; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +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.DataConstants.NOTIFY_DEVICE_METADATA_KEY; @Slf4j +@ExtendWith(MockitoExtension.class) class TbMsgAttributesNodeTest { + private static final DeviceId ORIGINATOR_ID = new DeviceId(UUID.randomUUID()); + private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + final String updateAttributesOnlyOnValueChangeKey = "updateAttributesOnlyOnValueChange"; @Test @@ -103,6 +131,55 @@ class TbMsgAttributesNodeTest { assertThat(filtered).containsExactlyInAnyOrderElementsOf(expected); } + // Notify device backward-compatibility test arguments + private static Stream provideNotifyDeviceMdValue() { + return Stream.of( + Arguments.of(null, true), + Arguments.of(true, true), + Arguments.of(false, false) + ); + } + + // Notify device backward-compatibility test + @ParameterizedTest + @MethodSource("provideNotifyDeviceMdValue") + void testNotifyDeviceArgumentForSaveAndNotify(Boolean mdValue, boolean expectedArgumentValue) throws TbNodeException { + var ctxMock = mock(TbContext.class); + var telemetryServiceMock = mock(RuleEngineTelemetryService.class); + TbMsgAttributesNode node = spy(TbMsgAttributesNode.class); + ObjectNode defaultConfig = (ObjectNode) JacksonUtil.valueToTree(new TbMsgAttributesNodeConfiguration().defaultConfiguration()); + defaultConfig.put("notifyDevice", false); + var tbNodeConfiguration = new TbNodeConfiguration(defaultConfig); + + assertThat(defaultConfig.has("notifyDevice")).as("pre condition has notifyDevice").isTrue(); + + when(ctxMock.getTenantId()).thenReturn(TENANT_ID); + when(ctxMock.getTelemetryService()).thenReturn(telemetryServiceMock); + willCallRealMethod().given(node).init(any(TbContext.class), any(TbNodeConfiguration.class)); + willCallRealMethod().given(node).saveAttr(any(), eq(ctxMock), any(TbMsg.class), anyString(), anyBoolean()); + + node.init(ctxMock, tbNodeConfiguration); + + TbMsgMetaData md = new TbMsgMetaData(); + if (mdValue != null) { + md.putValue(NOTIFY_DEVICE_METADATA_KEY, mdValue.toString()); + } + // dummy list with one ts kv to pass the empty list check. + var testTbMsg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ORIGINATOR_ID, md, TbMsg.EMPTY_STRING); + List testAttrList = List.of(new BaseAttributeKvEntry(0L, new StringDataEntry("testKey", "testValue"))); + + node.saveAttr(testAttrList, ctxMock, testTbMsg, DataConstants.SHARED_SCOPE, false); + + ArgumentCaptor notifyDeviceCaptor = ArgumentCaptor.forClass(Boolean.class); + + verify(telemetryServiceMock, times(1)).saveAndNotify( + eq(TENANT_ID), eq(ORIGINATOR_ID), eq(DataConstants.SHARED_SCOPE), + eq(testAttrList), notifyDeviceCaptor.capture(), any() + ); + boolean notifyDevice = notifyDeviceCaptor.getValue(); + assertThat(notifyDevice).isEqualTo(expectedArgumentValue); + } + @Test void testUpgrade_fromVersion0() throws TbNodeException {