8112c06dc1fd6b9f03e9d4ca6a7ea15d8a1cbd54
[osm/NG-UI.git] / src / app / dashboard / DashboardComponent.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: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17  */
18 /**
19  * @file Dashboard Component
20  */
21 import { Component, Injector, OnInit } from '@angular/core';
22 import { TranslateService } from '@ngx-translate/core';
23 import { NotifierService } from 'angular-notifier';
24 import { AuthenticationService } from 'AuthenticationService';
25 import { Chart, ChartType, LineController, LineElement, PointElement, LinearScale, Title, ChartEvent, ActiveElement } from 'chart.js';
26 import ChartDataLabels from 'chartjs-plugin-datalabels';
27 Chart.register(LineController, LineElement, PointElement, LinearScale, Title, ChartDataLabels);
28 import { ERRORDATA, TYPESECTION, VIM_TYPES } from 'CommonModel';
29 import { environment } from 'environment';
30 import { NSDDetails } from 'NSDModel';
31 import { NSInstanceDetails } from 'NSInstanceModel';
32 import { ProjectData, ProjectDetails } from 'ProjectModel';
33 import { ProjectService } from 'ProjectService';
34 import { RestService } from 'RestService';
35 import { Observable, Subscription } from 'rxjs';
36 import { SDNControllerModel } from 'SDNControllerModel';
37 import { SharedService, isNullOrUndefined } from 'SharedService';
38 import { ProjectRoleMappings, UserDetail } from 'UserModel';
39 import { VimAccountDetails } from 'VimAccountModel';
40 import { VNFInstanceDetails } from 'VNFInstanceModel';
41
42 /**
43  * Creating component
44  * @Component takes DashboardComponent.html as template url
45  */
46 @Component({
47     styleUrls: ['./DashboardComponent.scss'],
48     templateUrl: './DashboardComponent.html'
49 })
50
51 /**
52  * This file created during the angular project creation
53  */
54
55 /** Exporting a class @exports DashboardComponent */
56 export class DashboardComponent implements OnInit {
57     /** Invoke service injectors @public */
58     public injector: Injector;
59
60     /** Handle translate @public */
61     public translateService: TranslateService;
62
63     /** Observable holds logined value  @public */
64     public username$: Observable<string>;
65
66     /** Variables holds admin is logged or not @public */
67     public isAdmin: boolean;
68
69     /** List of NS failed Instances @public */
70     public nsFailedInstances: {}[] = [];
71
72     /** Setting up count for vnfdPackages @public */
73     public vnfdPackageCount: number;
74
75     /** Setting up count for nsdPackage @public */
76     public nsdPackageCount: number;
77
78     /** Setting up count for nsInstance @public */
79     public nsInstanceCount: number;
80
81     /** Setting up count for vnfInstance @public */
82     public vnfInstanceCount: number;
83
84     /** Setting up count for vimAccount @public */
85     public vimAccountCount: number;
86
87     /** Setting up count for sdnController @public */
88     public sdnControllerCount: number;
89
90     /** Variables holds current project details @public */
91     public currentProjectDetails: {};
92
93     /** Array holds all the projects @public */
94     public projectList: {}[] = [];
95
96     /** Array holds all the projects @public */
97     public allProjectList: {}[] = [];
98
99     /** Variables holds the selected project @public */
100     public selectedProject: Observable<string>;
101
102     /** Check the Instances loading results @public */
103     public isCanvasLoadingResults: boolean = true;
104
105     /** Check the Projects loading results @public */
106     public isProjectsLoadingResults: boolean = true;
107
108     /** Give the message for the loading @public */
109     public message: string = 'PLEASEWAIT';
110
111     /** List of NS Success Instances @public */
112     public nsRunningInstance: string[] = [];
113
114     /** Contains VIM Account details @public */
115     public vimData: VimAccountDetails[] = [];
116
117     /** Contains Selected VIM Details @public */
118     public selectedVIMDetails: VimAccountDetails = null;
119
120     /** List of VIM_TYPES @public */
121     public vimTypes: TYPESECTION[] = VIM_TYPES;
122
123     /** Array holds Vim data filtered with selected vimtype  */
124     public vimList: VimAccountDetails[] = [];
125
126     /** Model value used to hold selected vimtype Data @public */
127     public vimListData: string;
128
129     /** List of color for Instances @private */
130     private backgroundColor: string[] = [];
131
132     /** Utilizes rest service for any CRUD operations @private */
133     private restService: RestService;
134
135     /** Utilizes auth service for any auth operations @private */
136     private authService: AuthenticationService;
137
138     /** Used to subscribe vnfdPackage @private */
139     private vnfdPackageCountSub: Subscription;
140
141     /** Used to subscribe nsdPackage @private */
142     private nsdPackageCountSub: Subscription;
143
144     /** Used to subscribe nsInstance @private */
145     private nsInstanceCountSub: Subscription;
146
147     /** Used to subscribe vnfInstance @private */
148     private vnfInstanceCountSub: Subscription;
149
150     /** Used to subscribe vimAccount @private */
151     private vimAccountCountSub: Subscription;
152
153     /** Used to subscribe sdnController @private */
154     private sdnControllerCountSub: Subscription;
155
156     /** No of Hours of NS Success Instances @private */
157     private noOfHours: number[] = [];
158
159     /** collects charts objects @private */
160     private charts: object = [];
161
162     /** Contains all methods related to projects @private */
163     private projectService: ProjectService;
164
165     /** Contains all methods related to shared @private */
166     private sharedService: SharedService;
167
168     /** Contains NS Instance Details */
169     private nsInstancesDataArr: {}[];
170
171     /** Container created time array @private */
172     private createdTimes: string[] = [];
173
174     /** Contains slice limit const @private */
175     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
176     private sliceLimit: number = 10;
177
178     /** Contians hour converter @private */
179     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
180     private hourConverter: number = 3600;
181
182     /** Converter used to round off time to one decimal point @private */
183     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
184     private converter: number = 10;
185
186     /** Notifier service to popup notification @private */
187     private notifierService: NotifierService;
188
189     constructor(injector: Injector) {
190         this.injector = injector;
191         this.restService = this.injector.get(RestService);
192         this.authService = this.injector.get(AuthenticationService);
193         this.projectService = this.injector.get(ProjectService);
194         this.sharedService = this.injector.get(SharedService);
195         this.translateService = this.injector.get(TranslateService);
196         this.notifierService = this.injector.get(NotifierService);
197     }
198
199     /**
200      * Lifecyle Hooks the trigger before component is instantiate
201      */
202     public ngOnInit(): void {
203         this.username$ = this.authService.username;
204         this.isAdmin = (sessionStorage.getItem('isAdmin') === 'true') ? true : false;
205         this.selectedProject = this.authService.ProjectName;
206         this.checkAdminPrivilege();
207         this.getUserAccessedProjects();
208         this.getAllProjects();
209         this.getVnfdPackageCount();
210         this.getNsdPackageCount();
211         this.getNsInstanceCount();
212         this.getVnfInstanceCount();
213         this.getVimAccountCount();
214         this.getSDNControllerCount();
215     }
216
217     /** Get all the projects @public */
218     public getUserAccessedProjects(): void {
219         this.projectService.getUserProjects().subscribe((projects: UserDetail): void => {
220             const projectList: {}[] = projects.project_role_mappings;
221             this.projectList = projectList.filter(
222                 (thing: ProjectRoleMappings, i: number, arr: []): boolean => arr
223                     .findIndex((t: ProjectRoleMappings): boolean => t.project_name === thing.project_name) === i
224             );
225         }, (error: Error): void => {
226             // TODO: Handle failure
227         });
228     }
229
230     /** Fetching all the Project in dashboard @public */
231     public getAllProjects(): void {
232         this.isProjectsLoadingResults = true;
233         this.restService.getResource(environment.PROJECTS_URL).subscribe((projectsData: ProjectDetails[]): void => {
234             this.allProjectList = [];
235             projectsData.forEach((projectData: ProjectDetails): void => {
236                 const projectDataObj: ProjectData = this.generateProjectData(projectData);
237                 this.allProjectList.push(projectDataObj);
238             });
239             this.isProjectsLoadingResults = false;
240         }, (error: ERRORDATA): void => {
241             this.restService.handleError(error, 'get');
242             this.isProjectsLoadingResults = false;
243         });
244     }
245
246     /** Generate Projects object from loop and return for the datasource @public */
247     public generateProjectData(projectData: ProjectDetails): ProjectData {
248         return {
249             projectName: projectData.name,
250             modificationDate: this.sharedService.convertEpochTime(projectData._admin.modified),
251             creationDate: this.sharedService.convertEpochTime(projectData._admin.created),
252             id: projectData._id,
253             project: projectData._id
254         };
255     }
256
257     /** Function to check admin privilege @public */
258     public checkAdminPrivilege(): void {
259         if (!this.isAdmin) {
260             this.projectService.getCurrentProjectDetails().subscribe((projectDetails: {}): void => {
261                 this.currentProjectDetails = projectDetails;
262             }, (error: Error): void => {
263                 // TODO: Handle failure
264             });
265         }
266     }
267
268     /** Get VNFD Package details @public */
269     public getVnfdPackageCount(): void {
270         this.vnfdPackageCountSub = this.restService.getResource(environment.VNFPACKAGESCONTENT_URL)
271             .subscribe((vnfdPackageData: []): void => {
272                 this.vnfdPackageCount = vnfdPackageData.length;
273             }, (error: ERRORDATA): void => {
274                 this.restService.handleError(error, 'get');
275             });
276     }
277
278     /** Get NSD Package details @public */
279     public getNsdPackageCount(): void {
280         this.nsdPackageCountSub = this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL)
281             .subscribe((nsdPackageData: NSDDetails[]): void => {
282                 this.nsdPackageCount = nsdPackageData.length;
283             }, (error: ERRORDATA): void => {
284                 this.restService.handleError(error, 'get');
285             });
286     }
287
288     /** Get NS Instance details @public */
289     public getNsInstanceCount(): void {
290         this.isCanvasLoadingResults = true;
291         this.nsInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
292             .subscribe((nsInstancesData: NSInstanceDetails[]): void => {
293                 this.nsInstancesDataArr = nsInstancesData;
294                 this.nsInstanceCount = nsInstancesData.length;
295                 this.nsInstanceChart();
296                 this.isCanvasLoadingResults = false;
297             }, (error: ERRORDATA): void => {
298                 this.restService.handleError(error, 'get');
299                 this.isCanvasLoadingResults = false;
300             });
301     }
302
303     /** Get NS Instance chart details @public */
304     public nsInstanceChart(): void {
305         this.nsInstancesDataArr.forEach((nsdInstanceData: NSDDetails): void => {
306             const operationalStatus: string = nsdInstanceData['operational-status'];
307             const configStatus: string = nsdInstanceData['config-status'];
308             if (operationalStatus === 'failed' || configStatus === 'failed') {
309                 this.nsFailedInstances.push(nsdInstanceData);
310             } else if (operationalStatus === 'running' && configStatus === 'configured') {
311                 this.nsRunningInstance.push(nsdInstanceData.name);
312                 this.backgroundColor.push(this.sharedService.generateColor());
313                 this.createdTimes.push(((nsdInstanceData._admin.created).toString()).slice(0, this.sliceLimit));
314             }
315         });
316         const now: Date = new Date();
317         const currentTime: number = Number((now.getTime().toString().slice(0, this.sliceLimit)));
318         this.createdTimes.forEach((createdTime: string): void => {
319             this.noOfHours.push(Math.floor(((currentTime - Number(createdTime)) / this.hourConverter) * (this.converter)) / this.converter);
320         });
321         this.drawNsChart();
322     }
323
324     /** Prepare and sketch NS instance chart */
325     public drawNsChart(): void {
326         this.charts = new Chart('canvas', {
327             type: 'bar' as ChartType,
328             data: {
329                 labels: this.nsRunningInstance,
330                 datasets: [{
331                     data: this.noOfHours,
332                     label: this.translateService.instant('NOOFHOURS'),
333                     borderColor: this.backgroundColor,
334                     fill: false,
335                     backgroundColor: this.backgroundColor,
336                     hoverBackgroundColor: this.backgroundColor
337                 }]
338             },
339             options: {
340                 layout: {
341                     padding: {
342                         top: 25
343                     }
344                 },
345                 animation: false,
346                 // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
347                 onHover(event: ChartEvent, item: ActiveElement[], chart: Chart): void {
348                     const el: HTMLElement = document.getElementById('canvas');
349                     el.style.cursor = item[0] ? 'pointer' : 'default';
350                 },
351                 plugins: {
352                     legend: { display: false },
353                     datalabels: {
354                         anchor: 'end',
355                         align: 'top',
356                         font: {
357                             weight: 'bold'
358                         }
359                     }
360                 },
361                 scales: {
362                     x: {
363                         display: true,
364                         title: {
365                             display: true,
366                             text: this.translateService.instant('NSINSTANCES')
367                         }
368                     },
369                     y: {
370                         beginAtZero: true,
371                         display: true,
372                         title: {
373                             display: true,
374                             text: this.translateService.instant('NOOFHOURS')
375                         }
376                     }
377                 }
378             }
379         });
380     }
381
382     /** Get VNFD instance details @public */
383     public getVnfInstanceCount(): void {
384         this.vnfInstanceCountSub = this.restService.getResource(environment.VNFINSTANCES_URL)
385             .subscribe((vnfInstanceData: VNFInstanceDetails[]): void => {
386                 this.vnfInstanceCount = vnfInstanceData.length;
387             }, (error: ERRORDATA): void => {
388                 this.restService.handleError(error, 'get');
389             });
390     }
391
392     /** Get VIM account details @public */
393     public getVimAccountCount(): void {
394         this.vimAccountCountSub = this.restService.getResource(environment.VIMACCOUNTS_URL)
395             .subscribe((vimAccountData: VimAccountDetails[]): void => {
396                 this.vimAccountCount = vimAccountData.length;
397                 this.vimData = vimAccountData;
398             }, (error: ERRORDATA): void => {
399                 this.restService.handleError(error, 'get');
400             });
401     }
402
403     /** Get SDN Controller Count  @public */
404     public getSDNControllerCount(): void {
405         this.sdnControllerCountSub = this.restService.getResource(environment.SDNCONTROLLER_URL)
406             .subscribe((sdnControllerData: SDNControllerModel[]): void => {
407                 this.sdnControllerCount = sdnControllerData.length;
408             }, (error: ERRORDATA): void => {
409                 this.restService.handleError(error, 'get');
410             });
411     }
412
413     /** Get Vim data filtered by the selected Vim Type @public */
414     public getSelectedVimTypeList(selectedVIMType: string): void {
415         this.vimList = this.vimData.filter((vimData: VimAccountDetails): boolean =>
416             vimData.vim_type === selectedVIMType);
417         if (this.vimList.length === 0) {
418             this.vimListData = null;
419         }
420     }
421
422     /** Get Selected VIM details @public */
423     public getSelectedVIMDetails(vimDetails: VimAccountDetails): void {
424         if (!isNullOrUndefined(vimDetails.resources)) {
425             this.selectedVIMDetails = vimDetails;
426         } else {
427             this.notifierService.notify('error', this.translateService.instant('RESOURCESNOTFOUND'));
428         }
429     }
430
431     /**
432      * Lifecyle Hooks the trigger before component is deleted
433      */
434     public ngOnDestroy(): void {
435         this.vnfdPackageCountSub.unsubscribe();
436         this.nsdPackageCountSub.unsubscribe();
437         this.nsInstanceCountSub.unsubscribe();
438         this.vnfInstanceCountSub.unsubscribe();
439         this.vimAccountCountSub.unsubscribe();
440         this.sdnControllerCountSub.unsubscribe();
441     }
442 }