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