Bug 1383 Error when consulting NS instance's topology
[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 { AuthenticationService } from 'AuthenticationService';
24 import { Chart } from 'chart.js';
25 import { ERRORDATA } from 'CommonModel';
26 import { environment } from 'environment';
27 import { NSDDetails } from 'NSDModel';
28 import { NSInstanceDetails } from 'NSInstanceModel';
29 import { ProjectData, ProjectDetails } from 'ProjectModel';
30 import { ProjectService } from 'ProjectService';
31 import { RestService } from 'RestService';
32 import { Observable, Subscription } from 'rxjs';
33 import { SDNControllerModel } from 'SDNControllerModel';
34 import { SharedService } from 'SharedService';
35 import { ProjectRoleMappings, UserDetail } from 'UserModel';
36 import { VimAccountDetails } from 'VimAccountModel';
37 import { VNFInstanceDetails } from 'VNFInstanceModel';
38
39 /**
40  * Creating component
41  * @Component takes DashboardComponent.html as template url
42  */
43 @Component({
44     styleUrls: ['./DashboardComponent.scss'],
45     templateUrl: './DashboardComponent.html'
46 })
47
48 /**
49  * This file created during the angular project creation
50  */
51
52 /** Exporting a class @exports DashboardComponent */
53 export class DashboardComponent implements OnInit {
54     /** Invoke service injectors @public */
55     public injector: Injector;
56
57     /** handle translate @public */
58     public translateService: TranslateService;
59
60     /** Observable holds logined value  @public */
61     public username$: Observable<string>;
62
63     /** Variables holds admin is logged or not @public */
64     public isAdmin: boolean;
65
66     /** List of NS failed Instances @public */
67     public nsFailedInstances: {}[] = [];
68
69     /** Setting up count for vnfdPackages @public */
70     public vnfdPackageCount: number;
71
72     /** Setting up count for nsdPackage @public */
73     public nsdPackageCount: number;
74
75     /** Setting up count for nsInstance @public */
76     public nsInstanceCount: number;
77
78     /** Setting up count for vnfInstance @public */
79     public vnfInstanceCount: number;
80
81     /** Setting up count for vimAccount @public */
82     public vimAccountCount: number;
83
84     /** Setting up count for sdnController @public */
85     public sdnControllerCount: number;
86
87     /** Variables holds current project details @public */
88     public currentProjectDetails: {};
89
90     /** Array holds all the projects @public */
91     public projectList: {}[] = [];
92
93     /** Array holds all the projects @public */
94     public allProjectList: {}[] = [];
95
96     /** Variables holds the selected project @public */
97     public selectedProject: Observable<string>;
98
99     /** Check the Instances loading results @public */
100     public isCanvasLoadingResults: boolean = true;
101
102     /** Check the Projects loading results @public */
103     public isProjectsLoadingResults: boolean = true;
104
105     /** Give the message for the loading @public */
106     public message: string = 'PLEASEWAIT';
107
108     /** List of NS Success Instances @public */
109     public nsRunningInstance: string[] = [];
110
111     /** List of color for Instances @private */
112     private backgroundColor: string[] = [];
113
114     /** Utilizes rest service for any CRUD operations @private */
115     private restService: RestService;
116
117     /** Utilizes auth service for any auth operations @private */
118     private authService: AuthenticationService;
119
120     /** Used to subscribe vnfdPackage @private */
121     private vnfdPackageCountSub: Subscription;
122
123     /** Used to subscribe nsdPackage @private */
124     private nsdPackageCountSub: Subscription;
125
126     /** Used to subscribe nsInstance @private */
127     private nsInstanceCountSub: Subscription;
128
129     /** Used to subscribe vnfInstance @private */
130     private vnfInstanceCountSub: Subscription;
131
132     /** Used to subscribe vimAccount @private */
133     private vimAccountCountSub: Subscription;
134
135     /** Used to subscribe sdnController @private */
136     private sdnControllerCountSub: Subscription;
137
138     /** No of Hours of NS Success Instances @private */
139     private noOfHours: number[] = [];
140
141     /** collects charts objects @private */
142     private charts: object = [];
143
144     /** Contains all methods related to projects @private */
145     private projectService: ProjectService;
146
147     /** Contains all methods related to shared @private */
148     private sharedService: SharedService;
149
150     /** Contains NS Instance Details */
151     private nsInstancesDataArr: {}[];
152
153     /** Container created time array @private */
154     private createdTimes: string[] = [];
155
156     /** Contains slice limit const @private */
157     private sliceLimit: number = 10;
158
159     /** Contians hour converter @private */
160     private hourConverter: number = 3600;
161
162     constructor(injector: Injector) {
163         this.injector = injector;
164         this.restService = this.injector.get(RestService);
165         this.authService = this.injector.get(AuthenticationService);
166         this.projectService = this.injector.get(ProjectService);
167         this.sharedService = this.injector.get(SharedService);
168         this.translateService = this.injector.get(TranslateService);
169     }
170
171     /**
172      * Lifecyle Hooks the trigger before component is instantiate
173      */
174     public ngOnInit(): void {
175         this.username$ = this.authService.username;
176         this.isAdmin = (localStorage.getItem('isAdmin') === 'true') ? true : false;
177         this.selectedProject = this.authService.ProjectName;
178         this.checkAdminPrivilege();
179         this.getUserAccessedProjects();
180         this.getAllProjects();
181         this.getVnfdPackageCount();
182         this.getNsdPackageCount();
183         this.getNsInstanceCount();
184         this.getVnfInstanceCount();
185         this.getVimAccountCount();
186         this.getSDNControllerCount();
187     }
188
189     /** Get all the projects @public */
190     public getUserAccessedProjects(): void {
191         this.projectService.getUserProjects().subscribe((projects: UserDetail): void => {
192             const projectList: {}[] = projects.project_role_mappings;
193             this.projectList = projectList.filter(
194                 (thing: ProjectRoleMappings, i: number, arr: []): boolean => arr
195                     .findIndex((t: ProjectRoleMappings): boolean => t.project_name === thing.project_name) === i
196             );
197         }, (error: Error): void => {
198             // TODO: Handle failure
199         });
200     }
201
202     /** Fetching all the Project in dashboard @public */
203     public getAllProjects(): void {
204         this.isProjectsLoadingResults = true;
205         this.restService.getResource(environment.PROJECTS_URL).subscribe((projectsData: ProjectDetails[]): void => {
206             this.allProjectList = [];
207             projectsData.forEach((projectData: ProjectDetails): void => {
208                 const projectDataObj: ProjectData = this.generateProjectData(projectData);
209                 this.allProjectList.push(projectDataObj);
210             });
211             this.isProjectsLoadingResults = false;
212         }, (error: ERRORDATA): void => {
213             this.restService.handleError(error, 'get');
214             this.isProjectsLoadingResults = false;
215         });
216     }
217
218     /** Generate Projects object from loop and return for the datasource @public */
219     public generateProjectData(projectData: ProjectDetails): ProjectData {
220         return {
221             projectName: projectData.name,
222             modificationDate: this.sharedService.convertEpochTime(projectData._admin.modified),
223             creationDate: this.sharedService.convertEpochTime(projectData._admin.created),
224             id: projectData._id,
225             project: projectData._id
226         };
227     }
228
229     /** Function to check admin privilege @public */
230     public checkAdminPrivilege(): void {
231         if (!this.isAdmin) {
232             this.projectService.getCurrentProjectDetails().subscribe((projectDetails: {}): void => {
233                 this.currentProjectDetails = projectDetails;
234             }, (error: Error): void => {
235                 // TODO: Handle failure
236             });
237         }
238     }
239
240     /** Get VNFD Package details @public */
241     public getVnfdPackageCount(): void {
242         this.vnfdPackageCountSub = this.restService.getResource(environment.VNFPACKAGESCONTENT_URL)
243             .subscribe((vnfdPackageData: []): void => {
244                 this.vnfdPackageCount = vnfdPackageData.length;
245             }, (error: ERRORDATA): void => {
246                 this.restService.handleError(error, 'get');
247             });
248     }
249
250     /** Get NSD Package details @public */
251     public getNsdPackageCount(): void {
252         this.nsdPackageCountSub = this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL)
253             .subscribe((nsdPackageData: NSDDetails[]): void => {
254                 this.nsdPackageCount = nsdPackageData.length;
255             }, (error: ERRORDATA): void => {
256                 this.restService.handleError(error, 'get');
257             });
258     }
259
260     /** Get NS Instance details @public */
261     public getNsInstanceCount(): void {
262         this.isCanvasLoadingResults = true;
263         this.nsInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
264             .subscribe((nsInstancesData: NSInstanceDetails[]): void => {
265                 this.nsInstancesDataArr = nsInstancesData;
266                 this.nsInstanceCount = nsInstancesData.length;
267                 this.nsInstanceChart();
268                 this.isCanvasLoadingResults = false;
269             }, (error: ERRORDATA): void => {
270                 this.restService.handleError(error, 'get');
271                 this.isCanvasLoadingResults = false;
272             });
273     }
274
275     /** Get NS Instance chart details @public */
276     public nsInstanceChart(): void {
277         this.nsInstancesDataArr.forEach((nsdInstanceData: NSDDetails): void => {
278             const operationalStatus: string = nsdInstanceData['operational-status'];
279             const configStatus: string = nsdInstanceData['config-status'];
280             if (operationalStatus === 'failed' || configStatus === 'failed') {
281                 this.nsFailedInstances.push(nsdInstanceData);
282             } else if (operationalStatus === 'running' && configStatus === 'configured') {
283                 this.nsRunningInstance.push(nsdInstanceData.name);
284                 this.backgroundColor.push(this.sharedService.generateColor());
285                 this.createdTimes.push(((nsdInstanceData._admin.created).toString()).slice(0, this.sliceLimit));
286             }
287         });
288         const now: Date = new Date();
289         const currentTime: number = Number((now.getTime().toString().slice(0, this.sliceLimit)));
290         this.createdTimes.forEach((createdTime: string): void => {
291             this.noOfHours.push((Math.round((currentTime - Number(createdTime)) / this.hourConverter)));
292         });
293         this.drawNsChart();
294     }
295
296     /** Prepare and sketch NS instance chart */
297     public drawNsChart(): void {
298         this.charts = new Chart('canvas', {
299             type: 'bar',
300             data: {
301                 labels: this.nsRunningInstance,
302                 datasets: [{
303                     data: this.noOfHours,
304                     label: this.translateService.instant('NOOFHOURS'),
305                     borderColor: this.backgroundColor,
306                     fill: false,
307                     backgroundColor: this.backgroundColor
308                 }]
309             },
310             options: {
311                 hover: {
312                     onHover(evt: Event, item: {}): void {
313                         const el: HTMLElement = document.getElementById('canvas');
314                         el.style.cursor = item[0] ? 'pointer' : 'default';
315                     }
316                 },
317                 legend: { display: false },
318                 scales: {
319                     xAxes: [{
320                         display: true,
321                         scaleLabel: {
322                             display: true,
323                             labelString: this.translateService.instant('INSTANCES')
324                         }
325                     }],
326                     yAxes: [{
327                         ticks: {
328                             beginAtZero: true
329                         },
330                         display: true,
331                         scaleLabel: {
332                             display: true,
333                             labelString: this.translateService.instant('NOOFHOURS')
334                         }
335                     }]
336                 }
337             }
338         });
339     }
340
341     /** Get VNFD instance details @public */
342     public getVnfInstanceCount(): void {
343         this.vnfInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
344             .subscribe((vnfInstanceData: VNFInstanceDetails[]): void => {
345                 this.vnfInstanceCount = vnfInstanceData.length;
346             }, (error: ERRORDATA): void => {
347                 this.restService.handleError(error, 'get');
348             });
349     }
350
351     /** Get VIM account details @public */
352     public getVimAccountCount(): void {
353         this.vimAccountCountSub = this.restService.getResource(environment.VIMACCOUNTS_URL)
354             .subscribe((vimAccountData: VimAccountDetails[]): void => {
355                 this.vimAccountCount = vimAccountData.length;
356             }, (error: ERRORDATA): void => {
357                 this.restService.handleError(error, 'get');
358             });
359     }
360
361     /** Get SDN Controller Count  @public */
362     public getSDNControllerCount(): void {
363         this.sdnControllerCountSub = this.restService.getResource(environment.SDNCONTROLLER_URL)
364             .subscribe((sdnControllerData: SDNControllerModel[]): void => {
365                 this.sdnControllerCount = sdnControllerData.length;
366             }, (error: ERRORDATA): void => {
367                 this.restService.handleError(error, 'get');
368             });
369     }
370
371     /**
372      * Lifecyle Hooks the trigger before component is deleted
373      */
374     public ngOnDestroy(): void {
375         this.vnfdPackageCountSub.unsubscribe();
376         this.nsdPackageCountSub.unsubscribe();
377         this.nsInstanceCountSub.unsubscribe();
378         this.vnfInstanceCountSub.unsubscribe();
379         this.vimAccountCountSub.unsubscribe();
380         this.sdnControllerCountSub.unsubscribe();
381     }
382 }