You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by ni...@apache.org on 2018/08/31 19:20:22 UTC
[26/50] [abbrv] metron git commit: METRON-1713 PCAP UI - Add a way to
kill a pcap job (tiborm via merrimanr) closes apache/metron#1143
METRON-1713 PCAP UI - Add a way to kill a pcap job (tiborm via merrimanr) closes apache/metron#1143
Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/14dcb2d9
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/14dcb2d9
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/14dcb2d9
Branch: refs/remotes/apache/feature/METRON-1699-create-batch-profiler
Commit: 14dcb2d90581835d8206c65918c24e8cb04bfd06
Parents: 5b3e2c3
Author: tiborm <ti...@gmail.com>
Authored: Thu Aug 9 08:33:21 2018 -0500
Committer: rmerriman <me...@gmail.com>
Committed: Thu Aug 9 08:33:21 2018 -0500
----------------------------------------------------------------------
.../pcap/pcap-panel/pcap-panel.component.html | 7 +-
.../pcap/pcap-panel/pcap-panel.component.scss | 33 +++++
.../pcap-panel/pcap-panel.component.spec.ts | 130 +++++++++++++++++++
.../app/pcap/pcap-panel/pcap-panel.component.ts | 42 +++++-
.../src/app/pcap/service/pcap.service.ts | 10 +-
5 files changed, 215 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/metron/blob/14dcb2d9/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.html
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.html b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.html
index 950f49c..0dda268 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.html
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.html
@@ -15,8 +15,11 @@
<div class="panel-header">
<app-pcap-filters [queryRunning]="queryRunning" (search)="onSearch($event)"></app-pcap-filters>
</div>
- <div *ngIf="queryRunning" class="progress pcap-progress-background">
- <div class="progress-bar progress-bar-animated pcap-progress" role="progressbar" attr.aria-valuenow="{{progressWidth}}" aria-valuemin="0" aria-valuemax="100" [ngStyle]="{'width': progressWidth + '%'}">{{progressWidth}}%</div>
+ <div *ngIf="queryRunning" class="pcap-progress-wrapper">
+ <div class="progress pcap-progress-background">
+ <div class="progress-bar progress-bar-animated pcap-progress" role="progressbar" attr.aria-valuenow="{{progressWidth}}" aria-valuemin="0" aria-valuemax="100" [ngStyle]="{'width': progressWidth + '%'}">{{progressWidth}}%</div>
+ </div>
+ <button data-qe-id="pcap-cancel-query-button" class="pcap-cancel-query-button btn btn-primary btn-sm" (click)="cancelQuery()" [disabled]="!queryId"></button>
</div>
<div *ngIf="errorMsg" class="alert alert-danger" role="alert" data-qe-id="error">
{{ errorMsg }}
http://git-wip-us.apache.org/repos/asf/metron/blob/14dcb2d9/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.scss b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.scss
index 8989bf9..523f5ce 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.scss
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.scss
@@ -31,4 +31,37 @@
.progress-bar {
width: 0;
+ height: 34px;
+ line-height: 34px;
+ vertical-align: middle;
+ font-size: 0.875rem;
+}
+
+.pcap-progress-wrapper {
+ position: relative;
+ padding-right: 55px;
+}
+
+.pcap-cancel-query-button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding-top: 6px;
+ padding-bottom: 6px;
+ background: $icon-button-background;
+ min-width: 42px;
+ padding-left: 0;
+ padding-right: 0;
+ border: 1px solid $blue-chill !important;
+ cursor: pointer;
+
+ &:focus {
+ box-shadow: none;
+ }
+
+ &::before {
+ font-family: "FontAwesome";
+ content: '\f00d';
+ color: $piction-blue;
+ }
}
http://git-wip-us.apache.org/repos/asf/metron/blob/14dcb2d9/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts
index 0804b79..9dacc7f 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts
@@ -50,6 +50,9 @@ class FakePcapService {
return '';
}
submitRequest() {}
+ cancelQuery() {
+ return defer(() => Promise.resolve());
+ }
}
describe('PcapPanelComponent', () => {
@@ -327,6 +330,133 @@ describe('PcapPanelComponent', () => {
expect(fixture.debugElement.query(By.css('app-pcap-list'))).toBeDefined();
}));
+ it('should render a cancel button only if a query runs', () => {
+ component.queryRunning = false;
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'))).toBeFalsy();
+
+ component.queryRunning = true;
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'))).toBeDefined();
+ });
+
+ it('should hide the progress bar if the user clicks on the cancel button', fakeAsync(() => {
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeDefined();
+
+ const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'));
+ const cancelBtnEl = cancelBtn.nativeElement;
+
+ cancelBtnEl.click();
+ tick();
+ fixture.detectChanges();
+
+ expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeFalsy();
+ }));
+
+ it('should hide the progress bar if the cancellation request fails', fakeAsync(() => {
+ const restError = new RestError();
+ pcapService.cancelQuery = jasmine.createSpy('cancelQuery').and.returnValue(
+ defer(() => Promise.reject(restError))
+ );
+
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeDefined();
+
+ const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'));
+ const cancelBtnEl = cancelBtn.nativeElement;
+
+ cancelBtnEl.click();
+ tick();
+ fixture.detectChanges();
+
+ expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeFalsy();
+ }));
+
+ it('should show an error message if the cancellation request fails', fakeAsync(() => {
+ const restError = new RestError();
+ restError.message = 'cancellation error';
+ pcapService.cancelQuery = jasmine.createSpy('cancelQuery').and.returnValue(
+ defer(() => Promise.reject(restError))
+ );
+
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('[data-qe-id="error"]'))).toBeFalsy();
+
+ const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'));
+ const cancelBtnEl = cancelBtn.nativeElement;
+
+ cancelBtnEl.click();
+ tick();
+ fixture.detectChanges();
+
+ expect(
+ fixture.debugElement.query(By.css('[data-qe-id="error"]'))
+ .nativeElement
+ .textContent.trim()
+ ).toBe(`Response message: ${restError.message}. Something went wrong with the cancellation!`);
+ }));
+
+ it('cancel button should be disabled till we get back a queryId', fakeAsync(() => {
+ component.queryRunning = true;
+ component.queryId = '';
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]')).nativeElement.disabled).toBeTruthy();
+ }));
+
+ it('cancel button should be enabled when we have a queryId', fakeAsync(() => {
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]')).nativeElement.disabled).toBeFalsy();
+ }));
+
+ it('queryId should be emptied if the cancellation request fails', fakeAsync(() => {
+ const restError = new RestError();
+ restError.message = 'cancellation error';
+ pcapService.cancelQuery = jasmine.createSpy('cancelQuery').and.returnValue(
+ defer(() => Promise.reject(restError))
+ );
+
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+
+ const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'));
+ const cancelBtnEl = cancelBtn.nativeElement;
+
+ cancelBtnEl.click();
+ tick();
+ fixture.detectChanges();
+
+ expect(component.queryId).toBeFalsy();
+ }));
+
+ it('queryId should be emptied if the cancellation success', fakeAsync(() => {
+ pcapService.cancelQuery = jasmine.createSpy('cancelQuery').and.returnValue(
+ defer(() => Promise.resolve())
+ );
+
+ component.queryRunning = true;
+ component.queryId = 'testid';
+ fixture.detectChanges();
+
+ const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]'));
+ const cancelBtnEl = cancelBtn.nativeElement;
+
+ cancelBtnEl.click();
+ tick();
+ fixture.detectChanges();
+
+ expect(component.queryId).toBeFalsy();
+ }));
+
it('should handle get packet 404', fakeAsync(() => {
const searchResponse = new PcapStatusResponse();
searchResponse.jobId = '42';
http://git-wip-us.apache.org/repos/asf/metron/blob/14dcb2d9/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts
index 8e4ced0..b11d9df 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { Component, Input } from '@angular/core';
+import { Component, Input, OnDestroy } from '@angular/core';
import { PcapService } from '../service/pcap.service';
import { PcapStatusResponse } from '../model/pcap-status-response';
@@ -30,13 +30,16 @@ import {RestError} from "../../model/rest-error";
templateUrl: './pcap-panel.component.html',
styleUrls: ['./pcap-panel.component.scss']
})
-export class PcapPanelComponent {
+export class PcapPanelComponent implements OnDestroy {
@Input() pdml: Pdml = null;
@Input() pcapRequest: PcapRequest;
@Input() resetPaginationForSearch: boolean;
statusSubscription: Subscription;
+ cancelSubscription: Subscription;
+ submitSubscription: Subscription;
+ getSubscription: Subscription;
queryRunning: boolean = false;
queryId: string;
progressWidth: number = 0;
@@ -55,12 +58,13 @@ export class PcapPanelComponent {
onSearch(pcapRequest) {
this.queryRunning = true;
+ this.queryId = '';
this.savedPcapRequest = pcapRequest;
this.pagination.selectedPage = 1;
this.pdml = null;
this.progressWidth = 0;
this.errorMsg = null;
- this.pcapService.submitRequest(pcapRequest).subscribe((submitResponse: PcapStatusResponse) => {
+ this.submitSubscription = this.pcapService.submitRequest(pcapRequest).subscribe((submitResponse: PcapStatusResponse) => {
let id = submitResponse.jobId;
if (!id) {
this.errorMsg = submitResponse.description;
@@ -104,4 +108,34 @@ export class PcapPanelComponent {
getDownloadUrl() {
return this.pcapService.getDownloadUrl(this.queryId, this.pagination.selectedPage);
}
-}
\ No newline at end of file
+
+ unsubscribeAll() {
+ if (this.cancelSubscription) {
+ this.cancelSubscription.unsubscribe();
+ }
+ if (this.statusSubscription) {
+ this.statusSubscription.unsubscribe();
+ }
+ if (this.submitSubscription) {
+ this.submitSubscription.unsubscribe();
+ }
+ }
+
+ cancelQuery() {
+ this.cancelSubscription = this.pcapService.cancelQuery(this.queryId)
+ .subscribe(() => {
+ this.unsubscribeAll();
+ this.queryId = '';
+ this.queryRunning = false;
+ }, (error: any) => {
+ this.cancelSubscription.unsubscribe();
+ this.queryId = '';
+ this.errorMsg = `Response message: ${error.message}. Something went wrong with the cancellation!`;
+ this.queryRunning = false;
+ });
+ }
+
+ ngOnDestroy() {
+ this.unsubscribeAll();
+ }
+}
http://git-wip-us.apache.org/repos/asf/metron/blob/14dcb2d9/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts b/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
index 518cc92..85ed9cc 100644
--- a/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
@@ -52,7 +52,7 @@ export class PcapService {
new RequestOptions({headers: new Headers(this.defaultHeaders)}))
.map(HttpUtil.extractData)
.catch(HttpUtil.handleError);
- }
+ }
public getPackets(id: string, pageId: number): Observable<Pdml> {
return this.http.get(`/api/v1/pcap/${id}/pdml?page=${pageId}`, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
.map(HttpUtil.extractData)
@@ -62,4 +62,12 @@ export class PcapService {
public getDownloadUrl(id: string, pageId: number) {
return `/api/v1/pcap/${id}/raw?page=${pageId}`;
}
+
+ public cancelQuery(queryId: string) {
+ return this.http
+ .delete(`/api/v1/pcap/kill/${queryId}`, new RequestOptions({
+ headers: new Headers(this.defaultHeaders),
+ }))
+ .catch(HttpUtil.handleError);
+ }
}
\ No newline at end of file