Commit 26e84f7b1834955648ab54acd4ea7bf15941282e

Authored by Dmytro Shvaika
Committed by Andrew Shvayka
1 parent 158436b1

refactoring & added alarmCanBeClearedWithAlarmOriginator test

@@ -57,38 +57,15 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig @@ -57,38 +57,15 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig
57 @Override 57 @Override
58 protected ListenableFuture<AlarmResult> processAlarm(TbContext ctx, TbMsg msg) { 58 protected ListenableFuture<AlarmResult> processAlarm(TbContext ctx, TbMsg msg) {
59 String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg.getMetaData()); 59 String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg.getMetaData());
  60 + ListenableFuture<Alarm> alarmFuture;
60 if (msg.getOriginator().getEntityType().equals(EntityType.ALARM)) { 61 if (msg.getOriginator().getEntityType().equals(EntityType.ALARM)) {
61 - return clearAlarmByAlarmOriginator(ctx, msg); 62 + alarmFuture = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), new AlarmId(msg.getOriginator().getId()));
62 } else { 63 } else {
63 - ListenableFuture<Alarm> latest = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType);  
64 - return Futures.transformAsync(latest, a -> {  
65 - if (a != null && !a.getStatus().isCleared()) {  
66 - return clearAlarm(ctx, msg, a);  
67 - }  
68 - return Futures.immediateFuture(new AlarmResult(false, false, false, null));  
69 - }, ctx.getDbCallbackExecutor()); 64 + alarmFuture = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType);
70 } 65 }
71 - }  
72 -  
73 - private ListenableFuture<AlarmResult> clearAlarmByAlarmOriginator(TbContext ctx, TbMsg msg) {  
74 - ListenableFuture<Alarm> alarmByIdAsync = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), new AlarmId(msg.getOriginator().getId()));  
75 - return Futures.transformAsync(alarmByIdAsync, alarm -> {  
76 - if (alarm != null && !alarm.getStatus().isCleared()) {  
77 - ctx.logJsEvalRequest();  
78 - ListenableFuture<JsonNode> asyncDetails = buildAlarmDetails(ctx, msg, alarm.getDetails());  
79 - return Futures.transformAsync(asyncDetails, details -> {  
80 - ctx.logJsEvalRequest();  
81 - long clearTs = System.currentTimeMillis();  
82 - ListenableFuture<Boolean> clearAlarmFuture = ctx.getAlarmService().clearAlarm(ctx.getTenantId(), alarm.getId(), details, clearTs);  
83 - return Futures.transformAsync(clearAlarmFuture, cleared -> {  
84 - if (cleared) {  
85 - alarm.setClearTs(clearTs);  
86 - alarm.setDetails(details);  
87 - }  
88 - alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK);  
89 - return Futures.immediateFuture(new AlarmResult(false, false, true, alarm));  
90 - }, ctx.getDbCallbackExecutor());  
91 - }, ctx.getDbCallbackExecutor()); 66 + return Futures.transformAsync(alarmFuture, a -> {
  67 + if (a != null && !a.getStatus().isCleared()) {
  68 + return clearAlarm(ctx, msg, a);
92 } 69 }
93 return Futures.immediateFuture(new AlarmResult(false, false, false, null)); 70 return Futures.immediateFuture(new AlarmResult(false, false, false, null));
94 }, ctx.getDbCallbackExecutor()); 71 }, ctx.getDbCallbackExecutor());
@@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.TbContext; @@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.TbContext;
35 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 35 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
36 import org.thingsboard.rule.engine.api.TbNodeException; 36 import org.thingsboard.rule.engine.api.TbNodeException;
37 import org.thingsboard.server.common.data.alarm.Alarm; 37 import org.thingsboard.server.common.data.alarm.Alarm;
  38 +import org.thingsboard.server.common.data.id.AlarmId;
