http://git-wip-us.apache.org/repos/asf/metron/blob/0c4c622b/metron-interface/metron-config/src/app/sensors/sensor-field-schema/sensor-field-schema.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/sensors/sensor-field-schema/sensor-field-schema.component.spec.ts b/metron-interface/metron-config/src/app/sensors/sensor-field-schema/sensor-field-schema.component.spec.ts index d2066ea..2cb44e2 100644 --- a/metron-interface/metron-config/src/app/sensors/sensor-field-schema/sensor-field-schema.component.spec.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-field-schema/sensor-field-schema.component.spec.ts @@ -19,505 +19,641 @@ /* tslint:disable:max-line-length */ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; -import {Http} from '@angular/http'; -import {SimpleChanges, SimpleChange} from '@angular/core'; -import {SensorParserConfigService} from '../../service/sensor-parser-config.service'; -import {StellarService} from '../../service/stellar.service'; -import {MetronAlerts} from '../../shared/metron-alerts'; -import {SensorFieldSchemaModule} from './sensor-field-schema.module'; -import {SensorFieldSchemaComponent, FieldSchemaRow} from './sensor-field-schema.component'; -import {KafkaService} from '../../service/kafka.service'; -import {Observable} from 'rxjs/Observable'; -import {StellarFunctionDescription} from '../../model/stellar-function-description'; -import {SensorParserConfig} from '../../model/sensor-parser-config'; -import {SensorEnrichmentConfig, EnrichmentConfig, ThreatIntelConfig} from '../../model/sensor-enrichment-config'; -import {ParseMessageRequest} from '../../model/parse-message-request'; -import {AutocompleteOption} from '../../model/autocomplete-option'; -import {FieldTransformer} from '../../model/field-transformer'; -import {SensorEnrichmentConfigService} from '../../service/sensor-enrichment-config.service'; - +import { HttpClient } from '@angular/common/http'; +import { SimpleChanges, SimpleChange } from '@angular/core'; +import { SensorParserConfigService } from '../../service/sensor-parser-config.service'; +import { StellarService } from '../../service/stellar.service'; +import { MetronAlerts } from '../../shared/metron-alerts'; +import { SensorFieldSchemaModule } from './sensor-field-schema.module'; +import { + SensorFieldSchemaComponent, + FieldSchemaRow +} from './sensor-field-schema.component'; +import { KafkaService } from '../../service/kafka.service'; +import { Observable, throwError } from 'rxjs'; +import { StellarFunctionDescription } from '../../model/stellar-function-description'; +import { SensorParserConfig } from '../../model/sensor-parser-config'; +import { + SensorEnrichmentConfig, + EnrichmentConfig, + ThreatIntelConfig +} from '../../model/sensor-enrichment-config'; +import { ParseMessageRequest } from '../../model/parse-message-request'; +import { AutocompleteOption } from '../../model/autocomplete-option'; +import { FieldTransformer } from '../../model/field-transformer'; +import { SensorEnrichmentConfigService } from '../../service/sensor-enrichment-config.service'; class MockSensorParserConfigService { - - parseMessage(parseMessageRequest: ParseMessageRequest): Observable<{}> { - let parsedJson = { - 'elapsed': 415, - 'code': 200, - 'ip_dst_addr': '207.109.73.154', - 'original_string': '1467011157.401 415 127.0.0.1 TCP_MISS/200 337891 GET http://www.aliexpress.com/', - 'method': 'GET', - 'bytes': 337891, - 'action': 'TCP_MISS', - 'ip_src_addr': '127.0.0.1', - 'url': 'http://www.aliexpress.com/af/shoes.html?', - 'timestamp': '1467011157.401' - }; - return Observable.create((observable) => { - observable.next(parsedJson); - observable.complete(); - }); - } + parseMessage(parseMessageRequest: ParseMessageRequest): Observable<{}> { + let parsedJson = { + elapsed: 415, + code: 200, + ip_dst_addr: '207.109.73.154', + original_string: + '1467011157.401 415 127.0.0.1 TCP_MISS/200 337891 GET http://www.aliexpress.com/', + method: 'GET', + bytes: 337891, + action: 'TCP_MISS', + ip_src_addr: '127.0.0.1', + url: 'http://www.aliexpress.com/af/shoes.html?', + timestamp: '1467011157.401' + }; + return Observable.create(observable => { + observable.next(parsedJson); + observable.complete(); + }); + } } class MockTransformationValidationService { - public listSimpleFunctions(): Observable<StellarFunctionDescription[]> { - let stellarFunctionDescription: StellarFunctionDescription[] = []; - stellarFunctionDescription.push(new StellarFunctionDescription('TO_LOWER', 'TO_LOWER description', ['input - input field'])); - stellarFunctionDescription.push(new StellarFunctionDescription('TO_UPPER', 'TO_UPPER description', ['input - input field'])); - stellarFunctionDescription.push(new StellarFunctionDescription('TRIM', 'Lazy to copy desc', ['input - input field'])); - return Observable.create((observer) => { - observer.next(stellarFunctionDescription); - observer.complete(); - }); - } + public listSimpleFunctions(): Observable<StellarFunctionDescription[]> { + let stellarFunctionDescription: StellarFunctionDescription[] = []; + stellarFunctionDescription.push( + new StellarFunctionDescription('TO_LOWER', 'TO_LOWER description', [ + 'input - input field' + ]) + ); + stellarFunctionDescription.push( + new StellarFunctionDescription('TO_UPPER', 'TO_UPPER description', [ + 'input - input field' + ]) + ); + stellarFunctionDescription.push( + new StellarFunctionDescription('TRIM', 'Lazy to copy desc', [ + 'input - input field' + ]) + ); + return Observable.create(observer => { + observer.next(stellarFunctionDescription); + observer.complete(); + }); + } } class MockSensorEnrichmentConfigService { - public getAvailableEnrichments(): Observable<string[]> { - return Observable.create((observer) => { - observer.next(['geo', 'host', 'whois']); - observer.complete(); - }); - } + public getAvailableEnrichments(): Observable<string[]> { + return Observable.create(observer => { + observer.next(['geo', 'host', 'whois']); + observer.complete(); + }); + } } -class MockKafkaService { - -} +class MockKafkaService {} describe('Component: SensorFieldSchema', () => { - let component: SensorFieldSchemaComponent; - let sensorEnrichmentConfigService: SensorEnrichmentConfigService; - let sensorParserConfigService: SensorParserConfigService; - let fixture: ComponentFixture<SensorFieldSchemaComponent>; - let transformationValidationService: StellarService; - - let squidSensorConfigJson = { - 'parserClassName': 'org.apache.metron.parsers.GrokParser', - 'sensorTopic': 'squid', - 'parserConfig': { - 'grokPath': 'target/patterns/squid', - 'grokStatement': '%{NUMBER:timestamp} %{INT:elapsed} %{IPV4:ip_src_addr} %{WORD:action}/%{NUMBER:code} ' + - '%{NUMBER:bytes} %{WORD:method} %{NOTSPACE:url} - %{WORD:UNWANTED}\\/%{IPV4:ip_dst_addr} ' + - '%{WORD:UNWANTED}\\/%{WORD:UNWANTED}' - }, - 'fieldTransformations': [ - { - 'input': [], - 'output': ['method'], - 'transformation': 'STELLAR', - 'config': { - 'method': 'TRIM(TO_LOWER(method))' - } - }, - { - 'input': ['code'], - 'output': null, - 'transformation': 'REMOVE', - 'config': { - 'condition': 'exists(field2)' - } - }, - { - 'input': ['ip_src_addr'], - 'output': null, - 'transformation': 'REMOVE' - } - ] - }; - let squidEnrichmentJson = { - 'index': 'squid', - 'batchSize': 1, - 'enrichment': { - 'fieldMap': { - 'geo': ['ip_dst_addr', 'ip_src_addr'], - 'host': ['ip_dst_addr'], - 'whois': ['ip_src_addr'] - }, - 'fieldToTypeMap': {}, - 'config': {} + let component: SensorFieldSchemaComponent; + let sensorEnrichmentConfigService: SensorEnrichmentConfigService; + let sensorParserConfigService: SensorParserConfigService; + let fixture: ComponentFixture<SensorFieldSchemaComponent>; + let transformationValidationService: StellarService; + + let squidSensorConfigJson = { + parserClassName: 'org.apache.metron.parsers.GrokParser', + sensorTopic: 'squid', + parserConfig: { + grokPath: 'target/patterns/squid', + grokStatement: + '%{NUMBER:timestamp} %{INT:elapsed} %{IPV4:ip_src_addr} %{WORD:action}/%{NUMBER:code} ' + + '%{NUMBER:bytes} %{WORD:method} %{NOTSPACE:url} - %{WORD:UNWANTED}\\/%{IPV4:ip_dst_addr} ' + + '%{WORD:UNWANTED}\\/%{WORD:UNWANTED}' + }, + fieldTransformations: [ + { + input: [], + output: ['method'], + transformation: 'STELLAR', + config: { + method: 'TRIM(TO_LOWER(method))' + } + }, + { + input: ['code'], + output: null, + transformation: 'REMOVE', + config: { + condition: 'exists(field2)' + } + }, + { + input: ['ip_src_addr'], + output: null, + transformation: 'REMOVE' + } + ] + }; + let squidEnrichmentJson = { + index: 'squid', + batchSize: 1, + enrichment: { + fieldMap: { + geo: ['ip_dst_addr', 'ip_src_addr'], + host: ['ip_dst_addr'], + whois: ['ip_src_addr'] + }, + fieldToTypeMap: {}, + config: {} + }, + threatIntel: { + fieldMap: { + hbaseThreatIntel: ['ip_dst_addr'] + }, + fieldToTypeMap: { + ip_dst_addr: ['malicious_ip'] + }, + config: {}, + triageConfig: { + riskLevelRules: {}, + aggregator: 'MAX', + aggregationConfig: {} + } + }, + configuration: {} + }; + let sensorParserConfig = Object.assign( + new SensorParserConfig(), + squidSensorConfigJson + ); + let sensorEnrichmentConfig = Object.assign( + new SensorEnrichmentConfig(), + squidEnrichmentJson + ); + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [SensorFieldSchemaModule], + providers: [ + MetronAlerts, + { provide: HttpClient }, + { provide: KafkaService, useClass: MockKafkaService }, + { + provide: SensorEnrichmentConfigService, + useClass: MockSensorEnrichmentConfigService }, - 'threatIntel': { - 'fieldMap': { - 'hbaseThreatIntel': ['ip_dst_addr'] - }, - 'fieldToTypeMap': { - 'ip_dst_addr': ['malicious_ip'] - }, - 'config': {}, - 'triageConfig': { - 'riskLevelRules': {}, - 'aggregator': 'MAX', - 'aggregationConfig': {} - } + { + provide: SensorParserConfigService, + useClass: MockSensorParserConfigService }, - 'configuration': {} - }; - let sensorParserConfig = Object.assign(new SensorParserConfig(), squidSensorConfigJson); - let sensorEnrichmentConfig = Object.assign(new SensorEnrichmentConfig(), squidEnrichmentJson); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [SensorFieldSchemaModule], - providers: [ - MetronAlerts, - {provide: Http}, - {provide: KafkaService, useClass: MockKafkaService}, - {provide: SensorEnrichmentConfigService, useClass: MockSensorEnrichmentConfigService}, - {provide: SensorParserConfigService, useClass: MockSensorParserConfigService}, - {provide: StellarService, useClass: MockTransformationValidationService}, - - ] - }).compileComponents() - .then(() => { - fixture = TestBed.createComponent(SensorFieldSchemaComponent); - component = fixture.componentInstance; - sensorParserConfigService = fixture.debugElement.injector.get(SensorParserConfigService); - transformationValidationService = fixture.debugElement.injector.get(StellarService); - sensorEnrichmentConfigService = fixture.debugElement.injector.get(SensorEnrichmentConfigService); - }); - })); - - it('should create an instance', () => { - expect(component).toBeDefined(); - fixture.destroy(); - }); - - - - it('should read TransformFunctions, EnrichmentFunctions, ThreatIntelfunctions', () => { - component.ngOnInit(); - - expect(component.transformOptions.length).toEqual(3); - expect(Object.keys(component.transformFunctions).length).toEqual(3); - expect(component.enrichmentOptions.length).toEqual(3); - expect(component.threatIntelOptions.length).toEqual(1); - - fixture.destroy(); - }); - - it('should call getSampleData if showFieldSchema', () => { - spyOn(component.sampleData, 'getNextSample'); - - let changes: SimpleChanges = { - 'showFieldSchema': new SimpleChange(false, true) - }; - component.ngOnChanges(changes); - expect(component.sampleData.getNextSample['calls'].count()).toEqual(1); - - changes = { - 'showFieldSchema': new SimpleChange(true, false) - }; - component.ngOnChanges(changes); - expect(component.sampleData.getNextSample['calls'].count()).toEqual(1); - - fixture.destroy(); - }); - - it('should return isSimple function', () => { - component.ngOnInit(); - - expect(component.isSimpleFunction(['TO_LOWER', 'TO_UPPER'])).toEqual(true); - expect(component.isSimpleFunction(['TO_LOWER', 'TO_UPPER', 'TEST'])).toEqual(false); - - fixture.destroy(); - }); - - it('should create FieldSchemaRows', () => { - component.ngOnInit(); - - component.sensorParserConfig = sensorParserConfig; - component.sensorEnrichmentConfig = sensorEnrichmentConfig; - component.onSampleDataChanged('DoctorStrange'); - component.createFieldSchemaRows(); - - expect(component.fieldSchemaRows.length).toEqual(10); - expect(component.savedFieldSchemaRows.length).toEqual(10); - - let methodFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter(row => row.inputFieldName === 'method')[0]; - expect(methodFieldSchemaRow).toBeDefined(); - expect(methodFieldSchemaRow.transformConfigured.length).toEqual(2); - expect(methodFieldSchemaRow.enrichmentConfigured.length).toEqual(0); - expect(methodFieldSchemaRow.threatIntelConfigured.length).toEqual(0); - - let ipSrcAddrFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter(row => row.inputFieldName === 'ip_src_addr')[0]; - expect(ipSrcAddrFieldSchemaRow).toBeDefined(); - expect(ipSrcAddrFieldSchemaRow.transformConfigured.length).toEqual(0); - expect(ipSrcAddrFieldSchemaRow.enrichmentConfigured.length).toEqual(2); - expect(ipSrcAddrFieldSchemaRow.threatIntelConfigured.length).toEqual(0); - - let ipDstAddrFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter(row => row.inputFieldName === 'ip_dst_addr')[0]; - expect(ipDstAddrFieldSchemaRow).toBeDefined(); - expect(ipDstAddrFieldSchemaRow.transformConfigured.length).toEqual(0); - expect(ipDstAddrFieldSchemaRow.enrichmentConfigured.length).toEqual(2); - expect(ipDstAddrFieldSchemaRow.threatIntelConfigured.length).toEqual(1); - - let codeSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter(row => row.inputFieldName === 'code')[0]; - expect(codeSchemaRow).toBeDefined(); - expect(codeSchemaRow.isRemoved).toEqual(true); - expect(codeSchemaRow.conditionalRemove).toEqual(true); - expect(codeSchemaRow.transformConfigured.length).toEqual(0); - expect(codeSchemaRow.enrichmentConfigured.length).toEqual(0); - expect(codeSchemaRow.threatIntelConfigured.length).toEqual(0); - - fixture.destroy(); - }); - - it('should return getChanges', () => { - let fieldSchemaRow = new FieldSchemaRow('method'); - fieldSchemaRow.transformConfigured = []; - fieldSchemaRow.enrichmentConfigured = [new AutocompleteOption('GEO'), new AutocompleteOption('WHOIS')]; - fieldSchemaRow.threatIntelConfigured = [new AutocompleteOption('MALICIOUS-IP')]; - - expect(component.getChanges(fieldSchemaRow)).toEqual('Enrichments: GEO, WHOIS <br> Threat Intel: MALICIOUS-IP'); - - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_STRING')]; - fieldSchemaRow.enrichmentConfigured = [new AutocompleteOption('GEO')]; - fieldSchemaRow.threatIntelConfigured = [new AutocompleteOption('MALICIOUS-IP'), new AutocompleteOption('MALICIOUS-IP')]; - - expect(component.getChanges(fieldSchemaRow)).toEqual('Transforms: TO_STRING(method) <br> Enrichments: GEO <br> Threat Intel: MALICIOUS-IP, MALICIOUS-IP'); - - - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_STRING'), new AutocompleteOption('TO_STRING')]; - fieldSchemaRow.enrichmentConfigured = []; - fieldSchemaRow.threatIntelConfigured = [new AutocompleteOption('MALICIOUS-IP'), new AutocompleteOption('MALICIOUS-IP')]; - - expect(component.getChanges(fieldSchemaRow)).toEqual('Transforms: TO_STRING(TO_STRING(method)) <br> Threat Intel: MALICIOUS-IP, MALICIOUS-IP'); - - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_STRING'), new AutocompleteOption('TO_STRING')]; - fieldSchemaRow.enrichmentConfigured = []; - fieldSchemaRow.threatIntelConfigured = []; - - expect(component.getChanges(fieldSchemaRow)).toEqual('Transforms: TO_STRING(TO_STRING(method)) <br> '); - - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_STRING'), new AutocompleteOption('TO_STRING')]; - fieldSchemaRow.isRemoved = true; - expect(component.getChanges(fieldSchemaRow)).toEqual('Disabled'); - - fixture.destroy(); + { + provide: StellarService, + useClass: MockTransformationValidationService + } + ] }); + fixture = TestBed.createComponent(SensorFieldSchemaComponent); + component = fixture.componentInstance; + sensorParserConfigService = TestBed.get( + SensorParserConfigService + ); + transformationValidationService = TestBed.get( + StellarService + ); + sensorEnrichmentConfigService = TestBed.get( + SensorEnrichmentConfigService + ); + })); + + it('should create an instance', () => { + expect(component).toBeDefined(); + fixture.destroy(); + }); + + it('should read TransformFunctions, EnrichmentFunctions, ThreatIntelfunctions', () => { + component.ngOnInit(); + + expect(component.transformOptions.length).toEqual(3); + expect(Object.keys(component.transformFunctions).length).toEqual(3); + expect(component.enrichmentOptions.length).toEqual(3); + expect(component.threatIntelOptions.length).toEqual(1); + + fixture.destroy(); + }); + + it('should call getSampleData if showFieldSchema', () => { + spyOn(component.sampleData, 'getNextSample'); + + let changes: SimpleChanges = { + showFieldSchema: new SimpleChange(false, true, true) + }; + component.ngOnChanges(changes); + expect(component.sampleData.getNextSample['calls'].count()).toEqual(1); - it('should call appropriate functions when onSampleDataChanged is called ', () => { - let returnSuccess = true; - spyOn(component, 'createFieldSchemaRows'); - spyOn(component, 'onSampleDataNotAvailable'); - spyOn(sensorParserConfigService, 'parseMessage').and.callFake(function(parseMessageRequest: ParseMessageRequest) { - expect(parseMessageRequest.sensorParserConfig.parserConfig['patternLabel']).toEqual(parseMessageRequest.sensorParserConfig.sensorTopic.toUpperCase()); - expect(parseMessageRequest.sensorParserConfig.parserConfig['grokPath']).toEqual('./' + parseMessageRequest.sensorParserConfig.sensorTopic); - if (returnSuccess) { - return Observable.create(observer => { - observer.next({'a': 'b', 'c': 'd'}); - observer.complete(); - }); - } - return Observable.throw('Error'); + changes = { + showFieldSchema: new SimpleChange(true, false, false) + }; + component.ngOnChanges(changes); + expect(component.sampleData.getNextSample['calls'].count()).toEqual(1); + + fixture.destroy(); + }); + + it('should return isSimple function', () => { + component.ngOnInit(); + + expect(component.isSimpleFunction(['TO_LOWER', 'TO_UPPER'])).toEqual(true); + expect( + component.isSimpleFunction(['TO_LOWER', 'TO_UPPER', 'TEST']) + ).toEqual(false); + + fixture.destroy(); + }); + + it('should create FieldSchemaRows', () => { + component.ngOnInit(); + + component.sensorParserConfig = sensorParserConfig; + component.sensorEnrichmentConfig = sensorEnrichmentConfig; + component.onSampleDataChanged('DoctorStrange'); + component.createFieldSchemaRows(); + + expect(component.fieldSchemaRows.length).toEqual(10); + expect(component.savedFieldSchemaRows.length).toEqual(10); + + let methodFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter( + row => row.inputFieldName === 'method' + )[0]; + expect(methodFieldSchemaRow).toBeDefined(); + expect(methodFieldSchemaRow.transformConfigured.length).toEqual(2); + expect(methodFieldSchemaRow.enrichmentConfigured.length).toEqual(0); + expect(methodFieldSchemaRow.threatIntelConfigured.length).toEqual(0); + + let ipSrcAddrFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter( + row => row.inputFieldName === 'ip_src_addr' + )[0]; + expect(ipSrcAddrFieldSchemaRow).toBeDefined(); + expect(ipSrcAddrFieldSchemaRow.transformConfigured.length).toEqual(0); + expect(ipSrcAddrFieldSchemaRow.enrichmentConfigured.length).toEqual(2); + expect(ipSrcAddrFieldSchemaRow.threatIntelConfigured.length).toEqual(0); + + let ipDstAddrFieldSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter( + row => row.inputFieldName === 'ip_dst_addr' + )[0]; + expect(ipDstAddrFieldSchemaRow).toBeDefined(); + expect(ipDstAddrFieldSchemaRow.transformConfigured.length).toEqual(0); + expect(ipDstAddrFieldSchemaRow.enrichmentConfigured.length).toEqual(2); + expect(ipDstAddrFieldSchemaRow.threatIntelConfigured.length).toEqual(1); + + let codeSchemaRow: FieldSchemaRow = component.fieldSchemaRows.filter( + row => row.inputFieldName === 'code' + )[0]; + expect(codeSchemaRow).toBeDefined(); + expect(codeSchemaRow.isRemoved).toEqual(true); + expect(codeSchemaRow.conditionalRemove).toEqual(true); + expect(codeSchemaRow.transformConfigured.length).toEqual(0); + expect(codeSchemaRow.enrichmentConfigured.length).toEqual(0); + expect(codeSchemaRow.threatIntelConfigured.length).toEqual(0); + + fixture.destroy(); + }); + + it('should return getChanges', () => { + let fieldSchemaRow = new FieldSchemaRow('method'); + fieldSchemaRow.transformConfigured = []; + fieldSchemaRow.enrichmentConfigured = [ + new AutocompleteOption('GEO'), + new AutocompleteOption('WHOIS') + ]; + fieldSchemaRow.threatIntelConfigured = [ + new AutocompleteOption('MALICIOUS-IP') + ]; + + expect(component.getChanges(fieldSchemaRow)).toEqual( + 'Enrichments: GEO, WHOIS <br> Threat Intel: MALICIOUS-IP' + ); + + fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_STRING')]; + fieldSchemaRow.enrichmentConfigured = [new AutocompleteOption('GEO')]; + fieldSchemaRow.threatIntelConfigured = [ + new AutocompleteOption('MALICIOUS-IP'), + new AutocompleteOption('MALICIOUS-IP') + ]; + + expect(component.getChanges(fieldSchemaRow)).toEqual( + 'Transforms: TO_STRING(method) <br> Enrichments: GEO <br> Threat Intel: MALICIOUS-IP, MALICIOUS-IP' + ); + + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TO_STRING'), + new AutocompleteOption('TO_STRING') + ]; + fieldSchemaRow.enrichmentConfigured = []; + fieldSchemaRow.threatIntelConfigured = [ + new AutocompleteOption('MALICIOUS-IP'), + new AutocompleteOption('MALICIOUS-IP') + ]; + + expect(component.getChanges(fieldSchemaRow)).toEqual( + 'Transforms: TO_STRING(TO_STRING(method)) <br> Threat Intel: MALICIOUS-IP, MALICIOUS-IP' + ); + + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TO_STRING'), + new AutocompleteOption('TO_STRING') + ]; + fieldSchemaRow.enrichmentConfigured = []; + fieldSchemaRow.threatIntelConfigured = []; + + expect(component.getChanges(fieldSchemaRow)).toEqual( + 'Transforms: TO_STRING(TO_STRING(method)) <br> ' + ); + + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TO_STRING'), + new AutocompleteOption('TO_STRING') + ]; + fieldSchemaRow.isRemoved = true; + expect(component.getChanges(fieldSchemaRow)).toEqual('Disabled'); + + fixture.destroy(); + }); + + it('should call appropriate functions when onSampleDataChanged is called ', () => { + let returnSuccess = true; + spyOn(component, 'createFieldSchemaRows'); + spyOn(component, 'onSampleDataNotAvailable'); + spyOn(sensorParserConfigService, 'parseMessage').and.callFake(function( + parseMessageRequest: ParseMessageRequest + ) { + expect( + parseMessageRequest.sensorParserConfig.parserConfig['patternLabel'] + ).toEqual( + parseMessageRequest.sensorParserConfig.sensorTopic.toUpperCase() + ); + expect( + parseMessageRequest.sensorParserConfig.parserConfig['grokPath'] + ).toEqual('./' + parseMessageRequest.sensorParserConfig.sensorTopic); + if (returnSuccess) { + return Observable.create(observer => { + observer.next({ a: 'b', c: 'd' }); + observer.complete(); }); - - component.sensorParserConfig = sensorParserConfig; - component.sensorParserConfig.parserConfig['patternLabel'] = null; - component.onSampleDataChanged('DoctorStrange'); - expect(component.parserResult).toEqual({'a': 'b', 'c': 'd'}); - expect(component.createFieldSchemaRows).toHaveBeenCalled(); - expect(component.onSampleDataNotAvailable).not.toHaveBeenCalled(); - - returnSuccess = false; - component.parserResult = {}; - component.onSampleDataChanged('DoctorStrange'); - expect(component.parserResult).toEqual({}); - expect(component.onSampleDataNotAvailable).toHaveBeenCalled(); - expect(component.onSampleDataNotAvailable['calls'].count()).toEqual(1); - - fixture.destroy(); - }); - - it('should onSampleDataChanged available and onSampleDataNotAvailable ', () => { - let returnSuccess = true; - spyOn(component, 'createFieldSchemaRows'); - - component.onSampleDataNotAvailable(); - expect(component.createFieldSchemaRows['calls'].count()).toEqual(1); - - fixture.destroy(); - }); - - it('should call onSaveChange on onRemove/onEnable ', () => { - spyOn(component, 'onSave'); - - let fieldSchemaRow = new FieldSchemaRow('method'); - fieldSchemaRow.outputFieldName = 'copy-of-method'; - fieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; - fieldSchemaRow.isRemoved = false; - - component.savedFieldSchemaRows = [fieldSchemaRow]; - - let removeFieldSchemaRow = JSON.parse(JSON.stringify(fieldSchemaRow)); - component.onRemove(removeFieldSchemaRow); - expect(removeFieldSchemaRow.isRemoved).toEqual(true); - expect(component.savedFieldSchemaRows[0].isRemoved).toEqual(true); - expect(component.onSave['calls'].count()).toEqual(1); - - fieldSchemaRow.isRemoved = true; - let enableFieldSchemaRow = JSON.parse(JSON.stringify(fieldSchemaRow)); - component.onEnable(enableFieldSchemaRow); - expect(fieldSchemaRow.isRemoved).toEqual(false); - expect(component.savedFieldSchemaRows[0].isRemoved).toEqual(false); - expect(component.onSave['calls'].count()).toEqual(2); - - fixture.destroy(); + } + return throwError('Error'); }); - it('should revert changes on cancel ', () => { - let fieldSchemaRow = new FieldSchemaRow('method'); - fieldSchemaRow.showConfig = true; - fieldSchemaRow.outputFieldName = 'method'; - fieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; - fieldSchemaRow.isRemoved = false; - fieldSchemaRow.isSimple = true; - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_LOWER'), new AutocompleteOption('TRIM')]; - - component.savedFieldSchemaRows.push(fieldSchemaRow); - - component.onCancelChange(fieldSchemaRow); - expect(fieldSchemaRow.showConfig).toEqual(false); - - component.hideFieldSchema.emit = jasmine.createSpy('emit'); - component.onCancel(); - expect(component.hideFieldSchema.emit).toHaveBeenCalled(); - - fixture.destroy(); - }); - - it('should return formatted function on createTransformFunction call ', () => { - let fieldSchemaRow = new FieldSchemaRow('method'); - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TRIM'), new AutocompleteOption('TO_STRING')]; - - expect(component.createTransformFunction(fieldSchemaRow)).toEqual('TO_STRING(TRIM(method))'); - - fixture.destroy(); - }); - - it('should set preview value for FieldSchemaRow ', () => { - let fieldSchemaRow = new FieldSchemaRow('method'); - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TRIM'), new AutocompleteOption('TO_STRING')]; + component.sensorParserConfig = sensorParserConfig; + component.sensorParserConfig.parserConfig['patternLabel'] = null; + component.onSampleDataChanged('DoctorStrange'); + expect(component.parserResult).toEqual({ a: 'b', c: 'd' }); + expect(component.createFieldSchemaRows).toHaveBeenCalled(); + expect(component.onSampleDataNotAvailable).not.toHaveBeenCalled(); + + returnSuccess = false; + component.parserResult = {}; + component.onSampleDataChanged('DoctorStrange'); + expect(component.parserResult).toEqual({}); + expect(component.onSampleDataNotAvailable).toHaveBeenCalled(); + expect(component.onSampleDataNotAvailable['calls'].count()).toEqual(1); + + fixture.destroy(); + }); + + it('should onSampleDataChanged available and onSampleDataNotAvailable ', () => { + let returnSuccess = true; + spyOn(component, 'createFieldSchemaRows'); + + component.onSampleDataNotAvailable(); + expect(component.createFieldSchemaRows['calls'].count()).toEqual(1); + + fixture.destroy(); + }); + + it('should call onSaveChange on onRemove/onEnable ', () => { + spyOn(component, 'onSave'); + + let fieldSchemaRow = new FieldSchemaRow('method'); + fieldSchemaRow.outputFieldName = 'copy-of-method'; + fieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; + fieldSchemaRow.isRemoved = false; + + component.savedFieldSchemaRows = [fieldSchemaRow]; + + let removeFieldSchemaRow = JSON.parse(JSON.stringify(fieldSchemaRow)); + component.onRemove(removeFieldSchemaRow); + expect(removeFieldSchemaRow.isRemoved).toEqual(true); + expect(component.savedFieldSchemaRows[0].isRemoved).toEqual(true); + expect(component.onSave['calls'].count()).toEqual(1); + + fieldSchemaRow.isRemoved = true; + let enableFieldSchemaRow = JSON.parse(JSON.stringify(fieldSchemaRow)); + component.onEnable(enableFieldSchemaRow); + expect(fieldSchemaRow.isRemoved).toEqual(false); + expect(component.savedFieldSchemaRows[0].isRemoved).toEqual(false); + expect(component.onSave['calls'].count()).toEqual(2); + + fixture.destroy(); + }); + + it('should revert changes on cancel ', () => { + let fieldSchemaRow = new FieldSchemaRow('method'); + fieldSchemaRow.showConfig = true; + fieldSchemaRow.outputFieldName = 'method'; + fieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; + fieldSchemaRow.isRemoved = false; + fieldSchemaRow.isSimple = true; + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TO_LOWER'), + new AutocompleteOption('TRIM') + ]; + + component.savedFieldSchemaRows.push(fieldSchemaRow); + + component.onCancelChange(fieldSchemaRow); + expect(fieldSchemaRow.showConfig).toEqual(false); + + component.hideFieldSchema.emit = jasmine.createSpy('emit'); + component.onCancel(); + expect(component.hideFieldSchema.emit).toHaveBeenCalled(); + + fixture.destroy(); + }); + + it('should return formatted function on createTransformFunction call ', () => { + let fieldSchemaRow = new FieldSchemaRow('method'); + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TRIM'), + new AutocompleteOption('TO_STRING') + ]; + + expect(component.createTransformFunction(fieldSchemaRow)).toEqual( + 'TO_STRING(TRIM(method))' + ); + + fixture.destroy(); + }); + + it('should set preview value for FieldSchemaRow ', () => { + let fieldSchemaRow = new FieldSchemaRow('method'); + fieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TRIM'), + new AutocompleteOption('TO_STRING') + ]; + + component.onTransformsChange(fieldSchemaRow); + expect(fieldSchemaRow.preview).toEqual('TO_STRING(TRIM(method))'); + + fieldSchemaRow.transformConfigured = [new AutocompleteOption('TRIM')]; + component.onTransformsChange(fieldSchemaRow); + expect(fieldSchemaRow.preview).toEqual('TRIM(method)'); + + fieldSchemaRow.transformConfigured = []; + component.onTransformsChange(fieldSchemaRow); + expect(fieldSchemaRow.preview).toEqual(''); + + fixture.destroy(); + }); + + it('isConditionalRemoveTransform ', () => { + let fieldTransformationJson = { + input: ['method'], + transformation: 'REMOVE', + config: { + condition: 'IS_DOMAIN(elapsed)' + } + }; + let simpleFieldTransformationJson = { + input: ['method'], + transformation: 'REMOVE' + }; + let fieldTransformation: FieldTransformer = Object.assign( + new FieldTransformer(), + fieldTransformationJson + ); + expect(component.isConditionalRemoveTransform(fieldTransformation)).toEqual( + true + ); + + let simpleFieldTransformation: FieldTransformer = Object.assign( + new FieldTransformer(), + simpleFieldTransformationJson + ); + expect( + component.isConditionalRemoveTransform(simpleFieldTransformation) + ).toEqual(false); + + fixture.destroy(); + }); + + it('should save data ', () => { + let methodFieldSchemaRow = new FieldSchemaRow('method'); + methodFieldSchemaRow.outputFieldName = 'method'; + methodFieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; + methodFieldSchemaRow.isRemoved = false; + methodFieldSchemaRow.isSimple = true; + methodFieldSchemaRow.transformConfigured = [ + new AutocompleteOption('TO_LOWER'), + new AutocompleteOption('TRIM') + ]; + + let elapsedFieldSchemaRow = new FieldSchemaRow('elapsed'); + elapsedFieldSchemaRow.outputFieldName = 'elapsed'; + elapsedFieldSchemaRow.preview = 'IS_DOMAIN(elapsed)'; + elapsedFieldSchemaRow.isRemoved = true; + elapsedFieldSchemaRow.isSimple = true; + elapsedFieldSchemaRow.transformConfigured = [ + new AutocompleteOption('IS_DOMAIN') + ]; + elapsedFieldSchemaRow.enrichmentConfigured = [ + new AutocompleteOption('host') + ]; + + let ipDstAddrFieldSchemaRow = new FieldSchemaRow('ip_dst_addr'); + ipDstAddrFieldSchemaRow.outputFieldName = 'ip_dst_addr'; + ipDstAddrFieldSchemaRow.preview = 'IS_DOMAIN(elapsed)'; + ipDstAddrFieldSchemaRow.isRemoved = false; + ipDstAddrFieldSchemaRow.isSimple = false; + ipDstAddrFieldSchemaRow.threatIntelConfigured = [ + new AutocompleteOption('malicious_ip') + ]; + ipDstAddrFieldSchemaRow.enrichmentConfigured = [ + new AutocompleteOption('host') + ]; + + let codeFieldSchemaRow = new FieldSchemaRow('code'); + codeFieldSchemaRow.outputFieldName = 'code'; + codeFieldSchemaRow.isRemoved = true; + codeFieldSchemaRow.conditionalRemove = true; + + component.savedFieldSchemaRows = [ + methodFieldSchemaRow, + elapsedFieldSchemaRow, + ipDstAddrFieldSchemaRow, + codeFieldSchemaRow + ]; + + component.sensorParserConfig = new SensorParserConfig(); + component.sensorParserConfig.parserClassName = + 'org.apache.metron.parsers.GrokParser'; + component.sensorParserConfig.sensorTopic = 'squid'; + + component.sensorParserConfig.fieldTransformations = [ + new FieldTransformer() + ]; + component.sensorParserConfig.fieldTransformations[0].transformation = + 'REMOVE'; + component.sensorParserConfig.fieldTransformations[0].input = ['code']; + component.sensorParserConfig.fieldTransformations[0].config = { + condition: 'exists(method)' + }; - component.onTransformsChange(fieldSchemaRow); - expect(fieldSchemaRow.preview).toEqual('TO_STRING(TRIM(method))'); + component.sensorEnrichmentConfig = new SensorEnrichmentConfig(); + component.sensorEnrichmentConfig.enrichment = new EnrichmentConfig(); + component.sensorEnrichmentConfig.threatIntel = new ThreatIntelConfig(); + component.sensorEnrichmentConfig.configuration = {}; - fieldSchemaRow.transformConfigured = [new AutocompleteOption('TRIM')]; - component.onTransformsChange(fieldSchemaRow); - expect(fieldSchemaRow.preview).toEqual('TRIM(method)'); + component.onSave(); - fieldSchemaRow.transformConfigured = []; - component.onTransformsChange(fieldSchemaRow); - expect(fieldSchemaRow.preview).toEqual(''); + let fieldTransformationJson = { + output: ['method', 'elapsed'], + transformation: 'STELLAR', + config: { + method: 'TRIM(TO_LOWER(method))', + elapsed: 'IS_DOMAIN(elapsed)' + } + }; - fixture.destroy(); - }); + let fieldTransformationRemoveJson = { + input: ['elapsed'], + transformation: 'REMOVE' + }; - it('isConditionalRemoveTransform ', () => { - let fieldTransformationJson = { - 'input': ['method'], - 'transformation': 'REMOVE', - 'config': - { - 'condition': 'IS_DOMAIN(elapsed)' - } - }; - let simpleFieldTransformationJson = { - 'input': ['method'], - 'transformation': 'REMOVE' - }; - let fieldTransformation: FieldTransformer = Object.assign(new FieldTransformer(), fieldTransformationJson); - expect(component.isConditionalRemoveTransform(fieldTransformation)).toEqual(true); - - let simpleFieldTransformation: FieldTransformer = Object.assign(new FieldTransformer(), simpleFieldTransformationJson); - expect(component.isConditionalRemoveTransform(simpleFieldTransformation)).toEqual(false); - - fixture.destroy(); - }); + let conditionalFieldTransformationRemoveJson = { + input: ['code'], + transformation: 'REMOVE', + config: { + condition: 'exists(method)' + } + }; - it('should save data ', () => { - let methodFieldSchemaRow = new FieldSchemaRow('method'); - methodFieldSchemaRow.outputFieldName = 'method'; - methodFieldSchemaRow.preview = 'TRIM(TO_LOWER(method))'; - methodFieldSchemaRow.isRemoved = false; - methodFieldSchemaRow.isSimple = true; - methodFieldSchemaRow.transformConfigured = [new AutocompleteOption('TO_LOWER'), new AutocompleteOption('TRIM')]; - - let elapsedFieldSchemaRow = new FieldSchemaRow('elapsed'); - elapsedFieldSchemaRow.outputFieldName = 'elapsed'; - elapsedFieldSchemaRow.preview = 'IS_DOMAIN(elapsed)'; - elapsedFieldSchemaRow.isRemoved = true; - elapsedFieldSchemaRow.isSimple = true; - elapsedFieldSchemaRow.transformConfigured = [new AutocompleteOption('IS_DOMAIN')]; - elapsedFieldSchemaRow.enrichmentConfigured = [new AutocompleteOption('host')]; - - let ipDstAddrFieldSchemaRow = new FieldSchemaRow('ip_dst_addr'); - ipDstAddrFieldSchemaRow.outputFieldName = 'ip_dst_addr'; - ipDstAddrFieldSchemaRow.preview = 'IS_DOMAIN(elapsed)'; - ipDstAddrFieldSchemaRow.isRemoved = false; - ipDstAddrFieldSchemaRow.isSimple = false; - ipDstAddrFieldSchemaRow.threatIntelConfigured = [new AutocompleteOption('malicious_ip')]; - ipDstAddrFieldSchemaRow.enrichmentConfigured = [new AutocompleteOption('host')]; - - let codeFieldSchemaRow = new FieldSchemaRow('code'); - codeFieldSchemaRow.outputFieldName = 'code'; - codeFieldSchemaRow.isRemoved = true; - codeFieldSchemaRow.conditionalRemove = true; - - component.savedFieldSchemaRows = [methodFieldSchemaRow, elapsedFieldSchemaRow, ipDstAddrFieldSchemaRow, codeFieldSchemaRow]; - - component.sensorParserConfig = new SensorParserConfig(); - component.sensorParserConfig.parserClassName = 'org.apache.metron.parsers.GrokParser'; - component.sensorParserConfig.sensorTopic = 'squid'; - - component.sensorParserConfig.fieldTransformations = [new FieldTransformer()]; - component.sensorParserConfig.fieldTransformations[0].transformation = 'REMOVE'; - component.sensorParserConfig.fieldTransformations[0].input = ['code']; - component.sensorParserConfig.fieldTransformations[0].config = {'condition': 'exists(method)'}; - - component.sensorEnrichmentConfig = new SensorEnrichmentConfig(); - component.sensorEnrichmentConfig.enrichment = new EnrichmentConfig(); - component.sensorEnrichmentConfig.threatIntel = new ThreatIntelConfig(); - component.sensorEnrichmentConfig.configuration = {}; - - component.onSave(); - - let fieldTransformationJson = { - 'output': ['method', 'elapsed'], - 'transformation': 'STELLAR', - 'config': - { - 'method': 'TRIM(TO_LOWER(method))', - 'elapsed': 'IS_DOMAIN(elapsed)' - } - }; - - let fieldTransformationRemoveJson = { - 'input': ['elapsed'], - 'transformation': 'REMOVE', - }; - - let conditionalFieldTransformationRemoveJson = { - 'input': ['code'], - 'transformation': 'REMOVE', - 'config': { - 'condition': 'exists(method)' - } - }; - - let fieldTransformation = Object.assign(new FieldTransformer(), fieldTransformationJson); - let fieldTransformationRemove = Object.assign(new FieldTransformer(), fieldTransformationRemoveJson); - let conditionalFieldTransformationRemove = Object.assign(new FieldTransformer(), conditionalFieldTransformationRemoveJson); - - expect(component.sensorParserConfig.fieldTransformations.length).toEqual(3); - let expectedStellar = component.sensorParserConfig.fieldTransformations.filter(transform => transform.transformation === 'STELLAR')[0]; - let expectedRemove = component.sensorParserConfig.fieldTransformations.filter(transform => transform.transformation === 'REMOVE' && !transform.config)[0]; - let expectedConditionalRemove = component.sensorParserConfig.fieldTransformations.filter(transform => transform.transformation === 'REMOVE' && transform.config)[0]; - expect(expectedStellar).toEqual(fieldTransformation); - expect(expectedRemove).toEqual(fieldTransformationRemove); - expect(expectedConditionalRemove).toEqual(conditionalFieldTransformationRemove); - - fixture.destroy(); - }); + let fieldTransformation = Object.assign( + new FieldTransformer(), + fieldTransformationJson + ); + let fieldTransformationRemove = Object.assign( + new FieldTransformer(), + fieldTransformationRemoveJson + ); + let conditionalFieldTransformationRemove = Object.assign( + new FieldTransformer(), + conditionalFieldTransformationRemoveJson + ); + + expect(component.sensorParserConfig.fieldTransformations.length).toEqual(3); + let expectedStellar = component.sensorParserConfig.fieldTransformations.filter( + transform => transform.transformation === 'STELLAR' + )[0]; + let expectedRemove = component.sensorParserConfig.fieldTransformations.filter( + transform => transform.transformation === 'REMOVE' && !transform.config + )[0]; + let expectedConditionalRemove = component.sensorParserConfig.fieldTransformations.filter( + transform => transform.transformation === 'REMOVE' && transform.config + )[0]; + expect(expectedStellar).toEqual(fieldTransformation); + expect(expectedRemove).toEqual(fieldTransformationRemove); + expect(expectedConditionalRemove).toEqual( + conditionalFieldTransformationRemove + ); + + fixture.destroy(); + }); });
http://git-wip-us.apache.org/repos/asf/metron/blob/0c4c622b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.spec.ts b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.spec.ts index eac839e..6151e9d 100644 --- a/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.spec.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.spec.ts @@ -17,26 +17,26 @@ */ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; -import {SimpleChange} from '@angular/core'; -import {Http} from '@angular/http'; -import {SensorParserConfigService} from '../../service/sensor-parser-config.service'; -import {MetronAlerts} from '../../shared/metron-alerts'; -import {KafkaService} from '../../service/kafka.service'; -import {Observable} from 'rxjs/Observable'; -import {ParseMessageRequest} from '../../model/parse-message-request'; -import {SensorGrokComponent} from './sensor-grok.component'; -import {GrokValidationService} from '../../service/grok-validation.service'; -import {SensorGrokModule} from './sensor-grok.module'; -import {SensorParserConfig} from '../../model/sensor-parser-config'; -import '../../rxjs-operators'; +import { SimpleChange } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { SensorParserConfigService } from '../../service/sensor-parser-config.service'; +import { MetronAlerts } from '../../shared/metron-alerts'; +import { KafkaService } from '../../service/kafka.service'; +import { Observable, throwError } from 'rxjs'; +import { ParseMessageRequest } from '../../model/parse-message-request'; +import { SensorGrokComponent } from './sensor-grok.component'; +import { GrokValidationService } from '../../service/grok-validation.service'; +import { SensorGrokModule } from './sensor-grok.module'; +import { SensorParserConfig } from '../../model/sensor-parser-config'; class MockSensorParserConfigService { - private parsedMessage: string; - public parseMessage(parseMessageRequest: ParseMessageRequest): Observable<{}> { + public parseMessage( + parseMessageRequest: ParseMessageRequest + ): Observable<{}> { if (this.parsedMessage === 'ERROR') { - return Observable.throw({'_body': JSON.stringify({'abc': 'def'}) }); + return throwError({ _body: JSON.stringify({ abc: 'def' }) }); } return Observable.create(observer => { @@ -54,21 +54,21 @@ class MockGrokValidationService { public list(): Observable<string[]> { return Observable.create(observer => { observer.next({ - 'BASE10NUM': '(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+)))', - 'BASE16FLOAT': '\\b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]*)?)|(?:\\.[0-9A-Fa-f]+)))\\b', - 'BASE16NUM': '(?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))', - 'CISCOMAC': '(?:(?:[A-Fa-f0-9]{4}\\.){2}[A-Fa-f0-9]{4})', - 'COMMONMAC': '(?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})', - 'DATA': '.*?' + BASE10NUM: + '(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+)))', + BASE16FLOAT: + '\\b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]*)?)|(?:\\.[0-9A-Fa-f]+)))\\b', + BASE16NUM: '(?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))', + CISCOMAC: '(?:(?:[A-Fa-f0-9]{4}\\.){2}[A-Fa-f0-9]{4})', + COMMONMAC: '(?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})', + DATA: '.*?' }); observer.complete(); }); } } -class MockKafkaService { - -} +class MockKafkaService {} describe('Component: SensorGrok', () => { let component: SensorGrokComponent; @@ -81,19 +81,19 @@ describe('Component: SensorGrok', () => { imports: [SensorGrokModule], providers: [ MetronAlerts, - {provide: Http}, - {provide: KafkaService, useClass: MockKafkaService}, - {provide: SensorParserConfigService, useClass: MockSensorParserConfigService}, - {provide: GrokValidationService, useClass: MockGrokValidationService}, - + { provide: HttpClient }, + { provide: KafkaService, useClass: MockKafkaService }, + { + provide: SensorParserConfigService, + useClass: MockSensorParserConfigService + }, + { provide: GrokValidationService, useClass: MockGrokValidationService } ] - }).compileComponents() - .then(() => { - fixture = TestBed.createComponent(SensorGrokComponent); - component = fixture.componentInstance; - sensorParserConfigService = fixture.debugElement.injector.get(SensorParserConfigService); - grokValidationService = fixture.debugElement.injector.get(GrokValidationService); - }); + }); + fixture = TestBed.createComponent(SensorGrokComponent); + component = fixture.componentInstance; + sensorParserConfigService = TestBed.get(SensorParserConfigService); + grokValidationService = TestBed.get(GrokValidationService); })); it('should create an instance', () => { @@ -113,21 +113,27 @@ describe('Component: SensorGrok', () => { spyOn(component.sampleData, 'getNextSample'); let changes = { - 'showGrok': new SimpleChange(true, false) + showGrok: new SimpleChange(true, false, true) }; component.ngOnChanges(changes); expect(component.sampleData.getNextSample['calls'].count()).toEqual(0); changes = { - 'showGrok': new SimpleChange(false, true) + showGrok: new SimpleChange(false, true, false) }; - component.grokStatement = 'STATEMENT_1 grok statement 1\nSTATEMENT_2 grok statement 2\n'; + component.grokStatement = + 'STATEMENT_1 grok statement 1\nSTATEMENT_2 grok statement 2\n'; component.patternLabel = 'STATEMENT_2'; component.ngOnChanges(changes); - expect(component.newGrokStatement).toEqual('STATEMENT_1 grok statement 1\nSTATEMENT_2 grok statement 2\n'); + expect(component.newGrokStatement).toEqual( + 'STATEMENT_1 grok statement 1\nSTATEMENT_2 grok statement 2\n' + ); expect(component.newPatternLabel).toEqual('STATEMENT_2'); - expect(component.availablePatternLabels).toEqual(['STATEMENT_1', 'STATEMENT_2']); + expect(component.availablePatternLabels).toEqual([ + 'STATEMENT_1', + 'STATEMENT_2' + ]); component.grokStatement = ''; component.patternLabel = 'PATTERN_LABEL'; @@ -142,24 +148,25 @@ describe('Component: SensorGrok', () => { })); it('should test grok statement validation', async(() => { - let parsedMessage = { - 'action': 'TCP_MISS', - 'bytes': 337891, - 'code': 200, - 'elapsed': 415, - 'ip_dst_addr': '207.109.73.154', - 'ip_src_addr': '127.0.0.1', - 'method': 'GET', - 'timestamp': '1467011157.401', - 'url': 'http://www.aliexpress.com/af/shoes.html?' + action: 'TCP_MISS', + bytes: 337891, + code: 200, + elapsed: 415, + ip_dst_addr: '207.109.73.154', + ip_src_addr: '127.0.0.1', + method: 'GET', + timestamp: '1467011157.401', + url: 'http://www.aliexpress.com/af/shoes.html?' }; sensorParserConfigService.setParsedMessage(parsedMessage); - let sampleData = '1467011157.401 415 127.0.0.1 TCP_MISS/200 337891 GET http://www.aliexpress.com/af/shoes.html? ' + + let sampleData = + '1467011157.401 415 127.0.0.1 TCP_MISS/200 337891 GET http://www.aliexpress.com/af/shoes.html? ' + '- DIRECT/207.109.73.154 text/html'; - let grokStatement = 'SQUID_DELIMITED %{NUMBER:timestamp} %{INT:elapsed} %{IPV4:ip_src_addr} %{WORD:action}/%{NUMBER:code} ' + - '%{NUMBER:bytes} %{WORD:method} %{NOTSPACE:url} - %{WORD:UNWANTED}\/%{IPV4:ip_dst_addr} %{WORD:UNWANTED}\/%{WORD:UNWANTED}'; + let grokStatement = + 'SQUID_DELIMITED %{NUMBER:timestamp} %{INT:elapsed} %{IPV4:ip_src_addr} %{WORD:action}/%{NUMBER:code} ' + + '%{NUMBER:bytes} %{WORD:method} %{NOTSPACE:url} - %{WORD:UNWANTED}/%{IPV4:ip_dst_addr} %{WORD:UNWANTED}/%{WORD:UNWANTED}'; component.sensorParserConfig = new SensorParserConfig(); component.sensorParserConfig.sensorTopic = 'squid'; @@ -171,8 +178,17 @@ describe('Component: SensorGrok', () => { component.onSampleDataChanged(sampleData); expect(component.parsedMessage).toEqual(parsedMessage); - expect(component.parsedMessageKeys).toEqual(['action', 'bytes', 'code', 'elapsed', 'ip_dst_addr', - 'ip_src_addr', 'method', 'timestamp', 'url']); + expect(component.parsedMessageKeys).toEqual([ + 'action', + 'bytes', + 'code', + 'elapsed', + 'ip_dst_addr', + 'ip_src_addr', + 'method', + 'timestamp', + 'url' + ]); sensorParserConfigService.setParsedMessage('ERROR'); component.onTestGrokStatement(); @@ -195,8 +211,12 @@ describe('Component: SensorGrok', () => { component.onSaveGrok(); - expect(component.onSaveGrokStatement.emit).toHaveBeenCalledWith('grok statement'); - expect(component.onSavePatternLabel.emit).toHaveBeenCalledWith('PATTERN_LABEL'); + expect(component.onSaveGrokStatement.emit).toHaveBeenCalledWith( + 'grok statement' + ); + expect(component.onSavePatternLabel.emit).toHaveBeenCalledWith( + 'PATTERN_LABEL' + ); expect(component.hideGrok.emit).toHaveBeenCalled(); fixture.destroy(); }); @@ -230,5 +250,4 @@ describe('Component: SensorGrok', () => { component.newPatternLabel = 'LABEL_2'; expect(component.isSaveDisabled()).toEqual(false); }); - }); http://git-wip-us.apache.org/repos/asf/metron/blob/0c4c622b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.ts b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.ts index a7d4c8c..f601f5f 100644 --- a/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-grok/sensor-grok.component.ts @@ -130,7 +130,7 @@ export class SensorGrokComponent implements OnInit, OnChanges { this.hideGrok.emit(); } - private getAvailablePatternLabels() { + getAvailablePatternLabels() { this.availablePatternLabels = []; let statements = this.newGrokStatement.split('\n'); for (let statement of statements) { http://git-wip-us.apache.org/repos/asf/metron/blob/0c4c622b/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.spec.ts b/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.spec.ts index 5afa953..d744481 100644 --- a/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.spec.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.spec.ts @@ -15,37 +15,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; -import {Observable} from 'rxjs/Observable'; -import {Router, ActivatedRoute, Params} from '@angular/router'; -import {Inject} from '@angular/core'; -import {SensorParserConfigHistory} from '../../model/sensor-parser-config-history'; -import {RequestOptions, Response, ResponseOptions, Http} from '@angular/http'; -import {SensorParserConfigReadonlyComponent} from './sensor-parser-config-readonly.component'; -import {SensorParserConfigService} from '../../service/sensor-parser-config.service'; -import {KafkaService} from '../../service/kafka.service'; -import {TopologyStatus} from '../../model/topology-status'; -import {SensorParserConfig} from '../../model/sensor-parser-config'; -import {KafkaTopic} from '../../model/kafka-topic'; -import {AuthenticationService} from '../../service/authentication.service'; -import {SensorParserConfigHistoryService} from '../../service/sensor-parser-config-history.service'; -import {StormService} from '../../service/storm.service'; -import {MetronAlerts} from '../../shared/metron-alerts'; -import {FieldTransformer} from '../../model/field-transformer'; -import {SensorParserConfigReadonlyModule} from './sensor-parser-config-readonly.module'; -import {APP_CONFIG, METRON_REST_CONFIG} from '../../app.config'; -import {IAppConfig} from '../../app.config.interface'; -import {SensorEnrichmentConfigService} from '../../service/sensor-enrichment-config.service'; -import {SensorEnrichmentConfig, EnrichmentConfig, ThreatIntelConfig} from '../../model/sensor-enrichment-config'; -import {HdfsService} from '../../service/hdfs.service'; -import {GrokValidationService} from '../../service/grok-validation.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { Router, ActivatedRoute, Params } from '@angular/router'; +import { Inject } from '@angular/core'; +import { SensorParserConfigHistory } from '../../model/sensor-parser-config-history'; +import { HttpClient } from '@angular/common/http'; +import { SensorParserConfigReadonlyComponent } from './sensor-parser-config-readonly.component'; +import { SensorParserConfigService } from '../../service/sensor-parser-config.service'; +import { KafkaService } from '../../service/kafka.service'; +import { TopologyStatus } from '../../model/topology-status'; +import { SensorParserConfig } from '../../model/sensor-parser-config'; +import { KafkaTopic } from '../../model/kafka-topic'; +import { AuthenticationService } from '../../service/authentication.service'; +import { SensorParserConfigHistoryService } from '../../service/sensor-parser-config-history.service'; +import { StormService } from '../../service/storm.service'; +import { MetronAlerts } from '../../shared/metron-alerts'; +import { FieldTransformer } from '../../model/field-transformer'; +import { SensorParserConfigReadonlyModule } from './sensor-parser-config-readonly.module'; +import { APP_CONFIG, METRON_REST_CONFIG } from '../../app.config'; +import { IAppConfig } from '../../app.config.interface'; +import { SensorEnrichmentConfigService } from '../../service/sensor-enrichment-config.service'; +import { + SensorEnrichmentConfig, + EnrichmentConfig, + ThreatIntelConfig +} from '../../model/sensor-enrichment-config'; +import { HdfsService } from '../../service/hdfs.service'; +import { GrokValidationService } from '../../service/grok-validation.service'; +import { RiskLevelRule } from '../../model/risk-level-rule'; class MockRouter { - - navigateByUrl(url: string) { - - } - + navigateByUrl(url: string) {} } class MockActivatedRoute { @@ -55,34 +56,37 @@ class MockActivatedRoute { setNameForTest(name: string) { this.name = name; this.params = Observable.create(observer => { - observer.next({id: this.name}); + observer.next({ id: this.name }); observer.complete(); }); } } class MockAuthenticationService extends AuthenticationService { - - constructor(private http2: Http, private router2: Router, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + private router2: Router, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, router2, config2); } - public getCurrentUser(options: RequestOptions): Observable<Response> { - let responseOptions: ResponseOptions = new ResponseOptions(); - responseOptions.body = 'user'; - let response: Response = new Response(responseOptions); + public getCurrentUser(options): Observable<{}> { + let response: { body: 'user' }; return Observable.create(observer => { observer.next(response); observer.complete(); }); - }; + } } class MockSensorParserConfigHistoryService extends SensorParserConfigHistoryService { - private sensorParserConfigHistory: SensorParserConfigHistory; - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } @@ -99,17 +103,21 @@ class MockSensorParserConfigHistoryService extends SensorParserConfigHistoryServ } class MockSensorParserConfigService extends SensorParserConfigService { - - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } - } class MockStormService extends StormService { private topologyStatus: TopologyStatus; - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } @@ -126,20 +134,24 @@ class MockStormService extends StormService { } class MockGrokValidationService extends GrokValidationService { - - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } public list(): Observable<string[]> { return Observable.create(observer => { observer.next({ - 'BASE10NUM': '(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+)))', - 'BASE16FLOAT': '\\b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]*)?)|(?:\\.[0-9A-Fa-f]+)))\\b', - 'BASE16NUM': '(?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))', - 'CISCOMAC': '(?:(?:[A-Fa-f0-9]{4}\\.){2}[A-Fa-f0-9]{4})', - 'COMMONMAC': '(?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})', - 'DATA': '.*?' + BASE10NUM: + '(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+)))', + BASE16FLOAT: + '\\b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]*)?)|(?:\\.[0-9A-Fa-f]+)))\\b', + BASE16NUM: '(?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))', + CISCOMAC: '(?:(?:[A-Fa-f0-9]{4}\\.){2}[A-Fa-f0-9]{4})', + COMMONMAC: '(?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})', + DATA: '.*?' }); observer.complete(); }); @@ -147,10 +159,12 @@ class MockGrokValidationService extends GrokValidationService { } class MockKafkaService extends KafkaService { - private kafkaTopic: KafkaTopic; - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } @@ -167,7 +181,7 @@ class MockKafkaService extends KafkaService { public sample(name: string): Observable<string> { return Observable.create(observer => { - observer.next(JSON.stringify({'data': 'data1', 'data2': 'data3'})); + observer.next(JSON.stringify({ data: 'data1', data2: 'data3' })); observer.complete(); }); } @@ -177,7 +191,10 @@ class MockHdfsService extends HdfsService { private fileList: string[]; private contents: string; - constructor(private http2: Http, @Inject(APP_CONFIG) private config2: IAppConfig) { + constructor( + private http2: HttpClient, + @Inject(APP_CONFIG) private config2: IAppConfig + ) { super(http2, config2); } @@ -205,14 +222,14 @@ class MockHdfsService extends HdfsService { }); } - public post(path: string, contents: string): Observable<Response> { + public post(path: string, contents: string): Observable<{}> { return Observable.create(observer => { observer.next({}); observer.complete(); }); } - public deleteFile(path: string): Observable<Response> { + public deleteFile(path: string): Observable<{}> { return Observable.create(observer => { observer.next({}); observer.complete(); @@ -235,7 +252,7 @@ class MockSensorEnrichmentConfigService { } public getAvailable(): Observable<string[]> { - return Observable.create((observer) => { + return Observable.create(observer => { observer.next(['geo', 'host', 'whois']); observer.complete(); }); @@ -243,7 +260,6 @@ class MockSensorEnrichmentConfigService { } describe('Component: SensorParserConfigReadonly', () => { - let component: SensorParserConfigReadonlyComponent; let fixture: ComponentFixture<SensorParserConfigReadonlyComponent>; let sensorParserConfigHistoryService: MockSensorParserConfigHistoryService; @@ -259,41 +275,46 @@ describe('Component: SensorParserConfigReadonly', () => { let activatedRoute: MockActivatedRoute; beforeEach(async(() => { - TestBed.configureTestingModule({ imports: [SensorParserConfigReadonlyModule], providers: [ - {provide: Http}, - {provide: ActivatedRoute, useClass: MockActivatedRoute}, - {provide: AuthenticationService, useClass: MockAuthenticationService}, - {provide: SensorEnrichmentConfigService, useClass: MockSensorEnrichmentConfigService}, - {provide: SensorParserConfigHistoryService, useClass: MockSensorParserConfigHistoryService}, - {provide: SensorParserConfigService, useClass: MockSensorParserConfigService}, - {provide: StormService, useClass: MockStormService}, - {provide: KafkaService, useClass: MockKafkaService}, - {provide: HdfsService, useClass: MockHdfsService}, - {provide: GrokValidationService, useClass: MockGrokValidationService}, - {provide: Router, useClass: MockRouter}, - {provide: APP_CONFIG, useValue: METRON_REST_CONFIG}, + { provide: HttpClient }, + { provide: ActivatedRoute, useClass: MockActivatedRoute }, + { + provide: SensorEnrichmentConfigService, + useClass: MockSensorEnrichmentConfigService + }, + { + provide: SensorParserConfigHistoryService, + useClass: MockSensorParserConfigHistoryService + }, + { + provide: SensorParserConfigService, + useClass: MockSensorParserConfigService + }, + { provide: StormService, useClass: MockStormService }, + { provide: KafkaService, useClass: MockKafkaService }, + { provide: HdfsService, useClass: MockHdfsService }, + { provide: GrokValidationService, useClass: MockGrokValidationService }, + { provide: Router, useClass: MockRouter }, + { provide: APP_CONFIG, useValue: METRON_REST_CONFIG }, MetronAlerts ] - }).compileComponents() - .then(() => { - fixture = TestBed.createComponent(SensorParserConfigReadonlyComponent); - component = fixture.componentInstance; - activatedRoute = fixture.debugElement.injector.get(ActivatedRoute); - hdfsService = fixture.debugElement.injector.get(HdfsService); - authenticationService = fixture.debugElement.injector.get(AuthenticationService); - sensorParserConfigHistoryService = fixture.debugElement.injector.get(SensorParserConfigHistoryService); - sensorEnrichmentConfigService = fixture.debugElement.injector.get(SensorEnrichmentConfigService); - sensorParserConfigService = fixture.debugElement.injector.get(SensorParserConfigService); - stormService = fixture.debugElement.injector.get(StormService); - kafkaService = fixture.debugElement.injector.get(KafkaService); - grokValidationService = fixture.debugElement.injector.get(GrokValidationService); - router = fixture.debugElement.injector.get(Router); - alerts = fixture.debugElement.injector.get(MetronAlerts); - }); - + }); + fixture = TestBed.createComponent(SensorParserConfigReadonlyComponent); + component = fixture.componentInstance; + activatedRoute = TestBed.get(ActivatedRoute); + hdfsService = TestBed.get(HdfsService); + sensorParserConfigHistoryService = TestBed.get( + SensorParserConfigHistoryService + ); + sensorEnrichmentConfigService = TestBed.get(SensorEnrichmentConfigService); + sensorParserConfigService = TestBed.get(SensorParserConfigService); + stormService = TestBed.get(StormService); + kafkaService = TestBed.get(KafkaService); + grokValidationService = TestBed.get(GrokValidationService); + router = TestBed.get(Router); + alerts = TestBed.get(MetronAlerts); })); it('should create an instance', async(() => { @@ -313,7 +334,9 @@ describe('Component: SensorParserConfigReadonly', () => { sensorParserConfig.sensorTopic = 'bro'; sensorParserConfig.parserClassName = 'org.apache.metron.parsers.GrokParser'; - sensorParserConfig.parserConfig = {grokPattern: 'SQUID_DELIMITED squid grok statement'}; + sensorParserConfig.parserConfig = { + grokPattern: 'SQUID_DELIMITED squid grok statement' + }; sensorParserInfo.config = sensorParserConfig; kafkaTopic.name = 'bro'; @@ -325,22 +348,30 @@ describe('Component: SensorParserConfigReadonly', () => { topologyStatus.throughput = 15.2; let broEnrichment = { - 'fieldMap': { - 'geo': ['ip_dst_addr'], - 'host': ['ip_dst_addr'], - 'whois': [], - 'stellar': {'config': {'group1': {}}} + fieldMap: { + geo: ['ip_dst_addr'], + host: ['ip_dst_addr'], + whois: [], + stellar: { config: { group1: {} } } }, - 'fieldToTypeMap': {}, 'config': {} + fieldToTypeMap: {}, + config: {} }; - let broThreatIntel = {'threatIntel': { - 'fieldMap': { 'hbaseThreatIntel': ['ip_dst_addr'] }, - 'fieldToTypeMap': { 'ip_dst_addr': ['malicious_ip'] } - } + let broThreatIntel = { + threatIntel: { + fieldMap: { hbaseThreatIntel: ['ip_dst_addr'] }, + fieldToTypeMap: { ip_dst_addr: ['malicious_ip'] } + } }; let broEnrichments = new SensorEnrichmentConfig(); - broEnrichments.enrichment = Object.assign(new EnrichmentConfig(), broEnrichment); - broEnrichments.threatIntel = Object.assign(new ThreatIntelConfig(), broThreatIntel); + broEnrichments.enrichment = Object.assign( + new EnrichmentConfig(), + broEnrichment + ); + broEnrichments.threatIntel = Object.assign( + new ThreatIntelConfig(), + broThreatIntel + ); sensorEnrichmentConfigService.setForTest(broEnrichments); sensorParserConfigHistoryService.setForTest(sensorParserInfo); @@ -351,7 +382,9 @@ describe('Component: SensorParserConfigReadonly', () => { component.ngOnInit(); expect(component.startStopInProgress).toEqual(false); - expect(component.sensorParserConfigHistory).toEqual(Object.assign(new SensorParserConfigHistory(), sensorParserInfo)); + expect(component.sensorParserConfigHistory).toEqual( + Object.assign(new SensorParserConfigHistory(), sensorParserInfo) + ); expect(component.kafkaTopic).toEqual(kafkaTopic); expect(component.sensorEnrichmentConfig).toEqual(broEnrichments); })); @@ -410,11 +443,14 @@ describe('Component: SensorParserConfigReadonly', () => { let fieldTransformer1 = new FieldTransformer(); let fieldTransformer2 = new FieldTransformer(); - fieldTransformer1.config = {'a': 'abc', 'x': 'xyz'}; + fieldTransformer1.config = { a: 'abc', x: 'xyz' }; fieldTransformer1.output = ['a', 'b', 'c']; - fieldTransformer2.config = {'x': 'klm', 'b': 'def'}; + fieldTransformer2.config = { x: 'klm', b: 'def' }; fieldTransformer2.output = ['a', 'b', 'c']; - sensorParserConfig.fieldTransformations = [fieldTransformer1, fieldTransformer2]; + sensorParserConfig.fieldTransformations = [ + fieldTransformer1, + fieldTransformer2 + ]; sensorParserInfo.config = sensorParserConfig; component.setTransformsConfigKeys(); @@ -431,7 +467,11 @@ describe('Component: SensorParserConfigReadonly', () => { expect(component.transformsConfigKeys.length).toEqual(3); expect(component.transformsConfigKeys).toEqual(['a', 'b', 'x']); - expect(component.transformsConfigMap).toEqual({'a': ['abc'], 'b': ['def'], 'x': ['xyz', 'klm']}); + expect(component.transformsConfigMap).toEqual({ + a: ['abc'], + b: ['def'], + x: ['xyz', 'klm'] + }); expect(transformsOutput).toEqual('a, b, c'); })); @@ -449,48 +489,70 @@ describe('Component: SensorParserConfigReadonly', () => { component.selectedSensorName = 'abc'; component.onEditSensor(); - expect(router.navigateByUrl).toHaveBeenCalledWith('/sensors(dialog:sensors-config/abc)'); + expect(router.navigateByUrl).toHaveBeenCalledWith( + '/sensors(dialog:sensors-config/abc)' + ); })); it('should set sensorEnrichmentConfig and aggregationConfigKeys to be initialised', async(() => { let threatIntel = { - 'fieldMap': { - 'hbaseThreatIntel': [ 'ip_dst_addr', 'ip_src_addr', 'action'] + fieldMap: { + hbaseThreatIntel: ['ip_dst_addr', 'ip_src_addr', 'action'] }, - 'fieldToTypeMap': { - 'ip_dst_addr': [ 'malicious_ip'], 'ip_src_addr': [ 'malicious_ip'], 'action': [ 'malicious_ip'] + fieldToTypeMap: { + ip_dst_addr: ['malicious_ip'], + ip_src_addr: ['malicious_ip'], + action: ['malicious_ip'] }, - 'config': {}, - 'triageConfig': { - 'riskLevelRules': [ + config: {}, + triageConfig: { + riskLevelRules: [ { - 'rule': 'IN_SUBNET(ip_dst_addr, \'192.168.0.0/24\')', - 'score': 3 + rule: "IN_SUBNET(ip_dst_addr, '192.168.0.0/24')", + score: 3, + name: 'test1', + comment: 'This is a comment' }, { - 'rule': 'user.type in [ \'admin\', \'power\' ] and asset.type == \'web\'', - 'score': 3 - }, + rule: "user.type in [ 'admin', 'power' ] and asset.type == 'web'", + score: 3, + name: 'test2', + comment: 'This is another comment' + } ], - 'aggregator': 'MAX', - 'aggregationConfig': {} + aggregator: 'MAX', + aggregationConfig: {} } }; - let expected = [{'rule': 'IN_SUBNET(ip_dst_addr, \'192.168.0.0/24\')', 'score': 3}, - {'rule': 'user.type in [ \'admin\', \'power\' ] and asset.type == \'web\'', 'score': 3}]; + let expected: RiskLevelRule[] = [ + { + rule: "IN_SUBNET(ip_dst_addr, '192.168.0.0/24')", + score: 3, + name: 'test1', + comment: 'This is a comment' + }, + { + rule: "user.type in [ 'admin', 'power' ] and asset.type == 'web'", + score: 3, + name: 'test2', + comment: 'This is another comment' + } + ]; let sensorEnrichmentConfig = new SensorEnrichmentConfig(); - sensorEnrichmentConfig.threatIntel = Object.assign(new ThreatIntelConfig(), threatIntel); + sensorEnrichmentConfig.threatIntel = Object.assign( + new ThreatIntelConfig(), + threatIntel + ); sensorEnrichmentConfigService.setForTest(sensorEnrichmentConfig); component.getEnrichmentData(); - expect(component.sensorEnrichmentConfig).toEqual(sensorEnrichmentConfig); expect(component.rules).toEqual(expected); })); - let setDataForSensorOperation = function () { + let setDataForSensorOperation = function() { let sensorParserInfo = new SensorParserConfigHistory(); let sensorParserConfig = new SensorParserConfig(); let kafkaTopic = new KafkaTopic(); @@ -498,7 +560,9 @@ describe('Component: SensorParserConfigReadonly', () => { sensorParserConfig.sensorTopic = 'bro'; sensorParserConfig.parserClassName = 'org.apache.metron.parsers.GrokParser'; - sensorParserConfig.parserConfig = {grokPattern: 'SQUID_DELIMITED squid grok statement'}; + sensorParserConfig.parserConfig = { + grokPattern: 'SQUID_DELIMITED squid grok statement' + }; sensorParserInfo.config = sensorParserConfig; kafkaTopic.name = 'bro'; @@ -510,22 +574,30 @@ describe('Component: SensorParserConfigReadonly', () => { topologyStatus.throughput = 15.2; let broEnrichment = { - 'fieldMap': { - 'geo': ['ip_dst_addr'], - 'host': ['ip_dst_addr'], - 'whois': [], - 'stellar': {'config': {'group1': {}}} + fieldMap: { + geo: ['ip_dst_addr'], + host: ['ip_dst_addr'], + whois: [], + stellar: { config: { group1: {} } } }, - 'fieldToTypeMap': {}, 'config': {} + fieldToTypeMap: {}, + config: {} }; - let broThreatIntel = {'threatIntel': { - 'fieldMap': { 'hbaseThreatIntel': ['ip_dst_addr'] }, - 'fieldToTypeMap': { 'ip_dst_addr': ['malicious_ip'] } - } + let broThreatIntel = { + threatIntel: { + fieldMap: { hbaseThreatIntel: ['ip_dst_addr'] }, + fieldToTypeMap: { ip_dst_addr: ['malicious_ip'] } + } }; let broEnrichments = new SensorEnrichmentConfig(); - broEnrichments.enrichment = Object.assign(new EnrichmentConfig(), broEnrichment); - broEnrichments.threatIntel = Object.assign(new ThreatIntelConfig(), broThreatIntel); + broEnrichments.enrichment = Object.assign( + new EnrichmentConfig(), + broEnrichment + ); + broEnrichments.threatIntel = Object.assign( + new ThreatIntelConfig(), + broThreatIntel + ); kafkaService.setForTest(kafkaTopic); stormService.setForTest(topologyStatus); @@ -534,10 +606,12 @@ describe('Component: SensorParserConfigReadonly', () => { }; it('onStartSensor should start sensor', async(() => { - spyOn(stormService, 'startParser').and.returnValue(Observable.create(observer => { - observer.next({}); - observer.complete(); - })); + spyOn(stormService, 'startParser').and.returnValue( + Observable.create(observer => { + observer.next({}); + observer.complete(); + }) + ); alerts.showSuccessMessage = jasmine.createSpy('showSuccessMessage'); setDataForSensorOperation(); @@ -547,14 +621,18 @@ describe('Component: SensorParserConfigReadonly', () => { component.onStartSensor(); expect(stormService.startParser).toHaveBeenCalledWith('abc'); - expect(alerts.showSuccessMessage).toHaveBeenCalledWith('Started sensor abc'); + expect(alerts.showSuccessMessage).toHaveBeenCalledWith( + 'Started sensor abc' + ); })); it('onStopSensor should stop the sensor', async(() => { - spyOn(stormService, 'stopParser').and.returnValue(Observable.create(observer => { - observer.next({}); - observer.complete(); - })); + spyOn(stormService, 'stopParser').and.returnValue( + Observable.create(observer => { + observer.next({}); + observer.complete(); + }) + ); alerts.showSuccessMessage = jasmine.createSpy('showSuccessMessage'); setDataForSensorOperation(); @@ -564,14 +642,18 @@ describe('Component: SensorParserConfigReadonly', () => { component.onStopSensor(); expect(stormService.stopParser).toHaveBeenCalledWith('abc'); - expect(alerts.showSuccessMessage).toHaveBeenCalledWith('Stopped sensor abc'); + expect(alerts.showSuccessMessage).toHaveBeenCalledWith( + 'Stopped sensor abc' + ); })); it('onEnableSensor should enable sensor', async(() => { - spyOn(stormService, 'activateParser').and.returnValue(Observable.create(observer => { - observer.next({}); - observer.complete(); - })); + spyOn(stormService, 'activateParser').and.returnValue( + Observable.create(observer => { + observer.next({}); + observer.complete(); + }) + ); alerts.showSuccessMessage = jasmine.createSpy('showSuccessMessage'); setDataForSensorOperation(); @@ -581,14 +663,18 @@ describe('Component: SensorParserConfigReadonly', () => { component.onEnableSensor(); expect(stormService.activateParser).toHaveBeenCalledWith('abc'); - expect(alerts.showSuccessMessage).toHaveBeenCalledWith('Enabled sensor abc'); + expect(alerts.showSuccessMessage).toHaveBeenCalledWith( + 'Enabled sensor abc' + ); })); it('onDisableSensor should disable the sensor', async(() => { - spyOn(stormService, 'deactivateParser').and.returnValue(Observable.create(observer => { - observer.next({}); - observer.complete(); - })); + spyOn(stormService, 'deactivateParser').and.returnValue( + Observable.create(observer => { + observer.next({}); + observer.complete(); + }) + ); alerts.showSuccessMessage = jasmine.createSpy('showSuccessMessage'); setDataForSensorOperation(); @@ -598,14 +684,21 @@ describe('Component: SensorParserConfigReadonly', () => { component.onDisableSensor(); expect(stormService.deactivateParser).toHaveBeenCalledWith('abc'); - expect(alerts.showSuccessMessage).toHaveBeenCalledWith('Disabled sensor abc'); + expect(alerts.showSuccessMessage).toHaveBeenCalledWith( + 'Disabled sensor abc' + ); })); it('onDeleteSensor should delete the sensor', async(() => { - spyOn(sensorParserConfigService, 'deleteSensorParserConfig').and.returnValue(Observable.create(observer => { - observer.next({}); - observer.complete(); - })); + spyOn( + sensorParserConfigService, + 'deleteSensorParserConfig' + ).and.returnValue( + Observable.create(observer => { + observer.next({}); + observer.complete(); + }) + ); alerts.showSuccessMessage = jasmine.createSpy('showSuccessMessage'); router.navigateByUrl = jasmine.createSpy('navigateByUrl'); @@ -615,8 +708,12 @@ describe('Component: SensorParserConfigReadonly', () => { component.onDeleteSensor(); - expect(sensorParserConfigService.deleteSensorParserConfig).toHaveBeenCalledWith('abc'); - expect(alerts.showSuccessMessage).toHaveBeenCalledWith('Deleted sensor abc'); + expect( + sensorParserConfigService.deleteSensorParserConfig + ).toHaveBeenCalledWith('abc'); + expect(alerts.showSuccessMessage).toHaveBeenCalledWith( + 'Deleted sensor abc' + ); expect(router.navigateByUrl).toHaveBeenCalledWith('/sensors'); })); @@ -705,5 +802,4 @@ describe('Component: SensorParserConfigReadonly', () => { component.topologyStatus.status = 'KILLED'; expect(component.isDisableHidden()).toEqual(true); })); - });