Consumer service 39/6539/1 dawn
authorecaiyanlinux <martin.c.yan@est.tech>
Fri, 18 Jun 2021 08:41:57 +0000 (10:41 +0200)
committerecaiyanlinux <martin.c.yan@est.tech>
Thu, 29 Jul 2021 13:51:33 +0000 (15:51 +0200)
 - List jobs without producer

cherry-pick this commit from master branch

Issue-ID: NONRTRIC-537
Signed-off-by: ychacon <yennifer.chacon@est.tech>
Change-Id: Ib38f5b12472f956243ccec6fff8fad4250247f98
Signed-off-by: ecaiyanlinux <martin.c.yan@est.tech>
23 files changed:
docker-compose/nonrtric-gateway/config/application-nonrtricgateway.yaml
webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.html
webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.spec.ts
webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.ts
webapp-frontend/src/app/interceptor.mock.ts
webapp-frontend/src/app/interfaces/consumer.types.ts [new file with mode: 0644]
webapp-frontend/src/app/interfaces/producer.types.ts
webapp-frontend/src/app/mock/info-job1.json [new file with mode: 0644]
webapp-frontend/src/app/mock/info-job2.json [new file with mode: 0644]
webapp-frontend/src/app/mock/info-job3.json [new file with mode: 0644]
webapp-frontend/src/app/mock/job1-status.json [new file with mode: 0644]
webapp-frontend/src/app/mock/job2-status.json [new file with mode: 0644]
webapp-frontend/src/app/mock/job3-status.json [new file with mode: 0644]
webapp-frontend/src/app/mock/jobids.json [new file with mode: 0644]
webapp-frontend/src/app/mock/jobs-producer1.json [deleted file]
webapp-frontend/src/app/mock/jobs-producer2.json [deleted file]
webapp-frontend/src/app/mock/producer-status3.json [new file with mode: 0644]
webapp-frontend/src/app/mock/producer3.json [new file with mode: 0644]
webapp-frontend/src/app/mock/producerids.json
webapp-frontend/src/app/services/ei/consumer.service.spec.ts [new file with mode: 0644]
webapp-frontend/src/app/services/ei/consumer.service.ts [new file with mode: 0644]
webapp-frontend/src/app/services/ei/producer.service.spec.ts
webapp-frontend/src/app/services/ei/producer.service.ts

index fb8c106..cee5398 100644 (file)
@@ -27,11 +27,11 @@ spring:
         wiretap: true
       routes:
       - id: A1-Policy
