Fix Bug 2292: Invalid Member VNF index in Manual Scaling after NS Update remove operation
[osm/NG-UI.git] / src / app / utilities / vertical-scaling / VerticalScalingComponent.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: SANDHYA JS (sandhya.j@tataelxsi.co.in)
17 */
18 /**
19  * @file VerticalScaling Component
20  */
21 import { isNullOrUndefined } from 'util';
22 import { HttpHeaders } from '@angular/common/http';
23 import { Component, Injector, Input, OnInit } from '@angular/core';
24 import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
25 import { Router } from '@angular/router';
26 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
27 import { TranslateService } from '@ngx-translate/core';
28 import { NotifierService } from 'angular-notifier';
29 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
30 import { environment } from 'environment';
31 import { VerticalScaling } from 'NSInstanceModel';
32 import { RestService } from 'RestService';
33 import { SharedService } from 'SharedService';
34 import { InstanceData, VDUR, VNFInstanceDetails } from 'VNFInstanceModel';
35
36 /**
37  * Creating component
38  * @Component takes VerticalScalingComponent.html as template url
39  */
40 @Component({
41     selector: 'app-vertical-scaling',
42     templateUrl: './VerticalScalingComponent.html',
43     styleUrls: ['./VerticalScalingComponent.scss']
44 })
45 export class VerticalScalingComponent implements OnInit {
46     /** To inject services @public */
47     public injector: Injector;
48     /** Instance for active modal service @public */
49     public activeModal: NgbActiveModal;
50     /** Check the loading results @public */
51     public isLoadingResults: Boolean = false;
52     /** Give the message for the loading @public */
53     public message: string = 'PLEASEWAIT';
54     /** FormGroup instance added to the form @ html @public */
55     public scalingForm: FormGroup;
56     /** Items for the memberVNFIndex @public */
57     public memberTypes: {}[];
58     /** Contains MemberVNFIndex values @public */
59     public memberVnfIndex: {}[] = [];
60     /** Contains vnfInstanceId of the selected MemberVnfIndex  @public */
61     public instanceId: string;
62     /** Items for vduId & countIndex @public */
63     public vdu: {}[];
64     /** Selected VNFInstanceId @public */
65     public selectedvnfId: string = '';
66     /** Array holds VNFR Data filtered with nsr ID @public */
67     public nsIdFilteredData: {}[] = [];
68     /** Form valid on submit trigger @public */
69     public submitted: boolean = false;
70     /** Contains vduId @public */
71     public vduId: {};
72     /** Items for countIndex @public */
73     public countIndex: {}[];
74     /** Input contains component objects @private */
75     @Input() private params: URLPARAMS;
76     /** FormBuilder instance added to the formBuilder @private */
77     private formBuilder: FormBuilder;
78     /** Instance of the rest service @private */
79     private restService: RestService;
80     /** Controls the header form @private */
81     private headers: HttpHeaders;
82     /** Contains all methods related to shared @private */
83     private sharedService: SharedService;
84     /** Notifier service to popup notification @private */
85     private notifierService: NotifierService;
86     /** Contains tranlsate instance @private */
87     private translateService: TranslateService;
88     /** Holds the instance of AuthService class of type AuthService @private */
89     private router: Router;
90     constructor(injector: Injector) {
91         this.injector = injector;
92         this.restService = this.injector.get(RestService);
93         this.activeModal = this.injector.get(NgbActiveModal);
94         this.formBuilder = this.injector.get(FormBuilder);
95         this.sharedService = this.injector.get(SharedService);
96         this.notifierService = this.injector.get(NotifierService);
97         this.translateService = this.injector.get(TranslateService);
98         this.router = this.injector.get(Router);
99     }
100     /** convenience getter for easy access to form fields */
101     get f(): FormGroup['controls'] { return this.scalingForm.controls; }
102     /**
103      * Lifecyle Hooks the trigger before component is instantiate
104      */
105     public ngOnInit(): void {
106         this.initializeForm();
107         this.getMemberVnfIndex();
108         this.headers = new HttpHeaders({
109             'Content-Type': 'application/json',
110             Accept: 'application/json',
111             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
112         });
113     }
114     /** Initialize Scaling Forms @public */
115     public initializeForm(): void {
116         this.scalingForm = this.formBuilder.group({
117             memberVnfIndex: [null, [Validators.required]],
118             vduId: [null, [Validators.required]],
119             countIndex: [null, [Validators.required]],
120             virtualMemory: [null, [Validators.required]],
121             sizeOfStorage: [null, [Validators.required]],
122             numVirtualCpu: [null, [Validators.required]]
123         });
124     }
125
126     /** Getting MemberVnfIndex using VNFInstances API @public */
127     public getMemberVnfIndex(): void {
128         this.isLoadingResults = true;
129         const vnfInstanceData: {}[] = [];
130         this.restService.getResource(environment.VNFINSTANCES_URL).subscribe((vnfInstancesData: VNFInstanceDetails[]): void => {
131             vnfInstancesData.forEach((vnfData: VNFInstanceDetails): void => {
132                 const vnfdRef: string = 'vnfd-ref';
133                 const memberIndex: string = 'member-vnf-index-ref';
134                 const nsrId: string = 'nsr-id-ref';
135                 const vnfId: string = 'vnfd-id';
136                 const vnfDataObj: {} =
137                 {
138                     // eslint-disable-next-line security/detect-object-injection
139                     VNFD: vnfData[vnfdRef],
140                     VNFInstanceId: vnfData._id,
141                     // eslint-disable-next-line security/detect-object-injection
142                     MemberIndex: vnfData[memberIndex],
143                     // eslint-disable-next-line security/detect-object-injection
144                     NS: vnfData[nsrId],
145                     // eslint-disable-next-line security/detect-object-injection
146                     VNFID: vnfData[vnfId]
147                 };
148                 vnfInstanceData.push(vnfDataObj);
149             });
150             const nsId: string = 'NS';
151             // eslint-disable-next-line security/detect-object-injection
152             this.nsIdFilteredData = vnfInstanceData.filter((vnfdData: {}[]): boolean => vnfdData[nsId] === this.params.id);
153             this.nsIdFilteredData.forEach((resVNF: InstanceData): void => {
154                 const assignMemberIndex: {} = {
155                     id: resVNF.MemberIndex,
156                     vnfinstanceId: resVNF.VNFInstanceId
157                 };
158                 this.memberVnfIndex.push(assignMemberIndex);
159             });
160             this.memberTypes = this.memberVnfIndex;
161             this.isLoadingResults = false;
162         }, (error: ERRORDATA): void => {
163             this.restService.handleError(error, 'get');
164             this.isLoadingResults = false;
165         });
166     }
167
168     /** Getting vdu-id & count-index from API */
169     public getVdu(id: string): void {
170         const vnfInstanceData: {}[] = [];
171         this.getFormControl('vduId').setValue(null);
172         this.getFormControl('countIndex').setValue(null);
173         if (!isNullOrUndefined(id)) {
174             this.restService.getResource(environment.VNFINSTANCES_URL + '/' + id).
175                 subscribe((vnfInstanceDetail: VNFInstanceDetails[]): void => {
176                     this.instanceId = id;
177                     this.selectedvnfId = vnfInstanceDetail['vnfd-ref'];
178                     const VDU: string = 'vdur';
179                     // eslint-disable-next-line security/detect-object-injection
180                     if (vnfInstanceDetail[VDU] !== undefined) {
181                         // eslint-disable-next-line security/detect-object-injection
182                         vnfInstanceDetail[VDU].forEach((vdu: VDUR): void => {
183                             const vnfInstanceDataObj: {} =
184                             {
185                                 'count-index': vdu['count-index'],
186                                 VDU: vdu['vdu-id-ref']
187                             };
188                             vnfInstanceData.push(vnfInstanceDataObj);
189                         });
190                         this.vdu = vnfInstanceData;
191                         const vduName: string = 'VDU';
192                         this.vduId = this.vdu.filter((vdu: {}, index: number, self: {}[]): {} =>
193                             index === self.findIndex((t: {}): {} => (
194                                 // eslint-disable-next-line security/detect-object-injection
195                                 t[vduName] === vdu[vduName]
196                             ))
197                         );
198                     }
199                 }, (error: ERRORDATA): void => {
200                     this.restService.handleError(error, 'get');
201                     this.isLoadingResults = false;
202                 });
203         }
204     }
205
206     /** Getting count-index by filtering id  */
207     public getCountIndex(id: string): void {
208         const VDU: string = 'VDU';
209         // eslint-disable-next-line security/detect-object-injection
210         this.countIndex = this.vdu.filter((vnfdData: {}[]): boolean => vnfdData[VDU] === id);
211     }
212
213     /** Vertical Scaling on submit */
214     public triggerVerticalScaling(): void {
215         this.submitted = true;
216         this.sharedService.cleanForm(this.scalingForm);
217         if (!this.scalingForm.invalid) {
218             const scalingPayload: VerticalScaling = {
219                 lcmOperationType: 'verticalscale',
220                 verticalScale: 'CHANGE_VNFFLAVOR',
221                 nsInstanceId: this.params.id,
222                 changeVnfFlavorData: {
223                     vnfInstanceId: this.instanceId,
224                     additionalParams: {
225                         vduid: this.scalingForm.value.vduId,
226                         vduCountIndex: this.scalingForm.value.countIndex,
227                         virtualMemory: Number(this.scalingForm.value.virtualMemory),
228                         sizeOfStorage: Number(this.scalingForm.value.sizeOfStorage),
229                         numVirtualCpu: Number(this.scalingForm.value.numVirtualCpu)
230                     }
231                 }
232             };
233             this.verticalscaleInitialization(scalingPayload);
234         }
235     }
236
237     /** Initialize the vertical scaling operation @public */
238     public verticalscaleInitialization(scalingPayload: object): void {
239         this.isLoadingResults = true;
240         const apiURLHeader: APIURLHEADER = {
241             url: environment.NSDINSTANCES_URL + '/' + this.params.id + '/verticalscale',
242             httpOptions: { headers: this.headers }
243         };
244         const modalData: MODALCLOSERESPONSEDATA = {
245             message: 'Done'
246         };
247         this.restService.postResource(apiURLHeader, scalingPayload).subscribe((result: {}): void => {
248             this.activeModal.close(modalData);
249             this.router.navigate(['/instances/ns/history-operations/' + this.params.id]).catch((): void => {
250                 // Catch Navigation Error
251             });
252         }, (error: ERRORDATA): void => {
253             this.restService.handleError(error, 'post');
254             this.isLoadingResults = false;
255         });
256     }
257
258     /** Used to get the AbstractControl of controlName passed @private */
259     private getFormControl(controlName: string): AbstractControl {
260         // eslint-disable-next-line security/detect-object-injection
261         return this.scalingForm.controls[controlName];
262     }
263 }