Drop Nokia from file header copyright line
[portal/ric-dashboard.git] / webapp-frontend / src / app / stats / stats.component.ts
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 AT&T Intellectual Property
6  * %%
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20 import { Component, OnInit, ViewChildren, QueryList } from '@angular/core';
21 import { BaseChartDirective } from 'ng2-charts/ng2-charts';
22 import { StatsService } from '../services/stats/stats.service';
23 import { HttpClient } from '@angular/common/http';
24 import { map } from 'rxjs/operators';
25 import { DashboardSuccessTransport } from '../interfaces/dashboard.types';
26 import { DomSanitizer, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';
27
28 @Component({
29     selector: 'rd-stats',
30     templateUrl: './stats.component.html',
31     styleUrls: ['./stats.component.scss']
32 })
33 export class StatsComponent implements OnInit {
34
35     @ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;
36     timeLeft = 60;
37     interval;
38     checked = false;
39     load;
40     delay;
41     metricsUrlAc : SafeResourceUrl;
42     metricsUrlMc : SafeResourceUrl;
43
44     public latencyChartColors: Array<any> = [
45         { // blue
46             backgroundColor: 'rgba(197, 239, 247, 0.2)',
47             borderColor: 'lightblue',
48             pointBackgroundColor: 'lightblue',
49             pointBorderColor: '#fff',
50             pointHoverBackgroundColor: '#fff',
51             pointHoverBorderColor: 'rgba(148,159,177,0.8)'
52         }
53     ];
54     public latencyChartOptions = {
55         scaleShowVerticalLines: true,
56         responsive: true,
57         animation: {
58             duration: 800 * 1.5,
59             easing: 'linear'
60         },
61         hover: {
62             animationDuration: 1 // duration of animations when hovering an item
63         },
64         responsiveAnimationDuration: 500,
65         scales: {
66             yAxes: [{
67                 ticks: {
68                     // the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)
69                     suggestedMin: 0,
70                     // the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
71                     //                    suggestedMax: 1000
72                 },
73                 scaleLabel: {
74                     display: true,
75                     labelString: 'msecs'
76                 }
77             }],
78             xAxes: [{
79                 scaleLabel: {
80                     display: true,
81                     labelString: 'time (last 10 seconds)'
82                 }
83             }]
84         },
85     };
86     public latencyChartLabels = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
87     public latencyChartType = 'line';
88     public latencyChartLegend = true;
89     public latencyChartData = [
90         { data: [65, 59, 80, 81, 56, 55, 40, 20, 12, 34], label: 'Latency' },
91     ];
92
93     public loadChartColors: Array<any> = [
94
95         { // green
96             backgroundColor: 'rgba(200, 247, 197, 0.2)',
97             borderColor: 'lightgreen',
98             pointBackgroundColor: 'lightgreen',
99             pointBorderColor: '#fff',
100             pointHoverBackgroundColor: '#fff',
101             pointHoverBorderColor: 'rgba(0,200,0,0.5)'
102         }
103     ];
104     public loadChartOptions = {
105         scaleShowVerticalLines: false,
106         responsive: true,
107         animation: {
108             duration: 800 * 1.5,
109             easing: 'linear'
110         },
111         hover: {
112             animationDuration: 1 // duration of animations when hovering an item
113         },
114         responsiveAnimationDuration: 500,
115         scales: {
116             yAxes: [{
117                 ticks: {
118                     // the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)
119                     suggestedMin: 0,
120                     // the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
121                     //                    suggestedMax: 1000
122                 },
123                 scaleLabel: {
124                     display: true,
125                     labelString: '# of requests'
126                 }
127             }],
128             xAxes: [{
129                 scaleLabel: {
130                     display: true,
131                     labelString: 'time (last 10 seconds)'
132                 }
133             }]
134         },
135     };
136     public loadChartLabels = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
137     public loadChartType = 'line';
138     public loadChartLegend = true;
139     public loadChartData = [
140         { data: [28, 48, 40, 19, 86, 77, 90, 20, 12, 34], label: 'Load' }
141     ];
142
143     public cpuChartColors: Array<any> = [
144
145         { // red
146             backgroundColor: 'rgba(241, 169, 160, 0.2)',
147             borderColor: 'brown',
148             pointBackgroundColor: 'brown',
149             pointBorderColor: '#fff',
150             pointHoverBackgroundColor: '#fff',
151             pointHoverBorderColor: 'rgba(0,200,0,0.5)'
152         }
153     ];
154     public cpuChartOptions = {
155         scaleShowVerticalLines: false,
156         responsive: true,
157         animation: {
158             duration: 800 * 1.5,
159             easing: 'linear'
160         },
161         hover: {
162             animationDuration: 1 // duration of animations when hovering an item
163         },
164         responsiveAnimationDuration: 500,
165         scales: {
166             yAxes: [{
167                 ticks: {
168                     // the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)
169                     suggestedMin: 0,
170                     // the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
171                     //                    suggestedMax: 1000
172                 },
173                 scaleLabel: {
174                     display: true,
175                     labelString: '# of requests'
176                 }
177             }],
178             xAxes: [{
179                 scaleLabel: {
180                     display: true,
181                     labelString: 'time (last 10 seconds)'
182                 }
183             }]
184         },
185     };
186     public cpuChartLabels = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
187     public cpuChartType = 'line';
188     public cpuChartLegend = true;
189     public cpuChartData = [
190         { data: [15, 29, 30, 31, 53, 52, 41, 70, 32, 14], label: 'RICLoad' }
191     ];
192
193     public x = 11;
194     public y = 11;
195     public z = 11;
196     public loop = true;
197
198     public sliderLoadMax = Number(this.service.loadMax) || 0;
199
200     public sliderDelayMax = Number(this.service.delayMax) || 0;
201
202     latencyClickData() {
203         // this.latencyChartData = [{data: [Math.random() * 100, Math.random() * 100, Math.random() * 100,
204         // Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100,
205         // Math.random() * 100, Math.random() * 100], label: 'Latency'}];
206         this.charts.forEach((child) => {
207             if (child.datasets[0].label === 'Latency') {
208                 this.latencyChartLabels.shift();
209                 child.datasets[0].data.shift();
210
211                 const latencyData = this.service.getLatencyMetrics();
212                 child.datasets[0].data.push(latencyData);
213                 this.latencyChartLabels.push('' + this.x++);
214             }
215             // once new data is computed and datasets are updated, tell our baseChart the datasets changed
216             child.ngOnChanges({
217                 datasets: {
218                     currentValue: child.datasets,
219                     previousValue: null,
220                     firstChange: true,
221                     isFirstChange: () => true
222                 }
223             });
224         });
225     }
226
227     loadClickData() {
228         if (this.loop) {
229             this.loop = false;
230             this.startLoadTimer();
231         } else {
232             this.loop = true;
233             this.pauseLoadTimer();
234         }
235     }
236
237     loopLoadData(metricsv: any) {
238         this.charts.forEach((child) => {
239             if (child.datasets[0].label === 'Load') {
240                 this.loadChartLabels.shift();
241                 child.datasets[0].data.shift();
242
243                 // const loadData = this.service.getLoad();
244                 // child.datasets[0].data.push(this.service.load);
245                 child.datasets[0].data.push(metricsv['load']);
246                 this.loadChartLabels.push('' + this.x++);
247             }
248             if (child.datasets[0].label === 'Latency') {
249                 this.latencyChartLabels.shift();
250                 child.datasets[0].data.shift();
251
252                 // const loadData = this.service.getLoad();
253                 // child.datasets[0].data.push(this.service.load);
254                 child.datasets[0].data.push(metricsv['latency']);
255                 this.latencyChartLabels.push('' + this.x++);
256             }
257             if (child.datasets[0].label === 'RICLoad') {
258                 this.latencyChartLabels.shift();
259                 child.datasets[0].data.shift();
260
261                 // const loadData = this.service.getLoad();
262                 // child.datasets[0].data.push(this.service.load);
263                 child.datasets[0].data.push(metricsv['ricload']);
264                 this.latencyChartLabels.push('' + this.x++);
265             }
266             // once new data is computed and datasets are updated, tell our baseChart the datasets changed
267             child.ngOnChanges({
268                 datasets: {
269                     currentValue: child.datasets,
270                     previousValue: null,
271                     firstChange: true,
272                     isFirstChange: () => true
273                 }
274             });
275         });
276     }
277
278     cpuClickData() {
279         // this.cpuChartData = [{data: [Math.random() * 100, Math.random() * 100, Math.random() * 100,
280         // Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100,
281         // Math.random() * 100, Math.random() * 100], label: 'CPU'}];
282         const cpuData = this.service.getLatencyMetrics();
283         this.newDataPoint([cpuData], this.z++);
284     }
285
286     newDataPoint(dataArr = [100], label) {
287
288         this.cpuChartData.forEach((dataset, index) => {
289             this.cpuChartData[index] = Object.assign({}, this.cpuChartData[index], {
290                 data: [...this.cpuChartData[index].data, dataArr[index]]
291             });
292         });
293
294         this.cpuChartLabels = [...this.cpuChartLabels, label];
295         // console.log(this.cpuChartLabels);
296         // console.log(this.cpuChartData);
297     }
298
299     formatLabel(value: number | null) {
300         if (!value) {
301             return 0;
302         }
303
304         if (value >= 1000) {
305             return Math.round(value / 1000);
306         }
307
308         return value;
309     }
310
311     constructor(private service: StatsService, private httpClient: HttpClient, private sanitize: DomSanitizer) {
312         this.sliderLoadMax = Number(this.service.loadMax) || 0;
313         this.sliderDelayMax = Number(this.service.delayMax) || 0;
314         // console.log('this.sliderLoadMax: ' + this.sliderLoadMax);
315         // console.log('this.sliderDelayMax: ' + this.sliderDelayMax);
316     }
317     ngOnInit() {
318         this.fetchLoad().subscribe(loadv => {
319             // console.log('loadv: ' + loadv);
320             this.checked = loadv;
321         });
322         this.fetchDelay().subscribe(delayv => {
323             // console.log('delayv: ' + delayv);
324             this.delay = delayv;
325         });
326         this.fetchMetrics().subscribe(metricsv => {
327             // console.log('metricsv.load: ' + metricsv['load']);
328         });
329         this.service.getAppMetricsUrl('AC').subscribe((res:DashboardSuccessTransport) => {
330             this.metricsUrlAc = this.sanitize.bypassSecurityTrustResourceUrl(res.data);
331         });
332         this.service.getAppMetricsUrl('MC').subscribe((res:DashboardSuccessTransport) => {
333             this.metricsUrlMc = this.sanitize.bypassSecurityTrustResourceUrl(res.data);
334         });
335     }
336
337     startLoadTimer() {
338         this.interval = setInterval(() => {
339             if (this.timeLeft > 0) {
340                 this.timeLeft--;
341                 this.fetchMetrics().subscribe(metricsv => {
342                     // console.log('metricsv.load: ' + metricsv['latency']);
343                     // console.log('metricsv.load: ' + metricsv['load']);
344                     // console.log('metricsv.load: ' + metricsv['ricload']);
345                     this.loopLoadData(metricsv);
346                 });
347
348             } else {
349                 this.timeLeft = 60;
350             }
351         }, 1000);
352     }
353
354     pauseLoadTimer() {
355         clearInterval(this.interval);
356     }
357
358     fetchMetrics() {
359         return this.httpClient.get<any[]>(this.service.hostURL + this.service.metricsPath, this.service.httpOptions).pipe(map(res => {
360             return res;
361         }));
362     }
363
364     fetchDelay() {
365         return this.httpClient.get<any[]>(this.service.hostURL + this.service.delayPath, this.service.httpOptions).pipe(map(res => {
366             const delayv = res['delay'];
367             this.delay = delayv;
368             return this.delay;
369         }));
370     }
371
372     saveDelay() {
373         this.service.putDelay(this.delay);
374     }
375
376     fetchLoad() {
377         return this.httpClient.get<any[]>(this.service.hostURL + this.service.loadPath, this.service.httpOptions).pipe(map(res => {
378             const loadv = res['load'];
379             this.load = loadv;
380             return this.load;
381         }));
382
383     }
384
385     saveLoad() {
386         this.service.putLoad(this.load);
387     }
388
389 }