-        uri: https://localhost:8433
+        uri: https://policy-agent:8433
         predicates:
         - Path=/a1-policy/**
       - id: A1-EI
-        uri: https://localhost:8434
+        uri: https://ecs:8434
         predicates:
         - Path=/data-producer/**,/data-consumer/**
 management:
index aca0931..d2d8bf9 100644 (file)
@@ -38,18 +38,18 @@ limitations under the License.
             </mat-header-cell>
             <mat-cell *matCellDef="let job"> {{job.jobId}} </mat-cell>
         </ng-container>
-        <ng-container matColumnDef="prodId">
+        <ng-container matColumnDef="prodIds">
             <mat-header-cell *matHeaderCellDef mat-sort-header>
                 <div (click)="stopSort($event)">
                     <form style="display: flex" [formGroup]="jobForm">
                         <mat-form-field>
-                            <input id="jobProdIdFilter" matInput formControlName="prodId">
-                            <mat-placeholder>Producer ID</mat-placeholder>
+                            <input id="jobProdIdFilter" matInput formControlName="prodIds">
+                            <mat-placeholder>Producers</mat-placeholder>
                         </mat-form-field>
                     </form>
                 </div>
             </mat-header-cell>
-            <mat-cell *matCellDef="let job"> {{job.prodId}} </mat-cell>
+            <mat-cell *matCellDef="let job"> {{job.prodIds}} </mat-cell>
         </ng-container>
         <ng-container matColumnDef="typeId">
             <mat-header-cell *matHeaderCellDef mat-sort-header>
@@ -90,8 +90,8 @@ limitations under the License.
             </mat-header-cell>
             <mat-cell *matCellDef="let job"> {{job.targetUri}} </mat-cell>
         </ng-container>
-        <mat-header-row *matHeaderRowDef="['jobId', 'prodId', 'typeId', 'owner', 'targetUri']"></mat-header-row>
-        <mat-row *matRowDef="let row; columns: ['jobId', 'prodId', 'typeId', 'owner', 'targetUri'];"></mat-row>
+        <mat-header-row *matHeaderRowDef="['jobId', 'prodIds', 'typeId', 'owner', 'targetUri']"></mat-header-row>
+        <mat-row *matRowDef="let row; columns: ['jobId', 'prodIds', 'typeId', 'owner', 'targetUri'];"></mat-row>
     </mat-table>
     <mat-paginator [length]="jobs()?.length" [pageSize]="10" [pageSizeOptions]="[5, 10, 25, 100]" showFirstLastButtons
         class="ei-coordinator-table mat-elevation-z8"></mat-paginator>
index f5021df..6e815af 100644 (file)
@@ -41,56 +41,41 @@ import { MatTableModule } from "@angular/material/table";
 import { MatTableHarness } from "@angular/material/table/testing";
 import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
 import { of } from "rxjs/observable/of";
-import { JobInfo } from "@interfaces/producer.types";
-import { ProducerService } from "@services/ei/producer.service";
+import { ConsumerStatus, JobInfo } from "@interfaces/consumer.types";
 import { UiService } from "@services/ui/ui.service";
 
 import { Job, JobsListComponent } from "./jobs-list.component";
 import { Subscription } from "rxjs";
+import { ConsumerService } from "@services/ei/consumer.service";
 
 let component: JobsListComponent;
 let fixture: ComponentFixture<JobsListComponent>;
 
 const jobInfo1 = {
-  info_job_identity: "job1",
-  info_type_identity: "type1",
-  owner: "owner1",
-  target_uri: "http://one",
-} as JobInfo;
-const jobInfo2 = {
-  info_job_identity: "job2",
-  info_type_identity: "type2",
-  owner: "owner2",
-  target_uri: "http://two",
+  info_type_id: "type1",
+  job_owner: "owner1",
+  job_result_uri: "http://one",
+  job_definition: {},
 } as JobInfo;
 
+const jobStatus1 = {
+  info_job_status: "ENABLED",
+  producers: ["producer1"],
+} as ConsumerStatus;
+
 const job1 = {
   jobId: "job1",
   typeId: "type1",
   owner: "owner1",
   targetUri: "http://one",
-  prodId: "producer1",
+  prodIds: ["producer1"],
 } as Job;
 const job2 = {
   jobId: "job2",
-  typeId: "type2",
-  owner: "owner2",
-  targetUri: "http://two",
-  prodId: "producer1",
-} as Job;
-const job3 = {
-  jobId: "job1",
   typeId: "type1",
   owner: "owner1",
   targetUri: "http://one",
-  prodId: "producer2",
-} as Job;
-const job4 = {
-  jobId: "job2",
-  typeId: "type2",
-  owner: "owner2",
-  targetUri: "http://two",
-  prodId: "producer2",
+  prodIds: ["producer1"],
 } as Job;
 
 describe("JobsListComponent", () => {
@@ -98,8 +83,9 @@ describe("JobsListComponent", () => {
 
   beforeEach(async(() => {
     const spy = jasmine.createSpyObj("EIService", [
-      "getProducerIds",
-      "getJobsForProducer",
+      "getJobIds",
+      "getJobInfo",
+      "getConsumerStatus",
     ]);
 
     TestBed.configureTestingModule({
@@ -115,7 +101,7 @@ describe("JobsListComponent", () => {
       ],
       schemas: [CUSTOM_ELEMENTS_SCHEMA],
       declarations: [JobsListComponent],
-      providers: [{ provide: ProducerService, useValue: spy }, UiService],
+      providers: [{ provide: ConsumerService, useValue: spy }, UiService],
     })
       .compileComponents()
       .then(() => {
@@ -127,7 +113,7 @@ describe("JobsListComponent", () => {
 
   const expectedJob1Row = {
     jobId: "job1",
-    prodId: "producer1",
+    prodIds: "producer1",
     typeId: "type1",
     owner: "owner1",
     targetUri: "http://one",
@@ -144,8 +130,8 @@ describe("JobsListComponent", () => {
       tick(0);
 
       const actualJobs: Job[] = component.jobs();
-      expect(actualJobs.length).toEqual(4);
-      expect(actualJobs).toEqual([job1, job2, job3, job4]);
+      expect(actualJobs.length).toEqual(2);
+      expect(actualJobs).toEqual([job1, job2]);
       newSub.unsubscribe();
     }));
 
@@ -161,7 +147,7 @@ describe("JobsListComponent", () => {
             headerRow[0].getCellTextByColumnName().then((header) => {
               expect(header).toEqual({
                 jobId: "Job ID",
-                prodId: "Producer ID",
+                prodIds: "Producers",
                 typeId: "Type ID",
                 owner: "Owner",
                 targetUri: "Target URI",
@@ -198,32 +184,18 @@ describe("JobsListComponent", () => {
         expectedJob1Row,
         {
           jobId: "job2",
-          prodId: "producer1",
-          typeId: "type2",
-          owner: "owner2",
-          targetUri: "http://two",
-        },
-        {
-          jobId: "job1",
-          prodId: "producer2",
+          prodIds: "producer1",
           typeId: "type1",
           owner: "owner1",
           targetUri: "http://one",
         },
-        {
-          jobId: "job2",
-          prodId: "producer2",
-          typeId: "type2",
-          owner: "owner2",
-          targetUri: "http://two",
-        },
       ];
 
       loader
         .getHarness(MatTableHarness.with({ selector: "#jobsTable" }))
         .then((loadTable) => {
           loadTable.getRows().then((jobRows) => {
-            expect(jobRows.length).toEqual(4);
+            expect(jobRows.length).toEqual(2);
             jobRows.forEach((row) => {
               row.getCellTextByColumnName().then((values) => {
                 expect(expectedJobRows).toContain(
@@ -238,26 +210,32 @@ describe("JobsListComponent", () => {
 
     it("should display default values for non required properties ", fakeAsync(() => {
       const jobMissingProperties = {
-        info_job_identity: "job1",
-        info_job_data: {
+        job_definition: {
           jobparam2: "value2_job2",
           jobparam3: "value3_job2",
           jobparam1: "value1_job2",
         },
-        target_uri: "http://one",
+        job_result_uri: "http://one",
       } as JobInfo;
-
-      let producerServiceSpy = TestBed.inject(ProducerService) as jasmine.SpyObj<ProducerService>;
-      producerServiceSpy.getProducerIds.and.returnValue(of(["producer1"]));
-      producerServiceSpy.getJobsForProducer.and.returnValue(
-        of([jobMissingProperties])
+      const jobMissingPropertiesStatus = {
+        info_job_status: "ENABLED",
+        producers: ["producer1"],
+      } as ConsumerStatus;
+
+      let consumerServiceSpy = TestBed.inject(
+        ConsumerService
+      ) as jasmine.SpyObj<ConsumerService>;
+      consumerServiceSpy.getJobIds.and.returnValue(of(["job1"]));
+      consumerServiceSpy.getJobInfo.and.returnValue(of(jobMissingProperties));
+      consumerServiceSpy.getConsumerStatus.and.returnValue(
+        of(jobMissingPropertiesStatus)
       );
 
       component.ngOnInit();
       tick(0);
       const expectedJobRow = {
         jobId: "job1",
-        prodId: "producer1",
+        prodIds: "producer1",
         typeId: "< No type >",
         owner: "< No owner >",
         targetUri: "http://one",
@@ -290,7 +268,7 @@ describe("JobsListComponent", () => {
               idFilter.setValue("1").then((_) => {
                 tick(10);
                 loadTable.getRows().then((jobRows) => {
-                  expect(jobRows.length).toEqual(2);
+                  expect(jobRows.length).toEqual(1);
                   jobRows[0].getCellTextByColumnName().then((value) => {
                     expect(expectedJob1Row).toEqual(
                       jasmine.objectContaining(value)
@@ -440,8 +418,8 @@ describe("JobsListComponent", () => {
 
       it("should not sort when clicking on filtering box", fakeAsync(() => {
         const expectedJobRow = {
-          jobId: "job1",
-          prodId: "producer2",
+          jobId: "job2",
+          prodIds: "producer1",
           typeId: "type1",
           owner: "owner1",
           targetUri: "http://one",
@@ -460,8 +438,8 @@ describe("JobsListComponent", () => {
                 tick(10);
                 idFilter.setValue("").then((_) => {
                   loadTable.getRows().then((jobRows) => {
-                    expect(jobRows.length).toEqual(4);
-                    jobRows[2].getCellTextByColumnName().then((value) => {
+                    expect(jobRows.length).toEqual(2);
+                    jobRows[1].getCellTextByColumnName().then((value) => {
                       expect(expectedJobRow).toEqual(
                         jasmine.objectContaining(value)
                       );
@@ -477,8 +455,8 @@ describe("JobsListComponent", () => {
                 tick(10);
                 typeIdFilter.setValue("").then((_) => {
                   loadTable.getRows().then((jobRows) => {
-                    expect(jobRows.length).toEqual(4);
-                    jobRows[2].getCellTextByColumnName().then((value) => {
+                    expect(jobRows.length).toEqual(2);
+                    jobRows[1].getCellTextByColumnName().then((value) => {
                       expect(expectedJobRow).toEqual(
                         jasmine.objectContaining(value)
                       );
@@ -492,8 +470,8 @@ describe("JobsListComponent", () => {
                 tick(10);
                 ownerFilter.setValue("").then((_) => {
                   loadTable.getRows().then((jobRows) => {
-                    expect(jobRows.length).toEqual(4);
-                    jobRows[2].getCellTextByColumnName().then((value) => {
+                    expect(jobRows.length).toEqual(2);
+                    jobRows[1].getCellTextByColumnName().then((value) => {
                       expect(expectedJobRow).toEqual(
                         jasmine.objectContaining(value)
                       );
@@ -509,8 +487,8 @@ describe("JobsListComponent", () => {
                 tick(10);
                 targetUriFilter.setValue("").then((_) => {
                   loadTable.getRows().then((jobRows) => {
-                    expect(jobRows.length).toEqual(4);
-                    jobRows[2].getCellTextByColumnName().then((value) => {
+                    expect(jobRows.length).toEqual(2);
+                    jobRows[1].getCellTextByColumnName().then((value) => {
                       expect(expectedJobRow).toEqual(
                         jasmine.objectContaining(value)
                       );
@@ -525,52 +503,56 @@ describe("JobsListComponent", () => {
 
     describe("#paging", () => {
       it("should work properly on the table", fakeAsync(() => {
-        let producerServiceSpy = TestBed.inject(
-          ProducerService
-        ) as jasmine.SpyObj<ProducerService>;
-        producerServiceSpy.getProducerIds.and.returnValue(
-          of(["producer1", "producer2"])
-        );
-        producerServiceSpy.getJobsForProducer.and.returnValue(
-          of([jobInfo1, jobInfo2, jobInfo1])
+        let consumerServiceSpy = TestBed.inject(
+          ConsumerService
+        ) as jasmine.SpyObj<ConsumerService>;
+        consumerServiceSpy.getJobIds.and.returnValue(
+          of(["job1", "job2", "job3", "job4", "job5", "job6", "job7"])
         );
-        tick(0);
+        consumerServiceSpy.getJobInfo.and.returnValue(of(jobInfo1));
+        consumerServiceSpy.getConsumerStatus.and.returnValue(of(jobStatus1));
+        component.ngOnInit();
+        tick();
 
         loader.getHarness(MatPaginatorHarness).then((paging) => {
           paging.setPageSize(5);
-
+          tick(1000);
           loader
             .getHarness(MatTableHarness.with({ selector: "#jobsTable" }))
             .then((loadTable) => {
               loadTable.getRows().then((jobRows) => {
                 expect(jobRows.length).toEqual(5);
               });
+
               paging.goToNextPage();
+              tick(1000);
+
               loadTable.getRows().then((jobRows) => {
-                expect(jobRows.length).toEqual(1);
+                expect(jobRows.length).toEqual(2);
                 jobRows[0].getCellTextByColumnName().then((value) => {
                   const expectedRow = {
-                    jobId: "job1",
-                    prodId: "producer2",
+                    jobId: "job6",
+                    prodIds: "producer1",
                     typeId: "type1",
                     owner: "owner1",
                     targetUri: "http://one",
                   };
-                  expect(expectedRow).toContain(
-                    jasmine.objectContaining(value)
-                  );
+                  discardPeriodicTasks();
+                  expect(expectedRow).toEqual(jasmine.objectContaining(value));
                 });
               });
             });
         });
-        discardPeriodicTasks();
       }));
     });
   });
 });
 
 function setServiceSpy() {
-  let producerServiceSpy = TestBed.inject(ProducerService) as jasmine.SpyObj<ProducerService>;
-  producerServiceSpy.getProducerIds.and.returnValue(of(["producer1", "producer2"]));
-  producerServiceSpy.getJobsForProducer.and.returnValue(of([jobInfo1, jobInfo2]));
+  let consumerServiceSpy = TestBed.inject(
+    ConsumerService
+  ) as jasmine.SpyObj<ConsumerService>;
+  consumerServiceSpy.getJobIds.and.returnValue(of(["job1", "job2"]));
+  consumerServiceSpy.getJobInfo.and.returnValue(of(jobInfo1));
+  consumerServiceSpy.getConsumerStatus.and.returnValue(of(jobStatus1));
 }
index f06202c..43b3ad8 100644 (file)
@@ -22,20 +22,18 @@ import { FormControl, FormGroup } from "@angular/forms";
 import { MatPaginator } from "@angular/material/paginator";
 import { Sort } from "@angular/material/sort";
 import { MatTableDataSource } from "@angular/material/table";
-import { EMPTY, forkJoin, Subscription, timer } from "rxjs";
+import { EMPTY, forkJoin, of, Subscription, timer } from "rxjs";
 import { BehaviorSubject } from "rxjs/BehaviorSubject";
 import { mergeMap, finalize, map, tap, switchMap } from "rxjs/operators";
-import { JobInfo } from "@interfaces/producer.types";
-import { ProducerService } from "@services/ei/producer.service";
+import { ConsumerService } from "@services/ei/consumer.service";
 import { UiService } from "@services/ui/ui.service";
 
 export interface Job {
   jobId: string;
-  jobData: any;
   typeId: string;
   targetUri: string;
   owner: string;
-  prodId: string;
+  prodIds: string[];
 }
 
 @Component({
@@ -58,13 +56,13 @@ export class JobsListComponent implements OnInit {
   checked: boolean = false;
   firstTime: boolean = true;
 
-  constructor(private producerService: ProducerService, private ui: UiService) {
+  constructor(private consumerService: ConsumerService, private ui: UiService) {
     this.jobForm = new FormGroup({
       jobId: new FormControl(""),
       typeId: new FormControl(""),
       owner: new FormControl(""),
       targetUri: new FormControl(""),
-      prodId: new FormControl(""),
+      prodIds: new FormControl(""),
     });
   }
 
@@ -82,7 +80,7 @@ export class JobsListComponent implements OnInit {
           this.isDataIncluding(data.jobId, searchTerms.jobId) &&
           this.isDataIncluding(data.owner, searchTerms.owner) &&
           this.isDataIncluding(data.typeId, searchTerms.typeId) &&
-          this.isDataIncluding(data.prodId, searchTerms.prodId)
+          this.isArrayIncluding(data.prodIds, searchTerms.prodIds)
         );
       }) as (data: Job, filter: any) => boolean;
     });
@@ -97,11 +95,15 @@ export class JobsListComponent implements OnInit {
   }
 
   dataSubscription(): Subscription {
-    let prodId = [];
-    const jobs$ = this.producerService.getProducerIds().pipe(
-      tap((data) => (prodId = data)),
-      mergeMap((prodIds) =>
-        forkJoin(prodIds.map((id) => this.producerService.getJobsForProducer(id)))
+    const jobsInfo$ = this.consumerService.getJobIds().pipe(
+      mergeMap((jobIds) =>
+        forkJoin(jobIds.map((jobId) => {
+          return forkJoin([
+            of(jobId),
+            this.consumerService.getJobInfo(jobId),
+            this.consumerService.getConsumerStatus(jobId)
+          ])
+        }))
       ),
       finalize(() => this.loadingSubject$.next(false))
     );
@@ -112,8 +114,8 @@ export class JobsListComponent implements OnInit {
           tap((_) => {
             this.loadingSubject$.next(true);
           }),
-          switchMap((_) => jobs$),
-          map((response) => this.extractJobs(prodId, response))
+          switchMap((_) => jobsInfo$),
+          map((response) => this.extractJobs(response))
         )
       )
     );
@@ -137,7 +139,7 @@ export class JobsListComponent implements OnInit {
     this.jobForm.get("typeId").setValue("");
     this.jobForm.get("owner").setValue("");
     this.jobForm.get("targetUri").setValue("");
-    this.jobForm.get("prodId").setValue("");
+    this.jobForm.get("prodIds").setValue("");
   }
 
   sortJobs(sort: Sort) {
@@ -153,8 +155,8 @@ export class JobsListComponent implements OnInit {
           return this.compare(a.owner, b.owner, isAsc);
         case "targetUri":
           return this.compare(a.targetUri, b.targetUri, isAsc);
-        case "prodId":
-          return this.compare(a.prodId, b.prodId, isAsc);
+        case "prodIds":
+          return this.compare(a.prodIds, b.prodIds, isAsc);
         default:
           return 0;
       }
@@ -180,6 +182,14 @@ export class JobsListComponent implements OnInit {
     return data.toLowerCase().includes(transformedFilter);
   }
 
+  isArrayIncluding(data: string[], filter: string): boolean {
+    if(!data)
+      return true;
+    for (let i = 0; i < data.length; i++) {
+      return this.isDataIncluding(data[i], filter);
+    }
+  }
+
   getJobTypeId(job: Job): string {
     if (job.typeId) {
       return job.typeId;
@@ -198,13 +208,19 @@ export class JobsListComponent implements OnInit {
     return this.jobsSubject$.value;
   }
 
-  private extractJobs(prodId: number[], res: JobInfo[][]) {
+  private extractJobs(res: any) {
     this.clearFilter();
     let jobList = [];
-    prodId.forEach((element, index) => {
-      let jobs = res[index];
-      jobList = jobList.concat(jobs.map((job) => this.createJob(element, job)));
-    });
+    res.forEach(element => {
+      let jobObj = <Job>{};
+      jobObj.jobId = element[0];
+      jobObj.owner = element[1].job_owner;
+      jobObj.targetUri = element[1].job_result_uri;
+      jobObj.typeId = element[1].info_type_id;
+      jobObj.prodIds = (element[2].producers) ? element[2].producers : ["No Producers"];      
+      jobList = jobList.concat(jobObj);
+    });  
+   
     this.jobsSubject$.next(jobList);
     if (this.firstTime && jobList.length > 0) {
       this.polling$.next(jobList.length);
@@ -213,25 +229,6 @@ export class JobsListComponent implements OnInit {
     return jobList;
   }
 
-  createJobList(prodId: any[], result: JobInfo[][]) {
-    let jobList = [];
-    prodId.forEach((element, index) => {
-      let jobs = result[index];
-      jobList = jobList.concat(jobs.map((job) => this.createJob(element, job)));
-    });
-    return jobList;
-  }
-
-  createJob(element: any, job: JobInfo): any {
-    let infoJob = <Job>{};
-    infoJob.jobId = job.info_job_identity;
-    infoJob.typeId = job.info_type_identity;
-    infoJob.owner = job.owner;
-    infoJob.targetUri = job.target_uri;
-    infoJob.prodId = element;
-    return infoJob;
-  }
-
   refreshDataClick() {
     this.refresh$.next("");
   }
index b0603c9..d40a0fc 100644 (file)
@@ -35,23 +35,31 @@ import * as policyinstance2 from "./mock/policy-instance-2.json";
 import * as noTypePolicyinstance from "./mock/policy-instance-notype.json";
 import * as policyinstance1Status from "./mock/policy-instance-1-status.json";
 import * as policyinstance2Status from "./mock/policy-instance-2-status.json";
-import * as jobsProd1 from "./mock/jobs-producer1.json";
-import * as jobsProd2 from "./mock/jobs-producer2.json";
 import * as producerIds from "./mock/producerids.json";
 import * as producer1 from "./mock/producer1.json";
 import * as producer2 from "./mock/producer2.json";
+import * as producer3 from "./mock/producer3.json";
 import * as producerstatus1 from "./mock/producer-status1.json";
 import * as producerstatus2 from "./mock/producer-status2.json";
+import * as producerstatus3 from "./mock/producer-status3.json";
 import * as policytypes1 from "./mock/policy-type1.json";
 import * as policytypes0 from "./mock/policy-type0.json";
 import * as policyinstanceedit from "./mock/policy-instance-edit.json";
 import * as ric1 from "./mock/ric1.json";
 import * as ric2 from "./mock/ric2.json";
 import * as ricconfig from "./mock/ric-configuration.json";
+import * as jobIds from "./mock/jobids.json";
+import * as infoJob1 from "./mock/info-job1.json";
+import * as infoJob2 from "./mock/info-job2.json";
+import * as infoJob3 from "./mock/info-job3.json";
+import * as job1Status from "./mock/job1-status.json";
+import * as job2Status from "./mock/job2-status.json";
+import * as job3Status from "./mock/job3-status.json";
 import { delay } from "rxjs/operators";
 
 const POLICY_PATH = "/a1-policy/v2"
 const INFO_PATH = "/data-producer/v1"
+const CONSUMER_PATH = "/data-consumer/v1"
 
 const urls = [
   {
@@ -142,6 +150,10 @@ const urls = [
     url: INFO_PATH + "/info-producers/producer2",
     json: producer2,
   },
+  {
+    url: INFO_PATH + "/info-producers/producer3",
+    json: producer3,
+  },
   {
     url: INFO_PATH + "/info-producers/producer1/status",
     json: producerstatus1,
@@ -151,12 +163,36 @@ const urls = [
     json: producerstatus2,
   },
   {
-    url: INFO_PATH + "/info-producers/producer1/info-jobs",
-    json: jobsProd1,
+    url: INFO_PATH + "/info-producers/producer3/status",
+    json: producerstatus3,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs",
+    json: jobIds,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs/job1",
+    json: infoJob1,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs/job2",
+    json: infoJob2,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs/job3",
+    json: infoJob3,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs/job1/status",
+    json: job1Status,
+  },
+  {
+    url: CONSUMER_PATH + "/info-jobs/job2/status",
+    json: job2Status,
   },
   {
-    url: INFO_PATH + "/info-producers/producer2/info-jobs",
-    json: jobsProd2,
+    url: CONSUMER_PATH + "/info-jobs/job3/status",
+    json: job3Status,
   },
     {
         url: '/a1-policy/v2/configuration',
diff --git a/webapp-frontend/src/app/interfaces/consumer.types.ts b/webapp-frontend/src/app/interfaces/consumer.types.ts
new file mode 100644 (file)
index 0000000..7a81385
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2020 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+// Models of data used by the EI Coordinator
+
+export interface JobInfo {
+  info_type_id: string;
+  job_definition: any;
+  job_result_uri: string;
+  job_owner: string;
+  status_notification_uri: string;
+}
+
+export interface Consumer {
+  consumer_id: string;
+  status: string;
+}
+
+export enum OperationalState {
+  ENABLED = 'ENABLED',
+  DISABLED = 'DISABLED'
+}
+
+export interface ConsumerStatus {
+  info_job_status: OperationalState;
+  producers: string[];
+}
\ No newline at end of file
index 1e80fdf..1b548da 100644 (file)
 
 // Models of data used by the EI Coordinator
 
-export interface JobInfo {
-  info_job_identity: string;
-  info_job_data: any;
-  info_type_identity: string;
-  target_uri: string;
-  owner: string;
-}
-
 export interface Producer {
   producer_id: string;
   producer_types: string[];
@@ -44,4 +36,4 @@ export enum OperationalState {
 }
 export interface ProducerStatus {
   operational_state: OperationalState
-}
\ No newline at end of file
+}
diff --git a/webapp-frontend/src/app/mock/info-job1.json b/webapp-frontend/src/app/mock/info-job1.json
new file mode 100644 (file)
index 0000000..50492de
--- /dev/null
@@ -0,0 +1,7 @@
+{\r
+    "info_type_id": "type1",\r
+    "job_owner": "ricsim_g3_2",\r
+    "job_definition": {},\r
+    "job_result_uri": "https://ricsim_g3_1:8185/datadelivery",\r
+    "status_notification_uri": "http://producer:80/"\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/info-job2.json b/webapp-frontend/src/app/mock/info-job2.json
new file mode 100644 (file)
index 0000000..3e810a6
--- /dev/null
@@ -0,0 +1,7 @@
+{\r
+    "info_type_id": "type2",\r
+    "job_owner": "ricsim_g3_1",\r
+    "job_definition": {},\r
+    "job_result_uri": "https://ricsim_g3_1:8185/datadelivery",\r
+    "status_notification_uri": "http://producer:80/"\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/info-job3.json b/webapp-frontend/src/app/mock/info-job3.json
new file mode 100644 (file)
index 0000000..19fc1ac
--- /dev/null
@@ -0,0 +1,7 @@
+{\r
+    "info_type_id": "type5",\r
+    "job_owner": "ricsim_g3_5",\r
+    "job_definition": {},\r
+    "job_result_uri": "https://ricsim_g3_5:8185/datadelivery",\r
+    "status_notification_uri": "http://producer:80/"\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/job1-status.json b/webapp-frontend/src/app/mock/job1-status.json
new file mode 100644 (file)
index 0000000..23b96b8
--- /dev/null
@@ -0,0 +1,6 @@
+{\r
+    "info_job_status": "DISABLED",\r
+    "producers": [\r
+        "producer3"\r
+    ]\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/job2-status.json b/webapp-frontend/src/app/mock/job2-status.json
new file mode 100644 (file)
index 0000000..af73a47
--- /dev/null
@@ -0,0 +1,7 @@
+{\r
+    "info_job_status": "ENABLED",\r
+    "producers": [\r
+        "producer1",\r
+        "producer2"\r
+    ]\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/job3-status.json b/webapp-frontend/src/app/mock/job3-status.json
new file mode 100644 (file)
index 0000000..b2015c0
--- /dev/null
@@ -0,0 +1,3 @@
+{\r
+    "info_job_status": "ENABLED"\r
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/jobids.json b/webapp-frontend/src/app/mock/jobids.json
new file mode 100644 (file)
index 0000000..9b33b55
--- /dev/null
@@ -0,0 +1,5 @@
+[\r
+    "job1",\r
+    "job2",\r
+    "job3"\r
+]
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/jobs-producer1.json b/webapp-frontend/src/app/mock/jobs-producer1.json
deleted file mode 100644 (file)
index 746add9..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-[
-    {
-      "info_job_identity": "job1",
-      "info_type_identity": "type1",
-      "owner": "owner1",
-      "info_job_data": {
-        "jobparam2": "value2_job1",
-        "jobparam3": "value3_job1",
-        "jobparam1": "value1_job1"
-      },
-      "target_uri": "https://ricsim_g1_1:8185/datadelivery"
-    },
-    {
-      "info_job_identity": "job2",
-      "info_type_identity": "type1",
-      "owner": "owner2",
-      "info_job_data": {
-        "jobparam2": "value2_job2",
-        "jobparam3": "value3_job2",
-        "jobparam1": "value1_job2"
-      },
-      "target_uri": "https://ricsim_g2_1:8185/datadelivery"
-    },
-    {
-      "info_job_identity": "job4",
-      "info_type_identity": "type1",
-      "owner": "owner3",
-      "info_job_data": {
-        "jobparam2": "value2_job2",
-        "jobparam3": "value3_job2",
-        "jobparam1": "value1_job2"
-      },
-      "target_uri": "https://ricsim_g3_1:8185/datadelivery"
-    }
-  ]
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/jobs-producer2.json b/webapp-frontend/src/app/mock/jobs-producer2.json
deleted file mode 100644 (file)
index bb4fe01..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-    {
-      "info_job_identity": "job3",
-      "info_type_identity": "type2",
-      "owner": "owner1",
-      "info_job_data": {
-        "jobparam2": "value2_job3",
-        "jobparam3": "value3_job3",
-        "jobparam1": "value1_job3"
-      },
-      "target_uri": "https://ricsim_g3_1:8185/datadelivery"
-    },
-    {
-      "info_job_identity": "job5",
-      "info_type_identity": "type2",
-      "owner": "owner5",
-      "info_job_data": {
-        "jobparam2": "value2_job2",
-        "jobparam3": "value3_job2",
-        "jobparam1": "value1_job2"
-      },
-      "target_uri": "https://ricsim_g3_1:8185/datadelivery"
-    }
-  ]
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/producer-status3.json b/webapp-frontend/src/app/mock/producer-status3.json
new file mode 100644 (file)
index 0000000..a487293
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "operational_state": "ENABLED"
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/mock/producer3.json b/webapp-frontend/src/app/mock/producer3.json
new file mode 100644 (file)
index 0000000..3eda758
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "supported_info_types": [ "type1"]
+}
\ No newline at end of file
index c6789c0..86232c6 100644 (file)
@@ -1,4 +1,5 @@
 [
     "producer1",
-    "producer2"
+    "producer2",
+    "producer3"
 ]
\ No newline at end of file
diff --git a/webapp-frontend/src/app/services/ei/consumer.service.spec.ts b/webapp-frontend/src/app/services/ei/consumer.service.spec.ts
new file mode 100644 (file)
index 0000000..352e1e3
--- /dev/null
@@ -0,0 +1,108 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+import { ConsumerService } from "./consumer.service";
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { JobInfo, ConsumerStatus, OperationalState } from '@app/interfaces/consumer.types';
+
+describe('ConsumerService', () => {
+    let basePath = '/data-consumer/v1';
+    let service: ConsumerService;
+    let httpTestingController: HttpTestingController;
+    let expectedEIJobs: string[];
+    let expectedConsumerStatus: ConsumerStatus;
+    let expectedJobInfo: JobInfo;
+
+    beforeEach(() => TestBed.configureTestingModule({
+        imports: [
+            HttpClientTestingModule
+        ],
+        providers: [
+            ConsumerService
+        ]
+    }));
+
+    beforeEach(() => {
+        service = TestBed.inject(ConsumerService);
+        httpTestingController = TestBed.inject(HttpTestingController);
+        expectedEIJobs = ['job1', 'job2'];
+        expectedConsumerStatus = {
+            info_job_status: OperationalState.ENABLED,
+            producers: [
+                'producer1'
+            ]
+        }
+        expectedJobInfo = {
+          job_definition: 'data',
+          info_type_id: 'type1',
+          job_result_uri: 'uri',
+          job_owner: 'owner1',
+          status_notification_uri: 'status_uri'
+        }
+    })
+
+    it('should be created', () => {
+        service = TestBed.inject(ConsumerService);
+        expect(service).toBeTruthy();
+    });
+
+    it('should get all the jobs ids', () => {
+        service.getJobIds().subscribe(
+            jobs => expect(jobs).toEqual(expectedEIJobs, 'should return expected Jobs'),
+            fail
+        );
+
+        const req = httpTestingController.expectOne(basePath + '/' + service.jobsPath);
+        expect(req.request.method).toEqual('GET');
+
+        req.flush(expectedEIJobs); //Return expected jobs ids
+
+        httpTestingController.verify();
+    });
+
+
+    it('should return consumer status', () => {
+        service.getConsumerStatus('job1').subscribe(
+            consumerStatus => expect(consumerStatus).toEqual(expectedConsumerStatus, 'should return expected status'),
+            fail
+        );
+
+        const req = httpTestingController.expectOne(basePath + '/' + service.jobsPath + '/job1/' + service.consumerStatusPath);
+        expect(req.request.method).toEqual('GET');
+
+        req.flush(expectedConsumerStatus); //Return expected status
+
+        httpTestingController.verify();
+    });
+
+    it('should return the job info', () => {
+        service.getJobInfo('job1').subscribe(
+            jobInfo => expect(jobInfo).toEqual(expectedJobInfo, 'should return expected job info'),
+            fail
+        );
+
+        const req = httpTestingController.expectOne(basePath + '/' + service.jobsPath + '/job1');
+        expect(req.request.method).toEqual('GET');
+
+        req.flush(expectedJobInfo); //Return expected job info
+
+        httpTestingController.verify();
+    });
+});
\ No newline at end of file
diff --git a/webapp-frontend/src/app/services/ei/consumer.service.ts b/webapp-frontend/src/app/services/ei/consumer.service.ts
new file mode 100644 (file)
index 0000000..19ec3cb
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { ConsumerStatus, JobInfo } from '@interfaces/consumer.types';
+
+/**
+ * Services for calling the EI endpoints.
+ */
+@Injectable({
+    providedIn: 'root'
+})
+export class ConsumerService {
+
+    private basePath = '/data-consumer/v1';
+    readonly jobsPath = 'info-jobs';
+    readonly consumerStatusPath = 'status';
+
+    private buildPath(...args: any[]) {
+        let result = this.basePath;
+        args.forEach(part => {
+            result = result + '/' + part;
+        });
+        return result;
+    }
+
+    constructor(private httpClient: HttpClient) {
+        // injects to variable httpClient
+    }
+
+    getJobIds(): Observable<string[]> {
+        const url = this.buildPath(this.jobsPath);
+        return this.httpClient.get<string[]>(url);
+    }
+
+    getJobInfo(infoJobId: string): Observable<JobInfo> {
+        const url = this.buildPath(this.jobsPath, infoJobId);
+        return this.httpClient.get<JobInfo>(url);
+    }
+
+    getConsumerStatus(infoJobId: string): Observable<ConsumerStatus> {
+        const url = this.buildPath(this.jobsPath, infoJobId, this.consumerStatusPath);
+        return this.httpClient.get<ConsumerStatus>(url);
+    }
+}
index 61ba253..a5562ee 100644 (file)
@@ -20,7 +20,7 @@
 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'
 import { TestBed } from '@angular/core/testing';
 
