From 023f6e9f1d0cc11eeeafce2575e38fe15d6d1579 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Mon, 22 Apr 2024 16:10:42 +0300 Subject: [PATCH 1/3] Increase max stats size for notification request --- application/src/main/data/upgrade/3.6.4/schema_update.sql | 6 ++++++ dao/src/main/resources/sql/schema-entities.sql | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/application/src/main/data/upgrade/3.6.4/schema_update.sql b/application/src/main/data/upgrade/3.6.4/schema_update.sql index d7d8887d13..3367e4df97 100644 --- a/application/src/main/data/upgrade/3.6.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.4/schema_update.sql @@ -134,3 +134,9 @@ DELETE FROM asset WHERE type='TbServiceQueue'; DELETE FROM asset_profile WHERE name ='TbServiceQueue'; -- QUEUE STATS UPDATE END + +-- NOTIFICATIONS UPDATE START + +ALTER TABLE notification_request ALTER COLUMN stats SET DATA TYPE varchar(100000); + +-- NOTIFICATIONS UPDATE END diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 1199f45181..9505e5aad7 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -855,7 +855,7 @@ CREATE TABLE IF NOT EXISTS notification_request ( originator_entity_type VARCHAR(32), rule_id UUID NULL, status VARCHAR(32), - stats VARCHAR(10000) + stats VARCHAR(100000) ); CREATE TABLE IF NOT EXISTS notification ( From dd51aba417837db39e381feeea0aefa551e97978 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 23 Apr 2024 12:41:41 +0300 Subject: [PATCH 2/3] Fix notifications count update race condition in tests --- .../service/notification/NotificationApiWsClient.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java index 96e3e4732e..1ecae638a6 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java @@ -106,8 +106,11 @@ public class NotificationApiWsClient extends TbTestWebSocketClient { } } } else if (updateType == CmdUpdateType.NOTIFICATIONS_COUNT) { - lastCountUpdate = JacksonUtil.treeToValue(update, UnreadNotificationsCountUpdate.class); - unreadCount = lastCountUpdate.getTotalUnreadCount(); + UnreadNotificationsCountUpdate countUpdate = JacksonUtil.treeToValue(update, UnreadNotificationsCountUpdate.class); + if (lastCountUpdate == null || countUpdate.getSequenceNumber() > lastCountUpdate.getSequenceNumber()) { + lastCountUpdate = countUpdate; + unreadCount = lastCountUpdate.getTotalUnreadCount(); + } } super.onMessage(s); } From 285b8803da384690d48eb7c79a05c9345e7acb59 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 25 Apr 2024 12:19:47 +0300 Subject: [PATCH 3/3] Limit notification request errors stats to 100 --- .../main/data/upgrade/3.6.4/schema_update.sql | 6 ------ .../notification/NotificationApiTest.java | 17 ++++++++--------- .../notification/NotificationRequestStats.java | 16 +++++++++++++--- dao/src/main/resources/sql/schema-entities.sql | 2 +- .../sent/sent-table-config.resolver.ts | 3 +-- .../app/shared/models/notification.models.ts | 2 +- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/application/src/main/data/upgrade/3.6.4/schema_update.sql b/application/src/main/data/upgrade/3.6.4/schema_update.sql index 3367e4df97..d7d8887d13 100644 --- a/application/src/main/data/upgrade/3.6.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.4/schema_update.sql @@ -134,9 +134,3 @@ DELETE FROM asset WHERE type='TbServiceQueue'; DELETE FROM asset_profile WHERE name ='TbServiceQueue'; -- QUEUE STATS UPDATE END - --- NOTIFICATIONS UPDATE START - -ALTER TABLE notification_request ALTER COLUMN stats SET DATA TYPE varchar(100000); - --- NOTIFICATIONS UPDATE END diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java index 060af9eac1..4bb8058e7f 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java @@ -523,18 +523,17 @@ public class NotificationApiTest extends AbstractNotificationApiTest { @Test public void testNotificationRequestStats() throws Exception { - wsClient.subscribeForUnreadNotifications(10); - wsClient.waitForReply(true); - - wsClient.registerWaitForUpdate(); NotificationTarget notificationTarget = createNotificationTarget(customerUserId); - NotificationRequest notificationRequest = submitNotificationRequest(notificationTarget.getId(), "Test :)", NotificationDeliveryMethod.WEB); - wsClient.waitForUpdate(); - await().atMost(2, TimeUnit.SECONDS) - .until(() -> findNotificationRequest(notificationRequest.getId()).isSent()); - NotificationRequestStats stats = getStats(notificationRequest.getId()); + NotificationRequest notificationRequest = submitNotificationRequest(notificationTarget.getId(), "Test :)", NotificationDeliveryMethod.WEB); + NotificationRequestStats stats = awaitNotificationRequest(notificationRequest.getId()); assertThat(stats.getSent().get(NotificationDeliveryMethod.WEB)).hasValue(1); + + doDelete("/api/user/mobile/session").andExpect(status().isOk()); + notificationRequest = submitNotificationRequest(notificationTarget.getId(), "Test", NotificationDeliveryMethod.MOBILE_APP); + stats = awaitNotificationRequest(notificationRequest.getId()); + assertThat(stats.getErrors().get(NotificationDeliveryMethod.MOBILE_APP)).hasSize(1); + assertThat(stats.getTotalErrors()).hasValue(1); } @Test diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java index 2bd9c526fd..e9e22e81ee 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java @@ -34,7 +34,6 @@ public class NotificationRequestStats { @JsonIgnore private final AtomicInteger totalSent; private final Map> errors; - @JsonIgnore private final AtomicInteger totalErrors; private String error; @JsonIgnore @@ -51,11 +50,19 @@ public class NotificationRequestStats { @JsonCreator public NotificationRequestStats(@JsonProperty("sent") Map sent, @JsonProperty("errors") Map> errors, + @JsonProperty("totalErrors") Integer totalErrors, @JsonProperty("error") String error) { this.sent = sent; this.totalSent = null; this.errors = errors; - this.totalErrors = null; + if (totalErrors == null) { + if (errors != null) { + totalErrors = errors.values().stream().mapToInt(Map::size).sum(); + } else { + totalErrors = 0; + } + } + this.totalErrors = new AtomicInteger(totalErrors); this.error = error; this.processedRecipients = Collections.emptyMap(); } @@ -73,7 +80,10 @@ public class NotificationRequestStats { if (errorMessage == null) { errorMessage = error.getClass().getSimpleName(); } - errors.computeIfAbsent(deliveryMethod, k -> new ConcurrentHashMap<>()).put(recipient.getTitle(), errorMessage); + Map errors = this.errors.computeIfAbsent(deliveryMethod, k -> new ConcurrentHashMap<>()); + if (errors.size() < 100) { + errors.put(recipient.getTitle(), errorMessage); + } totalErrors.incrementAndGet(); } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 9505e5aad7..1199f45181 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -855,7 +855,7 @@ CREATE TABLE IF NOT EXISTS notification_request ( originator_entity_type VARCHAR(32), rule_id UUID NULL, status VARCHAR(32), - stats VARCHAR(100000) + stats VARCHAR(10000) ); CREATE TABLE IF NOT EXISTS notification ( diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts index 97b353555a..baee27ff73 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts @@ -165,8 +165,7 @@ export class SentTableConfigResolver implements Resolve countError += Object.keys(stats.errors[method]).length); + const countError = stats.totalErrors; if (countError === 0) { return ''; } diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index 2cc7d8547b..b8097d18cb 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -81,7 +81,7 @@ export interface NotificationRequestPreview { export interface NotificationRequestStats { sent: Map; errors: { [key in NotificationDeliveryMethod]: {[errorKey in string]: string}}; - processedRecipients: Map>; + totalErrors: number; } export interface NotificationRequestConfig {