This is an automated email from the ASF dual-hosted git repository.
sardell pushed a commit to branch feature/METRON-1856-parser-aggregation
in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to
refs/heads/feature/METRON-1856-parser-aggregation by this push:
new 423eed6 METRON-2139 Refactoring sensor-parser-config.component and
wire NgRx (ruffle1986 via sardell) closes apache/metron#1494
423eed6 is described below
commit 423eed6d04f7c82ecf36717c5b19a65c0dffcae5
Author: ruffle1986 <[email protected]>
AuthorDate: Mon Aug 26 14:12:34 2019 +0200
METRON-2139 Refactoring sensor-parser-config.component and wire NgRx
(ruffle1986 via sardell) closes apache/metron#1494
---
.../sensor-parser-config-readonly.component.html | 2 +-
.../sensor-parser-config.component.html | 4 +-
.../sensor-parser-config.component.spec.ts | 219 +++++++++++----------
.../sensor-parser-config.component.ts | 70 ++++---
.../sensor-parser-latency.pipe.ts} | 15 +-
.../sensor-parser-throughput.pipe.ts} | 15 +-
.../src/app/sensors/sensors.module.ts | 4 +-
.../metron-config/src/tsconfig.spec.json | 1 +
8 files changed, 192 insertions(+), 138 deletions(-)
diff --git
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.html
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.html
index bd13c1c..d0c3caf 100644
---
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.html
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config-readonly/sensor-parser-config-readonly.component.html
@@ -44,7 +44,7 @@
<div *ngIf="item.model == 'kafkaTopic'" class="col-sm-6 px-0
float-left form-value">{{ kafkaTopic[item.value] ? kafkaTopic[item.value] : "-"
}}</div>
<div *ngIf="item.model == 'topologyStatus'" class="col-sm-6 px-0
float-left form-value">{{ getTopologyStatus(item.value) }}</div>
- <div *ngIf="item.model == 'grokStatement' &&
sensorParserConfigHistory.config.parserClassName ===
'org.apache.metron.parsers.GrokParser'" style="border: none">
+ <div *ngIf="item.model == 'grokStatement' &&
sensorParserConfig.parserClassName === 'org.apache.metron.parsers.GrokParser'"
style="border: none">
<div class="col-sm-12 form-sub-title">Grok Statement</div>
<div id="collapseGrok" class="col-sm-12 float-left form-value
panel-collapse collapse"></div>
<div class="col-sm-12 float-left form-value grok"
[innerHtml]="grokStatement"></div>
diff --git
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.html
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.html
index b4bdd92..bdb006f 100644
---
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.html
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.html
@@ -11,7 +11,7 @@
OR CONDITIONS OF ANY KIND, either express or implied. See the License
for
the specific language governing permissions and limitations under the
License.
-->
-<metron-config-metron-modal>
+<metron-config-metron-modal *ngIf="sensorParserConfig">
<metron-config-sensor-grok [hidden]="!showGrokValidator"
[showGrok]="showGrokValidator"
[grokStatement]="grokStatement"
[(patternLabel)]="patternLabel"
@@ -44,7 +44,7 @@
<div class="form-title">{{sensorName}} </div>
<i class="fa fa-times float-right main close-button"
aria-hidden="true" (click)="goBack()"></i>
- <form role="form" [formGroup]="sensorConfigForm">
+ <form *ngIf="sensorConfigForm" role="form"
[formGroup]="sensorConfigForm">
<div class="form-group">
<label attr.for="sensorName">NAME * </label>
<input type="text" class="form-control" name="sensorName"
formControlName="sensorName" [(ngModel)]="sensorName"
(ngModelChange)="onSetSensorName()" [readonly]="editMode">
diff --git
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.spec.ts
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.spec.ts
index ff1a812..bb6ed77 100644
---
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.spec.ts
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.spec.ts
@@ -16,7 +16,6 @@
* limitations under the License.
*/
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { Inject } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { HttpClient, HttpResponse } from '@angular/common/http';
@@ -31,7 +30,7 @@ import { KafkaService } from '../../service/kafka.service';
import { KafkaTopic } from '../../model/kafka-topic';
import { GrokValidationService } from '../../service/grok-validation.service';
import { MetronAlerts } from '../../shared/metron-alerts';
-import { SensorParserConfig } from '../../model/sensor-parser-config';
+import { ParserConfigModel } from '../../sensors/models/parser-config.model';
import { ParseMessageRequest } from '../../model/parse-message-request';
import { SensorParserContext } from '../../model/sensor-parser-context';
import { AuthenticationService } from '../../service/authentication.service';
@@ -45,8 +44,9 @@ import { of } from 'rxjs';
import { HdfsService } from '../../service/hdfs.service';
import { RestError } from '../../model/rest-error';
import { RiskLevelRule } from '../../model/risk-level-rule';
-import {AppConfigService} from '../../service/app-config.service';
-import {MockAppConfigService} from '../../service/mock.app-config.service';
+import { Store } from '@ngrx/store';
+import { AppConfigService } from '../../service/app-config.service';
+import { MockAppConfigService } from '../../service/mock.app-config.service';
class MockRouter {
navigateByUrl(url: string) {}
@@ -67,15 +67,15 @@ class MockActivatedRoute {
class MockSensorParserConfigService extends SensorParserConfigService {
private name: string;
- private sensorParserConfig: SensorParserConfig;
+ private sensorParserConfig: ParserConfigModel;
private parsedMessage: any;
- private postedSensorParserConfig: SensorParserConfig;
+ private postedSensorParserConfig: ParserConfigModel;
private throwError: boolean;
- public post(
+ public saveConfig(
name: string,
- sensorParserConfig: SensorParserConfig
- ): Observable<SensorParserConfig> {
+ sensorParserConfig: ParserConfigModel
+ ): Observable<ParserConfigModel> {
if (this.throwError) {
let error = new RestError();
error.message = 'SensorParserConfig post error';
@@ -88,14 +88,14 @@ class MockSensorParserConfigService extends
SensorParserConfigService {
});
}
- public get(name: string): Observable<SensorParserConfig> {
+ public getConfig(name: string): Observable<ParserConfigModel> {
return Observable.create(observer => {
observer.next(this.sensorParserConfig);
observer.complete();
});
}
- public getAll(): Observable<{}> {
+ public getAllConfig(): Observable<{}> {
return Observable.create(observer => {
let results = {};
results[this.name] = this.sensorParserConfig;
@@ -125,7 +125,7 @@ class MockSensorParserConfigService extends
SensorParserConfigService {
public setSensorParserConfig(
name: string,
- sensorParserConfig: SensorParserConfig
+ sensorParserConfig: ParserConfigModel
) {
this.name = name;
this.sensorParserConfig = sensorParserConfig;
@@ -450,71 +450,87 @@ describe('Component: SensorParserConfig', () => {
let activatedRoute: MockActivatedRoute;
let metronAlerts: MetronAlerts;
let router: MockRouter;
+ let squidSensorParserConfig;
+ let squidParserMetaInfo;
+ let squidSensorEnrichmentConfig;
+ let squidIndexingConfigurations;
+ let store: Store<any>;
- let squidSensorParserConfig: any = {
- parserClassName: 'org.apache.metron.parsers.GrokParser',
- sensorTopic: 'squid',
- parserConfig: {
- grokPath: '/apps/metron/patterns/squid',
- patternLabel: 'SQUID_DELIMITED',
- timestampField: 'timestamp'
- },
- fieldTransformations: [
- {
- input: [],
- output: ['full_hostname', 'domain_without_subdomains', 'hostname'],
- transformation: 'STELLAR',
- config: {
- full_hostname: 'URL_TO_HOST(url)',
- domain_without_subdomains: 'DOMAIN_REMOVE_SUBDOMAINS(full_hostname)'
+ beforeEach(async(() => {
+
+ squidSensorParserConfig = new ParserConfigModel('squid', {
+ parserClassName: 'org.apache.metron.parsers.GrokParser',
+ sensorTopic: 'squid',
+ parserConfig: {
+ grokPath: '/apps/metron/patterns/squid',
+ patternLabel: 'SQUID_DELIMITED',
+ timestampField: 'timestamp'
+ },
+ fieldTransformations: [
+ {
+ input: [],
+ output: ['full_hostname', 'domain_without_subdomains', 'hostname'],
+ transformation: 'STELLAR',
+ config: {
+ full_hostname: 'URL_TO_HOST(url)',
+ domain_without_subdomains:
'DOMAIN_REMOVE_SUBDOMAINS(full_hostname)'
+ }
}
- }
- ]
- };
-
- let squidSensorEnrichmentConfig = {
- enrichment: {
- fieldMap: {
- geo: ['ip_dst_addr'],
- host: ['ip_dst_addr'],
- whois: [],
- stellar: { config: { group1: {} } }
+ ]
+ });
+
+ squidParserMetaInfo = {
+ config: squidSensorParserConfig,
+ };
+
+ squidSensorEnrichmentConfig = {
+ enrichment: {
+ fieldMap: {
+ geo: ['ip_dst_addr'],
+ host: ['ip_dst_addr'],
+ whois: [],
+ stellar: { config: { group1: {} } }
+ },
+ fieldToTypeMap: {},
+ config: {}
},
- fieldToTypeMap: {},
- config: {}
- },
- threatIntel: {
threatIntel: {
- fieldMap: { hbaseThreatIntel: ['ip_dst_addr'] },
- fieldToTypeMap: { ip_dst_addr: ['malicious_ip'] }
+ threatIntel: {
+ fieldMap: { hbaseThreatIntel: ['ip_dst_addr'] },
+ fieldToTypeMap: { ip_dst_addr: ['malicious_ip'] }
+ }
}
- }
- };
-
- let squidIndexingConfigurations = {
- hdfs: {
- index: 'squid',
- batchSize: 5,
- enabled: true
- },
- elasticsearch: {
- index: 'squid',
- batchSize: 10,
- enabled: true
- },
- solr: {
- index: 'squid',
- batchSize: 1,
- enabled: false
- }
- };
+ };
+
+ squidIndexingConfigurations = {
+ hdfs: {
+ index: 'squid',
+ batchSize: 5,
+ enabled: true
+ },
+ elasticsearch: {
+ index: 'squid',
+ batchSize: 10,
+ enabled: true
+ },
+ solr: {
+ index: 'squid',
+ batchSize: 1,
+ enabled: false
+ }
+ };
- beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [SensorParserConfigModule],
providers: [
MetronAlerts,
{ provide: HttpClient },
+ { provide: Store, useValue: {
+ pipe: () => {
+ return of(squidParserMetaInfo);
+ },
+ dispatch: () => {}
+ } },
{
provide: SensorParserConfigService,
useClass: MockSensorParserConfigService
@@ -552,6 +568,7 @@ describe('Component: SensorParserConfig', () => {
activatedRoute = TestBed.get(ActivatedRoute);
metronAlerts = TestBed.get(MetronAlerts);
router = TestBed.get(Router);
+ store = TestBed.get(Store);
}));
afterEach(() => {
@@ -564,21 +581,17 @@ describe('Component: SensorParserConfig', () => {
it('should handle ngOnInit', async(() => {
spyOn(component, 'init');
- spyOn(component, 'createForms');
- spyOn(component, 'getAvailableParsers');
activatedRoute.setNameForTest('squid');
component.ngOnInit();
expect(component.init).toHaveBeenCalledWith('squid');
- expect(component.createForms).toHaveBeenCalled();
- expect(component.getAvailableParsers).toHaveBeenCalled();
}));
it('should createForms', async(() => {
component.sensorParserConfig = Object.assign(
- new SensorParserConfig(),
+ new ParserConfigModel('TestConfigId01'),
squidSensorParserConfig
);
component.createForms();
@@ -611,13 +624,10 @@ describe('Component: SensorParserConfig', () => {
);
component.init('new');
- let expectedSensorParserConfig = new SensorParserConfig();
- expectedSensorParserConfig.parserClassName =
- 'org.apache.metron.parsers.GrokParser';
+ let expectedSensorParserConfig = new ParserConfigModel('new');
+ expectedSensorParserConfig.parserClassName =
'org.apache.metron.parsers.GrokParser';
expect(component.sensorParserConfig).toEqual(expectedSensorParserConfig);
- expect(component.sensorEnrichmentConfig).toEqual(
- new SensorEnrichmentConfig()
- );
+ expect(component.sensorEnrichmentConfig).toEqual(new
SensorEnrichmentConfig());
expect(component.indexingConfigurations).toEqual(
new IndexingConfigurations()
);
@@ -625,10 +635,7 @@ describe('Component: SensorParserConfig', () => {
expect(component.currentSensors).toEqual(['squid']);
spyOn(component, 'getKafkaStatus');
- let sensorParserConfig = Object.assign(
- new SensorParserConfig(),
- squidSensorParserConfig
- );
+ let sensorParserConfig = squidSensorParserConfig.clone({ sensorTopic:
'squid' });
sensorParserConfigService.setSensorParserConfig(
'squid',
sensorParserConfig
@@ -647,9 +654,7 @@ describe('Component: SensorParserConfig', () => {
);
component.init('squid');
- expect(component.sensorParserConfig).toEqual(
- Object.assign(new SensorParserConfig(), squidSensorParserConfig)
- );
+ expect(component.sensorParserConfig).toEqual(squidSensorParserConfig);
expect(component.sensorNameValid).toEqual(true);
expect(component.getKafkaStatus).toHaveBeenCalled();
expect(component.showAdvancedParserConfiguration).toEqual(true);
@@ -662,13 +667,17 @@ describe('Component: SensorParserConfig', () => {
Object.assign(new IndexingConfigurations(), squidIndexingConfigurations)
);
- component.sensorParserConfig.parserConfig['grokPath'] = '/patterns/squid';
+ component.sensorParserConfig.parserConfig.grokPath = '/patterns/squid';
hdfsService.setContents('/patterns/squid', null);
grokValidationService.setContents(
'/patterns/squid',
'SQUID grok statement from classpath'
);
+ store.pipe = () => {
+ return of({ config: component.sensorParserConfig });
+ }
+
component.init('squid');
expect(component.grokStatement).toEqual(
'SQUID grok statement from classpath'
@@ -695,11 +704,15 @@ describe('Component: SensorParserConfig', () => {
'Could not find grok statement in HDFS or classpath at /patterns/squid'
);
- sensorParserConfig = new SensorParserConfig();
+ sensorParserConfig = new ParserConfigModel('bro');
sensorParserConfig.sensorTopic = 'bro';
sensorParserConfigService.setSensorParserConfig('bro', sensorParserConfig);
component.showAdvancedParserConfiguration = false;
+ store.pipe = () => {
+ return of({ config: sensorParserConfig });
+ }
+
component.init('bro');
expect(component.showAdvancedParserConfiguration).toEqual(false);
}));
@@ -714,6 +727,8 @@ describe('Component: SensorParserConfig', () => {
it('should handle onSetKafkaTopic', async(() => {
spyOn(component, 'getKafkaStatus');
+ component.init('new');
+
component.onSetKafkaTopic();
expect(component.getKafkaStatus).not.toHaveBeenCalled();
@@ -782,6 +797,8 @@ describe('Component: SensorParserConfig', () => {
it('should handle onParserTypeChange', async(() => {
spyOn(component, 'hidePane');
+ component.init('new');
+
component.onParserTypeChange();
expect(component.hidePane).not.toHaveBeenCalled();
@@ -816,8 +833,7 @@ describe('Component: SensorParserConfig', () => {
expect(component.isConfigValid()).toEqual(true);
- component.sensorParserConfig.parserClassName =
- 'org.apache.metron.parsers.GrokParser';
+ component.sensorParserConfig.parserClassName =
'org.apache.metron.parsers.GrokParser';
expect(component.isConfigValid()).toEqual(false);
component.grokStatement = 'grok statement';
@@ -825,6 +841,8 @@ describe('Component: SensorParserConfig', () => {
}));
it('should getKafkaStatus', async(() => {
+ component.init('bro');
+
component.getKafkaStatus();
expect(component.currentKafkaStatus).toEqual(null);
@@ -846,6 +864,10 @@ describe('Component: SensorParserConfig', () => {
}));
it('should getTransforms', async(() => {
+ component.init('bro');
+
+ component.sensorParserConfig.fieldTransformations = [];
+
expect(component.getTransforms()).toEqual('0 Transformations Applied');
component.sensorParserConfig.fieldTransformations.push(
@@ -859,6 +881,8 @@ describe('Component: SensorParserConfig', () => {
}));
it('should handle onSaveGrokStatement', async(() => {
+ component.init('bro');
+
component.sensorName = 'squid';
component.onSaveGrokStatement('grok statement');
@@ -881,6 +905,8 @@ describe('Component: SensorParserConfig', () => {
}));
it('should onSavePatternLabel', async(() => {
+ component.init('bro');
+
component.onSavePatternLabel('PATTERN_LABEL');
expect(component.patternLabel).toEqual('PATTERN_LABEL');
expect(component.sensorParserConfig.parserConfig['patternLabel']).toEqual(
@@ -897,13 +923,15 @@ describe('Component: SensorParserConfig', () => {
}));
it('should save sensor configuration', async(() => {
+ component.init('new');
+
let fieldTransformer = Object.assign(new FieldTransformer(), {
input: [],
output: ['url_host'],
transformation: 'MTL',
config: { url_host: 'TO_LOWER(URL_TO_HOST(url))' }
});
- let sensorParserConfigSave: SensorParserConfig = new SensorParserConfig();
+ let sensorParserConfigSave: ParserConfigModel = new
ParserConfigModel('whatever');
sensorParserConfigSave.sensorTopic = 'squid';
sensorParserConfigSave.parserClassName =
'org.apache.metron.parsers.GrokParser';
@@ -917,6 +945,7 @@ describe('Component: SensorParserConfig', () => {
spyOn(metronAlerts, 'showErrorMessage');
component.sensorParserConfig.sensorTopic = 'squid';
+ component.sensorName = 'whatever';
component.sensorParserConfig.parserClassName =
'org.apache.metron.parsers.GrokParser';
component.sensorParserConfig.parserConfig['grokPath'] =
@@ -982,6 +1011,8 @@ describe('Component: SensorParserConfig', () => {
}));
it('should getTransformationCount', async(() => {
+ component.init('new');
+
let transforms = [
Object.assign(new FieldTransformer(), {
input: ['method'],
@@ -1103,16 +1134,6 @@ describe('Component: SensorParserConfig', () => {
expect(component.patternLabel).toEqual('PATTERN_LABEL');
}));
- it('should handle onRawJsonChanged', async(() => {
- spyOn(component.sensorFieldSchema, 'createFieldSchemaRows');
-
- component.onRawJsonChanged();
-
- expect(
- component.sensorFieldSchema.createFieldSchemaRows
- ).toHaveBeenCalled();
- }));
-
it('should handle onAdvancedConfigFormClose', async(() => {
component.onAdvancedConfigFormClose();
diff --git
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.ts
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.ts
index bb59de5..ca3a451 100644
---
a/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.ts
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-config/sensor-parser-config.component.ts
@@ -17,7 +17,7 @@
*/
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup, Validators, FormControl } from '@angular/forms';
-import { SensorParserConfig } from '../../model/sensor-parser-config';
+import { ParserConfigModel } from '../models/parser-config.model';
import { SensorParserConfigService } from
'../../service/sensor-parser-config.service';
import { Router, ActivatedRoute } from '@angular/router';
import { MetronAlerts } from '../../shared/metron-alerts';
@@ -32,6 +32,12 @@ import { IndexingConfigurations } from
'../../model/sensor-indexing-config';
import { RestError } from '../../model/rest-error';
import { HdfsService } from '../../service/hdfs.service';
import { GrokValidationService } from '../../service/grok-validation.service';
+import { SensorState } from '../reducers';
+import { Store, select } from '@ngrx/store';
+import { ParserMetaInfoModel } from '../models/parser-meta-info.model';
+import { filter } from 'rxjs/operators';
+import * as fromReducers from '../reducers';
+import * as fromActions from '../actions';
export enum Pane {
GROK,
@@ -57,7 +63,7 @@ export class SensorParserConfigComponent implements OnInit {
transformsValidationForm: FormGroup;
sensorName: string = '';
- sensorParserConfig: SensorParserConfig = new SensorParserConfig();
+ sensorParserConfig: ParserConfigModel = new ParserConfigModel('');
sensorEnrichmentConfig: SensorEnrichmentConfig = new
SensorEnrichmentConfig();
indexingConfigurations: IndexingConfigurations = new
IndexingConfigurations();
@@ -109,26 +115,39 @@ export class SensorParserConfigComponent implements
OnInit {
private grokValidationService: GrokValidationService,
private router: Router,
private kafkaService: KafkaService,
- private hdfsService: HdfsService
- ) {
- this.sensorParserConfig.parserConfig = {};
+ private hdfsService: HdfsService,
+ private store: Store<SensorState>,
+ ) {}
+
+ ngOnInit() {
+ this.route.params.subscribe(params => {
+ const id = params['id'];
+ this.init(id);
+ });
}
init(id: string): void {
if (id !== 'new') {
this.editMode = true;
this.sensorName = id;
- this.sensorParserConfigService
- .get(id)
- .subscribe((results: SensorParserConfig) => {
- this.sensorParserConfig = results;
+ this.store.pipe(select(fromReducers.getParserConfig(), { id }))
+ .subscribe((parserConfig: ParserMetaInfoModel) => {
+
+ if (!parserConfig) {
+ return;
+ }
+
+ this.sensorParserConfig = (parserConfig.config as
ParserConfigModel).clone();
this.sensorNameValid = true;
this.getKafkaStatus();
+ this.createForms();
+ this.getAvailableParsers();
+
if (Object.keys(this.sensorParserConfig.parserConfig).length > 0) {
this.showAdvancedParserConfiguration = true;
}
if (this.isGrokParser(this.sensorParserConfig)) {
- let path = this.sensorParserConfig.parserConfig['grokPath'];
+ let path = this.sensorParserConfig.parserConfig.grokPath;
if (path) {
this.hdfsService.read(path).subscribe(
contents => {
@@ -180,24 +199,18 @@ export class SensorParserConfigComponent implements
OnInit {
}
);
} else {
- this.sensorParserConfig = new SensorParserConfig();
+ // in case of new parser config
+ this.sensorParserConfig = new ParserConfigModel(id || '');
this.sensorParserConfig.parserClassName =
'org.apache.metron.parsers.GrokParser';
- this.sensorParserConfigService.getAll().subscribe((results: {}) => {
+ this.sensorParserConfigService.getAllConfig().subscribe((results: {}) =>
{
this.currentSensors = Object.keys(results);
});
+ this.createForms();
+ this.getAvailableParsers();
}
}
- ngOnInit() {
- this.route.params.subscribe(params => {
- let id = params['id'];
- this.init(id);
- });
- this.createForms();
- this.getAvailableParsers();
- }
-
createSensorConfigForm(): FormGroup {
let group: any = {};
@@ -274,7 +287,7 @@ export class SensorParserConfigComponent implements OnInit {
createForms() {
this.sensorConfigForm = this.createSensorConfigForm();
this.transformsValidationForm = this.createTransformsValidationForm();
- if (Object.keys(this.sensorParserConfig.parserConfig).length > 0) {
+ if (Object.keys(this.sensorParserConfig &&
this.sensorParserConfig.parserConfig).length > 0) {
this.showAdvancedParserConfiguration = true;
}
}
@@ -398,6 +411,7 @@ export class SensorParserConfigComponent implements OnInit {
}
onSave() {
+
if (!this.indexingConfigurations.hdfs.index) {
this.indexingConfigurations.hdfs.index = this.sensorName;
}
@@ -407,8 +421,16 @@ export class SensorParserConfigComponent implements OnInit
{
if (!this.indexingConfigurations.solr.index) {
this.indexingConfigurations.solr.index = this.sensorName;
}
+
+ let sensorParserConfigToSave = this.sensorParserConfig.clone({ id:
this.sensorName });
+ if (this.editMode) {
+ this.store.dispatch(new
fromActions.UpdateParserConfig(sensorParserConfigToSave));
+ } else {
+ this.store.dispatch(new
fromActions.AddParserConfig(sensorParserConfigToSave));
+ }
+
this.sensorParserConfigService
- .post(this.sensorName, this.sensorParserConfig)
+ .saveConfig(this.sensorName, sensorParserConfigToSave)
.subscribe(
sensorParserConfig => {
if (this.isGrokParser(sensorParserConfig)) {
@@ -463,7 +485,7 @@ export class SensorParserConfigComponent implements OnInit {
);
}
- isGrokParser(sensorParserConfig: SensorParserConfig): boolean {
+ isGrokParser(sensorParserConfig: ParserConfigModel): boolean {
if (sensorParserConfig && sensorParserConfig.parserClassName) {
return (
sensorParserConfig.parserClassName ===
diff --git a/metron-interface/metron-config/src/app/sensors/effects/index.ts
b/metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-latency.pipe.ts
similarity index 68%
copy from metron-interface/metron-config/src/app/sensors/effects/index.ts
copy to
metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-latency.pipe.ts
index 8f6ad93..e54e3a3 100644
--- a/metron-interface/metron-config/src/app/sensors/effects/index.ts
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-latency.pipe.ts
@@ -15,9 +15,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { Pipe, PipeTransform } from '@angular/core';
+import { TopologyStatus } from '../../model/topology-status';
- import { SensorsEffects } from './sensors.effects';
-
- export * from './sensors.effects';
-
- export const effects = [ SensorsEffects ];
+@Pipe({ name: 'latency' })
+export class SensorParserLatencyPipe implements PipeTransform {
+ transform(status: TopologyStatus): string {
+ return status && status.status === 'ACTIVE' && status.throughput != null
+ ? (status.latency + 'ms')
+ : '-';
+ }
+}
diff --git a/metron-interface/metron-config/src/app/sensors/effects/index.ts
b/metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-throughput.pipe.ts
similarity index 66%
rename from metron-interface/metron-config/src/app/sensors/effects/index.ts
rename to
metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-throughput.pipe.ts
index 8f6ad93..b3f3cf0 100644
--- a/metron-interface/metron-config/src/app/sensors/effects/index.ts
+++
b/metron-interface/metron-config/src/app/sensors/sensor-parser-list/sensor-parser-throughput.pipe.ts
@@ -15,9 +15,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { Pipe, PipeTransform } from '@angular/core';
+import { TopologyStatus } from '../../model/topology-status';
- import { SensorsEffects } from './sensors.effects';
-
- export * from './sensors.effects';
-
- export const effects = [ SensorsEffects ];
+@Pipe({ name: 'throughput' })
+export class SensorParserThroughputPipe implements PipeTransform {
+ transform(status: TopologyStatus): string {
+ return status && status.status === 'ACTIVE' && status.throughput != null
+ ? (Math.round(status.throughput * 100) / 100) + 'kb/s'
+ : '-';
+ }
+}
diff --git a/metron-interface/metron-config/src/app/sensors/sensors.module.ts
b/metron-interface/metron-config/src/app/sensors/sensors.module.ts
index 929c0b5..964d350 100644
--- a/metron-interface/metron-config/src/app/sensors/sensors.module.ts
+++ b/metron-interface/metron-config/src/app/sensors/sensors.module.ts
@@ -31,7 +31,7 @@ import { SensorParserConfigService } from
'../service/sensor-parser-config.servi
import { KafkaService } from '../service/kafka.service';
import { StormService } from '../service/storm.service';
import { EffectsModule } from '@ngrx/effects';
-import { effects } from './effects';
+import { SensorsEffects } from './effects/sensors.effects';
import { StoreModule } from '@ngrx/store';
import { reducers } from './reducers';
@@ -41,7 +41,7 @@ import { reducers } from './reducers';
SensorParserConfigReadonlyModule,
SensorParserConfigModule,
SensorParserAggregateSidebarModule,
- EffectsModule.forFeature(effects),
+ EffectsModule.forFeature([SensorsEffects]),
StoreModule.forFeature('sensors', reducers),
],
declarations: [],
diff --git a/metron-interface/metron-config/src/tsconfig.spec.json
b/metron-interface/metron-config/src/tsconfig.spec.json
index eb43ad2..5112ba4 100644
--- a/metron-interface/metron-config/src/tsconfig.spec.json
+++ b/metron-interface/metron-config/src/tsconfig.spec.json
@@ -4,6 +4,7 @@
"outDir": "../out-tsc/spec",
"module": "commonjs",
"target": "es5",
+ "sourceMap": true,
"baseUrl": "",
"types": [
"jquery",