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 <ftamas.m...@gmail.com>
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",

Reply via email to