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 57 @Override
58 58 protected ListenableFuture<AlarmResult> processAlarm(TbContext ctx, TbMsg msg) {
59 59 String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg.getMetaData());
  60 + ListenableFuture<Alarm> alarmFuture;
60 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 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 70 return Futures.immediateFuture(new AlarmResult(false, false, false, null));
94 71 }, ctx.getDbCallbackExecutor());
... ...
... ... @@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.TbContext;
35 35 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
36 36 import org.thingsboard.rule.engine.api.TbNodeException;
37 37 import org.thingsboard.server.common.data.alarm.Alarm;
  38 +import org.thingsboard.server.common.data.id.AlarmId;
38 39 import org.thingsboard.server.common.data.id.DeviceId;
39 40 import org.thingsboard.server.common.data.id.EntityId;
40 41 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -95,6 +96,7 @@ public class TbAlarmNodeTest {
95 96 private ListeningExecutor dbExecutor;
96 97
97 98 private EntityId originator = new DeviceId(UUIDs.timeBased());
  99 + private EntityId alarmOriginator = new AlarmId(UUIDs.timeBased());
98 100 private TenantId tenantId = new TenantId(UUIDs.timeBased());
99 101 private TbMsgMetaData metaData = new TbMsgMetaData();
100 102 private String rawJson = "{\"name\": \"Vit\", \"passed\": 5}";
... ... @@ -325,6 +327,55 @@ public class TbAlarmNodeTest {
325 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 379 private void initWithCreateAlarmScript() {
329 380 try {
330 381 TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration();
... ...