diff --git a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java index 793063d2d7..dcc8f35ba3 100644 --- a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java @@ -15,16 +15,23 @@ */ package org.thingsboard.server.rules.flow; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.util.ReflectionTestUtils; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; -import org.thingsboard.server.common.data.*; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.page.PageData; @@ -38,12 +45,14 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.TbMsgCallback; import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; import org.thingsboard.server.dao.attributes.AttributesService; +import org.thingsboard.server.dao.event.EventService; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import static org.mockito.Mockito.spy; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -61,8 +70,26 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule @Autowired protected AttributesService attributesService; + @Autowired + protected EventService eventService; + @Before public void beforeTest() throws Exception { + + EventService spyEventService = spy(eventService); + + Mockito.doAnswer((Answer>) invocation -> { + Object[] args = invocation.getArguments(); + Event event = (Event) args[0]; + ListenableFuture future = eventService.saveAsync(event); + try { + future.get(); + } catch (Exception e) {} + return future; + }).when(spyEventService).saveAsync(Mockito.any(Event.class)); + + ReflectionTestUtils.setField(actorSystem, "eventService", spyEventService); + loginSysAdmin(); Tenant tenant = new Tenant(); diff --git a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java index 8bae26583f..8011cbe952 100644 --- a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java @@ -15,13 +15,16 @@ */ package org.thingsboard.server.rules.lifecycle; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.util.ReflectionTestUtils; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; @@ -42,6 +45,7 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.TbMsgCallback; import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; import org.thingsboard.server.dao.attributes.AttributesService; +import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.memory.InMemoryStorage; import java.util.Collections; @@ -50,6 +54,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.awaitility.Awaitility.await; +import static org.mockito.Mockito.spy; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -67,8 +72,26 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac @Autowired protected AttributesService attributesService; + @Autowired + protected EventService eventService; + @Before public void beforeTest() throws Exception { + + EventService spyEventService = spy(eventService); + + Mockito.doAnswer((Answer>) invocation -> { + Object[] args = invocation.getArguments(); + Event event = (Event) args[0]; + ListenableFuture future = eventService.saveAsync(event); + try { + future.get(); + } catch (Exception e) {} + return future; + }).when(spyEventService).saveAsync(Mockito.any(Event.class)); + + ReflectionTestUtils.setField(actorSystem, "eventService", spyEventService); + loginSysAdmin(); Tenant tenant = new Tenant(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java index b67662dfe7..cb1d0a294d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java @@ -171,6 +171,8 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode) invocationOnMock -> (Alarm) (invocationOnMock.getArguments())[0]).when(alarmService).createOrUpdateAlarm(any(Alarm.class)); + long ts = msg.getTs(); + node.onMsg(ctx, msg); + + verify(ctx, atMost(10)).enqueue(any(), successCaptor.capture(), failureCaptor.capture()); + successCaptor.getValue().run(); + verify(ctx, atMost(10)).tellNext(any(), eq("Created")); + + ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(TbMsg.class); + ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor originatorCaptor = ArgumentCaptor.forClass(EntityId.class); + ArgumentCaptor metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class); + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(String.class); + verify(ctx, atMost(10)).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture()); + + assertEquals("ALARM", typeCaptor.getValue()); + assertEquals(originator, originatorCaptor.getValue()); + assertEquals("value", metadataCaptor.getValue().getValue("key")); + assertEquals(Boolean.TRUE.toString(), metadataCaptor.getValue().getValue(IS_NEW_ALARM)); + assertNotSame(metaData, metadataCaptor.getValue()); + + Alarm actualAlarm = new ObjectMapper().readValue(dataCaptor.getValue().getBytes(), Alarm.class); + Alarm expectedAlarm = Alarm.builder() + .startTs(ts) + .endTs(ts) + .tenantId(tenantId) + .originator(originator) + .status(ACTIVE_UNACK) + .severity(CRITICAL) + .propagateToTenant(true) + .type("SomeType" + i) + .details(null) + .build(); + + assertEquals(expectedAlarm, actualAlarm); + } + } + private void initWithCreateAlarmScript() { try { TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration();