From b9e6c2b75e28b6259405a2180dbfc18b4efbe49d Mon Sep 17 00:00:00 2001 From: Swoq Date: Fri, 29 Oct 2021 15:28:07 +0300 Subject: [PATCH 1/8] Event clearing --- .../server/controller/EventController.java | 33 +++++++++++++++++ .../server/dao/event/EventService.java | 1 + .../server/dao/event/BaseEventService.java | 37 ++++++++++++++----- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index d1e9ad8efc..8547126643 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -18,6 +18,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -26,6 +27,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.event.EventFilter; @@ -238,4 +240,35 @@ public class EventController extends BaseController { } } + @ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events for specified entity.") + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}/clear", method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + public void clearEvents( + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @PathVariable(ENTITY_TYPE) String strEntityType, + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @PathVariable(ENTITY_ID) String strEntityId, + @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @RequestParam("tenantId") String strTenantId, + @ApiParam(value = "A string value representing event type", example = "STATS", required = true) + @PathVariable("eventType") String eventType, + @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @RequestParam(required = false) Long startTime, + @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @RequestParam(required = false) Long endTime) throws ThingsboardException { + checkParameter("EntityId", strEntityId); + checkParameter("EntityType", strEntityType); + try { + TenantId tenantId = new TenantId(toUUID(strTenantId)); + + EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); + checkEntityId(entityId, Operation.DELETE); + + eventService.removeEventsByTypeInPeriod(tenantId, entityId, eventType, startTime, endTime); + } catch (Exception e) { + throw handleException(e); + } + } + } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index db1c77697e..973b5ad3cc 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -48,4 +48,5 @@ public interface EventService { void cleanupEvents(long ttl, long debugTtl); + void removeEventsByTypeInPeriod(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 2785df90df..a8888a230c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -25,14 +25,18 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.event.EventFilter; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.IdBased; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; +import java.sql.Time; import java.util.List; import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; @Service @Slf4j @@ -118,17 +122,8 @@ public class BaseEventService implements EventService { @Override public void removeEvents(TenantId tenantId, EntityId entityId) { - PageData eventPageData; TimePageLink eventPageLink = new TimePageLink(1000); - do { - eventPageData = findEvents(tenantId, entityId, eventPageLink); - for (Event event : eventPageData.getData()) { - eventDao.removeById(tenantId, event.getUuidId()); - } - if (eventPageData.hasNext()) { - eventPageLink = eventPageLink.nextPageLink(); - } - } while (eventPageData.hasNext()); + removeEventsByTypeAndPageLink(tenantId, entityId, null, eventPageLink); } @Override @@ -136,6 +131,28 @@ public class BaseEventService implements EventService { eventDao.cleanupEvents(ttl, debugTtl); } + @Override + public void removeEventsByTypeInPeriod(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime) { + TimePageLink eventPageLink = + new TimePageLink(1000, 0, null, null, startTime, endTime); + removeEventsByTypeAndPageLink(tenantId, entityId, eventType, eventPageLink); + } + + private void removeEventsByTypeAndPageLink(TenantId tenantId, EntityId entityId, String eventType, TimePageLink eventPageLink) { + PageData eventPageData; + do { + if (eventType == null) + eventPageData = findEvents(tenantId, entityId, eventPageLink); + else + eventPageData = findEvents(tenantId, entityId, eventType, eventPageLink); + List eventsIds = eventPageData.getData().stream().map(IdBased::getUuidId).collect(Collectors.toList()); + eventDao.removeAllByIds(eventsIds); + if (eventPageData.hasNext()) { + eventPageLink = eventPageLink.nextPageLink(); + } + } while (eventPageData.hasNext()); + } + private DataValidator eventValidator = new DataValidator() { @Override From 144da0367aa76b703e29f9cf038d83c7ea160235 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Fri, 29 Oct 2021 16:52:19 +0300 Subject: [PATCH 2/8] Refactor events clearing --- .../server/controller/EventController.java | 2 +- .../server/dao/event/EventService.java | 3 +- .../server/dao/event/BaseEventService.java | 45 +++++++++---------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index 8547126643..ea8dda9673 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -265,7 +265,7 @@ public class EventController extends BaseController { EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); checkEntityId(entityId, Operation.DELETE); - eventService.removeEventsByTypeInPeriod(tenantId, entityId, eventType, startTime, endTime); + eventService.removeEvents(tenantId, entityId, eventType, startTime, endTime); } catch (Exception e) { throw handleException(e); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 973b5ad3cc..3591627c51 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -46,7 +46,8 @@ public interface EventService { void removeEvents(TenantId tenantId, EntityId entityId); + void removeEvents(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime); + void cleanupEvents(long ttl, long debugTtl); - void removeEventsByTypeInPeriod(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index a8888a230c..5e0cba7f5e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -32,7 +32,6 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; -import java.sql.Time; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -122,35 +121,33 @@ public class BaseEventService implements EventService { @Override public void removeEvents(TenantId tenantId, EntityId entityId) { - TimePageLink eventPageLink = new TimePageLink(1000); - removeEventsByTypeAndPageLink(tenantId, entityId, null, eventPageLink); + removeEvents(tenantId, entityId, null, null, null); } @Override - public void cleanupEvents(long ttl, long debugTtl) { - eventDao.cleanupEvents(ttl, debugTtl); - } + public void removeEvents(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime) { + TimePageLink eventsPageLink = new TimePageLink(1000, 0, null, null, startTime, endTime); + PageData eventsPageData; + do { + if (eventType == null) { + eventsPageData = findEvents(tenantId, entityId, eventsPageLink); + } else { + eventsPageData = findEvents(tenantId, entityId, eventType, eventsPageLink); + } - @Override - public void removeEventsByTypeInPeriod(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime) { - TimePageLink eventPageLink = - new TimePageLink(1000, 0, null, null, startTime, endTime); - removeEventsByTypeAndPageLink(tenantId, entityId, eventType, eventPageLink); - } + eventDao.removeAllByIds(eventsPageData.getData().stream() + .map(IdBased::getUuidId) + .collect(Collectors.toList())); - private void removeEventsByTypeAndPageLink(TenantId tenantId, EntityId entityId, String eventType, TimePageLink eventPageLink) { - PageData eventPageData; - do { - if (eventType == null) - eventPageData = findEvents(tenantId, entityId, eventPageLink); - else - eventPageData = findEvents(tenantId, entityId, eventType, eventPageLink); - List eventsIds = eventPageData.getData().stream().map(IdBased::getUuidId).collect(Collectors.toList()); - eventDao.removeAllByIds(eventsIds); - if (eventPageData.hasNext()) { - eventPageLink = eventPageLink.nextPageLink(); + if (eventsPageData.hasNext()) { + eventsPageLink = eventsPageLink.nextPageLink(); } - } while (eventPageData.hasNext()); + } while (eventsPageData.hasNext()); + } + + @Override + public void cleanupEvents(long ttl, long debugTtl) { + eventDao.cleanupEvents(ttl, debugTtl); } private DataValidator eventValidator = From c3d86624ed1663241b5647d45bef3b3b352da899 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Fri, 5 Nov 2021 17:29:46 +0200 Subject: [PATCH 3/8] Added 'clean' button for rule-node events --- .../components/entity/entities-table.component.html | 2 +- .../home/components/event/event-table-config.ts | 12 +++++++++++- .../home/components/event/event-table.component.ts | 7 +++++-- .../models/entity/entities-table-config.models.ts | 2 +- ui-ngx/src/assets/locale/locale.constant-en_US.json | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html index c4f470bbd2..3242bb5a53 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html @@ -84,7 +84,7 @@ [fxShow]="actionDescriptor.isEnabled()" *ngFor="let actionDescriptor of headerActionDescriptors" matTooltip="{{ actionDescriptor.name }}" matTooltipPosition="above" - (click)="actionDescriptor.onAction($event)"> + (click)="actionDescriptor.onAction($event, entitiesTableConfig)"> {{actionDescriptor.icon}} diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 9bf6912c9f..2d5cfbb428 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -48,6 +48,7 @@ import { EventFilterPanelData, FilterEntityColumn } from '@home/components/event/event-filter-panel.component'; +import { HttpClient } from '@angular/common/http'; export class EventTableConfig extends EntityTableConfig { @@ -82,7 +83,8 @@ export class EventTableConfig extends EntityTableConfig { private debugEventTypes: Array = null, private overlay: Overlay, private viewContainerRef: ViewContainerRef, - private cd: ChangeDetectorRef) { + private cd: ChangeDetectorRef, + private http: HttpClient) { super(); this.loadDataOnInit = false; this.tableTitle = ''; @@ -135,6 +137,14 @@ export class EventTableConfig extends EntityTableConfig { onAction: ($event) => { this.editEventFilter($event); } + }, + { + name: this.translate.instant('event.clean-events'), + icon: 'delete', + isEnabled: () => true, + onAction: ($event, entity) => { + this.http.delete(`/events/${entity.entityId.entityType}/${entity.entityId.id}/${entity.eventTypeValue}/clear`).subscribe(); + } }); } diff --git a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts index 00aeb4f50c..e875036562 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts @@ -25,6 +25,7 @@ import { EventService } from '@core/http/event.service'; import { DialogService } from '@core/services/dialog.service'; import { DebugEventType, EventType } from '@shared/models/event.models'; import { Overlay } from '@angular/cdk/overlay'; +import { HttpClient } from '@angular/common/http'; @Component({ selector: 'tb-event-table', @@ -84,7 +85,8 @@ export class EventTableComponent implements OnInit { private dialog: MatDialog, private overlay: Overlay, private viewContainerRef: ViewContainerRef, - private cd: ChangeDetectorRef) { + private cd: ChangeDetectorRef, + private http: HttpClient) { } ngOnInit() { @@ -102,7 +104,8 @@ export class EventTableComponent implements OnInit { this.debugEventTypes, this.overlay, this.viewContainerRef, - this.cd + this.cd, + this.http ); } diff --git a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts index 2f3d58e61f..c86ae6fef8 100644 --- a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts +++ b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts @@ -75,7 +75,7 @@ export interface HeaderActionDescriptor { icon: string; isMdiIcon?: boolean; isEnabled: () => boolean; - onAction: ($event: MouseEvent) => void; + onAction: ($event: MouseEvent, entity?) => void; } export type EntityTableColumnType = 'content' | 'action'; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 5d3adba457..f4a868a5c9 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1853,6 +1853,7 @@ "event": { "event-type": "Event type", "events-filter": "Events Filter", + "clean-events": "Clean Events", "type-error": "Error", "type-lc-event": "Lifecycle event", "type-stats": "Statistics", From 4d86a61580b7b3c253bdb45a1058e35392d6430c Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 8 Nov 2021 12:39:44 +0200 Subject: [PATCH 4/8] Update event clearing API --- .../thingsboard/server/controller/EventController.java | 9 +++++---- ui-ngx/src/app/core/http/event.service.ts | 9 ++++++++- .../modules/home/components/event/event-table-config.ts | 6 ++---- .../home/components/event/event-table.component.ts | 3 +-- ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 +- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index ea8dda9673..28c922afda 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -242,7 +242,7 @@ public class EventController extends BaseController { @ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events for specified entity.") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}/clear", method = RequestMethod.DELETE) + @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}/clear", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) public void clearEvents( @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @@ -250,13 +250,14 @@ public class EventController extends BaseController { @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) - @RequestParam("tenantId") String strTenantId, - @ApiParam(value = "A string value representing event type", example = "STATS", required = true) @PathVariable("eventType") String eventType, @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @RequestParam("tenantId") String strTenantId, + @ApiParam(value = "A string value representing event type", example = "STATS", required = true) @RequestParam(required = false) Long startTime, @ApiParam(value = EVENT_END_TIME_DESCRIPTION) - @RequestParam(required = false) Long endTime) throws ThingsboardException { + @RequestParam(required = false) Long endTime, + @RequestBody EventFilter eventFilter) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); try { diff --git a/ui-ngx/src/app/core/http/event.service.ts b/ui-ngx/src/app/core/http/event.service.ts index fd740d73a7..e54f760b00 100644 --- a/ui-ngx/src/app/core/http/event.service.ts +++ b/ui-ngx/src/app/core/http/event.service.ts @@ -44,5 +44,12 @@ export class EventService { return this.http.post>(`/api/events/${entityId.entityType}/${entityId.id}` + `${pageLink.toQuery()}&tenantId=${tenantId}`, {...filters, eventType}, defaultHttpOptionsFromConfig(config)); } - + + public clearEvents(entityId: EntityId, eventType: EventType | DebugEventType, filters: FilterEventBody, tenantId: string, + startTime?: number, endTime?: number, config?: RequestConfig) { + return this.http.post(`/api/events/${entityId.entityType}/${entityId.id}/${eventType}/clear&tenantId=${tenantId}` + + (startTime ? `&startTime=${startTime}` : ``) + (endTime ? `&endTime=${endTime}` : ``), {...filters, eventType}, + defaultHttpOptionsFromConfig(config)); + } + } diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 2d5cfbb428..07d8bfb82f 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -48,7 +48,6 @@ import { EventFilterPanelData, FilterEntityColumn } from '@home/components/event/event-filter-panel.component'; -import { HttpClient } from '@angular/common/http'; export class EventTableConfig extends EntityTableConfig { @@ -83,8 +82,7 @@ export class EventTableConfig extends EntityTableConfig { private debugEventTypes: Array = null, private overlay: Overlay, private viewContainerRef: ViewContainerRef, - private cd: ChangeDetectorRef, - private http: HttpClient) { + private cd: ChangeDetectorRef) { super(); this.loadDataOnInit = false; this.tableTitle = ''; @@ -143,7 +141,7 @@ export class EventTableConfig extends EntityTableConfig { icon: 'delete', isEnabled: () => true, onAction: ($event, entity) => { - this.http.delete(`/events/${entity.entityId.entityType}/${entity.entityId.id}/${entity.eventTypeValue}/clear`).subscribe(); + this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, , ).subscribe(); } }); } diff --git a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts index e875036562..85bd4cf81a 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts @@ -104,8 +104,7 @@ export class EventTableComponent implements OnInit { this.debugEventTypes, this.overlay, this.viewContainerRef, - this.cd, - this.http + this.cd ); } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index f4a868a5c9..fee65c086f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1853,7 +1853,7 @@ "event": { "event-type": "Event type", "events-filter": "Events Filter", - "clean-events": "Clean Events", + "clean-events": "Clear Events", "type-error": "Error", "type-lc-event": "Lifecycle event", "type-stats": "Statistics", From e718e31f639320bd4ca32e1df48a56739d6d3ff8 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 8 Nov 2021 13:24:55 +0200 Subject: [PATCH 5/8] Update clear Events request --- ui-ngx/src/app/core/http/event.service.ts | 5 ++--- .../home/components/entity/entities-table.component.html | 2 +- .../app/modules/home/components/event/event-table-config.ts | 4 ++-- .../home/models/entity/entities-table-config.models.ts | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/core/http/event.service.ts b/ui-ngx/src/app/core/http/event.service.ts index e54f760b00..5a3ec9e51f 100644 --- a/ui-ngx/src/app/core/http/event.service.ts +++ b/ui-ngx/src/app/core/http/event.service.ts @@ -46,10 +46,9 @@ export class EventService { } public clearEvents(entityId: EntityId, eventType: EventType | DebugEventType, filters: FilterEventBody, tenantId: string, - startTime?: number, endTime?: number, config?: RequestConfig) { + pageLink: TimePageLink, config?: RequestConfig) { return this.http.post(`/api/events/${entityId.entityType}/${entityId.id}/${eventType}/clear&tenantId=${tenantId}` + - (startTime ? `&startTime=${startTime}` : ``) + (endTime ? `&endTime=${endTime}` : ``), {...filters, eventType}, + `${pageLink.toQuery()}`, {...filters, eventType}, defaultHttpOptionsFromConfig(config)); } - } diff --git a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html index 3242bb5a53..b103c29df5 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html @@ -84,7 +84,7 @@ [fxShow]="actionDescriptor.isEnabled()" *ngFor="let actionDescriptor of headerActionDescriptors" matTooltip="{{ actionDescriptor.name }}" matTooltipPosition="above" - (click)="actionDescriptor.onAction($event, entitiesTableConfig)"> + (click)="actionDescriptor.onAction($event, entitiesTableConfig, pageLink)"> {{actionDescriptor.icon}} diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 07d8bfb82f..8a5201dc3f 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -140,8 +140,8 @@ export class EventTableConfig extends EntityTableConfig { name: this.translate.instant('event.clean-events'), icon: 'delete', isEnabled: () => true, - onAction: ($event, entity) => { - this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, , ).subscribe(); + onAction: ($event, entity, pageLink: TimePageLink) => { + this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, pageLink).subscribe(); } }); } diff --git a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts index c86ae6fef8..7a352e8f17 100644 --- a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts +++ b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts @@ -75,7 +75,7 @@ export interface HeaderActionDescriptor { icon: string; isMdiIcon?: boolean; isEnabled: () => boolean; - onAction: ($event: MouseEvent, entity?) => void; + onAction: ($event: MouseEvent, entity?, pageLink?) => void; } export type EntityTableColumnType = 'content' | 'action'; From 13a74c784ee50344eac515b169ac18d2493850d9 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 8 Nov 2021 14:19:44 +0200 Subject: [PATCH 6/8] Events clearing by filter --- .../server/controller/EventController.java | 6 +-- .../server/dao/event/EventService.java | 2 +- .../server/dao/event/BaseEventService.java | 7 ++- ui-ngx/src/app/core/http/event.service.ts | 5 ++- .../components/event/event-table-config.ts | 43 +++++++++++-------- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index 28c922afda..5759ffcac4 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -242,15 +242,13 @@ public class EventController extends BaseController { @ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events for specified entity.") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}/clear", method = RequestMethod.POST) + @RequestMapping(value = "/events/{entityType}/{entityId}/clear", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) public void clearEvents( @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) - @PathVariable("eventType") String eventType, @ApiParam(value = EVENT_START_TIME_DESCRIPTION) @RequestParam("tenantId") String strTenantId, @ApiParam(value = "A string value representing event type", example = "STATS", required = true) @@ -266,7 +264,7 @@ public class EventController extends BaseController { EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); checkEntityId(entityId, Operation.DELETE); - eventService.removeEvents(tenantId, entityId, eventType, startTime, endTime); + eventService.removeEvents(tenantId, entityId, eventFilter, startTime, endTime); } catch (Exception e) { throw handleException(e); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 3591627c51..f43d17915e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -46,7 +46,7 @@ public interface EventService { void removeEvents(TenantId tenantId, EntityId entityId); - void removeEvents(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime); + void removeEvents(TenantId tenantId, EntityId entityId, EventFilter eventFilter, Long startTime, Long endTime); void cleanupEvents(long ttl, long debugTtl); diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 5e0cba7f5e..0c9cede327 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -34,7 +34,6 @@ import org.thingsboard.server.dao.service.DataValidator; import java.util.List; import java.util.Optional; -import java.util.UUID; import java.util.stream.Collectors; @Service @@ -125,14 +124,14 @@ public class BaseEventService implements EventService { } @Override - public void removeEvents(TenantId tenantId, EntityId entityId, String eventType, Long startTime, Long endTime) { + public void removeEvents(TenantId tenantId, EntityId entityId, EventFilter eventFilter, Long startTime, Long endTime) { TimePageLink eventsPageLink = new TimePageLink(1000, 0, null, null, startTime, endTime); PageData eventsPageData; do { - if (eventType == null) { + if (eventFilter == null) { eventsPageData = findEvents(tenantId, entityId, eventsPageLink); } else { - eventsPageData = findEvents(tenantId, entityId, eventType, eventsPageLink); + eventsPageData = findEventsByFilter(tenantId, entityId, eventFilter, eventsPageLink); } eventDao.removeAllByIds(eventsPageData.getData().stream() diff --git a/ui-ngx/src/app/core/http/event.service.ts b/ui-ngx/src/app/core/http/event.service.ts index 5a3ec9e51f..df3466bc3e 100644 --- a/ui-ngx/src/app/core/http/event.service.ts +++ b/ui-ngx/src/app/core/http/event.service.ts @@ -47,8 +47,9 @@ export class EventService { public clearEvents(entityId: EntityId, eventType: EventType | DebugEventType, filters: FilterEventBody, tenantId: string, pageLink: TimePageLink, config?: RequestConfig) { - return this.http.post(`/api/events/${entityId.entityType}/${entityId.id}/${eventType}/clear&tenantId=${tenantId}` + - `${pageLink.toQuery()}`, {...filters, eventType}, + return this.http.post(`/api/events/${entityId.entityType}/${entityId.id}/clear?tenantId=${tenantId}` + + (pageLink.startTime ? `&startTime=${pageLink.startTime}` : ``) + + (pageLink.endTime ? `&endTime=${pageLink.endTime}` : ``), {...filters, eventType}, defaultHttpOptionsFromConfig(config)); } } diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 8a5201dc3f..9cd905492c 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -20,28 +20,28 @@ import { EntityTableColumn, EntityTableConfig } from '@home/models/entity/entities-table-config.models'; -import { DebugEventType, Event, EventType, FilterEventBody } from '@shared/models/event.models'; -import { TimePageLink } from '@shared/models/page/page-link'; -import { TranslateService } from '@ngx-translate/core'; -import { DatePipe } from '@angular/common'; -import { MatDialog } from '@angular/material/dialog'; -import { EntityId } from '@shared/models/id/entity-id'; -import { EventService } from '@app/core/http/event.service'; -import { EventTableHeaderComponent } from '@home/components/event/event-table-header.component'; -import { EntityTypeResource } from '@shared/models/entity-type.models'; -import { Observable } from 'rxjs'; -import { PageData } from '@shared/models/page/page-data'; -import { Direction } from '@shared/models/page/sort-order'; -import { DialogService } from '@core/services/dialog.service'; -import { ContentType } from '@shared/models/constants'; +import {DebugEventType, Event, EventType, FilterEventBody} from '@shared/models/event.models'; +import {TimePageLink} from '@shared/models/page/page-link'; +import {TranslateService} from '@ngx-translate/core'; +import {DatePipe} from '@angular/common'; +import {MatDialog} from '@angular/material/dialog'; +import {EntityId} from '@shared/models/id/entity-id'; +import {EventService} from '@app/core/http/event.service'; +import {EventTableHeaderComponent} from '@home/components/event/event-table-header.component'; +import {EntityTypeResource} from '@shared/models/entity-type.models'; +import {Observable} from 'rxjs'; +import {PageData} from '@shared/models/page/page-data'; +import {Direction} from '@shared/models/page/sort-order'; +import {DialogService} from '@core/services/dialog.service'; +import {ContentType} from '@shared/models/constants'; import { EventContentDialogComponent, EventContentDialogData } from '@home/components/event/event-content-dialog.component'; -import { isEqual, sortObjectKeys } from '@core/utils'; -import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; -import { ChangeDetectorRef, Injector, StaticProvider, ViewContainerRef } from '@angular/core'; -import { ComponentPortal } from '@angular/cdk/portal'; +import {isEqual, sortObjectKeys} from '@core/utils'; +import {ConnectedPosition, Overlay, OverlayConfig, OverlayRef} from '@angular/cdk/overlay'; +import {ChangeDetectorRef, Injector, StaticProvider, ViewContainerRef} from '@angular/core'; +import {ComponentPortal} from '@angular/cdk/portal'; import { EVENT_FILTER_PANEL_DATA, EventFilterPanelComponent, @@ -141,7 +141,12 @@ export class EventTableConfig extends EntityTableConfig { icon: 'delete', isEnabled: () => true, onAction: ($event, entity, pageLink: TimePageLink) => { - this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, pageLink).subscribe(); + this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, pageLink).subscribe( + () => { + this.table.paginator.pageIndex = 0; + this.table.updateData(); + } + ); } }); } From 6e2c1e3419c21890a6bed123e5b1653f268f9b10 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 8 Nov 2021 19:21:26 +0200 Subject: [PATCH 7/8] Events clearing UI refactoring --- .../entity/entities-table.component.html | 2 +- .../components/event/event-table-config.ts | 40 +++++++++---------- .../components/event/event-table.component.ts | 4 +- .../entity/entities-table-config.models.ts | 5 ++- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html index b103c29df5..c4f470bbd2 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html @@ -84,7 +84,7 @@ [fxShow]="actionDescriptor.isEnabled()" *ngFor="let actionDescriptor of headerActionDescriptors" matTooltip="{{ actionDescriptor.name }}" matTooltipPosition="above" - (click)="actionDescriptor.onAction($event, entitiesTableConfig, pageLink)"> + (click)="actionDescriptor.onAction($event)"> {{actionDescriptor.icon}} diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 9cd905492c..d407cf262b 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -20,28 +20,28 @@ import { EntityTableColumn, EntityTableConfig } from '@home/models/entity/entities-table-config.models'; -import {DebugEventType, Event, EventType, FilterEventBody} from '@shared/models/event.models'; -import {TimePageLink} from '@shared/models/page/page-link'; -import {TranslateService} from '@ngx-translate/core'; -import {DatePipe} from '@angular/common'; -import {MatDialog} from '@angular/material/dialog'; -import {EntityId} from '@shared/models/id/entity-id'; -import {EventService} from '@app/core/http/event.service'; -import {EventTableHeaderComponent} from '@home/components/event/event-table-header.component'; -import {EntityTypeResource} from '@shared/models/entity-type.models'; -import {Observable} from 'rxjs'; -import {PageData} from '@shared/models/page/page-data'; -import {Direction} from '@shared/models/page/sort-order'; -import {DialogService} from '@core/services/dialog.service'; -import {ContentType} from '@shared/models/constants'; +import { DebugEventType, Event, EventType, FilterEventBody } from '@shared/models/event.models'; +import { TimePageLink } from '@shared/models/page/page-link'; +import { TranslateService } from '@ngx-translate/core'; +import { DatePipe } from '@angular/common'; +import { MatDialog } from '@angular/material/dialog'; +import { EntityId } from '@shared/models/id/entity-id'; +import { EventService } from '@app/core/http/event.service'; +import { EventTableHeaderComponent } from '@home/components/event/event-table-header.component'; +import { EntityTypeResource } from '@shared/models/entity-type.models'; +import { Observable } from 'rxjs'; +import { PageData } from '@shared/models/page/page-data'; +import { Direction } from '@shared/models/page/sort-order'; +import { DialogService } from '@core/services/dialog.service'; +import { ContentType } from '@shared/models/constants'; import { EventContentDialogComponent, EventContentDialogData } from '@home/components/event/event-content-dialog.component'; -import {isEqual, sortObjectKeys} from '@core/utils'; -import {ConnectedPosition, Overlay, OverlayConfig, OverlayRef} from '@angular/cdk/overlay'; -import {ChangeDetectorRef, Injector, StaticProvider, ViewContainerRef} from '@angular/core'; -import {ComponentPortal} from '@angular/cdk/portal'; +import { isEqual, sortObjectKeys } from '@core/utils'; +import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; +import { ChangeDetectorRef, Injector, StaticProvider, ViewContainerRef } from '@angular/core'; +import { ComponentPortal } from '@angular/cdk/portal'; import { EVENT_FILTER_PANEL_DATA, EventFilterPanelComponent, @@ -140,8 +140,8 @@ export class EventTableConfig extends EntityTableConfig { name: this.translate.instant('event.clean-events'), icon: 'delete', isEnabled: () => true, - onAction: ($event, entity, pageLink: TimePageLink) => { - this.eventService.clearEvents(entity.entityId, entity.eventType, entity.filterParams, entity.tenantId, pageLink).subscribe( + onAction: ($event) => { + this.eventService.clearEvents(this.entityId, this.eventType, this.filterParams, this.tenantId, this.table.pageLink as TimePageLink).subscribe( () => { this.table.paginator.pageIndex = 0; this.table.updateData(); diff --git a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts index 85bd4cf81a..00aeb4f50c 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table.component.ts @@ -25,7 +25,6 @@ import { EventService } from '@core/http/event.service'; import { DialogService } from '@core/services/dialog.service'; import { DebugEventType, EventType } from '@shared/models/event.models'; import { Overlay } from '@angular/cdk/overlay'; -import { HttpClient } from '@angular/common/http'; @Component({ selector: 'tb-event-table', @@ -85,8 +84,7 @@ export class EventTableComponent implements OnInit { private dialog: MatDialog, private overlay: Overlay, private viewContainerRef: ViewContainerRef, - private cd: ChangeDetectorRef, - private http: HttpClient) { + private cd: ChangeDetectorRef) { } ngOnInit() { diff --git a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts index 7a352e8f17..93e68e40b7 100644 --- a/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts +++ b/ui-ngx/src/app/modules/home/models/entity/entities-table-config.models.ts @@ -25,7 +25,8 @@ import { EntityComponent } from '@home/components/entity/entity.component'; import { Type } from '@angular/core'; import { EntityAction } from './entity-component.models'; import { HasUUID } from '@shared/models/id/has-uuid'; -import { PageLink } from '@shared/models/page/page-link'; +import { PageLink, TimePageLink } from '@shared/models/page/page-link'; +import { EntitiesTableComponent } from '@home/components/entity/entities-table.component'; import { EntityTableHeaderComponent } from '@home/components/entity/entity-table-header.component'; import { ActivatedRoute } from '@angular/router'; import { EntityTabsComponent } from '../../components/entity/entity-tabs.component'; @@ -75,7 +76,7 @@ export interface HeaderActionDescriptor { icon: string; isMdiIcon?: boolean; isEnabled: () => boolean; - onAction: ($event: MouseEvent, entity?, pageLink?) => void; + onAction: ($event: MouseEvent) => void; } export type EntityTableColumnType = 'content' | 'action'; From 1ad5b83cb6100042cafacb875d9d3df6388ee21e Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 4 Jan 2022 13:17:50 +0200 Subject: [PATCH 8/8] Refactor events clearing api --- .../server/controller/EventController.java | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index 5759ffcac4..ea77fce94c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -240,31 +240,27 @@ public class EventController extends BaseController { } } - @ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events for specified entity.") + @ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events by filter for specified entity.") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/clear", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) - public void clearEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) - @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) - @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) - @RequestParam("tenantId") String strTenantId, - @ApiParam(value = "A string value representing event type", example = "STATS", required = true) - @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) - @RequestParam(required = false) Long endTime, - @RequestBody EventFilter eventFilter) throws ThingsboardException { + public void clearEvents(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @PathVariable(ENTITY_TYPE) String strEntityType, + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @PathVariable(ENTITY_ID) String strEntityId, + @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @RequestParam(required = false) Long startTime, + @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @RequestParam(required = false) Long endTime, + @ApiParam(value = EVENT_FILTER_DEFINITION) + @RequestBody EventFilter eventFilter) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); try { - TenantId tenantId = new TenantId(toUUID(strTenantId)); - EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); - checkEntityId(entityId, Operation.DELETE); + checkEntityId(entityId, Operation.WRITE); - eventService.removeEvents(tenantId, entityId, eventFilter, startTime, endTime); + eventService.removeEvents(getTenantId(), entityId, eventFilter, startTime, endTime); } catch (Exception e) { throw handleException(e); }