Feature 11011: Multiple NS deletion in OSM
[osm/NG-UI.git] / src / app / utilities / ns-instances-action / NSInstancesActionComponent.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15
16  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18 /**
19  * @file NS InstancesAction Component
20  */
21 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector } from '@angular/core';
22 import { Router } from '@angular/router';
23 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
24 import { TranslateService } from '@ngx-translate/core';
25 import { NotifierService } from 'angular-notifier';
26 import { ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
27 import { DeleteComponent } from 'DeleteComponent';
28 import { environment } from 'environment';
29 import { HealingComponent } from 'HealingComponent';
30 import { NSDDetails } from 'NSDModel';
31 import { NSDInstanceData } from 'NSInstanceModel';
32 import { NSPrimitiveComponent } from 'NSPrimitiveComponent';
33 import { NsUpdateComponent } from 'NsUpdateComponent';
34 import { RestService } from 'RestService';
35 import { forkJoin, Observable } from 'rxjs';
36 import { ScalingComponent } from 'ScalingComponent';
37 import { SharedService, isNullOrUndefined } from 'SharedService';
38 import { ShowInfoComponent } from 'ShowInfoComponent';
39 import { StartStopRebuildComponent } from 'StartStopRebuildComponent';
40 import { VerticalScalingComponent } from 'VerticalScalingComponent';
41 import { VmMigrationComponent } from 'VmMigrationComponent';
42 import { DF, VDU, VNFD } from 'VNFDModel';
43 /**
44  * Creating component
45  * @Component takes NSInstancesActionComponent.html as template url
46  */
47 @Component({
48   templateUrl: './NSInstancesActionComponent.html',
49   styleUrls: ['./NSInstancesActionComponent.scss'],
50   changeDetection: ChangeDetectionStrategy.OnPush
51 })
52 /** Exporting a class @exports NSInstancesActionComponent */
53 export class NSInstancesActionComponent {
54   /** To get the value from the nspackage via valuePrepareFunction default Property of ng-smarttable @public */
55   public value: NSDInstanceData;
56
57   /** Invoke service injectors @public */
58   public injector: Injector;
59
60   /** Instance of the modal service @public */
61   public restService: RestService;
62
63   /** Config Status Check @public */
64   public configStatus: string;
65
66   /** Operational Status Check @public */
67   public operationalStatus: string;
68
69   /** CNF Status Check @public */
70   public k8sStatus: boolean = false;
71
72   /** get Admin Details @public */
73   public getAdminDetails: {};
74
75   /** Scaling is accepted @public */
76   public isScalingPresent: boolean = false;
77
78   /** Check the loading results for loader status @public */
79   public isLoadingNSInstanceAction: boolean = false;
80
81   /** Give the message for the loading @public */
82   public message: string = 'PLEASEWAIT';
83
84   /** Assign the VNF Details @public */
85   public vnfDetails: VNFD[] = [];
86
87   /** Contains instance ID @public */
88   public instanceID: string;
89
90   /** Contains operational dashboard view @public */
91   public isShowOperationalDashboard: boolean = false;
92
93   /** Instance of the modal service @private */
94   private modalService: NgbModal;
95
96   /** Holds teh instance of AuthService class of type AuthService @private */
97   private router: Router;
98
99   /** Contains all methods related to shared @private */
100   private sharedService: SharedService;
101
102   /** Notifier service to popup notification @private */
103   private notifierService: NotifierService;
104
105   /** Contains tranlsate instance @private */
106   private translateService: TranslateService;
107
108   /** Detect changes for the User Input */
109   private cd: ChangeDetectorRef;
110
111   /** Set timeout @private */
112   // eslint-disable-next-line @typescript-eslint/no-magic-numbers
113   private timeOut: number = 100;
114
115   constructor(injector: Injector) {
116     this.injector = injector;
117     this.modalService = this.injector.get(NgbModal);
118     this.restService = this.injector.get(RestService);
119     this.router = this.injector.get(Router);
120     this.sharedService = this.injector.get(SharedService);
121     this.notifierService = this.injector.get(NotifierService);
122     this.translateService = this.injector.get(TranslateService);
123     this.cd = this.injector.get(ChangeDetectorRef);
124   }
125
126   /**
127    * Lifecyle Hooks the trigger before component is instantiate
128    */
129   public ngOnInit(): void {
130     this.configStatus = this.value.ConfigStatus;
131     this.operationalStatus = this.value.OperationalStatus;
132     this.instanceID = this.value.identifier;
133     this.getAdminDetails = this.value.adminDetails;
134     for (const key of Object.keys(this.getAdminDetails)) {
135       if (key === 'deployed') {
136         // eslint-disable-next-line security/detect-object-injection
137         const adminData: {} = this.getAdminDetails[key];
138         for (const k8sData of Object.keys(adminData)) {
139           if (k8sData === 'K8s') {
140             // eslint-disable-next-line security/detect-object-injection
141             if (adminData[k8sData].length !== 0) {
142               this.k8sStatus = true;
143             }
144           }
145         }
146       }
147     }
148     this.isShowOperationalDashboard = !isNullOrUndefined(this.value.vcaStatus) ?
149       Object.keys(this.value.vcaStatus).length === 0 && typeof this.value.vcaStatus === 'object' : true;
150   }
151
152   /** Shows information using modalservice @public */
153   public infoNs(): void {
154     // eslint-disable-next-line security/detect-non-literal-fs-filename
155     this.modalService.open(ShowInfoComponent, { backdrop: 'static' }).componentInstance.params = {
156       id: this.instanceID,
157       page: 'ns-instance',
158       titleName: 'INSTANCEDETAILS'
159     };
160   }
161
162   /** Delete NS Instanace @public */
163   public deleteNSInstance(forceAction: boolean): void {
164     // eslint-disable-next-line security/detect-non-literal-fs-filename
165     const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
166     modalRef.componentInstance.params = {
167       forceDeleteType: forceAction,
168       name: this.value.name,
169       page: 'ns-instance',
170       id: this.instanceID
171     };
172     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
173       if (result) {
174         this.sharedService.callData();
175       }
176     }).catch((): void => {
177       // Catch Navigation Error
178     });
179   }
180
181   /** History of operations for an Instanace @public */
182   public historyOfOperations(): void {
183     this.router.navigate(['/instances/ns/history-operations/', this.instanceID]).catch((): void => {
184       // Catch Navigation Error
185     });
186   }
187
188   /** NS Topology */
189   public nsTopology(): void {
190     this.router.navigate(['/instances/ns/', this.instanceID]).catch((): void => {
191       // Catch Navigation Error
192     });
193   }
194
195   /** Exec NS Primitive @public */
196   public execNSPrimitiveModal(): void {
197     // eslint-disable-next-line security/detect-non-literal-fs-filename
198     this.modalService.open(NSPrimitiveComponent, { backdrop: 'static' }).componentInstance.params = {
199       memberIndex: this.value.memberIndex,
200       nsConfig: this.value.nsConfig,
201       name: this.value.NsdName,
202       id: this.value.constituent
203     };
204   }
205
206   /** Redirect to Grafana Metrics @public */
207   public metrics(): void {
208     this.isLoadingNSInstanceAction = true;
209     this.restService.getResource(environment.NSDINSTANCES_URL + '/' + this.instanceID).subscribe((nsData: NSDDetails[]): void => {
210       nsData['vnfd-id'].forEach((vnfdID: string[]): void => {
211         this.restService.getResource(environment.VNFPACKAGES_URL + '/' + vnfdID)
212           .subscribe((vnfd: VNFD): void => {
213             vnfd.vdu.forEach((vduData: VDU): void => {
214               if (vduData['monitoring-parameter'] !== undefined && vduData['monitoring-parameter'].length > 0) {
215                 this.isLoadingNSInstanceAction = false;
216                 const location: string = environment.GRAFANA_URL + '/' + this.instanceID + '/osm-ns-metrics-metrics';
217                 // eslint-disable-next-line security/detect-non-literal-fs-filename
218                 window.open(location);
219               } else {
220                 this.isLoadingNSInstanceAction = false;
221                 this.notifierService.notify('error', this.translateService.instant('PAGE.NSMETRIC.METRICERROR'));
222               }
223             });
224             this.doChanges();
225           }, (error: ERRORDATA): void => {
226             this.restService.handleError(error, 'get');
227             this.isLoadingNSInstanceAction = false;
228           });
229       });
230     }, (error: ERRORDATA): void => {
231       this.restService.handleError(error, 'get');
232       this.isLoadingNSInstanceAction = false;
233     });
234   }
235
236   /**
237    * Do the manual scaling
238    * Here we are going to get a list of VNFD ID used in the instances
239    * and have this in array with URL created then pass to checkscaling method for forkjoin to get the data @public
240    */
241   public manualScaling(): void {
242     this.isLoadingNSInstanceAction = true;
243     const tempURL: Observable<{}>[] = [];
244     this.value.vnfID.forEach((id: string): void => {
245       const apiUrl: string = environment.VNFPACKAGESCONTENT_URL + '/' + id;
246       tempURL.push(this.restService.getResource(apiUrl));
247     });
248     this.checkScaling(tempURL);
249   }
250
251   /**
252    * Used to forkjoin to all the request to send parallely, get the data and check 'scaling-aspect' key is present @public
253    */
254   public checkScaling(URLS: Observable<{}>[]): void {
255     forkJoin(URLS).subscribe((data: VNFD[]): void => {
256       this.vnfDetails = data;
257       if (this.vnfDetails.length > 0) {
258         this.vnfDetails.forEach((vnfdData: VNFD): void => {
259           vnfdData.df.forEach((dfData: DF): void => {
260             if (!isNullOrUndefined(dfData['scaling-aspect']) && dfData['scaling-aspect'].length > 0) {
261               this.isScalingPresent = true;
262             }
263           });
264         });
265       }
266       this.isLoadingNSInstanceAction = false;
267       if (this.isScalingPresent) {
268         this.openScaling();
269       } else {
270         this.notifierService.notify('error', this.translateService.instant('SCALINGNOTFOUND'));
271       }
272       this.doChanges();
273     });
274   }
275
276   /** Open the scaling pop-up @public */
277   public openScaling(): void {
278     // eslint-disable-next-line security/detect-non-literal-fs-filename
279     const modalRef: NgbModalRef = this.modalService.open(ScalingComponent, { backdrop: 'static' });
280     modalRef.componentInstance.params = {
281       id: this.instanceID,
282       vnfID: this.value.vnfID,
283       nsID: this.value['nsd-id'],
284       nsd: this.value.nsd,
285       data: this.vnfDetails
286     };
287     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
288       if (result) {
289         this.sharedService.callData();
290       }
291     }).catch((): void => {
292       // Catch Navigation Error
293     });
294   }
295
296   /** To open VM Migration in NS Instances */
297   public openVmMigration(): void {
298     // eslint-disable-next-line security/detect-non-literal-fs-filename
299     const modalRef: NgbModalRef = this.modalService.open(VmMigrationComponent, { backdrop: 'static' });
300     modalRef.componentInstance.params = {
301       id: this.instanceID
302     };
303     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
304       if (result) {
305         this.sharedService.callData();
306       }
307     }).catch((): void => {
308       // Catch Navigation Error
309     });
310   }
311
312   /** To open the Ns Update pop-up */
313   public openNsUpdate(): void {
314     // eslint-disable-next-line security/detect-non-literal-fs-filename
315     const modalRef: NgbModalRef = this.modalService.open(NsUpdateComponent, { backdrop: 'static' });
316     modalRef.componentInstance.params = {
317       id: this.instanceID
318     };
319     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
320       if (result) {
321         this.sharedService.callData();
322       }
323     }).catch((): void => {
324       // Catch Navigation Error
325     });
326   }
327
328   /** To open the Start, Stop & Rebuild pop-up */
329   public openStart(actionType: string): void {
330     // eslint-disable-next-line security/detect-non-literal-fs-filename
331     const modalRef: NgbModalRef = this.modalService.open(StartStopRebuildComponent, { backdrop: 'static' });
332     modalRef.componentInstance.params = {
333       id: this.instanceID
334     };
335     if (actionType === 'start') {
336       modalRef.componentInstance.instanceTitle = this.translateService.instant('START');
337     } else if (actionType === 'stop') {
338       modalRef.componentInstance.instanceTitle = this.translateService.instant('STOP');
339     } else {
340       modalRef.componentInstance.instanceTitle = this.translateService.instant('REBUILD');
341     }
342     modalRef.componentInstance.instanceType = actionType;
343     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
344       if (result) {
345         this.sharedService.callData();
346       }
347     }).catch((): void => {
348       // Catch Navigation Error
349     });
350   }
351
352   /** To open the vertical Scaling pop-up */
353   public openVerticalScaling(): void {
354     // eslint-disable-next-line security/detect-non-literal-fs-filename
355     const modalRef: NgbModalRef = this.modalService.open(VerticalScalingComponent, { backdrop: 'static' });
356     modalRef.componentInstance.params = {
357       id: this.instanceID
358     };
359     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
360       if (result) {
361         this.sharedService.callData();
362       }
363     }).catch((): void => {
364       // Catch Navigation Error
365     });
366   }
367
368   /** Open the Healing pop-up @public */
369   public openHealing(): void {
370     // eslint-disable-next-line security/detect-non-literal-fs-filename
371     const modalRef: NgbModalRef = this.modalService.open(HealingComponent, { backdrop: 'static' });
372     modalRef.componentInstance.params = {
373       id: this.instanceID
374     };
375     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
376       if (result) {
377         this.sharedService.callData();
378       }
379     }).catch((): void => {
380       // Catch Navigation Error
381     });
382   }
383
384   /**
385    * Check any changes in the child component @public
386    */
387   public doChanges(): void {
388     setTimeout((): void => {
389       this.cd.detectChanges();
390     }, this.timeOut);
391   }
392 }