Merge pull request #10612 from thingsboard/fix/notification-request-stats

Limit notification request errors stats
This commit is contained in:
Viacheslav Klimov 2024-04-25 13:48:08 +03:00 committed by GitHub
commit 299ecd1cb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 28 additions and 17 deletions

View File

@ -523,18 +523,17 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
@Test @Test
public void testNotificationRequestStats() throws Exception { public void testNotificationRequestStats() throws Exception {
wsClient.subscribeForUnreadNotifications(10);
wsClient.waitForReply(true);
wsClient.registerWaitForUpdate();
NotificationTarget notificationTarget = createNotificationTarget(customerUserId); NotificationTarget notificationTarget = createNotificationTarget(customerUserId);
NotificationRequest notificationRequest = submitNotificationRequest(notificationTarget.getId(), "Test :)", NotificationDeliveryMethod.WEB);
wsClient.waitForUpdate();
await().atMost(2, TimeUnit.SECONDS) NotificationRequest notificationRequest = submitNotificationRequest(notificationTarget.getId(), "Test :)", NotificationDeliveryMethod.WEB);
.until(() -> findNotificationRequest(notificationRequest.getId()).isSent()); NotificationRequestStats stats = awaitNotificationRequest(notificationRequest.getId());
NotificationRequestStats stats = getStats(notificationRequest.getId());
assertThat(stats.getSent().get(NotificationDeliveryMethod.WEB)).hasValue(1); 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 @Test

View File

@ -106,9 +106,12 @@ public class NotificationApiWsClient extends TbTestWebSocketClient {
} }
} }
} else if (updateType == CmdUpdateType.NOTIFICATIONS_COUNT) { } else if (updateType == CmdUpdateType.NOTIFICATIONS_COUNT) {
lastCountUpdate = JacksonUtil.treeToValue(update, UnreadNotificationsCountUpdate.class); UnreadNotificationsCountUpdate countUpdate = JacksonUtil.treeToValue(update, UnreadNotificationsCountUpdate.class);
if (lastCountUpdate == null || countUpdate.getSequenceNumber() > lastCountUpdate.getSequenceNumber()) {
lastCountUpdate = countUpdate;
unreadCount = lastCountUpdate.getTotalUnreadCount(); unreadCount = lastCountUpdate.getTotalUnreadCount();
} }
}
super.onMessage(s); super.onMessage(s);
} }

View File

@ -34,7 +34,6 @@ public class NotificationRequestStats {
@JsonIgnore @JsonIgnore
private final AtomicInteger totalSent; private final AtomicInteger totalSent;
private final Map<NotificationDeliveryMethod, Map<String, String>> errors; private final Map<NotificationDeliveryMethod, Map<String, String>> errors;
@JsonIgnore
private final AtomicInteger totalErrors; private final AtomicInteger totalErrors;
private String error; private String error;
@JsonIgnore @JsonIgnore
@ -51,11 +50,19 @@ public class NotificationRequestStats {
@JsonCreator @JsonCreator
public NotificationRequestStats(@JsonProperty("sent") Map<NotificationDeliveryMethod, AtomicInteger> sent, public NotificationRequestStats(@JsonProperty("sent") Map<NotificationDeliveryMethod, AtomicInteger> sent,
@JsonProperty("errors") Map<NotificationDeliveryMethod, Map<String, String>> errors, @JsonProperty("errors") Map<NotificationDeliveryMethod, Map<String, String>> errors,
@JsonProperty("totalErrors") Integer totalErrors,
@JsonProperty("error") String error) { @JsonProperty("error") String error) {
this.sent = sent; this.sent = sent;
this.totalSent = null; this.totalSent = null;
this.errors = errors; 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.error = error;
this.processedRecipients = Collections.emptyMap(); this.processedRecipients = Collections.emptyMap();
} }
@ -73,7 +80,10 @@ public class NotificationRequestStats {
if (errorMessage == null) { if (errorMessage == null) {
errorMessage = error.getClass().getSimpleName(); errorMessage = error.getClass().getSimpleName();
} }
errors.computeIfAbsent(deliveryMethod, k -> new ConcurrentHashMap<>()).put(recipient.getTitle(), errorMessage); Map<String, String> errors = this.errors.computeIfAbsent(deliveryMethod, k -> new ConcurrentHashMap<>());
if (errors.size() < 100) {
errors.put(recipient.getTitle(), errorMessage);
}
totalErrors.incrementAndGet(); totalErrors.incrementAndGet();
} }

View File

@ -165,8 +165,7 @@ export class SentTableConfigResolver implements Resolve<EntityTableConfig<Notifi
if (!stats?.errors) { if (!stats?.errors) {
return ''; return '';
} }
let countError = 0; const countError = stats.totalErrors;
Object.keys(stats.errors).forEach(method => countError += Object.keys(stats.errors[method]).length);
if (countError === 0) { if (countError === 0) {
return ''; return '';
} }

View File

@ -81,7 +81,7 @@ export interface NotificationRequestPreview {
export interface NotificationRequestStats { export interface NotificationRequestStats {
sent: Map<NotificationDeliveryMethod, any>; sent: Map<NotificationDeliveryMethod, any>;
errors: { [key in NotificationDeliveryMethod]: {[errorKey in string]: string}}; errors: { [key in NotificationDeliveryMethod]: {[errorKey in string]: string}};
processedRecipients: Map<NotificationDeliveryMethod, Set<UserId>>; totalErrors: number;
} }
export interface NotificationRequestConfig { export interface NotificationRequestConfig {