38 import org.thingsboard.server.common.data.id.DeviceId; 39 import org.thingsboard.server.common.data.id.DeviceId;
39 import org.thingsboard.server.common.data.id.EntityId; 40 import org.thingsboard.server.common.data.id.EntityId;
40 import org.thingsboard.server.common.data.id.RuleChainId; 41 import org.thingsboard.server.common.data.id.RuleChainId;
@@ -95,6 +96,7 @@ public class TbAlarmNodeTest { @@ -95,6 +96,7 @@ public class TbAlarmNodeTest {
95 private ListeningExecutor dbExecutor; 96 private ListeningExecutor dbExecutor;
96 97
97 private EntityId originator = new DeviceId(UUIDs.timeBased()); 98 private EntityId originator = new DeviceId(UUIDs.timeBased());
  99 + private EntityId alarmOriginator = new AlarmId(UUIDs.timeBased());
98 private TenantId tenantId = new TenantId(UUIDs.timeBased()); 100 private TenantId tenantId = new TenantId(UUIDs.timeBased());
99 private TbMsgMetaData metaData = new TbMsgMetaData(); 101 private TbMsgMetaData metaData = new TbMsgMetaData();
100 private String rawJson = "{\"name\": \"Vit\", \"passed\": 5}"; 102 private String rawJson = "{\"name\": \"Vit\", \"passed\": 5}";
@@ -325,6 +327,55 @@ public class TbAlarmNodeTest { @@ -325,6 +327,55 @@ public class TbAlarmNodeTest {
325 assertEquals(expectedAlarm, actualAlarm); 327 assertEquals(expectedAlarm, actualAlarm);
326 } 328 }
327 329
  330 + @Test
  331 + public void alarmCanBeClearedWithAlarmOriginator() throws ScriptException, IOException {
  332 + initWithClearAlarmScript();
  333 + metaData.putValue("key", "value");
  334 + TbMsg msg = TbMsg.newMsg( "USER", alarmOriginator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId);
  335 +
  336 + long oldEndDate = System.currentTimeMillis();
  337 + AlarmId id = new AlarmId(alarmOriginator.getId());
  338 + Alarm activeAlarm = Alarm.builder().type("SomeType").tenantId(tenantId).originator(originator).status(ACTIVE_UNACK).severity(WARNING).endTs(oldEndDate).build();
  339 + activeAlarm.setId(id);
  340 +
  341 + when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFuture(null));
  342 + when(alarmService.findAlarmByIdAsync(tenantId, id)).thenReturn(Futures.immediateFuture(activeAlarm));
  343 + when(alarmService.clearAlarm(eq(activeAlarm.getTenantId()), eq(activeAlarm.getId()), org.mockito.Mockito.any(JsonNode.class), anyLong())).thenReturn(Futures.immediateFuture(true));
  344 +// doAnswer((Answer<Alarm>) invocationOnMock -> (Alarm) (invocationOnMock.getArguments())[0]).when(alarmService).createOrUpdateAlarm(activeAlarm);
  345 +
  346 + node.onMsg(ctx, msg);
  347 +
  348 + verify(ctx).tellNext(any(), eq("Cleared"));
  349 +
  350 + ArgumentCaptor<TbMsg> msgCaptor = ArgumentCaptor.forClass(TbMsg.class);
  351 + ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class);
  352 + ArgumentCaptor<EntityId> originatorCaptor = ArgumentCaptor.forClass(EntityId.class);
  353 + ArgumentCaptor<TbMsgMetaData> metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class);
  354 + ArgumentCaptor<String> dataCaptor = ArgumentCaptor.forClass(String.class);
  355 + verify(ctx).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture());
  356 +
  357 + assertEquals("ALARM", typeCaptor.getValue());
  358 + assertEquals(alarmOriginator, originatorCaptor.getValue());
  359 + assertEquals("value", metadataCaptor.getValue().getValue("key"));
  360 + assertEquals(Boolean.TRUE.toString(), metadataCaptor.getValue().getValue(IS_CLEARED_ALARM));
  361 + assertNotSame(metaData, metadataCaptor.getValue());
  362 +
  363 + Alarm actualAlarm = new ObjectMapper().readValue(dataCaptor.getValue().getBytes(), Alarm.class);
  364 + Alarm expectedAlarm = Alarm.builder()
  365 + .tenantId(tenantId)
  366 + .originator(originator)
  367 + .status(CLEARED_UNACK)
  368 + .severity(WARNING)
  369 + .propagate(false)
  370 + .type("SomeType")
  371 + .details(null)
  372 + .endTs(oldEndDate)
  373 + .build();
  374 + expectedAlarm.setId(id);
  375 +
  376 + assertEquals(expectedAlarm, actualAlarm);
  377 + }
  378 +
328 private void initWithCreateAlarmScript() { 379 private void initWithCreateAlarmScript() {
329 try { 380 try {
330 TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration(); 381 TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration();