Fix Bug 2048:The VCA Status for an NS with both a KNF and a VNF does not provide...
[osm/NG-UI.git] / src / app / operational-view / OperationalViewComponent.ts
1 /* eslint-disable security/detect-object-injection */
2 /*
3  Copyright 2020 TATA ELXSI
4
5  Licensed under the Apache License, Version 2.0 (the 'License');
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8
9     http://www.apache.org/licenses/LICENSE-2.0
10
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16
17  Author: BARATH KUMAR R (barath.r@tataelxsi.co.in)
18 */
19
20 /**
21  * @file Page for Operational View Component
22  */
23 import { Component, Injector, OnInit } from '@angular/core';
24 import { ActivatedRoute } from '@angular/router';
25 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
26 import { TranslateService } from '@ngx-translate/core';
27 import { CONSTANTNUMBER, ERRORDATA } from 'CommonModel';
28 import { environment } from 'environment';
29 import * as HttpStatus from 'http-status-codes';
30 import { OperationalViewAppActionsComponent } from 'OperationalAppActionsComponent';
31 import { OperationalViewAppConfigsComponent } from 'OperationalAppConfigsComponent';
32 import { OperationalViewAppExecutedActionsComponent } from 'OperationalAppExecutedActionsComponent';
33 import { EXECUTEDACTIONS, MACHINES, SET_TIMER, SETMODELS, SETTIMER, VCAAPPLICATIONS, VCADETAILS, VCASTATUS, VCAUNITS } from 'OperationalModel';
34 import { RestService } from 'RestService';
35 import { Observable } from 'rxjs';
36 import { Subscription } from 'rxjs';
37 import { map } from 'rxjs/operators';
38 import { SharedService, isNullOrUndefined } from 'SharedService';
39 /**
40  * Creating component
41  * @Component takes OperationalViewComponent.html as template url
42  */
43 @Component({
44     selector: 'app-operational-view',
45     templateUrl: './OperationalViewComponent.html'
46 })
47 /** Exporting a class @exports OperationalViewComponent */
48 export class OperationalViewComponent implements OnInit {
49     /** Invoke service injectors @public */
50     public injector: Injector;
51
52     /** Check the loading results @public */
53     public isLoadingResults: boolean = false;
54
55     /** Give the message for the loading @public */
56     public message: string = 'PLEASEWAIT';
57
58     /** Formation of appropriate Data for vcaStatus Details @public */
59     public vcaDetails: VCADETAILS[] = [];
60
61     /** Contains all methods related to shared @public */
62     public sharedService: SharedService;
63
64     /** Utilizes rest service for any CRUD operations @public */
65     public restService: RestService;
66
67     /** variables contains activeID @public */
68     public activeID: string = null;
69
70     /** variables contains NS Instances ID @public */
71     public instancesID: string = null;
72
73     /** variables contains URL of operational Dashboard @public */
74     public openURL: string = 'instances/operational-view/';
75
76     /** variables contains default seconds for the timeout @public */
77     public timeOutDefaultSeconds: number = CONSTANTNUMBER.timeOutDefaultSeconds;
78
79     /** variables contains minimum seconds for the timeout @public */
80     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
81     public minSeconds: number = 5;
82
83     /** variables contains maximum seconds for the timeout @public */
84     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
85     public maxSeconds: number = 60;
86
87     /** variables contains timer calculation value of milliseconds @public */
88     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
89     public timeDefaultCal: number = 1000;
90
91     /** variables contains timeout @public */
92     public timeOut: number;
93
94     /** Set the timer button @public */
95     // eslint-disable-next-line no-magic-numbers
96     public setSeconds: SETTIMER[] = SET_TIMER;
97
98     /** Instance of subscriptions @private */
99     private generateDataSub: Subscription;
100
101     /** Contains tranlsate instance @private */
102     private translateService: TranslateService;
103
104     /** Holds teh instance of AuthService class of type AuthService @private */
105     private activatedRoute: ActivatedRoute;
106
107     /** Instance of the modal service @private */
108     private modalService: NgbModal;
109
110     /** creates Operational view component */
111     constructor(injector: Injector) {
112         this.injector = injector;
113         this.restService = this.injector.get(RestService);
114         this.sharedService = this.injector.get(SharedService);
115         this.translateService = this.injector.get(TranslateService);
116         this.activatedRoute = this.injector.get(ActivatedRoute);
117         this.modalService = this.injector.get(NgbModal);
118     }
119
120     /**
121      * Lifecyle Hooks the trigger before component is instantiate
122      */
123     public ngOnInit(): void {
124         this.instancesID = this.activatedRoute.snapshot.paramMap.get('id');
125         this.generateData();
126         this.generateDataSub = this.sharedService.dataEvent.subscribe((): void => { this.generateData(); });
127     }
128     /** Fetching the juju vca_status data from API and Load it in the respective table @public */
129     public generateData(): void {
130         this.clearTimeoutAndInterval();
131         this.modalService.dismissAll();
132         this.isLoadingResults = true;
133         this.vcaDetails = [];
134         let NSURL: string = environment.NSDINSTANCES_URL;
135         if (this.instancesID !== null) {
136             NSURL = NSURL + '/' + this.instancesID;
137             this.generateIndividualNSData(NSURL);
138         } else {
139             this.generateAllNSData(NSURL);
140         }
141     }
142     /**
143      * Show all NS Data that contains the juju vca_status from API and Load it in the table @public
144      * @param NSURL : osm/nslcm/v1/ns_instances
145      */
146     public generateAllNSData(NSURL: string): void {
147         this.restService.getResource(NSURL).subscribe((operationalList: VCASTATUS[]): void => {
148             if (operationalList.length > 0) {
149                 operationalList.forEach((list: VCASTATUS): void => {
150                     if (!isNullOrUndefined(list.vcaStatus)) {
151                         const getVCAStatusDetails: VCADETAILS = this.vcaDetailsData(list, false, this.timeOutDefaultSeconds);
152                         this.vcaDetails.push(getVCAStatusDetails);
153                     }
154                 });
155                 if (this.activeID === null && this.vcaDetails.length > 0) {
156                     this.activeID = this.vcaDetails[0].ns_id;
157                 }
158             }
159             this.isLoadingResults = false;
160         }, (error: ERRORDATA): void => {
161             this.isLoadingResults = false;
162             this.restService.handleError(error, 'get');
163         });
164     }
165     /**
166      * Show the individual NS Data that contains the juju vca_status from generateNSData method and Load it in the table @public
167      * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
168      */
169     public generateIndividualNSData(NSURL: string): void {
170         this.generateNSData(NSURL, false, this.timeOutDefaultSeconds).subscribe((getVCAStatusDetails: VCADETAILS): void => {
171             this.vcaDetails.push(getVCAStatusDetails);
172             if (this.activeID === null && this.vcaDetails.length > 0) {
173                 this.activeID = this.instancesID;
174             }
175             this.isLoadingResults = false;
176         }, (error: ERRORDATA): void => {
177             this.isLoadingResults = false;
178             this.restService.handleError(error, 'get');
179         });
180     }
181     /**
182      * Fetching the Individual NS Data that contains the juju vca_status from API and return the VCADetails @public
183      * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
184      * @param liveData : Needs to repeat the httprequest
185      * @param timeOutSeconds : set the timeout seconds to trigger the httprequest
186      */
187     public generateNSData(NSURL: string, liveData: boolean, timeOutSeconds: number): Observable<VCADETAILS> {
188         if (liveData) {
189             NSURL = NSURL + '?vcaStatusRefresh=true';
190         }
191         return this.restService.getResource(NSURL).pipe(map((operationalList: VCASTATUS): VCADETAILS => this.vcaDetailsData(operationalList, liveData, timeOutSeconds)));
192     }
193     /**
194      * Form the VCA Details for each NS Instances
195      */
196     public formVCADetails(getData: VCADETAILS): VCADETAILS {
197         return {
198             isLiveloading: getData.isLiveloading,
199             ns_id: getData.ns_id,
200             vcaStatusModels: getData.vcaStatusModels,
201             timeOutSeconds: getData.timeOutSeconds,
202             vca_id: getData.vca_id,
203             vca_name: getData.vca_name
204         };
205     }
206     /**
207      * Assign the VCA Status of Multiple model in getModels array for each NS Instance
208      */
209     public assignVCAStatusOfEachModel(getData: SETMODELS): SETMODELS {
210         return {
211             applications: getData.applications,
212             branches: getData.branches,
213             controller_timestamp: getData.controller_timestamp,
214             executedActions: getData.executedActions,
215             machines: getData.machines,
216             model: getData.model,
217             offers: getData.offers,
218             relations: getData.relations,
219             remote_applications: getData.remote_applications,
220             units: getData.units,
221             unknown_fields: getData.unknown_fields
222         };
223     }
224     /**
225      * Use to fetch the vcaDetails from vca_status @public
226      */
227     public vcaDetailsData(list: VCASTATUS, liveData: boolean, timeOutSeconds: number): VCADETAILS {
228         const assignVCADetails: VCADETAILS[] = [];
229         const setModels: SETMODELS[] = [];
230         Object.keys(list.vcaStatus).forEach((key: string): void => {
231             let vcaStatus = [];
232             vcaStatus = Object.values(list.vcaStatus[key]);
233             if (!isNullOrUndefined(vcaStatus)) {
234                 vcaStatus.forEach((data): void => {
235                     const vcaApplication: VCAAPPLICATIONS[] = this.appData(data.applications);
236                     const vcaUnits: VCAUNITS[] = this.unitsData(vcaApplication);
237                     const vcaMachines: MACHINES[] = this.machinesData(data.machines);
238                     const assignNSInstancesID: string = key;
239                     data.units = vcaUnits;
240                     data.applications = vcaApplication;
241                     data.machines = vcaMachines;
242                     // eslint-disable-next-line no-self-assign
243                     data.relations = data.relations;
244                     // eslint-disable-next-line no-self-assign
245                     data.model = data.model;
246                     const getEachModelData: SETMODELS = this.assignVCAStatusOfEachModel(data);
247                     setModels.push(getEachModelData);
248                     list.vcaStatus[assignNSInstancesID].vca_id = key;
249                     list.vcaStatus[assignNSInstancesID].vca_name = list.name;
250                     list.vcaStatus[assignNSInstancesID].ns_id = list.id;
251                     list.vcaStatus[assignNSInstancesID].isLiveloading = liveData;
252                     list.vcaStatus[assignNSInstancesID].timeOutSeconds = timeOutSeconds;
253                     list.vcaStatus[assignNSInstancesID].vcaStatusModels = setModels;
254                     const getAssignedData: VCADETAILS = this.formVCADetails(list.vcaStatus[assignNSInstancesID]);
255                     assignVCADetails.push(getAssignedData);
256                 });
257             }
258         });
259         return assignVCADetails[0];
260     }
261     /**
262      * Use to fetch the app data from vca_status @public
263      */
264     public appData(applicationData: VCAAPPLICATIONS): VCAAPPLICATIONS[] {
265         const vcaApplication: VCAAPPLICATIONS[] = [];
266         Object.keys(applicationData).forEach((applicationKey: string): void => {
267             if (!isNullOrUndefined(applicationData[applicationKey].charm)) {
268                 const charmSplitlist: string[] = applicationData[applicationKey].charm.split('/');
269                 const status: string = applicationData[applicationKey].status.status;
270                 // eslint-disable-next-line deprecation/deprecation
271                 const charm: string = charmSplitlist[1].substr(0, charmSplitlist[1].lastIndexOf('-'));
272                 // eslint-disable-next-line deprecation/deprecation
273                 const store: string = charmSplitlist[0].substr(0, charmSplitlist[0].lastIndexOf(':'));
274                 applicationData[applicationKey].app_id = applicationKey;
275                 applicationData[applicationKey].charm = charm;
276                 applicationData[applicationKey].status = status;
277                 applicationData[applicationKey].scale = Object.keys(applicationData[applicationKey].units).length;
278                 applicationData[applicationKey].store = store;
279                 applicationData[applicationKey].configs = !isNullOrUndefined(applicationData[applicationKey].configs) ?
280                     applicationData[applicationKey].configs : null;
281                 applicationData[applicationKey].actions = !isNullOrUndefined(applicationData[applicationKey].actions) ?
282                     applicationData[applicationKey].actions : null;
283                 vcaApplication.push(applicationData[applicationKey]);
284             }
285         });
286         return vcaApplication;
287     }
288     /**
289      * Use to fetch the units data from vca_status @public
290      */
291     public unitsData(applicationData: VCAAPPLICATIONS[]): VCAUNITS[] {
292         const vcaUnits: VCAUNITS[] = [];
293         applicationData.forEach((applicationList: VCAAPPLICATIONS): void => {
294             Object.keys(applicationList.units).forEach((unitsKey: string): void => {
295                 applicationList.units[unitsKey].unit_id = unitsKey;
296                 vcaUnits.push(applicationList.units[unitsKey]);
297             });
298         });
299         return vcaUnits;
300     }
301     /**
302      * Use to fetch the machines data from vca_status @public
303      */
304     public machinesData(machinesData: MACHINES[]): MACHINES[] {
305         const vcaMachines: MACHINES[] = [];
306         Object.keys(machinesData).forEach((machineKey: string): void => {
307             vcaMachines.push(machinesData[machineKey]);
308         });
309         return vcaMachines;
310     }
311     /** Show the Config list in modal using modalservice @public */
312     public showExecutedActionsList(executeActionsList: EXECUTEDACTIONS[]): void {
313         // eslint-disable-next-line security/detect-non-literal-fs-filename
314         this.modalService.open(OperationalViewAppExecutedActionsComponent, { size: 'xl', backdrop: 'static' })
315             .componentInstance.params = { executedActions: executeActionsList };
316     }
317     /** Show the Config list in modal using modalservice @public */
318     public showConfigList(configList: object): void {
319         // eslint-disable-next-line security/detect-non-literal-fs-filename
320         this.modalService.open(OperationalViewAppConfigsComponent, { size: 'xl', backdrop: 'static' })
321             .componentInstance.params = { configs: configList };
322     }
323     /** Show the Config list in modal using modalservice @public */
324     public showActionsList(actionsList: object): void {
325         // eslint-disable-next-line security/detect-non-literal-fs-filename
326         this.modalService.open(OperationalViewAppActionsComponent, { size: 'xl', backdrop: 'static' })
327             .componentInstance.params = { actions: actionsList };
328     }
329     /** Call the live data to fetch the latest results @public */
330     public callLiveData(isChecked: boolean, getNSID: string, index: number): void {
331         this.vcaDetails[index].isLiveloading = isChecked;
332         if (isChecked) {
333             this.stopExistingModelLiveLoading(getNSID);
334             this.generateRefreshedData(getNSID, index, this.vcaDetails[index].timeOutSeconds);
335         } else {
336             this.clearTimeoutAndInterval();
337         }
338     }
339     /** Fetching the juju vca_status data from API and Load it in the respective model @public */
340     public generateRefreshedData(getNSID: string, index: number, secondsValue: number): void {
341         this.modalService.dismissAll();
342         const liveDataURL: string = environment.NSDINSTANCES_URL + '/' + getNSID;
343         this.generateNSData(liveDataURL, true, secondsValue).subscribe((getVCAStatusDetails: VCADETAILS): void => {
344             this.vcaDetails[index] = getVCAStatusDetails;
345             this.callSetTimeOut(getNSID, index, secondsValue);
346         }, (error: ERRORDATA): void => {
347             this.restService.handleError(error, 'get');
348             if (error.error.status === HttpStatus.NOT_FOUND) {
349                 this.vcaDetails.splice(index, 1);
350             }
351             this.clearTimeoutAndInterval();
352         });
353     }
354     /** Call the setimeout to refresh the all models data in regular timeout @public */
355     public callSetTimeOut(id: string, index: number, secondsValue: number): void {
356         this.clearTimeoutAndInterval();
357         this.timeOut = window.setTimeout((): void => {
358             this.generateRefreshedData(id, index, secondsValue);
359         }, secondsValue * this.timeDefaultCal);
360     }
361     /** Stop existing model live reload @public */
362     public stopExistingModelLiveLoading(getNSID: string): void {
363         this.clearTimeoutAndInterval();
364         this.vcaDetails.forEach((vcaDetail: VCADETAILS, i: number): void => {
365             if (vcaDetail.ns_id !== getNSID) {
366                 vcaDetail.isLiveloading = false;
367             }
368         });
369     }
370     /** Method to show/hide the tables @public */
371     public showHideTables(event: HTMLElement, getTableName: string, index: number): void {
372         let selectedClassName: string = getTableName + index;
373         if (selectedClassName === 'all' + index) {
374             selectedClassName = '';
375         }
376         document.querySelectorAll('.filter' + index).forEach((button: HTMLElement): void => {
377             button.classList.remove('active');
378             if (selectedClassName !== '') {
379                 if (button.classList.contains(selectedClassName)) {
380                     button.classList.add('active');
381                 }
382             } else if (button.classList.contains('all' + index)) {
383                 button.classList.add('active');
384             }
385         });
386         document.querySelectorAll('.filterTable' + index).forEach((table: HTMLElement): void => {
387             table.classList.remove('hide');
388             if (selectedClassName !== '') {
389                 if (!table.classList.contains(selectedClassName)) {
390                     table.classList.add('hide');
391                 }
392             }
393         });
394     }
395     /** Get the timer selected @public */
396     public onSetTimerSelector(getSeconds: number, nsID: string, index: number): void {
397         this.vcaDetails[index].timeOutSeconds = getSeconds;
398         this.callLiveData(true, nsID, index);
399     }
400     /** Clear settimeOut and setinterval @public */
401     public clearTimeoutAndInterval(): void {
402         clearTimeout(this.timeOut);
403     }
404     /**
405      * Lifecyle hook which get trigger on component destruction
406      */
407     public ngOnDestroy(): void {
408         this.clearTimeoutAndInterval();
409         this.generateDataSub.unsubscribe();
410     }
411 }