Fix producers and jobs don't appear on interface 92/5692/1
authorychacon <yennifer.chacon@est.tech>
Tue, 23 Feb 2021 08:58:39 +0000 (09:58 +0100)
committerychacon <yennifer.chacon@est.tech>
Thu, 25 Feb 2021 08:04:13 +0000 (09:04 +0100)
Issue-ID: NONRTRIC-450
Signed-off-by: ychacon <yennifer.chacon@est.tech>
Change-Id: I11702dd311f562206ed5762404cf8192332764f3

webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.spec.ts
webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts
webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts
webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.spec.ts
webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts
webapp-frontend/src/app/interfaces/ei.types.ts
webapp-frontend/src/app/mock/ei-producer-status1.json
webapp-frontend/src/app/mock/ei-producer-status2.json
webapp-frontend/src/app/services/ei/ei.service.spec.ts

index 9a47b4b..d516b14 100644 (file)
@@ -27,6 +27,7 @@ import { MatInputHarness } from '@angular/material/input/testing'
 import { MatTableModule } from '@angular/material/table';
 import { MatTableHarness } from '@angular/material/table/testing';
 import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
+import { of } from 'rxjs';
 
 import { EICoordinatorComponent } from './ei-coordinator.component';
 import { EIJobDataSource } from './ei-job.datasource';
