blob: 22d40771abee7477fee81091e0a0ee561f5aaa5e [file] [log] [blame]
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +05301/* eslint-disable security/detect-object-injection */
Barath Kumar Rf2ae5462021-03-01 12:52:33 +05302/*
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 */
23import { Component, Injector, OnInit } from '@angular/core';
24import { ActivatedRoute } from '@angular/router';
25import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
26import { TranslateService } from '@ngx-translate/core';
27import { CONSTANTNUMBER, ERRORDATA } from 'CommonModel';
28import { environment } from 'environment';
29import * as HttpStatus from 'http-status-codes';
30import { OperationalViewAppActionsComponent } from 'OperationalAppActionsComponent';
31import { OperationalViewAppConfigsComponent } from 'OperationalAppConfigsComponent';
32import { OperationalViewAppExecutedActionsComponent } from 'OperationalAppExecutedActionsComponent';
33import { EXECUTEDACTIONS, MACHINES, SET_TIMER, SETMODELS, SETTIMER, VCAAPPLICATIONS, VCADETAILS, VCASTATUS, VCAUNITS } from 'OperationalModel';
34import { RestService } from 'RestService';
35import { Observable } from 'rxjs';
36import { Subscription } from 'rxjs';
37import { map } from 'rxjs/operators';
SANDHYA.JSc84f1122024-06-04 21:50:03 +053038import { SharedService, isNullOrUndefined } from 'SharedService';
Barath Kumar Rf2ae5462021-03-01 12:52:33 +053039/**
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 */
48export 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 */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053080 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
Barath Kumar Rf2ae5462021-03-01 12:52:33 +053081 public minSeconds: number = 5;
82
83 /** variables contains maximum seconds for the timeout @public */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053084 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
Barath Kumar Rf2ae5462021-03-01 12:52:33 +053085 public maxSeconds: number = 60;
86
87 /** variables contains timer calculation value of milliseconds @public */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053088 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
Barath Kumar Rf2ae5462021-03-01 12:52:33 +053089 public timeDefaultCal: number = 1000;
90
91 /** variables contains timeout @public */
92 public timeOut: number;
93
94 /** Set the timer button @public */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053095 // eslint-disable-next-line no-magic-numbers
Barath Kumar Rf2ae5462021-03-01 12:52:33 +053096 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 {
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530124 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 }
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +0530191 return this.restService.getResource(NSURL).pipe(map((operationalList: VCASTATUS): VCADETAILS => this.vcaDetailsData(operationalList, liveData, timeOutSeconds)));
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530192 }
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[] = [];
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530230 Object.keys(list.vcaStatus).forEach((key: string): void => {
SANDHYA.JSb6ec4422024-06-11 12:47:55 +0530231 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 }
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530258 });
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 => {
SANDHYA.JSb6ec4422024-06-11 12:47:55 +0530267 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 }
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530285 });
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 {
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +0530313 // eslint-disable-next-line security/detect-non-literal-fs-filename
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530314 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 {
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +0530319 // eslint-disable-next-line security/detect-non-literal-fs-filename
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530320 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 {
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +0530325 // eslint-disable-next-line security/detect-non-literal-fs-filename
Barath Kumar Rf2ae5462021-03-01 12:52:33 +0530326 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}