Feature 10911-Vertical scaling of VM instances from 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 { NSDDetails } from 'NSDModel';
30 import { NSDInstanceData } from 'NSInstanceModel';
31 import { NSPrimitiveComponent } from 'NSPrimitiveComponent';
32 import { NsUpdateComponent } from 'NsUpdateComponent';
33 import { RestService } from 'RestService';
34 import { forkJoin, Observable } from 'rxjs';
35 import { ScalingComponent } from 'ScalingComponent';
36 import { SharedService } from 'SharedService';
37 import { ShowInfoComponent } from 'ShowInfoComponent';
38 import { StartStopRebuildComponent } from 'StartStopRebuildComponent';
39 import { isNullOrUndefined } from 'util';
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   /** get Admin Details @public */
70   public getAdminDetails: {};
71
72   /** Scaling is accepted @public */
73   public isScalingPresent: boolean = false;
74
75   /** Check the loading results for loader status @public */
76   public isLoadingNSInstanceAction: boolean = false;
77
78   /** Give the message for the loading @public */
79   public message: string = 'PLEASEWAIT';
80
81   /** Assign the VNF Details @public */
82   public vnfDetails: VNFD[] = [];
83
84   /** Contains instance ID @public */
85   public instanceID: string;
86
87   /** Contains operational dashboard view @public */
88   public isShowOperationalDashboard: boolean = false;
89
90   /** Instance of the modal service @private */
91   private modalService: NgbModal;
92
93   /** Holds teh instance of AuthService class of type AuthService @private */
94   private router: Router;
95
96   /** Contains all methods related to shared @private */
97   private sharedService: SharedService;
98
99   /** Notifier service to popup notification @private */
100   private notifierService: NotifierService;
101
102   /** Contains tranlsate instance @private */
103   private translateService: TranslateService;
104
105   /** Detect changes for the User Input */
106   private cd: ChangeDetectorRef;
107
108   /** Set timeout @private */
109   private timeOut: number = 100;
110
111   constructor(injector: Injector) {
112     this.injector = injector;
113     this.modalService = this.injector.get(NgbModal);
114     this.restService = this.injector.get(RestService);
115     this.router = this.injector.get(Router);
116     this.sharedService = this.injector.get(SharedService);
117     this.notifierService = this.injector.get(NotifierService);
118     this.translateService = this.injector.get(TranslateService);
119     this.cd = this.injector.get(ChangeDetectorRef);
120   }
121
122   /**
123    * Lifecyle Hooks the trigger before component is instantiate
124    */
125   public ngOnInit(): void {
126     this.configStatus = this.value.ConfigStatus;
127     this.operationalStatus = this.value.OperationalStatus;
128     this.instanceID = this.value.identifier;
129     this.getAdminDetails = this.value.adminDetails;
130     this.isShowOperationalDashboard = !isNullOrUndefined(this.value.vcaStatus) ?
131       Object.keys(this.value.vcaStatus).length === 0 && typeof this.value.vcaStatus === 'object' : true;
132   }
133
134   /** Shows information using modalservice @public */
135   public infoNs(): void {
136     this.modalService.open(ShowInfoComponent, { backdrop: 'static' }).componentInstance.params = {
137       id: this.instanceID,
138       page: 'ns-instance',
139       titleName: 'INSTANCEDETAILS'
140     };
141   }
142
143   /** Delete NS Instanace @public */
144   public deleteNSInstance(forceAction: boolean): void {
145     const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
146     modalRef.componentInstance.params = { forceDeleteType: forceAction };
147     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
148       if (result) {
149         this.sharedService.callData();
150       }
151     }).catch();
152   }
153
154   /** History of operations for an Instanace @public */
155   public historyOfOperations(): void {
156     this.router.navigate(['/instances/ns/history-operations/', this.instanceID]).catch((): void => {
157       // Catch Navigation Error
158     });
159   }
160
161   /** NS Topology */
162   public nsTopology(): void {
163     this.router.navigate(['/instances/ns/', this.instanceID]).catch((): void => {
164       // Catch Navigation Error
165     });
166   }
167
168   /** Exec NS Primitive @public */
169   public execNSPrimitiveModal(): void {
170     this.modalService.open(NSPrimitiveComponent, { backdrop: 'static' }).componentInstance.params = {
171       memberIndex: this.value.memberIndex,
172       nsConfig: this.value.nsConfig,
173       name: this.value.NsdName
174     };
175   }
176
177   /** Redirect to Grafana Metrics @public */
178   public metrics(): void {
179     this.isLoadingNSInstanceAction = true;
180     this.restService.getResource(environment.NSDINSTANCES_URL + '/' + this.instanceID).subscribe((nsData: NSDDetails[]): void => {
181       nsData['vnfd-id'].forEach((vnfdID: string[]): void => {
182         this.restService.getResource(environment.VNFPACKAGES_URL + '/' + vnfdID)
183           .subscribe((vnfd: VNFD): void => {
184             vnfd.vdu.forEach((vduData: VDU): void => {
185               if (vduData['monitoring-parameter'] !== undefined && vduData['monitoring-parameter'].length > 0) {
186                 this.isLoadingNSInstanceAction = false;
187                 const location: string = environment.GRAFANA_URL + '/' + this.instanceID + '/osm-ns-metrics-metrics';
188                 window.open(location);
189               } else {
190                 this.isLoadingNSInstanceAction = false;
191                 this.notifierService.notify('error', this.translateService.instant('PAGE.NSMETRIC.METRICERROR'));
192               }
193             });
194             this.doChanges();
195           }, (error: ERRORDATA): void => {
196             this.restService.handleError(error, 'get');
197             this.isLoadingNSInstanceAction = false;
198           });
199       });
200     }, (error: ERRORDATA): void => {
201       this.restService.handleError(error, 'get');
202       this.isLoadingNSInstanceAction = false;
203     });
204   }
205
206   /**
207    * Do the manual scaling
208    * Here we are going to get a list of VNFD ID used in the instances
209    * and have this in array with URL created then pass to checkscaling method for forkjoin to get the data @public
210    */
211   public manualScaling(): void {
212     this.isLoadingNSInstanceAction = true;
213     const tempURL: Observable<{}>[] = [];
214     this.value.vnfID.forEach((id: string): void => {
215       const apiUrl: string = environment.VNFPACKAGESCONTENT_URL + '/' + id;
216       tempURL.push(this.restService.getResource(apiUrl));
217     });
218     this.checkScaling(tempURL);
219   }
220
221   /**
222    * Used to forkjoin to all the request to send parallely, get the data and check 'scaling-aspect' key is present @public
223    */
224   public checkScaling(URLS: Observable<{}>[]): void {
225     forkJoin(URLS).subscribe((data: VNFD[]): void => {
226       this.vnfDetails = data;
227       if (this.vnfDetails.length > 0) {
228         this.vnfDetails.forEach((vnfdData: VNFD): void => {
229           vnfdData.df.forEach((dfData: DF): void => {
230             if (!isNullOrUndefined(dfData['scaling-aspect']) && dfData['scaling-aspect'].length > 0) {
231               this.isScalingPresent = true;
232             }
233           });
234         });
235       }
236       this.isLoadingNSInstanceAction = false;
237       if (this.isScalingPresent) {
238         this.openScaling();
239       } else {
240         this.notifierService.notify('error', this.translateService.instant('SCALINGNOTFOUND'));
241       }
242       this.doChanges();
243     });
244   }
245
246   /** Open the scaling pop-up @public */
247   public openScaling(): void {
248     const modalRef: NgbModalRef = this.modalService.open(ScalingComponent, { backdrop: 'static' });
249     modalRef.componentInstance.params = {
250       id: this.instanceID,
251       vnfID: this.value.vnfID,
252       nsID: this.value['nsd-id'],
253       nsd: this.value.nsd,
254       data: this.vnfDetails
255     };
256     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
257       if (result) {
258         this.sharedService.callData();
259       }
260     }).catch();
261   }
262
263   /** To open VM Migration in NS Instances */
264   public openVmMigration(): void {
265     const modalRef: NgbModalRef = this.modalService.open(VmMigrationComponent, { backdrop: 'static' });
266     modalRef.componentInstance.params = {
267       id: this.instanceID
268     };
269     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
270       if (result) {
271         this.sharedService.callData();
272       }
273     }).catch();
274   }
275
276   /** To open the Ns Update pop-up */
277   public openNsUpdate(): void {
278     const modalRef: NgbModalRef = this.modalService.open(NsUpdateComponent, { backdrop: 'static' });
279     modalRef.componentInstance.params = {
280       id: this.instanceID
281     };
282     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
283       if (result) {
284         this.sharedService.callData();
285       }
286     }).catch();
287   }
288
289   /** To open the Start, Stop & Rebuild pop-up */
290   public openStart(actionType: string): void {
291     const modalRef: NgbModalRef = this.modalService.open(StartStopRebuildComponent, { backdrop: 'static' });
292     modalRef.componentInstance.params = {
293       id: this.instanceID
294     };
295     if (actionType === 'start') {
296       modalRef.componentInstance.instanceTitle = this.translateService.instant('START');
297     } else if (actionType === 'stop') {
298       modalRef.componentInstance.instanceTitle = this.translateService.instant('STOP');
299     } else {
300       modalRef.componentInstance.instanceTitle = this.translateService.instant('REBUILD');
301     }
302     modalRef.componentInstance.instanceType = actionType;
303     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
304       if (result) {
305         this.sharedService.callData();
306       }
307     }).catch();
308   }
309
310   /** To open the vertical Scaling pop-up */
311   public openVerticalScaling(): void {
312     const modalRef: NgbModalRef = this.modalService.open(VerticalScalingComponent, { backdrop: 'static' });
313     modalRef.componentInstance.params = {
314       id: this.instanceID
315     };
316     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
317       if (result) {
318         this.sharedService.callData();
319       }
320     }).catch();
321   }
322
323   /**
324    * Check any changes in the child component @public
325    */
326   public doChanges(): void {
327     setTimeout((): void => {
328       this.cd.detectChanges();
329     }, this.timeOut);
330   }
331 }