From 38b2cf41c4dc5b61f05731a019c503f7f5943028 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 24 Feb 2023 14:56:06 +0200 Subject: [PATCH] Fix soem tests and added upgrade script --- .../main/data/upgrade/3.4.4/schema_update.sql | 18 +++++++++++++++++- .../DefaultAlarmSubscriptionService.java | 6 +++++- .../alarm/DefaultTbAlarmServiceTest.java | 11 +++++++---- .../main/resources/sql/schema-entities-idx.sql | 2 ++ dao/src/main/resources/sql/schema-entities.sql | 7 ------- .../rule/engine/action/TbAlarmNodeTest.java | 4 ++-- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 1cb9aaaf5b..4721001409 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -29,6 +29,7 @@ CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenan ALTER TABLE alarm ADD COLUMN IF NOT EXISTS acknowledged boolean; ALTER TABLE alarm ADD COLUMN IF NOT EXISTS cleared boolean; +ALTER TABLE alarm ADD COLUMN IF NOT EXISTS status varchar; -- to avoid failure of the subsequent upgrade. UPDATE alarm SET acknowledged = true, cleared = true WHERE status = 'CLEARED_ACK'; UPDATE alarm SET acknowledged = true, cleared = false WHERE status = 'ACTIVE_ACK'; UPDATE alarm SET acknowledged = false, cleared = true WHERE status = 'CLEARED_UNACK'; @@ -44,7 +45,22 @@ DROP INDEX IF EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id CREATE INDEX IF NOT EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id ON entity_alarm USING btree (tenant_id, entity_id, alarm_type, created_time DESC) INCLUDE(alarm_id); -ALTER TABLE alarm DROP COLUMN status; +DROP INDEX IF EXISTS idx_alarm_tenant_status_created_time; +ALTER TABLE alarm DROP COLUMN IF EXISTS status; + +-- Update old alarms and set their state to clear, if there are newer alarms. +UPDATE alarm a +SET cleared = TRUE +WHERE cleared = FALSE + AND id != (SELECT l.id + FROM alarm l + WHERE l.tenant_id = a.tenant_id + AND l.originator_id = a.originator_id + AND l.type = a.type + ORDER BY l.created_time DESC, l.id + LIMIT 1); + +VACUUM FULL ANALYZE alarm; -- ALARM STATUS REFACTORING END diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java index 0f8a9af900..48f8760503 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java @@ -99,7 +99,11 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService @Override public AlarmApiCallResult createAlarm(AlarmCreateOrUpdateActiveRequest request) { boolean creationEnabled = apiUsageStateService.getApiUsageState(request.getTenantId()).isAlarmCreationEnabled(); - return withWsCallback(alarmService.createAlarm(request, creationEnabled)); + var result = alarmService.createAlarm(request, creationEnabled); + if (result.isCreated()) { + apiUsageClient.report(request.getTenantId(), null, ApiUsageRecordKey.CREATED_ALARMS_COUNT); + } + return withWsCallback(result); } @Override diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java index 3d3615a3c4..93aeb17de6 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java @@ -85,6 +85,7 @@ public class DefaultTbAlarmServiceTest { var alarm = new AlarmInfo(); when(alarmSubscriptionService.createAlarm(any())).thenReturn(AlarmApiCallResult.builder() .successful(true) + .modified(true) .alarm(alarm) .build()); service.save(alarm, new User()); @@ -96,24 +97,26 @@ public class DefaultTbAlarmServiceTest { @Test public void testAck() throws ThingsboardException { var alarm = new Alarm(); - when(alarmSubscriptionService.ackAlarm(any(), any(), anyLong())).thenReturn(Futures.immediateFuture(true)); + when(alarmSubscriptionService.acknowledgeAlarm(any(), any(), anyLong())) + .thenReturn(AlarmApiCallResult.builder().successful(true).modified(true).build()); service.ack(alarm, new User(new UserId(UUID.randomUUID()))); verify(alarmCommentService, times(1)).createOrUpdateAlarmComment(any(), any()); verify(notificationEntityService, times(1)).notifyCreateOrUpdateAlarm(any(), any(), any()); - verify(alarmSubscriptionService, times(1)).ackAlarm(any(), any(), anyLong()); + verify(alarmSubscriptionService, times(1)).acknowledgeAlarm(any(), any(), anyLong()); } @Test public void testClear() throws ThingsboardException { var alarm = new Alarm(); alarm.setAcknowledged(true); - when(alarmSubscriptionService.clearAlarm(any(), any(), any(), anyLong())).thenReturn(Futures.immediateFuture(true)); + when(alarmSubscriptionService.clearAlarm(any(), any(), anyLong(), any())) + .thenReturn(AlarmApiCallResult.builder().successful(true).cleared(true).build()); service.clear(alarm, new User(new UserId(UUID.randomUUID()))); verify(alarmCommentService, times(1)).createOrUpdateAlarmComment(any(), any()); verify(notificationEntityService, times(1)).notifyCreateOrUpdateAlarm(any(), any(), any()); - verify(alarmSubscriptionService, times(1)).clearAlarm(any(), any(), any(), anyLong()); + verify(alarmSubscriptionService, times(1)).clearAlarm(any(), any(), anyLong(), any()); } @Test diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index cdcaef0ab3..031ce3eda6 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -20,6 +20,7 @@ CREATE INDEX IF NOT EXISTS idx_alarm_originator_created_time ON alarm(originator CREATE INDEX IF NOT EXISTS idx_alarm_tenant_created_time ON alarm(tenant_id, created_time DESC); +-- Drop index by 'status' column and replace with new one that has only active alarms; CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type_active ON alarm USING btree (originator_id, type, created_time DESC) WHERE cleared = false; @@ -29,6 +30,7 @@ CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenan CREATE INDEX IF NOT EXISTS idx_entity_alarm_created_time ON entity_alarm(tenant_id, entity_id, created_time DESC); +-- Cover index by alarm type to optimize propagated alarm queries; CREATE INDEX IF NOT EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id ON entity_alarm USING btree (tenant_id, entity_id, alarm_type, created_time DESC) INCLUDE(alarm_id); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 90c11fbd2c..c3d92e445c 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -430,13 +430,6 @@ CREATE TABLE IF NOT EXISTS relation ( additional_info varchar, CONSTRAINT relation_pkey PRIMARY KEY (from_id, from_type, relation_type_group, relation_type, to_id, to_type) ); --- ) PARTITION BY LIST (relation_type_group); --- --- CREATE TABLE other_relations PARTITION OF relation DEFAULT; --- CREATE TABLE common_relations PARTITION OF relation FOR VALUES IN ('COMMON'); --- CREATE TABLE alarm_relations PARTITION OF relation FOR VALUES IN ('ALARM'); --- CREATE TABLE dashboard_relations PARTITION OF relation FOR VALUES IN ('DASHBOARD'); --- CREATE TABLE rule_relations PARTITION OF relation FOR VALUES IN ('RULE_CHAIN', 'RULE_NODE'); CREATE TABLE IF NOT EXISTS tb_user ( id uuid NOT NULL CONSTRAINT tb_user_pkey PRIMARY KEY, diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java index 88b36b96cc..c3a72392e1 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java @@ -185,7 +185,7 @@ public class TbAlarmNodeTest { verify(ctx).createScriptEngine(ScriptLanguage.JS, "DETAILS"); verify(ctx).getAlarmService(); - verify(ctx, times(3)).getDbCallbackExecutor(); + verify(ctx, times(2)).getDbCallbackExecutor(); verify(ctx).logJsEvalRequest(); verify(ctx).getTenantId(); verify(alarmService).findLatestActiveByOriginatorAndType(tenantId, originator, "SomeType"); @@ -372,7 +372,7 @@ public class TbAlarmNodeTest { expectedAlarm.setId(id); when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFuture(null)); - when(alarmService.findAlarmByIdAsync(tenantId, id)).thenReturn(Futures.immediateFuture(activeAlarm)); + when(alarmService.findAlarmById(tenantId, id)).thenReturn(activeAlarm); when(alarmService.clearAlarm(eq(activeAlarm.getTenantId()), eq(activeAlarm.getId()), anyLong(), nullable(JsonNode.class))) .thenReturn(AlarmApiCallResult.builder() .successful(true)