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 => {
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 // eslint-disable-next-line no-self-assign
239 list.vcaStatus[key].relations = list.vcaStatus[key].relations;
240 // eslint-disable-next-line no-self-assign
241 list.vcaStatus[key].model = list.vcaStatus[key].model;
242 const getEachModelData: SETMODELS = this.assignVCAStatusOfEachModel(list.vcaStatus[key]);
243 setModels.push(getEachModelData);
244 list.vcaStatus[assignNSInstancesID].vca_id = key;
245 list.vcaStatus[assignNSInstancesID].vca_name = list.name;
246 list.vcaStatus[assignNSInstancesID].ns_id = list.id;
247 list.vcaStatus[assignNSInstancesID].isLiveloading = liveData;
248 list.vcaStatus[assignNSInstancesID].timeOutSeconds = timeOutSeconds;
249 list.vcaStatus[assignNSInstancesID].vcaStatusModels = setModels;
250 const getAssignedData: VCADETAILS = this.formVCADetails(list.vcaStatus[assignNSInstancesID]);
251 assignVCADetails.push(getAssignedData);
253 return assignVCADetails[0];
256 * Use to fetch the app data from vca_status @public
258 public appData(applicationData: VCAAPPLICATIONS): VCAAPPLICATIONS[] {
259 const vcaApplication: VCAAPPLICATIONS[] = [];
260 Object.keys(applicationData).forEach((applicationKey: string): void => {
261 const charmSplitlist: string[] = applicationData[applicationKey].charm.split('/');
262 const status: string = applicationData[applicationKey].status.status;
263 // eslint-disable-next-line deprecation/deprecation
264 const charm: string = charmSplitlist[1].substr(0, charmSplitlist[1].lastIndexOf('-'));
265 // eslint-disable-next-line deprecation/deprecation
266 const store: string = charmSplitlist[0].substr(0, charmSplitlist[0].lastIndexOf(':'));
267 applicationData[applicationKey].app_id = applicationKey;
268 applicationData[applicationKey].charm = charm;
269 applicationData[applicationKey].status = status;
270 applicationData[applicationKey].scale = Object.keys(applicationData[applicationKey].units).length;
271 applicationData[applicationKey].store = store;
272 applicationData[applicationKey].configs = !isNullOrUndefined(applicationData[applicationKey].configs) ?
273 applicationData[applicationKey].configs : null;
274 applicationData[applicationKey].actions = !isNullOrUndefined(applicationData[applicationKey].actions) ?
275 applicationData[applicationKey].actions : null;
276 vcaApplication.push(applicationData[applicationKey]);
278 return vcaApplication;
281 * Use to fetch the units data from vca_status @public
283 public unitsData(applicationData: VCAAPPLICATIONS[]): VCAUNITS[] {
284 const vcaUnits: VCAUNITS[] = [];
285 applicationData.forEach((applicationList: VCAAPPLICATIONS): void => {
286 Object.keys(applicationList.units).forEach((unitsKey: string): void => {
287 applicationList.units[unitsKey].unit_id = unitsKey;
288 vcaUnits.push(applicationList.units[unitsKey]);
294 * Use to fetch the machines data from vca_status @public
296 public machinesData(machinesData: MACHINES[]): MACHINES[] {
297 const vcaMachines: MACHINES[] = [];
298 Object.keys(machinesData).forEach((machineKey: string): void => {
299 vcaMachines.push(machinesData[machineKey]);
303 /** Show the Config list in modal using modalservice @public */
304 public showExecutedActionsList(executeActionsList: EXECUTEDACTIONS[]): void {
305 // eslint-disable-next-line security/detect-non-literal-fs-filename
306 this.modalService.open(OperationalViewAppExecutedActionsComponent, { size: 'xl', backdrop: 'static' })
307 .componentInstance.params = { executedActions: executeActionsList };
309 /** Show the Config list in modal using modalservice @public */
310 public showConfigList(configList: object): void {
311 // eslint-disable-next-line security/detect-non-literal-fs-filename
312 this.modalService.open(OperationalViewAppConfigsComponent, { size: 'xl', backdrop: 'static' })
313 .componentInstance.params = { configs: configList };
315 /** Show the Config list in modal using modalservice @public */
316 public showActionsList(actionsList: object): void {
317 // eslint-disable-next-line security/detect-non-literal-fs-filename
318 this.modalService.open(OperationalViewAppActionsComponent, { size: 'xl', backdrop: 'static' })
319 .componentInstance.params = { actions: actionsList };
321 /** Call the live data to fetch the latest results @public */
322 public callLiveData(isChecked: boolean, getNSID: string, index: number): void {
323 this.vcaDetails[index].isLiveloading = isChecked;
325 this.stopExistingModelLiveLoading(getNSID);
326 this.generateRefreshedData(getNSID, index, this.vcaDetails[index].timeOutSeconds);
328 this.clearTimeoutAndInterval();
331 /** Fetching the juju vca_status data from API and Load it in the respective model @public */
332 public generateRefreshedData(getNSID: string, index: number, secondsValue: number): void {
333 this.modalService.dismissAll();
334 const liveDataURL: string = environment.NSDINSTANCES_URL + '/' + getNSID;
335 this.generateNSData(liveDataURL, true, secondsValue).subscribe((getVCAStatusDetails: VCADETAILS): void => {
336 this.vcaDetails[index] = getVCAStatusDetails;
337 this.callSetTimeOut(getNSID, index, secondsValue);
338 }, (error: ERRORDATA): void => {
339 this.restService.handleError(error, 'get');
340 if (error.error.status === HttpStatus.NOT_FOUND) {
341 this.vcaDetails.splice(index, 1);
343 this.clearTimeoutAndInterval();
346 /** Call the setimeout to refresh the all models data in regular timeout @public */
347 public callSetTimeOut(id: string, index: number, secondsValue: number): void {
348 this.clearTimeoutAndInterval();
349 this.timeOut = window.setTimeout((): void => {
350 this.generateRefreshedData(id, index, secondsValue);
351 }, secondsValue * this.timeDefaultCal);
353 /** Stop existing model live reload @public */
354 public stopExistingModelLiveLoading(getNSID: string): void {
355 this.clearTimeoutAndInterval();
356 this.vcaDetails.forEach((vcaDetail: VCADETAILS, i: number): void => {
357 if (vcaDetail.ns_id !== getNSID) {
358 vcaDetail.isLiveloading = false;
362 /** Method to show/hide the tables @public */
363 public showHideTables(event: HTMLElement, getTableName: string, index: number): void {
364 let selectedClassName: string = getTableName + index;
365 if (selectedClassName === 'all' + index) {
366 selectedClassName = '';
368 document.querySelectorAll('.filter' + index).forEach((button: HTMLElement): void => {
369 button.classList.remove('active');
370 if (selectedClassName !== '') {
371 if (button.classList.contains(selectedClassName)) {
372 button.classList.add('active');
374 } else if (button.classList.contains('all' + index)) {
375 button.classList.add('active');
378 document.querySelectorAll('.filterTable' + index).forEach((table: HTMLElement): void => {
379 table.classList.remove('hide');
380 if (selectedClassName !== '') {
381 if (!table.classList.contains(selectedClassName)) {
382 table.classList.add('hide');
387 /** Get the timer selected @public */
388 public onSetTimerSelector(getSeconds: number, nsID: string, index: number): void {
389 this.vcaDetails[index].timeOutSeconds = getSeconds;
390 this.callLiveData(true, nsID, index);
392 /** Clear settimeOut and setinterval @public */
393 public clearTimeoutAndInterval(): void {
394 clearTimeout(this.timeOut);
397 * Lifecyle hook which get trigger on component destruction
399 public ngOnDestroy(): void {
400 this.clearTimeoutAndInterval();
401 this.generateDataSub.unsubscribe();