| Barath Kumar R | f2ae546 | 2021-03-01 12:52:33 +0530 | [diff] [blame] | 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[] = []; |
| Barath Kumar R | f2ae546 | 2021-03-01 12:52:33 +0530 | [diff] [blame] | 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); |
| SANDHYA.JS | dfef923 | 2022-03-08 17:17:23 +0530 | [diff] [blame^] | 234 | const assignNSInstancesID: string = key; |
| Barath Kumar R | f2ae546 | 2021-03-01 12:52:33 +0530 | [diff] [blame] | 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 | } |