Fix Bug 1974: No.Of Hours Value for the running instances is hidden in Dashboard
[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 } from 'chart.js';
26 import 'chartjs-plugin-labels';
27 import { ERRORDATA, TYPESECTION, VIM_TYPES } from 'CommonModel';
28 import { environment } from 'environment';
29 import { NSDDetails } from 'NSDModel';
30 import { NSInstanceDetails } from 'NSInstanceModel';
31 import { ProjectData, ProjectDetails } from 'ProjectModel';
32 import { ProjectService } from 'ProjectService';
33 import { RestService } from 'RestService';
34 import { Observable, Subscription } from 'rxjs';
35 import { SDNControllerModel } from 'SDNControllerModel';
36 import { SharedService } from 'SharedService';
37 import { ProjectRoleMappings, UserDetail } from 'UserModel';
38 import { isNullOrUndefined } from 'util';
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     private sliceLimit: number = 10;
176
177     /** Contians hour converter @private */
178     private hourConverter: number = 3600;
179
180     /** Notifier service to popup notification @private */
181     private notifierService: NotifierService;
182
183     constructor(injector: Injector) {
184         this.injector = injector;
185         this.restService = this.injector.get(RestService);
186         this.authService = this.injector.get(AuthenticationService);
187         this.projectService = this.injector.get(ProjectService);
188         this.sharedService = this.injector.get(SharedService);
189         this.translateService = this.injector.get(TranslateService);
190         this.notifierService = this.injector.get(NotifierService);
191     }
192
193     /**
194      * Lifecyle Hooks the trigger before component is instantiate
195      */
196     public ngOnInit(): void {
197         this.username$ = this.authService.username;
198         this.isAdmin = (localStorage.getItem('isAdmin') === 'true') ? true : false;
199         this.selectedProject = this.authService.ProjectName;
200         this.checkAdminPrivilege();
201         this.getUserAccessedProjects();
202         this.getAllProjects();
203         this.getVnfdPackageCount();
204         this.getNsdPackageCount();
205         this.getNsInstanceCount();
206         this.getVnfInstanceCount();
207         this.getVimAccountCount();
208         this.getSDNControllerCount();
209     }
210
211     /** Get all the projects @public */
212     public getUserAccessedProjects(): void {
213         this.projectService.getUserProjects().subscribe((projects: UserDetail): void => {
214             const projectList: {}[] = projects.project_role_mappings;
215             this.projectList = projectList.filter(
216                 (thing: ProjectRoleMappings, i: number, arr: []): boolean => arr
217                     .findIndex((t: ProjectRoleMappings): boolean => t.project_name === thing.project_name) === i
218             );
219         }, (error: Error): void => {
220             // TODO: Handle failure
221         });
222     }
223
224     /** Fetching all the Project in dashboard @public */
225     public getAllProjects(): void {
226         this.isProjectsLoadingResults = true;
227         this.restService.getResource(environment.PROJECTS_URL).subscribe((projectsData: ProjectDetails[]): void => {
228             this.allProjectList = [];
229             projectsData.forEach((projectData: ProjectDetails): void => {
230                 const projectDataObj: ProjectData = this.generateProjectData(projectData);
231                 this.allProjectList.push(projectDataObj);
232             });
233             this.isProjectsLoadingResults = false;
234         }, (error: ERRORDATA): void => {
235             this.restService.handleError(error, 'get');
236             this.isProjectsLoadingResults = false;
237         });
238     }
239
240     /** Generate Projects object from loop and return for the datasource @public */
241     public generateProjectData(projectData: ProjectDetails): ProjectData {
242         return {
243             projectName: projectData.name,
244             modificationDate: this.sharedService.convertEpochTime(projectData._admin.modified),
245             creationDate: this.sharedService.convertEpochTime(projectData._admin.created),
246             id: projectData._id,
247             project: projectData._id
248         };
249     }
250
251     /** Function to check admin privilege @public */
252     public checkAdminPrivilege(): void {
253         if (!this.isAdmin) {
254             this.projectService.getCurrentProjectDetails().subscribe((projectDetails: {}): void => {
255                 this.currentProjectDetails = projectDetails;
256             }, (error: Error): void => {
257                 // TODO: Handle failure
258             });
259         }
260     }
261
262     /** Get VNFD Package details @public */
263     public getVnfdPackageCount(): void {
264         this.vnfdPackageCountSub = this.restService.getResource(environment.VNFPACKAGESCONTENT_URL)
265             .subscribe((vnfdPackageData: []): void => {
266                 this.vnfdPackageCount = vnfdPackageData.length;
267             }, (error: ERRORDATA): void => {
268                 this.restService.handleError(error, 'get');
269             });
270     }
271
272     /** Get NSD Package details @public */
273     public getNsdPackageCount(): void {
274         this.nsdPackageCountSub = this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL)
275             .subscribe((nsdPackageData: NSDDetails[]): void => {
276                 this.nsdPackageCount = nsdPackageData.length;
277             }, (error: ERRORDATA): void => {
278                 this.restService.handleError(error, 'get');
279             });
280     }
281
282     /** Get NS Instance details @public */
283     public getNsInstanceCount(): void {
284         this.isCanvasLoadingResults = true;
285         this.nsInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
286             .subscribe((nsInstancesData: NSInstanceDetails[]): void => {
287                 this.nsInstancesDataArr = nsInstancesData;
288                 this.nsInstanceCount = nsInstancesData.length;
289                 this.nsInstanceChart();
290                 this.isCanvasLoadingResults = false;
291             }, (error: ERRORDATA): void => {
292                 this.restService.handleError(error, 'get');
293                 this.isCanvasLoadingResults = false;
294             });
295     }
296
297     /** Get NS Instance chart details @public */
298     public nsInstanceChart(): void {
299         this.nsInstancesDataArr.forEach((nsdInstanceData: NSDDetails): void => {
300             const operationalStatus: string = nsdInstanceData['operational-status'];
301             const configStatus: string = nsdInstanceData['config-status'];
302             if (operationalStatus === 'failed' || configStatus === 'failed') {
303                 this.nsFailedInstances.push(nsdInstanceData);
304             } else if (operationalStatus === 'running' && configStatus === 'configured') {
305                 this.nsRunningInstance.push(nsdInstanceData.name);
306                 this.backgroundColor.push(this.sharedService.generateColor());
307                 this.createdTimes.push(((nsdInstanceData._admin.created).toString()).slice(0, this.sliceLimit));
308             }
309         });
310         const now: Date = new Date();
311         const currentTime: number = Number((now.getTime().toString().slice(0, this.sliceLimit)));
312         this.createdTimes.forEach((createdTime: string): void => {
313             this.noOfHours.push((Math.round((currentTime - Number(createdTime)) / this.hourConverter)));
314         });
315         this.drawNsChart();
316     }
317
318     /** Prepare and sketch NS instance chart */
319     public drawNsChart(): void {
320         this.charts = new Chart('canvas', {
321             type: 'bar',
322             data: {
323                 labels: this.nsRunningInstance,
324                 datasets: [{
325                     data: this.noOfHours,
326                     label: this.translateService.instant('NOOFHOURS'),
327                     borderColor: this.backgroundColor,
328                     fill: false,
329                     backgroundColor: this.backgroundColor
330                 }]
331             },
332             options: {
333                 layout: {
334                     padding: {
335                         top: 20
336                     }
337                 },
338                 hover: {
339                     onHover(evt: Event, item: {}): void {
340                         const el: HTMLElement = document.getElementById('canvas');
341                         el.style.cursor = item[0] ? 'pointer' : 'default';
342                     }
343                 },
344                 plugins: {
345                     labels: {
346                         // render 'label', 'value', 'percentage', 'image' or custom function, default is 'percentage'
347                         render: 'value'
348                     }
349                 },
350                 legend: { display: false },
351                 scales: {
352                     xAxes: [{
353                         display: true,
354                         scaleLabel: {
355                             display: true,
356                             labelString: this.translateService.instant('INSTANCES')
357                         }
358                     }],
359                     yAxes: [{
360                         ticks: {
361                             beginAtZero: true
362                         },
363                         display: true,
364                         scaleLabel: {
365                             display: true,
366                             labelString: this.translateService.instant('NOOFHOURS')
367                         }
368                     }]
369                 }
370             }
371         });
372     }
373
374     /** Get VNFD instance details @public */
375     public getVnfInstanceCount(): void {
376         this.vnfInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
377             .subscribe((vnfInstanceData: VNFInstanceDetails[]): void => {
378                 this.vnfInstanceCount = vnfInstanceData.length;
379             }, (error: ERRORDATA): void => {
380                 this.restService.handleError(error, 'get');
381             });
382     }
383
384     /** Get VIM account details @public */
385     public getVimAccountCount(): void {
386         this.vimAccountCountSub = this.restService.getResource(environment.VIMACCOUNTS_URL)
387             .subscribe((vimAccountData: VimAccountDetails[]): void => {
388                 this.vimAccountCount = vimAccountData.length;
389                 this.vimData = vimAccountData;
390             }, (error: ERRORDATA): void => {
391                 this.restService.handleError(error, 'get');
392             });
393     }
394
395     /** Get SDN Controller Count  @public */
396     public getSDNControllerCount(): void {
397         this.sdnControllerCountSub = this.restService.getResource(environment.SDNCONTROLLER_URL)
398             .subscribe((sdnControllerData: SDNControllerModel[]): void => {
399                 this.sdnControllerCount = sdnControllerData.length;
400             }, (error: ERRORDATA): void => {
401                 this.restService.handleError(error, 'get');
402             });
403     }
404
405     /** Get Vim data filtered by the selected Vim Type @public */
406     public getSelectedVimTypeList(selectedVIMType: string): void {
407         this.vimList = this.vimData.filter((vimData: VimAccountDetails): boolean =>
408             vimData.vim_type === selectedVIMType);
409         if (this.vimList.length === 0) {
410             this.vimListData = null;
411         }
412
413     }
414
415     /** Get Selected VIM details @public */
416     public getSelectedVIMDetails(vimDetails: VimAccountDetails): void {
417         if (!isNullOrUndefined(vimDetails.resources)) {
418             this.selectedVIMDetails = vimDetails;
419         } else {
420             this.notifierService.notify('error', this.translateService.instant('RESOURCESNOTFOUND'));
421         }
422     }
423
424     /**
425      * Lifecyle Hooks the trigger before component is deleted
426      */
427     public ngOnDestroy(): void {
428         this.vnfdPackageCountSub.unsubscribe();
429         this.nsdPackageCountSub.unsubscribe();
430         this.nsInstanceCountSub.unsubscribe();
431         this.vnfInstanceCountSub.unsubscribe();
432         this.vimAccountCountSub.unsubscribe();
433         this.sdnControllerCountSub.unsubscribe();
434     }
435 }