Fix Bug 2336: Manual Healing option in Ui
[osm/NG-UI.git] / src / app / utilities / healing / HealingComponent.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 Healing 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, FormArray, 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 { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
29 import { environment } from 'environment';
30 import { VDUMAP, VDUMAPPINGS } from 'NSInstanceModel';
31 import { RestService } from 'RestService';
32 import { SharedService } from 'SharedService';
33 import { InstanceData, VDUR, VNFInstanceDetails } from 'VNFInstanceModel';
34 /**
35  * Creating component
36  * @Component takes HealingComponent.html as template url
37  */
38 @Component({
39     selector: 'app-healing',
40     templateUrl: './HealingComponent.html',
41     styleUrls: ['./HealingComponent.scss']
42 })
43 export class HealingComponent 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     /** Member index of the NS @public */
53     public memberVNFIndex: {}[] = [];
54     /** Items for the memberVNFIndex @public */
55     public memberTypes: {}[];
56     /** Items for the Day1 operation  @public */
57     public day1Operation: {}[];
58     /** Items for the vdu-Id and count-index @public */
59     public vdu: {}[];
60     /** Selected VNFInstanceId @public */
61     public selectedvnfId: string = '';
62     /** Contains vduId @public */
63     public vduId: {};
64     /** VDU Mapping @public */
65     public vduMap: VDUMAP = {};
66     /** Items for countIndex @public */
67     public countIndex: {}[];
68     /** Contains vnfInstanceId of the selected MemberVnfIndex  @public */
69     public instanceId: string;
70     /** FormGroup instance added to the form @ html @public */
71     public healingForm: FormGroup;
72     /** Form valid on submit trigger @public */
73     public submitted: boolean = false;
74     /** VDU Form array @private */
75     private vduFormArray: FormArray;
76     /** Array holds VNFR Data filtered with nsr ID @private */
77     private nsIdFilteredData: {}[] = [];
78     /** FormBuilder instance added to the formBuilder @private */
79     private formBuilder: FormBuilder;
80     /** Instance of the rest service @private */
81     private restService: RestService;
82     /** Controls the header form @private */
83     private headers: HttpHeaders;
84     /** Contains tranlsate instance @private */
85     private translateService: TranslateService;
86     /** Input contains component objects @private */
87     @Input() private params: URLPARAMS;
88     /** Contains all methods related to shared @private */
89     private sharedService: SharedService;
90     /** Holds teh instance of AuthService class of type AuthService @private */
91     private router: Router;
92
93     constructor(injector: Injector) {
94         this.injector = injector;
95         this.restService = this.injector.get(RestService);
96         this.activeModal = this.injector.get(NgbActiveModal);
97         this.translateService = this.injector.get(TranslateService);
98         this.formBuilder = this.injector.get(FormBuilder);
99         this.sharedService = this.injector.get(SharedService);
100         this.router = this.injector.get(Router);
101     }
102
103     /** convenience getter for easy access to form fields */
104     get f(): FormGroup['controls'] { return this.healingForm.controls; }
105
106     /**
107      * Lifecyle Hooks the trigger before component is instantiate
108      */
109     public ngOnInit(): void {
110         this.initializeForm();
111         this.getmemberIndex();
112         this.day1Operation = [
113             { id: 'true', name: this.translateService.instant('True') },
114             { id: '', name: this.translateService.instant('False') }
115         ];
116         this.headers = new HttpHeaders({
117             'Content-Type': 'application/json',
118             Accept: 'application/json',
119             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
120         });
121     }
122
123     /** Generate primitive params @public */
124     get vduParamsBuilder(): FormGroup {
125         return this.formBuilder.group({
126             vduId: [null],
127             countIndex: [null],
128             runDay1: [null]
129         });
130     }
131
132     /** Initialize Healing Forms @public */
133     public initializeForm(): void {
134         this.healingForm = this.formBuilder.group({
135             memberIndex: [null, [Validators.required]],
136             run_day1: [null],
137             vdu: this.formBuilder.array([])
138         });
139     }
140
141     /** Handle FormArray Controls @public */
142     public getControls(): AbstractControl[] {
143         return (this.healingForm.get('vdu') as FormArray).controls;
144     }
145
146     /** Get the member-vnf-index from NS Package -> vnf-profile @private */
147     private getmemberIndex(): void {
148         this.isLoadingResults = true;
149         const vnfInstanceData: {}[] = [];
150         this.restService.getResource(environment.VNFINSTANCES_URL).subscribe((vnfInstancesData: VNFInstanceDetails[]): void => {
151             vnfInstancesData.forEach((vnfData: VNFInstanceDetails): void => {
152                 const nsrId: string = 'nsr-id-ref';
153                 const memberIndex: string = 'member-vnf-index-ref';
154                 const vnfDataObj: {} =
155                 {
156                     VNFInstanceId: vnfData._id,
157                     // eslint-disable-next-line security/detect-object-injection
158                     MemberIndex: vnfData[memberIndex],
159                     // eslint-disable-next-line security/detect-object-injection
160                     NS: vnfData[nsrId]
161                 };
162                 vnfInstanceData.push(vnfDataObj);
163             });
164             const nsId: string = 'NS';
165             // eslint-disable-next-line security/detect-object-injection
166             this.nsIdFilteredData = vnfInstanceData.filter((vnfdData: {}[]): boolean => vnfdData[nsId] === this.params.id);
167             this.nsIdFilteredData.forEach((resVNF: InstanceData): void => {
168                 const assignMemberIndex: {} = {
169                     id: resVNF.MemberIndex,
170                     vnfinstanceId: resVNF.VNFInstanceId
171                 };
172                 this.memberVNFIndex.push(assignMemberIndex);
173             });
174             this.memberTypes = this.memberVNFIndex;
175             this.isLoadingResults = false;
176         }, (error: ERRORDATA): void => {
177             this.restService.handleError(error, 'get');
178             this.isLoadingResults = false;
179         });
180     }
181
182     /** Getting vdu-id & count-index from VNFInstance API */
183     public getVdu(id: string): void {
184         this.isLoadingResults = true;
185         this.vdu = [];
186         const vnfInstanceData: {}[] = [];
187         this.instanceId = id;
188         if (!isNullOrUndefined(id)) {
189             this.restService.getResource(environment.VNFINSTANCES_URL + '/' + id).
190                 subscribe((vnfInstanceDetail: VNFInstanceDetails): void => {
191                     this.selectedvnfId = vnfInstanceDetail['vnfd-ref'];
192                     if (!isNullOrUndefined(vnfInstanceDetail.vdur)) {
193                         vnfInstanceDetail.vdur.forEach((vdu: VDUR): void => {
194                             const vnfInstanceDataObj: {} =
195                             {
196                                 'count-index': vdu['count-index'],
197                                 VDU: vdu['vdu-id-ref']
198                             };
199                             vnfInstanceData.push(vnfInstanceDataObj);
200                         });
201                         this.vdu = vnfInstanceData;
202                         this.vduId = this.vdu.filter((vdu: { VDU?: string }, index: number, self: {}[]): {} =>
203                             index === self.findIndex((t: { VDU?: string }): {} => (
204                                 // eslint-disable-next-line security/detect-object-injection
205                                 t.VDU === vdu.VDU
206                             ))
207                         );
208                         this.isLoadingResults = false;
209                     }
210                 }
211                     , (error: ERRORDATA): void => {
212                         this.restService.handleError(error, 'get');
213                         this.isLoadingResults = false;
214                     });
215         }
216     }
217
218     /** Getting count-index by filtering id  */
219     public getCountIndex(id: string): void {
220         const VDU: string = 'VDU';
221         // eslint-disable-next-line security/detect-object-injection
222         this.countIndex = this.vdu.filter((vnfdData: {}[]): boolean => vnfdData[VDU] === id);
223     }
224
225
226     /** Add vdu @public */
227     public addVdu(): void {
228         this.vduFormArray = this.healingForm.get('vdu') as FormArray;
229         this.vduFormArray.push(this.vduParamsBuilder);
230     }
231
232     /** Remove vdu @public */
233     public removeMapping(index: number): void {
234         this.vduFormArray.removeAt(index);
235     }
236
237     /** If form is valid and call healInstances method to initialize healing @public */
238     public manualHealingTrigger(): void {
239         this.submitted = true;
240         let healingPayload: object = {};
241         this.sharedService.cleanForm(this.healingForm);
242         if (this.healingForm.invalid) { return; } // Proceed, onces form is valid
243         this.vduMap.vdu_mappings = [];
244         this.healingForm.value.vdu.forEach((res: VDUMAPPINGS): void => {
245             this.vduMap.vdu_mappings.push({ 'vdu-id': res.vduId, 'count-index': res.countIndex, 'run-day1': Boolean(res.runDay1) });
246         });
247         if (this.vduMap.vdu_mappings.length !== 0) {
248             healingPayload = {
249                 healVnfData:
250                     [{
251                         vnfInstanceId: this.instanceId,
252                         cause: 'manual',
253                         additionalParams: {
254                             'run-day1': false,
255                             vdu: this.vduMap.vdu_mappings
256                         }
257                     }]
258             };
259         } else {
260             healingPayload = {
261                 healVnfData:
262                     [{
263                         vnfInstanceId: this.instanceId,
264                         cause: 'manual',
265                         additionalParams: {
266                             'run-day1': Boolean(this.getFormControl('run_day1').value)
267                         }
268                     }]
269             };
270         }
271         this.healInstances(healingPayload);
272     }
273
274     /** Initialize the healing @public */
275     public healInstances(healingPayload: object): void {
276         this.isLoadingResults = true;
277         const apiURLHeader: APIURLHEADER = {
278             url: environment.NSDINSTANCES_URL + '/' + this.params.id + '/heal',
279             httpOptions: { headers: this.headers }
280         };
281         const modalData: MODALCLOSERESPONSEDATA = {
282             message: 'Done'
283         };
284         this.restService.postResource(apiURLHeader, healingPayload).subscribe((result: {}): void => {
285             this.activeModal.close(modalData);
286             this.router.navigate(['/instances/ns/history-operations/' + this.params.id]).catch((): void => {
287                 // Catch Navigation Error
288             });
289         }, (error: ERRORDATA): void => {
290             this.restService.handleError(error, 'post');
291             this.isLoadingResults = false;
292         });
293     }
294
295     /** Used to get the AbstractControl of controlName passed @private */
296     private getFormControl(controlName: string): AbstractControl {
297         // eslint-disable-next-line security/detect-object-injection
298         return this.healingForm.controls[controlName];
299     }
300 }