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