]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
f3a99505e2cee920058115b7ca85a252159a7b19
[ceph.git] /
1 import { Component, OnDestroy, OnInit } from '@angular/core';
2
3 import _ from 'lodash';
4 import { Observable, ReplaySubject, Subscription, combineLatest, of } from 'rxjs';
5
6 import { Permissions } from '~/app/shared/models/permissions';
7 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
8 import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
9 import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
10 import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
11 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
12 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
13 import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
14 import { PrometheusService } from '~/app/shared/api/prometheus.service';
15
16 import { RgwPromqls as queries } from '~/app/shared/enum/dashboard-promqls.enum';
17 import { Icons } from '~/app/shared/enum/icons.enum';
18 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
19 import { catchError, shareReplay, switchMap, tap } from 'rxjs/operators';
20
21 @Component({
22   selector: 'cd-rgw-overview-dashboard',
23   templateUrl: './rgw-overview-dashboard.component.html',
24   styleUrls: ['./rgw-overview-dashboard.component.scss']
25 })
26 export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
27   icons = Icons;
28
29   interval = new Subscription();
30   permissions: Permissions;
31   rgwDaemonCount = 0;
32   rgwRealmCount = 0;
33   rgwZonegroupCount = 0;
34   rgwZoneCount = 0;
35   rgwBucketCount = 0;
36   objectCount = 0;
37   UserCount = 0;
38   totalPoolUsedBytes = 0;
39   averageObjectSize = 0;
40   realmData: any;
41   realmSub: Subscription;
42   multisiteInfo: object[] = [];
43   ZonegroupSub: Subscription;
44   ZoneSUb: Subscription;
45   queriesResults: { [key: string]: [] } = {
46     RGW_REQUEST_PER_SECOND: [],
47     BANDWIDTH: [],
48     AVG_GET_LATENCY: [],
49     AVG_PUT_LATENCY: []
50   };
51   timerGetPrometheusDataSub: Subscription;
52   chartTitles = ['Metadata Sync', 'Data Sync'];
53   realm: string;
54   zonegroup: string;
55   zone: string;
56   metadataSyncInfo: string;
57   replicaZonesInfo: any = [];
58   metadataSyncData: {};
59   showMultisiteCard = true;
60   loading = true;
61   multisiteSyncStatus$: Observable<any>;
62   subject = new ReplaySubject<any>();
63   syncCardLoading = true;
64   fetchDataSub: Subscription;
65
66   constructor(
67     private authStorageService: AuthStorageService,
68     private refreshIntervalService: RefreshIntervalService,
69     private rgwDaemonService: RgwDaemonService,
70     private rgwRealmService: RgwRealmService,
71     private rgwZonegroupService: RgwZonegroupService,
72     private rgwZoneService: RgwZoneService,
73     private rgwBucketService: RgwBucketService,
74     private prometheusService: PrometheusService,
75     private rgwMultisiteService: RgwMultisiteService
76   ) {
77     this.permissions = this.authStorageService.getPermissions();
78   }
79
80   ngOnInit() {
81     this.interval = this.refreshIntervalService.intervalData$.subscribe(() => {
82       this.fetchDataSub = combineLatest([
83         this.rgwDaemonService.list(),
84         this.rgwBucketService.fetchAndTransformBuckets(),
85         this.rgwBucketService.totalNumObjects$,
86         this.rgwBucketService.totalUsedCapacity$,
87         this.rgwBucketService.averageObjectSize$,
88         this.rgwBucketService.getTotalBucketsAndUsersLength()
89       ]).subscribe(([daemonData, _, objectCount, usedCapacity, averageSize, bucketData]) => {
90         this.rgwDaemonCount = daemonData.length;
91         this.objectCount = objectCount;
92         this.totalPoolUsedBytes = usedCapacity;
93         this.averageObjectSize = averageSize;
94         this.rgwBucketCount = bucketData.buckets_count;
95         this.UserCount = bucketData.users_count;
96         this.getSyncStatus();
97       });
98     });
99     this.realmSub = this.rgwRealmService.list().subscribe((data: any) => {
100       this.rgwRealmCount = data['realms'].length;
101     });
102     this.ZonegroupSub = this.rgwZonegroupService.list().subscribe((data: any) => {
103       this.rgwZonegroupCount = data['zonegroups'].length;
104     });
105     this.ZoneSUb = this.rgwZoneService.list().subscribe((data: any) => {
106       this.rgwZoneCount = data['zones'].length;
107     });
108     this.getPrometheusData(this.prometheusService.lastHourDateObject);
109     this.multisiteSyncStatus$ = this.subject.pipe(
110       switchMap(() =>
111         this.rgwMultisiteService.getSyncStatus().pipe(
112           tap((data: any) => {
113             this.loading = false;
114             this.replicaZonesInfo = data['dataSyncInfo'];
115             this.metadataSyncInfo = data['metadataSyncInfo'];
116             if (this.replicaZonesInfo.length === 0) {
117               this.showMultisiteCard = false;
118               this.syncCardLoading = false;
119               this.loading = false;
120             }
121             [this.realm, this.zonegroup, this.zone] = data['primaryZoneData'];
122           }),
123           catchError((err) => {
124             this.showMultisiteCard = false;
125             this.syncCardLoading = false;
126             this.loading = false;
127             err.preventDefault();
128             return of(true);
129           })
130         )
131       ),
132       shareReplay(1)
133     );
134   }
135
136   ngOnDestroy() {
137     this.interval?.unsubscribe();
138     this.realmSub?.unsubscribe();
139     this.ZonegroupSub?.unsubscribe();
140     this.ZoneSUb?.unsubscribe();
141     this.fetchDataSub?.unsubscribe();
142     this.prometheusService?.unsubscribe();
143   }
144
145   getPrometheusData(selectedTime: any) {
146     this.queriesResults = this.prometheusService.getPrometheusQueriesData(
147       selectedTime,
148       queries,
149       this.queriesResults,
150       true
151     );
152   }
153
154   getSyncStatus() {
155     this.subject.next();
156   }
157
158   trackByFn(zone: any) {
159     return zone;
160   }
161 }