Commit 26e84f7b1834955648ab54acd4ea7bf15941282e
Committed by
Andrew Shvayka
1 parent
158436b1
refactoring & added alarmCanBeClearedWithAlarmOriginator test
Showing
2 changed files
with
57 additions
and
29 deletions
@@ -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(); |