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