1 /* eslint-disable security/detect-object-injection */
3 Copyright 2020 TATA ELXSI
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
9 http://www.apache.org/licenses/LICENSE-2.0
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.
17 Author: BARATH KUMAR R (barath.r@tataelxsi.co.in)
21 * @file Page for Operational View Component
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';
41 * @Component takes OperationalViewComponent.html as template url
44 selector: 'app-operational-view',
45 templateUrl: './OperationalViewComponent.html'
47 /** Exporting a class @exports OperationalViewComponent */
48 export class OperationalViewComponent implements OnInit {
49 /** Invoke service injectors @public */
50 public injector: Injector;
52 /** Check the loading results @public */
53 public isLoadingResults: boolean = false;
55 /** Give the message for the loading @public */
56 public message: string = 'PLEASEWAIT';
58 /** Formation of appropriate Data for vcaStatus Details @public */
59 public vcaDetails: VCADETAILS[] = [];
61 /** Contains all methods related to shared @public */
62 public sharedService: SharedService;
64 /** Utilizes rest service for any CRUD operations @public */
65 public restService: RestService;
67 /** variables contains activeID @public */
68 public activeID: string = null;
70 /** variables contains NS Instances ID @public */
71 public instancesID: string = null;
73 /** variables contains URL of operational Dashboard @public */
74 public openURL: string = 'instances/operational-view/';
76 /** variables contains default seconds for the timeout @public */
77 public timeOutDefaultSeconds: number = CONSTANTNUMBER.timeOutDefaultSeconds;
79 /** variables contains minimum seconds for the timeout @public */
80 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
81 public minSeconds: number = 5;
83 /** variables contains maximum seconds for the timeout @public */
84 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
85 public maxSeconds: number = 60;
87 /** variables contains timer calculation value of milliseconds @public */
88 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
89 public timeDefaultCal: number = 1000;
91 /** variables contains timeout @public */
92 public timeOut: number;
94 /** Set the timer button @public */
95 // eslint-disable-next-line no-magic-numbers
96 public setSeconds: SETTIMER[] = SET_TIMER;
98 /** Instance of subscriptions @private */
99 private generateDataSub: Subscription;
101 /** Contains tranlsate instance @private */
102 private translateService: TranslateService;
104 /** Holds teh instance of AuthService class of type AuthService @private */
105 private activatedRoute: ActivatedRoute;
107 /** Instance of the modal service @private */
108 private modalService: NgbModal;
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);
121 * Lifecyle Hooks the trigger before component is instantiate
123 public ngOnInit(): void {
124 this.instancesID = this.activatedRoute.snapshot.paramMap.get('id');
126 this.generateDataSub = this.sharedService.dataEvent.subscribe((): void => { this.generateData(); });
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);
139 this.generateAllNSData(NSURL);
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
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);
155 if (this.activeID === null && this.vcaDetails.length > 0) {
156 this.activeID = this.vcaDetails[0].ns_id;
159 this.isLoadingResults = false;
160 }, (error: ERRORDATA): void => {
161 this.isLoadingResults = false;
162 this.restService.handleError(error, 'get');
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>
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;
175 this.isLoadingResults = false;
176 }, (error: ERRORDATA): void => {
177 this.isLoadingResults = false;
178 this.restService.handleError(error, 'get');
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
187 public generateNSData(NSURL: string, liveData: boolean, timeOutSeconds: number): Observable<VCADETAILS> {
189 NSURL = NSURL + '?vcaStatusRefresh=true';
191 return this.restService.getResource(NSURL).pipe(map((operationalList: VCASTATUS): VCADETAILS => this.vcaDetailsData(operationalList, liveData, timeOutSeconds)));
194 * Form the VCA Details for each NS Instances
196 public formVCADetails(getData: VCADETAILS): VCADETAILS {
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
207 * Assign the VCA Status of Multiple model in getModels array for each NS Instance
209 public assignVCAStatusOfEachModel(getData: SETMODELS): SETMODELS {
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
225 * Use to fetch the vcaDetails from vca_status @public
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 => {
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);
259 return assignVCADetails[0];
262 * Use to fetch the app data from vca_status @public
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]);
286 return vcaApplication;
289 * Use to fetch the units data from vca_status @public
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]);
302 * Use to fetch the machines data from vca_status @public
304 public machinesData(machinesData: MACHINES[]): MACHINES[] {
305 const vcaMachines: MACHINES[] = [];
306 Object.keys(machinesData).forEach((machineKey: string): void => {
307 vcaMachines.push(machinesData[machineKey]);
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 };
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 };
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 };
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;
333 this.stopExistingModelLiveLoading(getNSID);
334 this.generateRefreshedData(getNSID, index, this.vcaDetails[index].timeOutSeconds);
336 this.clearTimeoutAndInterval();
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);
351 this.clearTimeoutAndInterval();
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);
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;
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 = '';
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');
382 } else if (button.classList.contains('all' + index)) {
383 button.classList.add('active');
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');
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);
400 /** Clear settimeOut and setinterval @public */
401 public clearTimeoutAndInterval(): void {
402 clearTimeout(this.timeOut);
405 * Lifecyle hook which get trigger on component destruction
407 public ngOnDestroy(): void {
408 this.clearTimeoutAndInterval();
409 this.generateDataSub.unsubscribe();