@@ -66,8 +67,11 @@ describe('EICoordinatorComponent', () => {
   } as EIJob;
 
   beforeEach(async () => {
-    producerDataSourceSpy = jasmine.createSpyObj('EIProducerDataSource', [ 'loadProducers', 'eiProducers' ]);
-    jobDataSourceSpy = jasmine.createSpyObj('EIJobDataSource', [ 'loadJobs', 'eiJobs' ]);
+    producerDataSourceSpy = jasmine.createSpyObj('EIProducerDataSource', [ 'loadProducers', 'eiProducers', 'eiProducersSubject' ]);
+    jobDataSourceSpy = jasmine.createSpyObj('EIJobDataSource', [ 'loadJobs', 'eiJobs', 'eiJobsSubject' ]);
+    
+    producerDataSourceSpy.eiProducersSubject.and.returnValue(of({ producers: [producer1, producer2] }));
+    jobDataSourceSpy.eiJobsSubject.and.returnValue(of({ jobs: [job1, job2] }));
 
     await TestBed.configureTestingModule({
       imports: [
@@ -102,7 +106,7 @@ describe('EICoordinatorComponent', () => {
   });
 
   describe('#content', () => {
-    it('should contain refresh button with coorect icon', () => {
+    it('should contain refresh button with correct icon', () => {
       const button = fixture.debugElement.nativeElement.querySelector('#refreshButton');
       expect(button).toBeTruthy();
       expect(button.innerHTML).toContain('refresh');
@@ -139,7 +143,7 @@ describe('EICoordinatorComponent', () => {
     const expectedProducer1Row = { id: 'producer1', types: 'type1,type2', status: 'ENABLED' };
     beforeEach(() => {
       const producers: EIProducer[] =[ producer1, producer2 ];
-      producerDataSourceSpy.eiProducers.and.returnValue(producers);
+      producerDataSourceSpy.eiProducersSubject.and.returnValue(of(producers));
     });
 
     it('should contain data after initialization', async () => {
@@ -164,7 +168,7 @@ describe('EICoordinatorComponent', () => {
           ei_producer_id: 'producer1'
         } as EIProducer;
         const producers: EIProducer[] =[ producerMissingProperties ];
-        producerDataSourceSpy.eiProducers.and.returnValue(producers);
+        producerDataSourceSpy.eiProducersSubject.and.returnValue(of(producers));
         component.ngOnInit();
 
         const expectedProducerRow = { id: 'producer1', types: '< No types >', status: '< No status >' };
@@ -179,7 +183,7 @@ describe('EICoordinatorComponent', () => {
           target_uri: 'http://one'
         } as EIJob;
         const jobs: EIJob[] =[ jobMissingProperties ];
-        jobDataSourceSpy.eiJobs.and.returnValue(jobs);
+        jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs));
         component.ngOnInit();
 
         const expectedJobRow = { id: 'job1', typeId: '< No type >', owner: '< No owner >', targetUri: 'http://one' };
@@ -222,7 +226,7 @@ describe('EICoordinatorComponent', () => {
     const expectedJob1Row = { id: 'job1', typeId: 'type1', owner: 'owner1', targetUri: 'http://one' };
     beforeEach(() => {
       const jobs: EIJob[] =[ job1, job2 ];
-      jobDataSourceSpy.eiJobs.and.returnValue(jobs);
+      jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs));
     });
 
     it('should contain data after initialization', async () => {
index 5e5b363..9698f55 100644 (file)
 import { Component, OnInit } from '@angular/core';
 import { Sort } from '@angular/material/sort';
 import { FormBuilder, FormGroup, AbstractControl } from '@angular/forms';
-import { MatTableDataSource, MatTable } from '@angular/material/table';
+import { MatTableDataSource } from '@angular/material/table';
 
 import { EIJob, EIProducer } from '../interfaces/ei.types';
 import { EIJobDataSource } from './ei-job.datasource';
 import { EIProducerDataSource } from './ei-producer.datasource';
 import { UiService } from '../services/ui/ui.service';
+import { Observable } from 'rxjs/Observable';
 
 @Component({
     selector: 'nrcp-ei-coordinator',
@@ -37,8 +38,8 @@ export class EICoordinatorComponent implements OnInit {
     darkMode: boolean;
     searchString: string;
     formGroup: FormGroup;
-    jobsDataSource: MatTableDataSource<EIJob>;
-    producersDataSource: MatTableDataSource<EIProducer>;
+    jobsDataSource: MatTableDataSource<EIJob> = new MatTableDataSource<EIJob>();
+    producersDataSource: MatTableDataSource<EIProducer>= new MatTableDataSource<EIProducer>();
 
     readonly jobsFormControl: AbstractControl;
     readonly producersFormControl: AbstractControl;
@@ -66,9 +67,13 @@ export class EICoordinatorComponent implements OnInit {
     ngOnInit() {
         this.eiJobsDataSource.loadJobs();
         this.eiProducersDataSource.loadProducers();
-        this.jobsDataSource = new MatTableDataSource(this.eiJobsDataSource.eiJobs());
-        const prods = this.eiProducersDataSource.eiProducers();
-        this.producersDataSource = new MatTableDataSource(prods);
+
+        this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
+            this.jobsDataSource.data = data;
+        });
+        this.eiProducersDataSource.eiProducersSubject().subscribe((data) => {
+            this.producersDataSource.data = data;
+        });
 
         this.jobsFormControl.valueChanges.subscribe(value => {
             const filter = {...value, id: value.id.trim().toLowerCase()} as string;
@@ -98,7 +103,6 @@ export class EICoordinatorComponent implements OnInit {
     }
 
     sortJobs(sort: Sort){
-        console.log('Jobs new sort: ', sort);
         const data = this.jobsDataSource.data
         data.sort((a: EIJob, b: EIJob) => {
             const isAsc = sort.direction === 'asc';
@@ -169,8 +173,13 @@ export class EICoordinatorComponent implements OnInit {
 
     refreshTables() {
         this.eiJobsDataSource.loadJobs();
-        this.jobsDataSource.data = this.eiJobsDataSource.eiJobs();
         this.eiProducersDataSource.loadProducers();
-        this.producersDataSource.data = this.eiProducersDataSource.eiProducers();
+        
+        this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
+            this.jobsDataSource.data = data;
+        });
+        this.eiProducersDataSource.eiProducersSubject().subscribe((data) => {
+            this.producersDataSource.data = data;
+        });
     }
 }
index bf3c867..ac4109d 100644 (file)
 import { Injectable } from '@angular/core';
 
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { mergeMap, finalize } from 'rxjs/operators';
+import { Observable, forkJoin } from 'rxjs';
 
 import { EIJob } from '../interfaces/ei.types';
 import { EIService } from '../services/ei/ei.service';
 
+
 @Injectable({
     providedIn: 'root'
 })
@@ -37,7 +40,12 @@ export class EIJobDataSource {
         return this.jobs;
     }
 
+    public eiJobsSubject(): Observable<EIJob[]> {
+        return this.jobsSubject.asObservable() as Observable<EIJob[]>;
+    }
+
     private loadingSubject = new BehaviorSubject<boolean>(false);
+    private jobsSubject = new BehaviorSubject<EIJob[]>([]);
 
     public loading$ = this.loadingSubject.asObservable();
 
@@ -50,20 +58,17 @@ export class EIJobDataSource {
     loadJobs() {
         this.loadingSubject.next(true);
         this.jobs = [];
-        this.eiSvc.getProducerIds()
-            .subscribe((producerIds: string[]) => {
-                producerIds.forEach(id => {
-                    this.getJobsForProducer(id);
-                });
-            });
+        this.eiSvc.getProducerIds().pipe(
+            mergeMap(prodIds => 
+                forkJoin(prodIds.map(id => this.eiSvc.getJobsForProducer(id)))),
+            mergeMap(result => result),
+            finalize(() => this.loadingSubject.next(false))
+        ).subscribe(result => {
+            this.jobs = this.jobs.concat(result);
+            this.jobsSubject.next(this.jobs);
+        } );       
         this.rowCount = this.jobs.length;
     }
 
-    private getJobsForProducer(id: string) {
-        console.log('Getting jobs for producer ID: ', id);
-        this.eiSvc.getJobsForProducer(id)
-        .subscribe(producerJobs => {
-            this.jobs = this.jobs.concat(producerJobs);
-        });
-    }
 }
index 0a8f820..c519b12 100644 (file)
@@ -36,10 +36,10 @@ describe('EIProducerDataSource', () => {
         supported_ei_types: [ 'type3', 'type4' ]
     } as ProducerRegistrationInfo;
     let producerStatus1 = {
-        opState: OperationalState.ENABLED
+        operational_state: OperationalState.ENABLED
     } as ProducerStatus;
     let producerStatus2 = {
-        opState: OperationalState.DISABLED
+        operational_state: OperationalState.DISABLED
     } as ProducerStatus;
 
     let expectedProducer1 = {
index 8dac859..439352d 100644 (file)
@@ -21,6 +21,8 @@
 import { Injectable } from '@angular/core';
 
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { mergeMap, finalize } from 'rxjs/operators';
+import { Observable, forkJoin, of } from 'rxjs';
 
 import { EIProducer } from '../interfaces/ei.types';
 import { EIService } from '../services/ei/ei.service';
@@ -37,7 +39,12 @@ export class EIProducerDataSource {
         return this.producers;
     }
 
+    public eiProducersSubject(): Observable<EIProducer[]> {
+        return this.producersSubject.asObservable() as Observable<EIProducer[]>;
+    }
+
     private loadingSubject = new BehaviorSubject<boolean>(false);
+    private producersSubject = new BehaviorSubject<EIProducer[]>([]);
 
     public loading$ = this.loadingSubject.asObservable();
 
@@ -50,21 +57,28 @@ export class EIProducerDataSource {
     loadProducers() {
         this.loadingSubject.next(true);
         this.producers = [];
-        this.eiSvc.getProducerIds()
-            .subscribe((prodIds: string[]) => {
-                console.log("ProducerIds: " + prodIds);
-                prodIds.forEach(id => {
-                    let eiProducer = <EIProducer>{};
-                    eiProducer.ei_producer_id = id;
-                    this.eiSvc.getProducer(id).subscribe(producer => {
-                        eiProducer.ei_producer_types = producer.supported_ei_types;
-                    });
-                    this.eiSvc.getProducerStatus(id).subscribe(prodStatus => {
-                        eiProducer.status = prodStatus.opState.toString();
-                    });
-                    this.producers.push(eiProducer);
-                });
-                this.rowCount = this.producers.length;
+
+        this.eiSvc.getProducerIds().pipe(
+            mergeMap(prodIds => 
+                forkJoin(prodIds.map(id => {
+                    return forkJoin([
+                        of(id),
+                        this.eiSvc.getProducer(id),
+                        this.eiSvc.getProducerStatus(id)
+                    ])
+                })
+            )),
+            finalize(() => this.loadingSubject.next(false))
+        ).subscribe(result => {
+            this.producers = result.map(producer => {
+                let eiProducer = <EIProducer>{};
+                eiProducer.ei_producer_id = producer[0];
+                eiProducer.ei_producer_types = producer[1].supported_ei_types;
+                eiProducer.status = producer[2].operational_state.toString();
+                return eiProducer;
             });
+            this.producersSubject.next(this.producers);
+        });
+        this.rowCount = this.producers.length;
     }
 }
\ No newline at end of file
index 1aecebc..24f678c 100644 (file)
@@ -43,5 +43,5 @@ export enum OperationalState {
   DISABLED = 'DISABLED'
 }
 export interface ProducerStatus {
-  opState: OperationalState
+  operational_state: OperationalState
 }
\ No newline at end of file
index 9977a3e..a487293 100644 (file)
@@ -1,3 +1,3 @@
 {
-  "opState": "ENABLED"
+  "operational_state": "ENABLED"
 }
\ No newline at end of file
index 721cddb..20f096a 100644 (file)
@@ -1,3 +1,3 @@
 {
-  "opState": "DISABLED"
+  "operational_state": "DISABLED"
 }
\ No newline at end of file
index 6ced48c..7b5ece5 100644 (file)
@@ -126,7 +126,7 @@ describe('EIService', () => {
       service = TestBed.inject(EIService);
       httpTestingController = TestBed.inject(HttpTestingController);
       expectedProducerStatus = {
-        opState: OperationalState.ENABLED
+        operational_state: OperationalState.ENABLED
       } as ProducerStatus;
     });