This is an automated email from the ASF dual-hosted git repository. rmerriman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to refs/heads/master by this push: new 64b0790 METRON-1654 findOne request after an alert patch returns with the original state of the alert item (merrimanr) closes apache/metron#1344 64b0790 is described below commit 64b079044f6840fc0bcb1bf9cb665790f37900f4 Author: merrimanr <merrim...@gmail.com> AuthorDate: Wed Apr 10 10:58:04 2019 -0500 METRON-1654 findOne request after an alert patch returns with the original state of the alert item (merrimanr) closes apache/metron#1344 --- .../alert-details/alert-details.component.spec.ts | 36 +++++++++++++-- .../alert-details/alert-details.component.ts | 53 ++++++---------------- .../alerts/alerts-list/alerts-list.component.ts | 31 ++++++------- .../alerts-list/table-view/table-view.component.ts | 8 ++++ .../alerts-list/tree-view/tree-view.component.ts | 24 +++++----- .../src/app/service/meta-alert.service.ts | 25 +++++----- .../src/app/service/update.service.ts | 26 ++++++----- 7 files changed, 108 insertions(+), 95 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts index b875613..7800517 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts @@ -35,10 +35,14 @@ import { By } from '@angular/platform-browser'; import { AlertComment } from './alert-comment'; import { Subject } from 'rxjs'; import { ConfirmationType } from 'app/model/confirmation-type'; +import {CommentAddRemoveRequest} from "../../model/comment-add-remove-request"; +import {AlertSource} from "../../model/alert-source"; +import {of} from "rxjs/index"; describe('AlertDetailsComponent', () => { let component: AlertDetailsComponent; let fixture: ComponentFixture<AlertDetailsComponent>; + let updateService: UpdateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -83,14 +87,26 @@ describe('AlertDetailsComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(AlertDetailsComponent); component = fixture.componentInstance; + updateService = fixture.debugElement.injector.get(UpdateService); fixture.detectChanges(); }); it('should delete a comment.', fakeAsync(() => { + const responseMock = new AlertSource(); + responseMock.guid = 'guid'; + const removeCommentSpy = spyOn(updateService, 'removeComment').and.returnValue( + of(responseMock) + ); + const setAlertSpy = spyOn(component, 'setAlert'); + expect(component).toBeTruthy(); + component.alertSource = new AlertSource(); + component.alertSource.guid = 'guid'; + component.alertSourceType = 'sourceType'; + const now = Date.now(); component.alertCommentsWrapper = [ new AlertCommentWrapper( - new AlertComment('lorem ipsum', 'user', Date.now()), + new AlertComment('lorem ipsum', 'user', now), (new Date()).toString() ) ]; @@ -101,8 +117,20 @@ describe('AlertDetailsComponent', () => { deleteComment.nativeElement.click(); tick(500); fixture.detectChanges(); - expect(component.alertCommentsWrapper.length).toEqual(0); - const comments = fixture.debugElement.queryAll(By.css('[data-qe-id="comment"]')); - expect(comments.length).toEqual(0); + + const expectedCommentRequest = new CommentAddRemoveRequest(); + expectedCommentRequest.guid = 'guid'; + expectedCommentRequest.comment = 'lorem ipsum'; + expectedCommentRequest.username = 'user'; + expectedCommentRequest.sensorType = 'sourceType'; + expectedCommentRequest.timestamp = now; + + const expectedAlertSource = new AlertSource(); + expectedAlertSource.guid = 'guid'; + + expect(removeCommentSpy).toHaveBeenCalledWith(expectedCommentRequest); + expect(removeCommentSpy).toHaveBeenCalledTimes(1); + expect(setAlertSpy).toHaveBeenCalledWith(expectedAlertSource); + expect(setAlertSpy).toHaveBeenCalledTimes(1); })); }); diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts index 73458a6..f5c55fa 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts @@ -98,7 +98,6 @@ export class AlertDetailsComponent implements OnInit { this.alertCommentStr = ''; this.searchService.getAlert(this.alertSourceType, this.alertId).subscribe(alertSource => { this.setAlert(alertSource); - this.setComments(alertSource['comments'] || []); }); } @@ -106,11 +105,9 @@ export class AlertDetailsComponent implements OnInit { this.alertSource = alertSource; this.alertSources = (alertSource.metron_alert && alertSource.metron_alert.length > 0) ? alertSource.metron_alert : [alertSource]; this.selectedAlertState = this.getAlertState(alertSource['alert_status']); - } - - setComments(alertComments) { + let alertComments = alertSource['comments'] || []; this.alertCommentsWrapper = alertComments.map(alertComment => - new AlertCommentWrapper(alertComment, moment(new Date(alertComment.timestamp)).fromNow())); + new AlertCommentWrapper(alertComment, moment(new Date(alertComment.timestamp)).fromNow())); } getAlertState(alertStatus) { @@ -177,12 +174,8 @@ export class AlertDetailsComponent implements OnInit { let tAlert = new Alert(); tAlert.source = this.alertSource; - let previousAlertStatus = this.alertSource['alert_status']; - this.alertSource['alert_status'] = state; - this.setAlert(this.alertSource); - this.updateService.updateAlertState([tAlert], state).subscribe(() => {}, () => { - this.alertSource['alert_status'] = previousAlertStatus; - this.setAlert(this.alertSource); + this.updateService.updateAlertState([tAlert], state).subscribe(alertSource => { + this.setAlert(alertSource[0]); }); } @@ -200,36 +193,25 @@ export class AlertDetailsComponent implements OnInit { patchRequest.sensorType = 'metaalert'; patchRequest.patch = [new Patch('add', '/name', this.alertName)]; - let previousName = this.alertSource['name']; - this.alertSource['name'] = this.alertName; - this.updateService.patch(patchRequest).subscribe(rep => { + this.updateService.patch(patchRequest).subscribe(alertSource => { + this.setAlert(alertSource); this.toggleNameEditor(); }, () => { - this.alertSource['name'] = previousName; - this.alertName = previousName; this.toggleNameEditor(); }); } } onAddComment() { - let newComment = new AlertComment(this.alertCommentStr, this.authenticationService.getCurrentUserName(), new Date().getTime()); - let alertComments = this.alertCommentsWrapper.map(alertsWrapper => alertsWrapper.alertComment); - alertComments.unshift(newComment); - this.setComments(alertComments); let commentRequest = new CommentAddRemoveRequest(); commentRequest.guid = this.alertSource.guid; commentRequest.comment = this.alertCommentStr; commentRequest.username = this.authenticationService.getCurrentUserName(); commentRequest.timestamp = new Date().getTime(); commentRequest.sensorType = this.alertSourceType; - this.updateService.addComment(commentRequest).subscribe( - () => {}, - () => { - let previousComments = this.alertCommentsWrapper.map(alertsWrapper => alertsWrapper.alertComment) - .filter(alertComment => alertComment !== newComment); - this.setComments(previousComments); - }); + this.updateService.addComment(commentRequest).subscribe(alertSource => { + this.setAlert(alertSource); + }); } patchAlert(patch: Patch, onPatchError) { @@ -252,20 +234,15 @@ export class AlertDetailsComponent implements OnInit { const confirmedSubscription = this.dialogService.launchDialog(commentText).subscribe(action => { if (action === ConfirmationType.Confirmed) { - let deletedCommentWrapper = this.alertCommentsWrapper.splice(index, 1)[0]; let commentRequest = new CommentAddRemoveRequest(); commentRequest.guid = this.alertSource.guid; - commentRequest.comment = deletedCommentWrapper.alertComment.comment; - commentRequest.username = deletedCommentWrapper.alertComment.username; - commentRequest.timestamp = deletedCommentWrapper.alertComment.timestamp; + commentRequest.comment = this.alertCommentsWrapper[index].alertComment.comment; + commentRequest.username = this.alertCommentsWrapper[index].alertComment.username; + commentRequest.timestamp = this.alertCommentsWrapper[index].alertComment.timestamp; commentRequest.sensorType = this.alertSourceType; - this.updateService.removeComment(commentRequest).subscribe( - null, - () => { - // add the deleted comment back - this.alertCommentsWrapper.unshift(deletedCommentWrapper); - this.alertCommentsWrapper.sort((a, b) => b.alertComment.timestamp - a.alertComment.timestamp); - }); + this.updateService.removeComment(commentRequest).subscribe(alertSource => { + this.setAlert(alertSource); + }); } confirmedSubscription.unsubscribe(); }); diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts index e743359..87c5aaa 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts @@ -47,6 +47,7 @@ import { GlobalConfigService } from '../../service/global-config.service'; import { DialogService } from 'app/service/dialog.service'; import { DialogType } from 'app/model/dialog-type'; import { Utils } from 'app/utils/utils'; +import {AlertSource} from "../../model/alert-source"; @Component({ selector: 'app-alerts-list', @@ -104,12 +105,15 @@ export class AlertsListComponent implements OnInit, OnDestroy { } addAlertChangedListner() { - this.metaAlertsService.alertChanged$.subscribe(metaAlertAddRemoveRequest => { - this.updateAlert(META_ALERTS_SENSOR_TYPE, metaAlertAddRemoveRequest.metaAlertGuid, (metaAlertAddRemoveRequest.alerts === null)); + this.metaAlertsService.alertChanged$.subscribe(alertSource => { + if (alertSource['status'] === 'inactive') { + this.removeAlert(alertSource) + } + this.updateAlert(alertSource); }); - this.alertChangedSubscription = this.updateService.alertChanged$.subscribe(patchRequest => { - this.updateAlert(patchRequest.sensorType, patchRequest.guid, false); + this.alertChangedSubscription = this.updateService.alertChanged$.subscribe(alertSource => { + this.updateAlert(alertSource); }); } @@ -478,20 +482,13 @@ export class AlertsListComponent implements OnInit, OnDestroy { this.searchService.interval = this.refreshInterval; } - updateAlert(sensorType: string, guid: string, isDelete: boolean) { - if (isDelete) { - let alertIndex = -1; - this.alerts.forEach((alert, index) => { - alertIndex = (alert.source.guid === guid) ? index : alertIndex; - }); - this.alerts.splice(alertIndex, 1); - return; - } + updateAlert(alertSource: AlertSource) { + this.alerts.filter(alert => alert.source.guid === alertSource.guid) + .map(alert => alert.source = alertSource); + } - this.searchService.getAlert(sensorType, guid).subscribe(alertSource => { - this.alerts.filter(alert => alert.source.guid === guid) - .map(alert => alert.source = alertSource); - }); + removeAlert(alertSource: AlertSource) { + this.alerts = this.alerts.filter(alert => alert.source.guid !== alertSource.guid); } updateSelectedAlertStatus(status: string) { diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts index 2190beb..e9d19a1 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts @@ -35,6 +35,7 @@ import {GetRequest} from '../../../model/get-request'; import { GlobalConfigService } from '../../../service/global-config.service'; import { DialogService } from '../../../service/dialog.service'; import { ConfirmationType } from 'app/model/confirmation-type'; +import {HttpErrorResponse} from "@angular/common/http"; export enum MetronAlertDisplayState { COLLAPSE, EXPAND @@ -277,6 +278,13 @@ export class TableViewComponent implements OnInit, OnChanges, OnDestroy { metaAlertAddRemoveRequest.alerts = [new GetRequest(alertToRemove.guid, alertToRemove[this.globalConfig['source.type.field']], '')]; this.metaAlertService.removeAlertsFromMetaAlert(metaAlertAddRemoveRequest).subscribe(() => { + }, (res: HttpErrorResponse) => { + let message = res.error['message']; + this.dialogService + .launchDialog(message) + .subscribe(action => { + this.configSubscription.unsubscribe(); + }) }); } diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts index 19aaa6e..d2c7c8d 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts @@ -39,6 +39,7 @@ import { GlobalConfigService } from '../../../service/global-config.service'; import { DialogService } from '../../../service/dialog.service'; import { DialogType } from 'app/model/dialog-type'; import { ConfirmationType } from 'app/model/confirmation-type'; +import {AlertSource} from "../../../model/alert-source"; @Component({ selector: 'app-tree-view', @@ -55,7 +56,7 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC treeGroupSubscriptionMap: {[key: string]: TreeAlertsSubscription } = {}; alertsChangedSubscription: Subscription; configSubscription: Subscription; - dialogService: DialogService + dialogService: DialogService; constructor(searchService: SearchService, updateService: UpdateService, @@ -66,8 +67,8 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC } addAlertChangedListner() { - this.alertsChangedSubscription = this.updateService.alertChanged$.subscribe(patchRequest => { - this.updateAlert(patchRequest); + this.alertsChangedSubscription = this.updateService.alertChanged$.subscribe(alertSource => { + this.updateAlert(alertSource); }); } @@ -436,16 +437,13 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC return false; } - updateAlert(patchRequest: PatchRequest) { - this.searchService.getAlert(patchRequest.sensorType, patchRequest.guid).subscribe(alertSource => { - - Object.keys(this.treeGroupSubscriptionMap).forEach(key => { - let group = this.treeGroupSubscriptionMap[key].group; - if (group.response && group.response.results && group.response.results.length > 0) { - group.response.results.filter(alert => alert.source.guid === patchRequest.guid) - .map(alert => alert.source = alertSource); - } - }); + updateAlert(alertSource: AlertSource) { + Object.keys(this.treeGroupSubscriptionMap).forEach(key => { + let group = this.treeGroupSubscriptionMap[key].group; + if (group.response && group.response.results && group.response.results.length > 0) { + group.response.results.filter(alert => alert.source.guid === alertSource.guid) + .forEach(alert => alert.source = alertSource); + } }); } } diff --git a/metron-interface/metron-alerts/src/app/service/meta-alert.service.ts b/metron-interface/metron-alerts/src/app/service/meta-alert.service.ts index 59ea0a7..62589a8 100644 --- a/metron-interface/metron-alerts/src/app/service/meta-alert.service.ts +++ b/metron-interface/metron-alerts/src/app/service/meta-alert.service.ts @@ -27,11 +27,12 @@ import { HttpClient } from '@angular/common/http'; import {MetaAlertCreateRequest} from '../model/meta-alert-create-request'; import {MetaAlertAddRemoveRequest} from '../model/meta-alert-add-remove-request'; import { AppConfigService } from './app-config.service'; +import {AlertSource} from "../model/alert-source"; @Injectable() export class MetaAlertService { private _selectedAlerts: Alert[]; - alertChangedSource = new Subject<MetaAlertAddRemoveRequest>(); + alertChangedSource = new Subject<AlertSource>(); alertChanged$ = this.alertChangedSource.asObservable(); constructor(private http: HttpClient, private appConfigService: AppConfigService) { @@ -51,23 +52,25 @@ export class MetaAlertService { catchError(HttpUtil.handleError)); } - public addAlertsToMetaAlert(metaAlertAddRemoveRequest: MetaAlertAddRemoveRequest) { + public addAlertsToMetaAlert(metaAlertAddRemoveRequest: MetaAlertAddRemoveRequest): Observable<AlertSource> { let url = this.appConfigService.getApiRoot() + '/metaalert/add/alert'; return this.http.post(url, metaAlertAddRemoveRequest).pipe( catchError(HttpUtil.handleError), map(result => { - this.alertChangedSource.next(metaAlertAddRemoveRequest); - return result; + let alertSource = result['document']; + this.alertChangedSource.next(alertSource); + return alertSource; })); } - public removeAlertsFromMetaAlert(metaAlertAddRemoveRequest: MetaAlertAddRemoveRequest) { + public removeAlertsFromMetaAlert(metaAlertAddRemoveRequest: MetaAlertAddRemoveRequest): Observable<AlertSource> { let url = this.appConfigService.getApiRoot() + '/metaalert/remove/alert'; return this.http.post(url, metaAlertAddRemoveRequest).pipe( catchError(HttpUtil.handleError), map(result => { - this.alertChangedSource.next(metaAlertAddRemoveRequest); - return result; + let alertSource = result['document']; + this.alertChangedSource.next(alertSource); + return alertSource; })); } @@ -76,11 +79,9 @@ export class MetaAlertService { return this.http.post(url, {}).pipe( catchError(HttpUtil.handleError), map(result => { - let metaAlertAddRemoveRequest = new MetaAlertAddRemoveRequest(); - metaAlertAddRemoveRequest.metaAlertGuid = guid; - metaAlertAddRemoveRequest.alerts = null; - this.alertChangedSource.next(metaAlertAddRemoveRequest); - return result; + let alertSource = result['document']; + this.alertChangedSource.next(alertSource); + return alertSource; })); } } diff --git a/metron-interface/metron-alerts/src/app/service/update.service.ts b/metron-interface/metron-alerts/src/app/service/update.service.ts index 6ce2c73..e14f0a7 100644 --- a/metron-interface/metron-alerts/src/app/service/update.service.ts +++ b/metron-interface/metron-alerts/src/app/service/update.service.ts @@ -29,14 +29,15 @@ import {Patch} from '../model/patch'; import { GlobalConfigService } from './global-config.service'; import {CommentAddRemoveRequest} from "../model/comment-add-remove-request"; import { AppConfigService } from './app-config.service'; +import {AlertSource} from "../model/alert-source"; @Injectable() export class UpdateService { - alertChangedSource = new Subject<PatchRequest>(); + alertChangedSource = new Subject<AlertSource>(); alertChanged$ = this.alertChangedSource.asObservable(); sourceType = 'source:type'; - alertCommentChangedSource = new Subject<CommentAddRemoveRequest>(); + alertCommentChangedSource = new Subject<AlertSource>(); alertCommentChanged$ = this.alertCommentChangedSource.asObservable(); constructor(private http: HttpClient, private globalConfigService: GlobalConfigService, private appConfigService: AppConfigService) { @@ -45,39 +46,42 @@ export class UpdateService { }); } - public addComment(commentRequest: CommentAddRemoveRequest, fireChangeListener = true): Observable<{}> { + public addComment(commentRequest: CommentAddRemoveRequest, fireChangeListener = true): Observable<AlertSource> { let url = this.appConfigService.getApiRoot() + '/update/add/comment'; return this.http.post(url, commentRequest).pipe( catchError(HttpUtil.handleError), map(result => { + let alertSource = result['document']; if (fireChangeListener) { - this.alertCommentChangedSource.next(commentRequest); + this.alertCommentChangedSource.next(alertSource); } - return result; + return alertSource; })); } - public removeComment(commentRequest: CommentAddRemoveRequest, fireChangeListener = true): Observable<{}> { + public removeComment(commentRequest: CommentAddRemoveRequest, fireChangeListener = true): Observable<AlertSource> { let url = this.appConfigService.getApiRoot() + '/update/remove/comment'; return this.http.post(url, commentRequest).pipe( catchError(HttpUtil.handleError), map(result => { + let alertSource = result['document']; if (fireChangeListener) { - this.alertCommentChangedSource.next(commentRequest); + this.alertCommentChangedSource.next(alertSource); } - return result; + return alertSource; })); } - public patch(patchRequest: PatchRequest, fireChangeListener = true): Observable<{}> { + public patch(patchRequest: PatchRequest, fireChangeListener = true): Observable<AlertSource> { let url = this.appConfigService.getApiRoot() + '/update/patch'; return this.http.patch(url, patchRequest).pipe( catchError(HttpUtil.handleError), map(result => { + let alertSource = result['document']; if (fireChangeListener) { - this.alertChangedSource.next(patchRequest); + this.alertChangedSource.next(alertSource); } - return result; + return alertSource; }),); }