You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dg...@apache.org on 2020/07/29 13:24:06 UTC
[incubator-dlab] 01/02: [DLAB-1715]: User should be notify if
project quota is exceeded
This is an automated email from the ASF dual-hosted git repository.
dgnatyshyn pushed a commit to branch DLAB-1715
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 42209c5f711462d3aff2febffcaded90c2038879
Author: Dmytro_Gnatyshyn <di...@ukr.net>
AuthorDate: Wed Jul 29 16:17:22 2020 +0300
[DLAB-1715]: User should be notify if project quota is exceeded
---
.../core/services/applicationSecurity.service.ts | 1 +
.../services/applicationServiceFacade.service.ts | 9 ++
.../src/app/core/services/healthStatus.service.ts | 8 ++
.../notification-dialog.component.ts | 5 +-
.../src/app/shared/navbar/navbar.component.ts | 110 +++++++++++++++------
5 files changed, 103 insertions(+), 30 deletions(-)
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationSecurity.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationSecurity.service.ts
index 1bcd4f8..fae09ef 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationSecurity.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationSecurity.service.ts
@@ -87,6 +87,7 @@ export class ApplicationSecurityService {
map(response => {
this.storage.destroyTokens();
this.storage.setBillingQuoteUsed('');
+ this.storage.setIsBillingQuoteUsed('');
this._loggedInStatus.next(false);
return response;
}, this));
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
index 2c0e661..39e92af 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
@@ -78,6 +78,7 @@ export class ApplicationServiceFacade {
private static readonly ENDPOINT = 'endpoint';
private static readonly ENDPOINT_CONNECTION = 'endpoint_connection';
private static readonly AUDIT = 'audit';
+ private static readonly QUOTA = 'quota';
private requestRegistry: Dictionary<string>;
@@ -307,6 +308,13 @@ export class ApplicationServiceFacade {
data);
}
+ public buildGetQuotaStatus(): Observable<any> {
+ return this.buildRequest(HTTPMethod.GET,
+ this.requestRegistry.Item(ApplicationServiceFacade.QUOTA),
+ null
+ );
+ }
+
public buildRunEdgeNodeRequest(): Observable<any> {
return this.buildRequest(HTTPMethod.POST,
this.requestRegistry.Item(ApplicationServiceFacade.EDGE_NODE_START),
@@ -723,6 +731,7 @@ export class ApplicationServiceFacade {
// billing report
this.requestRegistry.Add(ApplicationServiceFacade.BILLING, '/api/billing/report');
this.requestRegistry.Add(ApplicationServiceFacade.DOWNLOAD_REPORT, '/api/billing/report/download');
+ this.requestRegistry.Add(ApplicationServiceFacade.QUOTA, '/api/billing/quota');
// project
this.requestRegistry.Add(ApplicationServiceFacade.PROJECT, '/api/project');
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
index 02004f3..09f902e 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
@@ -84,6 +84,14 @@ export class HealthStatusService {
catchError(ErrorUtils.handleServiceError));
}
+ public getQuotaStatus(): Observable<{}> {
+ return this.applicationServiceFacade
+ .buildGetQuotaStatus()
+ .pipe(
+ map(response => response),
+ catchError(ErrorUtils.handleServiceError));
+ }
+
public runEdgeNode(): Observable<{}> {
return this.applicationServiceFacade
.buildRunEdgeNodeRequest()
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
index e185675..551e3e2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
@@ -56,7 +56,9 @@ import {Endpoint} from '../../../administration/project/project.component';
</div>
<span class="strong blue">by a schedule in less than 15 minutes.</span>
</div>
- <div *ngIf="data.type === 'message'"><span [innerHTML]="data.template"></span></div>
+ <div class="alert" *ngIf="data.type === 'message'">
+ <span [innerHTML]="data.template"></span>
+ </div>
<div *ngIf="data.type === 'confirmation'" class="confirm-dialog">
<p *ngIf="data.template; else label">
<span [innerHTML]="data.template"></span>
@@ -169,6 +171,7 @@ import {Endpoint} from '../../../administration/project/project.component';
label{cursor: pointer}
.bottom-message{padding-top: 15px;}
.table-header{padding-bottom: 10px;}
+ .alert{text-align: left; line-height: 22px; padding-bottom: 25px;padding-top: 15px;}
`]
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
index e30f8db..7be914f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
@@ -38,9 +38,14 @@ import {
animateChild,
state
} from '@angular/animations';
-import {skip} from 'rxjs/operators';
+import {skip, take} from 'rxjs/operators';
import {ProgressBarService} from '../../core/services/progress-bar.service';
+
+interface Quota {
+ projectQuotas: {};
+ totalQuotaUsed: number;
+}
@Component({
selector: 'dlab-navbar',
templateUrl: 'navbar.component.html',
@@ -110,7 +115,7 @@ export class NavbarComponent implements OnInit, OnDestroy {
if (this.isLoggedIn) {
this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
this.healthStatus = result;
- result.status && this.checkQuoteUsed(this.healthStatus);
+ result.status && this.checkQuoteUsed();
result.status && !result.projectAssigned && !result.admin && this.checkAssignment(this.healthStatus);
}));
this.subscriptions.add(timer(0, this.CHECK_ACTIVE_SCHEDULE_TIMEOUT).subscribe(() => this.refreshSchedulerData()));
@@ -148,9 +153,9 @@ export class NavbarComponent implements OnInit, OnDestroy {
this.isExpanded = !this.isExpanded;
}
- public emitQuotes(alert, user_quota?, total_quota?): void {
+ public emitQuotes(alert, total_quota?, exideedProjects?, informProjects?): void {
const dialogRef: MatDialogRef<NotificationDialogComponent> = this.dialog.open(NotificationDialogComponent, {
- data: { template: this.selectAlert(alert, user_quota, total_quota), type: 'message' },
+ data: { template: this.selectAlert(alert, total_quota, exideedProjects, informProjects), type: 'message' },
width: '550px'
});
dialogRef.afterClosed().subscribe(() => {
@@ -158,17 +163,43 @@ export class NavbarComponent implements OnInit, OnDestroy {
});
}
- private checkQuoteUsed(params): void {
- if (!this.storage.getBillingQuoteUsed() && params) {
- let checkQuotaAlert = '';
+ private checkQuoteUsed(): void {
+ if (!this.storage.getBillingQuoteUsed( ) && !this.storage.getIsBillingQuoteUsed()) {
+ this.healthStatusService.getQuotaStatus().pipe(take(1)).subscribe((params: Quota) => {
+ let checkQuotaAlert = '';
+ params = {
+ projectQuotas: {Proj1: 99, Proj2: 99, Proj3: 99, Proj4: 99},
+ totalQuotaUsed: 50
+ };
+
+ const exceedProjects = [], informProjects = [];
+ Object.keys(params.projectQuotas).forEach(key => {
+ if (params.projectQuotas[key] > this.quotesLimit && params.projectQuotas[key] < 100) {
+ informProjects.push(key);
+ } else if (params.projectQuotas[key] >= 100) {
+ exceedProjects.push(key);
+ }
+ });
+
+ if (informProjects.length > 0 && exceedProjects.length === 0) checkQuotaAlert = 'project_quota';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100) checkQuotaAlert = 'total_quota';
+ if (exceedProjects.length > 0 && informProjects.length === 0) checkQuotaAlert = 'project_exceed';
+ if (informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'project_inform_and_exceed';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_exceed';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_inform_and_exceed';
- if (params.billingUserQuoteUsed >= this.quotesLimit && params.billingUserQuoteUsed < 100) checkQuotaAlert = 'user_quota';
- if (params.billingQuoteUsed >= this.quotesLimit && params.billingQuoteUsed < 100) checkQuotaAlert = 'total_quota';
- if (Number(params.billingUserQuoteUsed) >= 100) checkQuotaAlert = 'user_exceed';
- if (Number(params.billingQuoteUsed) >= 100) checkQuotaAlert = 'total_exceed';
- if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
- checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.billingUserQuoteUsed, params.billingQuoteUsed);
+ if (Number(params.totalQuotaUsed) >= 100) checkQuotaAlert = 'total_exceed';
+
+ if (checkQuotaAlert === '') {
+ this.storage.setIsBillingQuoteUsed(true);
+ } else {
+ this.storage.setIsBillingQuoteUsed('');
+ }
+
+ if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
+ checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.totalQuotaUsed, exceedProjects, informProjects);
+ });
}
}
@@ -206,25 +237,46 @@ export class NavbarComponent implements OnInit, OnDestroy {
});
}
- private selectAlert(type: string, user_quota?: number, total_quota?: number): string {
+ private selectAlert(type: string, total_quota?: number, exideedProjects?: string[], informProjects?: string[]): string {
const alerts = {
- user_exceed: `Dear <b>${this.currentUserName}</b>,<br />
- DLab cloud infrastructure usage quota associated with your user has been exceeded.
- All your analytical environment will be stopped. To proceed working with environment,
- request increase of user quota from DLab administrator.`,
- total_exceed: `Dear <b>${this.currentUserName}</b>,<br />
+ total_quota_and_project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ If quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+ total_quota_and_project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+ project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ If quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment, request increase of project quota from DLab administrator.`,
+ project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded.
+ All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment,
+ request increase of project(s) quota from DLab administrator.`,
+ total_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
DLab cloud infrastructure usage quota has been exceeded.
- All your analytical environment will be stopped. To proceed working with environment,
+ All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment,
request increase application quota from DLab administrator.`,
- user_quota: `Dear <b>${this.currentUserName}</b>,<br />
- Cloud infrastructure usage quota associated with your user has been used for <b>${user_quota}%</b>.
- Once quota is depleted all your analytical environment will be stopped.
- To proceed working with environment you'll have to request increase of user quota from DLab administrator.`,
- total_quota: `Dear <b>${this.currentUserName}</b>,<br />
- DLab cloud infrastructure usage quota has been used for <b>${total_quota}%</b>.
- Once quota is depleted all your analytical environment will be stopped.
- To proceed working with environment you'll have to request increase of user quota from DLab administrator. `,
- permissions: `Dear <b>${this.currentUserName}</b>,<br />
+ project_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ Cloud infrastructure usage quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of project(s) quota from DLab administrator.`,
+ total_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of total quota from DLab administrator. `,
+ permissions: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
Currently, you are not assigned to any project. To start working with the environment
request permission from DLab administrator.`
};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org