-import { JobInfo, ProducerStatus, OperationalState, ProducerRegistrationInfo } from '@interfaces/producer.types';
+import { ProducerStatus, OperationalState, ProducerRegistrationInfo } from '@interfaces/producer.types';
 import { ProducerService } from './producer.service';
 
 describe('ProducerService', () => {
@@ -66,33 +66,6 @@ describe('ProducerService', () => {
     });
   });
 
-  describe('#getJobsForProducer', () => {
-    let expectedEIJobs: JobInfo[];
-
-    beforeEach(() => {
-      service = TestBed.inject(ProducerService);
-      httpTestingController = TestBed.inject(HttpTestingController);
-      expectedEIJobs = [
-        { info_job_identity: '1', info_job_data: 'data', info_type_identity: 'Type ID 1',  target_uri: 'hhtp://url', owner: 'owner'},
-        { info_job_identity: '2', info_job_data: 'EI Job 2', info_type_identity: 'Type ID 2',  target_uri: 'hhtp://url', owner: 'owner'}
-      ] as JobInfo[];
-    });
-
-    it('should return all jobs', () => {
-      service.getJobsForProducer('producer1').subscribe(
-        jobs => expect(jobs).toEqual(expectedEIJobs, 'should return expected Jobs'),
-        fail
-      );
-
-      const req = httpTestingController.expectOne(basePath + '/' + service.producersPath + '/producer1/' + service.jobsPath);
-      expect(req.request.method).toEqual('GET');
-
-      req.flush(expectedEIJobs); //Return expectedEIJobs
-
-      httpTestingController.verify();
-     });
-  });
-
   describe('#getProducer', () => {
     let expectedProducer: ProducerRegistrationInfo;
 
index 2c4571d..1744ff8 100644 (file)
@@ -21,7 +21,7 @@
 import { Injectable } from '@angular/core';
 import { HttpClient } from '@angular/common/http';
 import { Observable } from 'rxjs';
-import { JobInfo, ProducerStatus, ProducerRegistrationInfo } from '@interfaces/producer.types';
+import { ProducerStatus, ProducerRegistrationInfo } from '@interfaces/producer.types';
 
 /**
  * Services for calling the EI endpoints.
@@ -53,11 +53,6 @@ export class ProducerService {
         return this.httpClient.get<string[]>(url);
     }
 
-    getJobsForProducer(producerId: string): Observable<JobInfo[]> {
-        const url = this.buildPath(this.producersPath, producerId, this.jobsPath);
-        return this.httpClient.get<JobInfo[]>(url);
-    }
-
     getProducer(producerId: string): Observable<ProducerRegistrationInfo> {
         const url = this.buildPath(this.producersPath, producerId);
         return this.httpClient.get<ProducerRegistrationInfo>(url);