From 923a26d056fd5b613aa1342fff7d7f0f74d9267e Mon Sep 17 00:00:00 2001 From: ychacon Date: Tue, 23 Feb 2021 09:58:39 +0100 Subject: [PATCH] Fix producers and jobs don't appear on interface Issue-ID: NONRTRIC-450 Signed-off-by: ychacon Change-Id: I11702dd311f562206ed5762404cf8192332764f3 --- .../ei-coordinator.component.spec.ts | 18 +++++---- .../app/ei-coordinator/ei-coordinator.component.ts | 27 ++++++++----- .../src/app/ei-coordinator/ei-job.datasource.ts | 31 ++++++++------- .../ei-coordinator/ei-producer.datasource.spec.ts | 4 +- .../app/ei-coordinator/ei-producer.datasource.ts | 44 ++++++++++++++-------- webapp-frontend/src/app/interfaces/ei.types.ts | 2 +- .../src/app/mock/ei-producer-status1.json | 2 +- .../src/app/mock/ei-producer-status2.json | 2 +- .../src/app/services/ei/ei.service.spec.ts | 2 +- 9 files changed, 82 insertions(+), 50 deletions(-) diff --git a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.spec.ts b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.spec.ts index 9a47b4b..d516b14 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.spec.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.spec.ts @@ -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 () => { diff --git a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts index 5e5b363..9698f55 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts @@ -20,12 +20,13 @@ 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; - producersDataSource: MatTableDataSource; + jobsDataSource: MatTableDataSource = new MatTableDataSource(); + producersDataSource: MatTableDataSource= new MatTableDataSource(); 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; + }); } } diff --git a/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts b/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts index bf3c867..ac4109d 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts @@ -21,10 +21,13 @@ 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 { + return this.jobsSubject.asObservable() as Observable; + } + private loadingSubject = new BehaviorSubject(false); + private jobsSubject = new BehaviorSubject([]); 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); - }); - } + } diff --git a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.spec.ts b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.spec.ts index 0a8f820..c519b12 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.spec.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.spec.ts @@ -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 = { diff --git a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts index 8dac859..439352d 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts @@ -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 { + return this.producersSubject.asObservable() as Observable; + } + private loadingSubject = new BehaviorSubject(false); + private producersSubject = new BehaviorSubject([]); 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.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.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 diff --git a/webapp-frontend/src/app/interfaces/ei.types.ts b/webapp-frontend/src/app/interfaces/ei.types.ts index 1aecebc..24f678c 100644 --- a/webapp-frontend/src/app/interfaces/ei.types.ts +++ b/webapp-frontend/src/app/interfaces/ei.types.ts @@ -43,5 +43,5 @@ export enum OperationalState { DISABLED = 'DISABLED' } export interface ProducerStatus { - opState: OperationalState + operational_state: OperationalState } \ No newline at end of file diff --git a/webapp-frontend/src/app/mock/ei-producer-status1.json b/webapp-frontend/src/app/mock/ei-producer-status1.json index 9977a3e..a487293 100644 --- a/webapp-frontend/src/app/mock/ei-producer-status1.json +++ b/webapp-frontend/src/app/mock/ei-producer-status1.json @@ -1,3 +1,3 @@ { - "opState": "ENABLED" + "operational_state": "ENABLED" } \ No newline at end of file diff --git a/webapp-frontend/src/app/mock/ei-producer-status2.json b/webapp-frontend/src/app/mock/ei-producer-status2.json index 721cddb..20f096a 100644 --- a/webapp-frontend/src/app/mock/ei-producer-status2.json +++ b/webapp-frontend/src/app/mock/ei-producer-status2.json @@ -1,3 +1,3 @@ { - "opState": "DISABLED" + "operational_state": "DISABLED" } \ No newline at end of file diff --git a/webapp-frontend/src/app/services/ei/ei.service.spec.ts b/webapp-frontend/src/app/services/ei/ei.service.spec.ts index 6ced48c..7b5ece5 100644 --- a/webapp-frontend/src/app/services/ei/ei.service.spec.ts +++ b/webapp-frontend/src/app/services/ei/ei.service.spec.ts @@ -126,7 +126,7 @@ describe('EIService', () => { service = TestBed.inject(EIService); httpTestingController = TestBed.inject(HttpTestingController); expectedProducerStatus = { - opState: OperationalState.ENABLED + operational_state: OperationalState.ENABLED } as ProducerStatus; }); -- 2.16.6