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/31 13:30:54 UTC

[incubator-dlab] branch develop updated: [DLAB-1715]: Notification if project quota is exceeded (#836)

This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git


The following commit(s) were added to refs/heads/develop by this push:
     new d8a3478  [DLAB-1715]: Notification if project quota is exceeded (#836)
d8a3478 is described below

commit d8a3478f0ad60dcc6416fde6540aaabad79ce353
Author: Dmytro Gnatyshyn <42...@users.noreply.github.com>
AuthorDate: Fri Jul 31 16:30:46 2020 +0300

    [DLAB-1715]: Notification if project quota is exceeded (#836)
    
    [DLAB-1715]: Notification if project quota is exceeded
---
 .../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      | 105 +++++++++++++++------
 4 files changed, 97 insertions(+), 30 deletions(-)

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..7046696 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,38 @@ 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.healthStatusService.getQuotaStatus().pipe(take(1)).subscribe((params: Quota) => {
+        let checkQuotaAlert = '';
+        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 (Number(params.totalQuotaUsed) >= 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 (checkQuotaAlert === '') {
+          this.storage.setBillingQuoteUsed('informed');
+        } else {
+          this.storage.setBillingQuoteUsed('');
+        }
+
+        if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
+        checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.totalQuotaUsed, exceedProjects, informProjects);
+      });
     }
   }
 
@@ -206,25 +232,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