Fix Bug 2091: NS Update on NS Instances fail with database exception on screen when...
[osm/NG-UI.git] / src / app / utilities / ns-update / NsUpdateComponent.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 Ns Update Component
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, Injector, Input, OnInit } from '@angular/core';
23 import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { Router } from '@angular/router';
25 import { NgbActiveModal, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
26 import { TranslateService } from '@ngx-translate/core';
27 import { APIURLHEADER, CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
28 import { environment } from 'environment';
29 import { NSUPDATE, TERMINATEVNF } from 'NSInstanceModel';
30 import { RestService } from 'RestService';
31 import { SharedService } from 'SharedService';
32 import { isNullOrUndefined } from 'util';
33 import { VNFD } from 'VNFDModel';
34 import { VNFInstanceDetails } from 'VNFInstanceModel';
35 import { WarningComponent } from 'WarningComponent';
36
37 /**
38  * Creating component
39  * @Component takes NsUpdateComponent.html as template url
40  */
41 @Component({
42     selector: 'app-ns-update',
43     templateUrl: './NsUpdateComponent.html',
44     styleUrls: ['./NsUpdateComponent.scss']
45 })
46 export class NsUpdateComponent implements OnInit {
47     /** To inject services @public */
48     public injector: Injector;
49     /** Instance for active modal service @public */
50     public activeModal: NgbActiveModal;
51     /** Check the loading results @public */
52     public isLoadingResults: Boolean = false;
53     /** Give the message for the loading @public */
54     public message: string = 'PLEASEWAIT';
55     /** FormGroup instance added to the form @ html @public */
56     public nsUpdateForm: FormGroup;
57     /** Items for the member types @public */
58     public memberTypes: {}[];
59     /** Contains objects that is used to hold types of primitive @public */
60     public updateTypeList: {}[] = [];
61     /** Form valid on submit trigger @public */
62     public submitted: boolean = false;
63     /** Give the update type @public */
64     public terminateVnf: string;
65     /** Model value used to hold selected MemberVNFIndex @public */
66     public memberIndexValue: string;
67     /** Form Check vnfdId Section @public */
68     public vnfdIdShow: boolean = false;
69     /** Contains MemberVNFIndex values @public */
70     public memberVnfIndex: {}[] = [];
71     /** Contains MemberVNFIndex content @public */
72     public selectedVnf: {}[];
73     /** Array holds VNFR Data filtered with nsr ID @public */
74     public nsIdFilteredData: {}[] = [];
75     /** Contains vnfdId value @public */
76     public vnfdId: string;
77     /** Contains vnfId value of the selected MemberVnfIndex @public */
78     public vnfID: string;
79     /** Contains version of the selected MemberVnfIndex @public */
80     public version: string;
81     /** Contains version of the vnfId @public */
82     public vnfversion: string;
83     /** Contains vnfInstanceId of the selected MemberVnfIndex  @public */
84     public instanceId: string;
85     /** Selected VNFInstanceId @public */
86     public selectedvnfId: string = '';
87     /** Input contains component objects @private */
88     @Input() private params: URLPARAMS;
89     /** FormBuilder instance added to the formBuilder @private */
90     private formBuilder: FormBuilder;
91     /** Contains tranlsate instance @private */
92     private translateService: TranslateService;
93     /** Instance of the rest service @private */
94     private restService: RestService;
95     /** Controls the header form @private */
96     private headers: HttpHeaders;
97     /** Contains all methods related to shared @private */
98     private sharedService: SharedService;
99     /** Holds the instance of AuthService class of type AuthService @private */
100     private router: Router;
101     /** Instance of the modal service @private */
102     private modalService: NgbModal;
103     constructor(injector: Injector) {
104         this.injector = injector;
105         this.restService = this.injector.get(RestService);
106         this.activeModal = this.injector.get(NgbActiveModal);
107         this.formBuilder = this.injector.get(FormBuilder);
108         this.sharedService = this.injector.get(SharedService);
109         this.translateService = this.injector.get(TranslateService);
110         this.router = this.injector.get(Router);
111         this.modalService = this.injector.get(NgbModal);
112         this.updateTypeList = [
113             {
114                 title: this.translateService.instant('VNFPKGCHANGE'),
115                 value: 'CHANGE_VNFPKG'
116             },
117             {
118                 title: this.translateService.instant('REMOVEVNF'),
119                 value: 'REMOVE_VNF'
120             }
121         ];
122     }
123     /** convenience getter for easy access to form fields */
124     get f(): FormGroup['controls'] { return this.nsUpdateForm.controls; }
125     /**
126      * Lifecyle Hooks the trigger before component is instantiate
127      */
128     public ngOnInit(): void {
129         this.initializeForm();
130         this.getMemberVnfIndex();
131         this.headers = new HttpHeaders({
132             'Content-Type': 'application/json',
133             Accept: 'application/json',
134             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
135         });
136     }
137
138     /** Initialize Ns Update Forms @public */
139     public initializeForm(): void {
140         this.nsUpdateForm = this.formBuilder.group({
141             updateType: [null, [Validators.required]],
142             memberVnfIndex: [null, [Validators.required]],
143             vnfdId: [null, [Validators.required]]
144         });
145     }
146
147     /** Getting MemberVnfIndex using NSDescriptor API @public */
148     public getMemberVnfIndex(): void {
149         const vnfInstanceData: {}[] = [];
150         this.restService.getResource(environment.VNFINSTANCES_URL).subscribe((vnfInstancesData: VNFInstanceDetails[]): void => {
151             vnfInstancesData.forEach((vnfData: VNFInstanceDetails): void => {
152                 const vnfDataObj: {} =
153                 {
154                     VNFD: vnfData['vnfd-ref'],
155                     VNFInstanceId: vnfData._id,
156                     MemberIndex: vnfData['member-vnf-index-ref'],
157                     NS: vnfData['nsr-id-ref'],
158                     VNFID: vnfData['vnfd-id']
159                 };
160                 vnfInstanceData.push(vnfDataObj);
161             });
162             const nsId: string = 'NS';
163             this.nsIdFilteredData = vnfInstanceData.filter((vnfdData: {}[]): boolean => vnfdData[nsId] === this.params.id);
164             this.nsIdFilteredData.forEach((resVNF: {}[]): void => {
165                 const memberIndex: string = 'MemberIndex';
166                 const vnfinstanceID: string = 'VNFInstanceId';
167                 const assignMemberIndex: {} = {
168                     id: resVNF[memberIndex],
169                     vnfinstanceId: resVNF[vnfinstanceID]
170                 };
171                 this.memberVnfIndex.push(assignMemberIndex);
172             });
173             this.memberTypes = this.memberVnfIndex;
174             this.isLoadingResults = false;
175         }, (error: ERRORDATA): void => {
176             this.restService.handleError(error, 'get');
177             this.isLoadingResults = false;
178         });
179     }
180
181     /**
182      *  Fetching the VNFR Information filtered with MemberVnfIndex
183      *  Get the selected VNF Instance ID
184      */
185     public getSelectedVNF(id: string): void {
186         this.instanceId = id;
187         let memberIndexFilteredData: {}[] = [];
188         const memberIndex: string = 'MemberIndex';
189         memberIndexFilteredData = this.nsIdFilteredData.filter((vnfdData: {}[]): boolean =>
190             vnfdData[memberIndex] === this.memberIndexValue);
191         const vnfId: string = 'VNFID';
192         const selectedvnfId: string = 'VNFD';
193         this.selectedVnf = memberIndexFilteredData;
194         for (const data of memberIndexFilteredData) {
195             this.vnfID = data[vnfId];
196             this.selectedvnfId = data[selectedvnfId];
197         }
198     }
199
200     /** Trigger NsUpdate on submit */
201     public triggerNsUpdate(): void {
202         this.submitted = true;
203         this.sharedService.cleanForm(this.nsUpdateForm);
204         if (this.nsUpdateForm.invalid) { return; } // Proceed, onces form is valid
205         this.vnfdId = this.nsUpdateForm.value.vnfdId;
206         this.checkUpdateType();
207     }
208
209     /** Ns Update on submit */
210     public onSubmit(): void {
211         if (this.terminateVnf === 'REMOVE_VNF') {
212             const nsUpdateTerminatePayload: TERMINATEVNF = {
213                 lcmOperationType: 'update',
214                 updateType: this.nsUpdateForm.value.updateType,
215                 nsInstanceId: this.params.id,
216                 removeVnfInstanceId: this.instanceId
217             };
218             this.nsUpdateInitialization(nsUpdateTerminatePayload);
219         } else {
220             const nsUpdatePayload: NSUPDATE = {
221                 lcmOperationType: 'update',
222                 updateType: this.nsUpdateForm.value.updateType,
223                 nsInstanceId: this.params.id,
224                 changeVnfPackageData: {
225                     vnfInstanceId: this.instanceId,
226                     vnfdId: this.nsUpdateForm.value.vnfdId
227                 }
228             };
229             this.nsUpdateInitialization(nsUpdatePayload);
230         }
231     }
232
233     /**
234      *  Open Modal based on selected NS-UPDATE Type
235      */
236     public checkUpdateType(): void {
237         this.isLoadingResults = true;
238         if (this.nsUpdateForm.value.updateType === 'CHANGE_VNFPKG') {
239             this.checkVersion();
240         } else {
241             const modalRef: NgbModalRef = this.modalService.open(WarningComponent, { backdrop: 'static' });
242             modalRef.componentInstance.heading = this.translateService.instant('TERMINATEVNF');
243             modalRef.componentInstance.confirmationMessage = this.translateService.instant('TERMINATEVNFCONTENT');
244             modalRef.componentInstance.submitMessage = this.translateService.instant('TERMINATEVNF');
245             modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
246                 if (result.message === CONFIGCONSTANT.done) {
247                     this.onSubmit();
248                 }
249             }).catch((): void => { //empty
250              });
251         }
252         this.isLoadingResults = false;
253     }
254
255     /** To check the versions are matching or not for 'CHANGE_VNFPKG' type */
256     public checkVersion(): void {
257         this.isLoadingResults = true;
258         const vnfDetails: {}[] = [];
259         this.restService.getResource(environment.VNFPACKAGESCONTENT_URL + '/' + this.vnfdId).subscribe((vnfData: VNFD[]): void => {
260             if (!isNullOrUndefined(vnfData['software-version'])) {
261                 this.version = vnfData['software-version'];
262             }
263             this.restService.getResource(environment.VNFPACKAGESCONTENT_URL).subscribe((vnfDetail: VNFD[]): void => {
264                 vnfDetail.forEach((vnfDatas: VNFD): void => {
265                     const vnfDataObj: {} =
266                     {
267                         VNFID: vnfDatas._id,
268                         version: vnfDatas['software-version']
269                     };
270                     vnfDetails.push(vnfDataObj);
271                 });
272                 let vnfIdFilteredData: {}[] = [];
273                 const vnfID: string = 'VNFID';
274                 const version: string = 'version';
275                 vnfIdFilteredData = vnfDetails.filter((vnfdData: {}[]): boolean => vnfdData[vnfID] === this.vnfID);
276                 for (const data of vnfIdFilteredData) {
277                     this.vnfversion = data[version];
278                 }
279                 if (this.version === this.vnfversion) {
280                     const modalRef: NgbModalRef = this.modalService.open(WarningComponent, { backdrop: 'static' });
281                     modalRef.componentInstance.heading = this.translateService.instant('UPDATENS');
282                     modalRef.componentInstance.confirmationMessage = this.translateService.instant('GENERICCONTENT');
283                     modalRef.componentInstance.submitMessage = this.translateService.instant('UPDATENS');
284                     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
285                         if (result.message === CONFIGCONSTANT.done) {
286                             this.onSubmit();
287                         }
288                     }).catch((): void => { //empty
289                      }
290                     );
291                 } else {
292                     const modalRef: NgbModalRef = this.modalService.open(WarningComponent, { backdrop: 'static' });
293                     modalRef.componentInstance.heading = this.translateService.instant('REDEPLOY');
294                     modalRef.componentInstance.confirmationMessage = this.translateService.instant('REDEPLOYCONTENT');
295                     modalRef.componentInstance.submitMessage = this.translateService.instant('REDEPLOY');
296                     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
297                         if (result.message === CONFIGCONSTANT.done) {
298                             this.onSubmit();
299                         }
300                     }).catch((): void => { //empty
301                      });
302                 }
303             }, (error: ERRORDATA): void => {
304                 this.restService.handleError(error, 'get');
305                 this.isLoadingResults = false;
306             });
307             this.isLoadingResults = false;
308         }, (error: ERRORDATA): void => {
309             this.restService.handleError(error, 'get');
310             this.isLoadingResults = false;
311         });
312     }
313
314     /** Initialize the Ns Update @public */
315     public nsUpdateInitialization(nsUpdatePayload: object): void {
316         this.isLoadingResults = true;
317         const apiURLHeader: APIURLHEADER = {
318             url: environment.NSDINSTANCES_URL + '/' + this.params.id + '/update',
319             httpOptions: { headers: this.headers }
320         };
321         const modalData: MODALCLOSERESPONSEDATA = {
322             message: 'Done'
323         };
324         this.restService.postResource(apiURLHeader, nsUpdatePayload).subscribe((result: {}): void => {
325             this.activeModal.close(modalData);
326             this.router.navigate(['/instances/ns/history-operations/' + this.params.id]).catch();
327         }, (error: ERRORDATA): void => {
328             this.restService.handleError(error, 'post');
329             this.isLoadingResults = false;
330         });
331     }
332
333     /** To enable or disable vnfdId field @public */
334     public terminateVNF(value: string): void {
335         this.terminateVnf = value;
336         if (this.terminateVnf === 'REMOVE_VNF') {
337             this.vnfdIdShow = true;
338             this.getFormControl('vnfdId').disable();
339         } else {
340             this.vnfdIdShow = false;
341             this.getFormControl('vnfdId').enable();
342         }
343     }
344
345     /** Used to get the AbstractControl of controlName passed @private */
346     private getFormControl(controlName: string): AbstractControl {
347         return this.nsUpdateForm.controls[controlName];
348     }
349 }