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