ae2a13c5a87b772e6448a782c22d57ca0768ca13
[osm/NG-UI.git] / src / app / operational-view / OperationalViewComponent.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: BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18
19 /**
20  * @file Page for Operational View Component
21  */
22 import { Component, Injector, OnInit } from '@angular/core';
23 import { ActivatedRoute } from '@angular/router';
24 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
25 import { TranslateService } from '@ngx-translate/core';
26 import { CONSTANTNUMBER, ERRORDATA } from 'CommonModel';
27 import { environment } from 'environment';
28 import * as HttpStatus from 'http-status-codes';
29 import { OperationalViewAppActionsComponent } from 'OperationalAppActionsComponent';
30 import { OperationalViewAppConfigsComponent } from 'OperationalAppConfigsComponent';
31 import { OperationalViewAppExecutedActionsComponent } from 'OperationalAppExecutedActionsComponent';
32 import { EXECUTEDACTIONS, MACHINES, SET_TIMER, SETMODELS, SETTIMER, VCAAPPLICATIONS, VCADETAILS, VCASTATUS, VCAUNITS } from 'OperationalModel';
33 import { RestService } from 'RestService';
34 import { Observable } from 'rxjs';
35 import { Subscription } from 'rxjs';
36 import { map } from 'rxjs/operators';
37 import { SharedService } from 'SharedService';
38 import { isNullOrUndefined } from 'util';
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     public minSeconds: number = 5;
81
82     /** variables contains maximum seconds for the timeout @public */
83     public maxSeconds: number = 60;
84
85     /** variables contains timer calculation value of milliseconds @public */
86     public timeDefaultCal: number = 1000;
87
88     /** variables contains timeout @public */
89     public timeOut: number;
90
91     /** Set the timer button @public */
92     // tslint:disable-next-line: no-magic-numbers
93     public setSeconds: SETTIMER[] = SET_TIMER;
94
95     /** Instance of subscriptions @private */
96     private generateDataSub: Subscription;
97
98     /** Contains tranlsate instance @private */
99     private translateService: TranslateService;
100
101     /** Holds teh instance of AuthService class of type AuthService @private */
102     private activatedRoute: ActivatedRoute;
103
104     /** Instance of the modal service @private */
105     private modalService: NgbModal;
106
107     /** creates Operational view component */
108     constructor(injector: Injector) {
109         this.injector = injector;
110         this.restService = this.injector.get(RestService);
111         this.sharedService = this.injector.get(SharedService);
112         this.translateService = this.injector.get(TranslateService);
113         this.activatedRoute = this.injector.get(ActivatedRoute);
114         this.modalService = this.injector.get(NgbModal);
115     }
116
117     /**
118      * Lifecyle Hooks the trigger before component is instantiate
119      */
120     public ngOnInit(): void {
121         // tslint:disable-next-line:no-backbone-get-set-outside-model
122         this.instancesID = this.activatedRoute.snapshot.paramMap.get('id');
123         this.generateData();
124         this.generateDataSub = this.sharedService.dataEvent.subscribe((): void => { this.generateData(); });
125     }
126     /** Fetching the juju vca_status data from API and Load it in the respective table @public */
127     public generateData(): void {
128         this.clearTimeoutAndInterval();
129         this.modalService.dismissAll();
130         this.isLoadingResults = true;
131         this.vcaDetails = [];
132         let NSURL: string = environment.NSDINSTANCES_URL;
133         if (this.instancesID !== null) {
134             NSURL = NSURL + '/' + this.instancesID;
135             this.generateIndividualNSData(NSURL);
136         } else {
137             this.generateAllNSData(NSURL);
138         }
139     }
140     /**
141      * Show all NS Data that contains the juju vca_status from API and Load it in the table @public
142      * @param NSURL : osm/nslcm/v1/ns_instances
143      */
144     public generateAllNSData(NSURL: string): void {
145         this.restService.getResource(NSURL).subscribe((operationalList: VCASTATUS[]): void => {
146             if (operationalList.length > 0) {
147                 operationalList.forEach((list: VCASTATUS): void => {
148                     if (!isNullOrUndefined(list.vcaStatus)) {
149                         const getVCAStatusDetails: VCADETAILS = this.vcaDetailsData(list, false, this.timeOutDefaultSeconds);
150                         this.vcaDetails.push(getVCAStatusDetails);
151                     }
152                 });
153                 if (this.activeID === null && this.vcaDetails.length > 0) {
154                     this.activeID = this.vcaDetails[0].ns_id;
155                 }
156             }
157             this.isLoadingResults = false;
158         }, (error: ERRORDATA): void => {
159             this.isLoadingResults = false;
160             this.restService.handleError(error, 'get');
161         });
162     }
163     /**
164      * Show the individual NS Data that contains the juju vca_status from generateNSData method and Load it in the table @public
165      * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
166      */
167     public generateIndividualNSData(NSURL: string): void {
168         this.generateNSData(NSURL, false, this.timeOutDefaultSeconds).subscribe((getVCAStatusDetails: VCADETAILS): void => {
169             this.vcaDetails.push(getVCAStatusDetails);
170             if (this.activeID === null && this.vcaDetails.length > 0) {
171                 this.activeID = this.instancesID;
172             }
173             this.isLoadingResults = false;
174         }, (error: ERRORDATA): void => {
175             this.isLoadingResults = false;
176             this.restService.handleError(error, 'get');
177         });
178     }
179     /**
180      * Fetching the Individual NS Data that contains the juju vca_status from API and return the VCADetails @public
181      * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
182      * @param liveData : Needs to repeat the httprequest
183      * @param timeOutSeconds : set the timeout seconds to trigger the httprequest
184      */
185     public generateNSData(NSURL: string, liveData: boolean, timeOutSeconds: number): Observable<VCADETAILS> {
186         if (liveData) {
187             NSURL = NSURL + '?vcaStatusRefresh=true';
188         }
189         return this.restService.getResource(NSURL).pipe(map((operationalList: VCASTATUS): VCADETAILS => {
190             return this.vcaDetailsData(operationalList, liveData, timeOutSeconds);
191         }));
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             const vcaApplication: VCAAPPLICATIONS[] = this.appData(list.vcaStatus[key].applications);
232             const vcaUnits: VCAUNITS[] = this.unitsData(vcaApplication);
233             const vcaMachines: MACHINES[] = this.machinesData(list.vcaStatus[key].machines);
234             const assignNSInstancesID: string = key;
235             list.vcaStatus[key].units = vcaUnits;
236             list.vcaStatus[key].applications = vcaApplication;
237             list.vcaStatus[key].machines = vcaMachines;
238             list.vcaStatus[key].relations = list.vcaStatus[key].relations;
239             list.vcaStatus[key].model = list.vcaStatus[key].model;
240             const getEachModelData: SETMODELS = this.assignVCAStatusOfEachModel(list.vcaStatus[key]);
241             setModels.push(getEachModelData);
242             list.vcaStatus[assignNSInstancesID].vca_id = key;
243             list.vcaStatus[assignNSInstancesID].vca_name = list.name;
244             list.vcaStatus[assignNSInstancesID].ns_id = list.id;
245             list.vcaStatus[assignNSInstancesID].isLiveloading = liveData;
246             list.vcaStatus[assignNSInstancesID].timeOutSeconds = timeOutSeconds;
247             list.vcaStatus[assignNSInstancesID].vcaStatusModels = setModels;
248             const getAssignedData: VCADETAILS = this.formVCADetails(list.vcaStatus[assignNSInstancesID]);
249             assignVCADetails.push(getAssignedData);
250         });
251         return assignVCADetails[0];
252     }
253     /**
254      * Use to fetch the app data from vca_status @public
255      */
256     public appData(applicationData: VCAAPPLICATIONS): VCAAPPLICATIONS[] {
257         const vcaApplication: VCAAPPLICATIONS[] = [];
258         Object.keys(applicationData).forEach((applicationKey: string): void => {
259             const charmSplitlist: string[] = applicationData[applicationKey].charm.split('/');
260             const status: string = applicationData[applicationKey].status.status;
261             const charm: string = charmSplitlist[1].substr(0, charmSplitlist[1].lastIndexOf('-'));
262             const store: string = charmSplitlist[0].substr(0, charmSplitlist[0].lastIndexOf(':'));
263             applicationData[applicationKey].app_id = applicationKey;
264             applicationData[applicationKey].charm = charm;
265             applicationData[applicationKey].status = status;
266             applicationData[applicationKey].scale = Object.keys(applicationData[applicationKey].units).length;
267             applicationData[applicationKey].store = store;
268             applicationData[applicationKey].configs = !isNullOrUndefined(applicationData[applicationKey].configs) ?
269                 applicationData[applicationKey].configs : null;
270             applicationData[applicationKey].actions = !isNullOrUndefined(applicationData[applicationKey].actions) ?
271                 applicationData[applicationKey].actions : null;
272             vcaApplication.push(applicationData[applicationKey]);
273         });
274         return vcaApplication;
275     }
276     /**
277      * Use to fetch the units data from vca_status @public
278      */
279     public unitsData(applicationData: VCAAPPLICATIONS[]): VCAUNITS[] {
280         const vcaUnits: VCAUNITS[] = [];
281         applicationData.forEach((applicationList: VCAAPPLICATIONS): void => {
282             Object.keys(applicationList.units).forEach((unitsKey: string): void => {
283                 applicationList.units[unitsKey].unit_id = unitsKey;
284                 vcaUnits.push(applicationList.units[unitsKey]);
285             });
286         });
287         return vcaUnits;
288     }
289     /**
290      * Use to fetch the machines data from vca_status @public
291      */
292     public machinesData(machinesData: MACHINES[]): MACHINES[] {
293         const vcaMachines: MACHINES[] = [];
294         Object.keys(machinesData).forEach((machineKey: string): void => {
295             vcaMachines.push(machinesData[machineKey]);
296         });
297         return vcaMachines;
298     }
299     /** Show the Config list in modal using modalservice @public */
300     public showExecutedActionsList(executeActionsList: EXECUTEDACTIONS[]): void {
301         this.modalService.open(OperationalViewAppExecutedActionsComponent, { size: 'xl', backdrop: 'static' })
302             .componentInstance.params = { executedActions: executeActionsList };
303     }
304     /** Show the Config list in modal using modalservice @public */
305     public showConfigList(configList: object): void {
306         this.modalService.open(OperationalViewAppConfigsComponent, { size: 'xl', backdrop: 'static' })
307             .componentInstance.params = { configs: configList };
308     }
309     /** Show the Config list in modal using modalservice @public */
310     public showActionsList(actionsList: object): void {
311         this.modalService.open(OperationalViewAppActionsComponent, { size: 'xl', backdrop: 'static' })
312             .componentInstance.params = { actions: actionsList };
313     }
314     /** Call the live data to fetch the latest results @public */
315     public callLiveData(isChecked: boolean, getNSID: string, index: number): void {
316         this.vcaDetails[index].isLiveloading = isChecked;
317         if (isChecked) {
318             this.stopExistingModelLiveLoading(getNSID);
319             this.generateRefreshedData(getNSID, index, this.vcaDetails[index].timeOutSeconds);
320         } else {
321             this.clearTimeoutAndInterval();
322         }
323     }
324     /** Fetching the juju vca_status data from API and Load it in the respective model @public */
325     public generateRefreshedData(getNSID: string, index: number, secondsValue: number): void {
326         this.modalService.dismissAll();
327         const liveDataURL: string = environment.NSDINSTANCES_URL + '/' + getNSID;
328         this.generateNSData(liveDataURL, true, secondsValue).subscribe((getVCAStatusDetails: VCADETAILS): void => {
329             this.vcaDetails[index] = getVCAStatusDetails;
330             this.callSetTimeOut(getNSID, index, secondsValue);
331         }, (error: ERRORDATA): void => {
332             this.restService.handleError(error, 'get');
333             if (error.error.status === HttpStatus.NOT_FOUND) {
334                 this.vcaDetails.splice(index, 1);
335             }
336             this.clearTimeoutAndInterval();
337         });
338     }
339     /** Call the setimeout to refresh the all models data in regular timeout @public */
340     public callSetTimeOut(id: string, index: number, secondsValue: number): void {
341         this.clearTimeoutAndInterval();
342         this.timeOut = window.setTimeout((): void => {
343             this.generateRefreshedData(id, index, secondsValue);
344         }, secondsValue * this.timeDefaultCal);
345     }
346     /** Stop existing model live reload @public */
347     public stopExistingModelLiveLoading(getNSID: string): void {
348         this.clearTimeoutAndInterval();
349         this.vcaDetails.forEach((vcaDetail: VCADETAILS, i: number): void => {
350             if (vcaDetail.ns_id !== getNSID) {
351                 vcaDetail.isLiveloading = false;
352             }
353         });
354     }
355     /** Method to show/hide the tables @public */
356     public showHideTables(event: HTMLElement, getTableName: string, index: number): void {
357         let selectedClassName: string = getTableName + index;
358         if (selectedClassName === 'all' + index) {
359             selectedClassName = '';
360         }
361         document.querySelectorAll('.filter' + index).forEach((button: HTMLElement): void => {
362             button.classList.remove('active');
363             if (selectedClassName !== '') {
364                 if (button.classList.contains(selectedClassName)) {
365                     button.classList.add('active');
366                 }
367             } else if (button.classList.contains('all' + index)) {
368                 button.classList.add('active');
369             }
370         });
371         document.querySelectorAll('.filterTable' + index).forEach((table: HTMLElement): void => {
372             table.classList.remove('hide');
373             if (selectedClassName !== '') {
374                 if (!table.classList.contains(selectedClassName)) {
375                     table.classList.add('hide');
376                 }
377             }
378         });
379     }
380     /** Get the timer selected @public */
381     public onSetTimerSelector(getSeconds: number, nsID: string, index: number): void {
382         this.vcaDetails[index].timeOutSeconds = getSeconds;
383         this.callLiveData(true, nsID, index);
384     }
385     /** Clear settimeOut and setinterval @public */
386     public clearTimeoutAndInterval(): void {
387         clearTimeout(this.timeOut);
388     }
389     /**
390      * Lifecyle hook which get trigger on component destruction
391      */
392     public ngOnDestroy(): void {
393         this.clearTimeoutAndInterval();
394         this.generateDataSub.unsubscribe();
395     }
396 }