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