You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by of...@apache.org on 2020/07/08 14:24:18 UTC

[incubator-dlab] branch DLAB-1919 updated: [DLAB-1919] Second part of changes

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

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


The following commit(s) were added to refs/heads/DLAB-1919 by this push:
     new 4ef5ba3  [DLAB-1919] Second part of changes
4ef5ba3 is described below

commit 4ef5ba3c839258f5e6f7c84a0e7f14e6653b3672
Author: Oleh Fuks <ol...@gmail.com>
AuthorDate: Tue Jul 7 15:38:42 2020 +0300

    [DLAB-1919] Second part of changes
---
 .../com/epam/dlab/backendapi/dao/AuditDAOImpl.java |  7 ++
 .../dlab/backendapi/domain/AuditActionEnum.java    |  2 +-
 .../backendapi/domain/AuditResourceTypeEnum.java   |  3 +-
 .../service/impl/ExploratoryServiceImpl.java       | 46 +++++++------
 .../service/impl/SchedulerJobServiceImpl.java      | 40 +++++------
 .../audit/audit-grid/audit-grid.component.ts       |  9 +--
 .../cluster-details/cluster-details.component.ts   |  2 +-
 .../detail-dialog/detail-dialog.component.ts       |  2 +-
 .../notification-dialog.component.ts               |  4 +-
 .../service/impl/ExploratoryServiceImplTest.java   |  8 +--
 .../service/impl/SchedulerJobServiceImplTest.java  | 80 +++++++++++-----------
 11 files changed, 106 insertions(+), 97 deletions(-)

diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
index 6ae8cbf..1106fdb 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
@@ -24,6 +24,7 @@ import com.epam.dlab.backendapi.domain.AuditPaginationDTO;
 import com.epam.dlab.exceptions.DlabException;
 import com.mongodb.client.model.Facet;
 import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.Sorts;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.bson.Document;
@@ -50,6 +51,7 @@ import static com.mongodb.client.model.Aggregates.group;
 import static com.mongodb.client.model.Aggregates.limit;
 import static com.mongodb.client.model.Aggregates.match;
 import static com.mongodb.client.model.Aggregates.skip;
+import static com.mongodb.client.model.Aggregates.sort;
 import static com.mongodb.client.model.Filters.gte;
 import static com.mongodb.client.model.Filters.in;
 import static com.mongodb.client.model.Filters.lte;
@@ -85,6 +87,7 @@ public class AuditDAOImpl extends BaseDAO implements AuditDAO {
         }
         countPipeline.add(count());
         valuesPipeline.addAll(Arrays.asList(skip(pageSize * (pageNumber - 1)), limit(pageSize)));
+        valuesPipeline.add(sortCriteria());
 
         List<Bson> userFilter = Collections.singletonList(group(getGroupingFields(USER)));
         List<Bson> projectFilter = Collections.singletonList(group(getGroupingFields(PROJECT)));
@@ -116,6 +119,10 @@ public class AuditDAOImpl extends BaseDAO implements AuditDAO {
         return searchCriteria;
     }
 
+    private Bson sortCriteria() {
+        return sort(Sorts.descending(TIMESTAMP_FIELD));
+    }
+
     private AuditPaginationDTO toAuditPaginationDTO(Document document) {
         List<Document> countDocuments = (List<Document>) document.get(TOTAL_COUNT_FACET);
         final int count = countDocuments.isEmpty() ? 0 : countDocuments.get(0).getInteger(COUNT_FIELD);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditActionEnum.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditActionEnum.java
index cd5eb7b..ee3823f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditActionEnum.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditActionEnum.java
@@ -20,5 +20,5 @@
 package com.epam.dlab.backendapi.domain;
 
 public enum AuditActionEnum {
-    CREATE, START, STOP, TERMINATE, RECONFIGURE, UPDATE, CONNECT, DISCONNECT, UPLOAD, DOWNLOAD, DELETE, INSTALL, FOLLOW_LINK, LOG_IN
+    CREATE, SET_UP_SCHEDULER, START, STOP, TERMINATE, RECONFIGURE, UPDATE, CONNECT, DISCONNECT, UPLOAD, DOWNLOAD, DELETE, INSTALL, FOLLOW_LINK, LOG_IN
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditResourceTypeEnum.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditResourceTypeEnum.java
index dce8f06..6976114 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditResourceTypeEnum.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/AuditResourceTypeEnum.java
@@ -20,6 +20,5 @@
 package com.epam.dlab.backendapi.domain;
 
 public enum AuditResourceTypeEnum {
-    PROJECT, EDGE_NODE, NOTEBOOK, NOTEBOOK_SCHEDULER, COMPUTE, COMPUTATIONAL_LIBS, COMPUTATIONAL_SCHEDULER,
-    BUCKET, ENDPOINT, NOTEBOOK_LIBS, GROUP, IMAGE, GIT_ACCOUNT, LOG_IN
+    PROJECT, EDGE_NODE, NOTEBOOK, COMPUTE, COMPUTATIONAL_LIBS, BUCKET, ENDPOINT, NOTEBOOK_LIBS, GROUP, IMAGE, GIT_ACCOUNT, LOG_IN, WEB_TERMINAL
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
index 39f7ec0..e89eda3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
@@ -183,13 +183,16 @@ public class ExploratoryServiceImpl implements ExploratoryService {
 	@Override
 	public void updateProjectExploratoryStatuses(UserInfo userInfo, String project, String endpoint, UserInstanceStatus status) {
 		exploratoryDAO.fetchProjectExploratoriesWhereStatusNotIn(project, endpoint, TERMINATED, FAILED)
-				.forEach(ui -> updateExploratoryStatus(userInfo, project, ui.getExploratoryName(), status, ui.getUser()));
+				.forEach(ui -> updateExploratoryComputeStatuses(userInfo, project, ui.getExploratoryName(), status, ui.getUser()));
 	}
 
 	@Override
 	public void updateProjectExploratoryStatuses(String project, String endpoint, UserInstanceStatus status) {
 		exploratoryDAO.fetchProjectExploratoriesWhereStatusNotIn(project, endpoint, TERMINATED, FAILED)
-				.forEach(ui -> updateExploratoryStatus(project, ui.getExploratoryName(), status, ui.getUser()));
+				.forEach(ui -> {
+					updateExploratoryStatus(ui.getUser(), project, ui.getExploratoryName(), status);
+					updateComputationalStatuses(ui.getUser(), project, ui.getExploratoryName(), TERMINATED, TERMINATED, TERMINATED, FAILED);
+				});
 	}
 
 	@Audit(action = RECONFIGURE, type = NOTEBOOK)
@@ -287,7 +290,7 @@ public class ExploratoryServiceImpl implements ExploratoryService {
 	 */
 	private String action(UserInfo userInfo, String resourceCreator, String project, String exploratoryName, String action, UserInstanceStatus status) {
 		try {
-			updateExploratoryStatus(project, exploratoryName, status, resourceCreator);
+			updateExploratoryComputeStatuses(userInfo.getName(), project, exploratoryName, status, resourceCreator);
 
 			UserInstanceDTO userInstance = exploratoryDAO.fetchExploratoryFields(resourceCreator, project, exploratoryName);
 			EndpointDTO endpointDTO = endpointService.get(userInstance.getEndpoint());
@@ -308,40 +311,39 @@ public class ExploratoryServiceImpl implements ExploratoryService {
 	}
 
 	@Audit(action = TERMINATE, type = NOTEBOOK)
-	public void updateExploratoryStatus(@User UserInfo userInfo, @Project String project, @ResourceName String exploratoryName, UserInstanceStatus status, String user) {
-		updateExploratoryStatus(user, project, exploratoryName, status);
-		updateComputationalStatuses(project, exploratoryName, status, user);
+	public void updateExploratoryComputeStatuses(@User UserInfo userInfo, @Project String project, @ResourceName String exploratoryName, UserInstanceStatus status, String resourceCreator) {
+		updateExploratoryStatus(resourceCreator, project, exploratoryName, status);
+		updateComputationalStatuses(userInfo.getName(), resourceCreator, project, exploratoryName, status);
 	}
 
-	private void updateExploratoryStatus(String project, String exploratoryName, UserInstanceStatus status, String user) {
-		updateExploratoryStatus(user, project, exploratoryName, status);
-		updateComputationalStatuses(project, exploratoryName, status, user);
+	private void updateExploratoryComputeStatuses(String user, String project, String exploratoryName, UserInstanceStatus status, String resourceCreator) {
+		updateExploratoryStatus(resourceCreator, project, exploratoryName, status);
+		updateComputationalStatuses(user, resourceCreator, project, exploratoryName, status);
 	}
 
-	private void updateComputationalStatuses(String project, String exploratoryName, UserInstanceStatus status, String user) {
+	private void updateComputationalStatuses(String user, String resourceCreator, String project, String exploratoryName, UserInstanceStatus status) {
 		if (status == STOPPING) {
 			if (configuration.isAuditEnabled()) {
-				saveAudit(project, exploratoryName, user, STOP);
+				saveAudit(user, resourceCreator, project, exploratoryName, STOP, RUNNING);
 			}
-			updateComputationalStatuses(user, project, exploratoryName, STOPPING, TERMINATING, FAILED, TERMINATED, STOPPED);
+			updateComputationalStatuses(resourceCreator, project, exploratoryName, STOPPING, TERMINATING, FAILED, TERMINATED, STOPPED);
 		} else if (status == TERMINATING) {
 			if (configuration.isAuditEnabled()) {
-				saveAudit(project, exploratoryName, user, TERMINATE);
+				saveAudit(user, resourceCreator, project, exploratoryName, TERMINATE, RUNNING, STOPPED);
 			}
-			updateComputationalStatuses(user, project, exploratoryName, TERMINATING, TERMINATING, TERMINATED, FAILED);
-		} else if (status == TERMINATED) {
-			updateComputationalStatuses(user, project, exploratoryName, TERMINATED, TERMINATED, TERMINATED, FAILED);
+			updateComputationalStatuses(resourceCreator, project, exploratoryName, TERMINATING, TERMINATING, TERMINATED, FAILED);
 		}
 	}
 
-	private void saveAudit(String project, String exploratoryName, String user, AuditActionEnum action) {
-		saveAuditForComputational(project, exploratoryName, user, action, DataEngineType.SPARK_STANDALONE);
-		saveAuditForComputational(project, exploratoryName, user, TERMINATE, DataEngineType.CLOUD_SERVICE);
+	private void saveAudit(String user, String resourceCreator, String project, String exploratoryName, AuditActionEnum action, UserInstanceStatus... sparkStatuses) {
+		saveAuditForComputational(user, resourceCreator, project, exploratoryName, action, DataEngineType.SPARK_STANDALONE, sparkStatuses);
+		saveAuditForComputational(user, resourceCreator, project, exploratoryName, TERMINATE, DataEngineType.CLOUD_SERVICE, RUNNING, STOPPED);
 	}
 
-	private void saveAuditForComputational(String project, String exploratoryName, String user, AuditActionEnum action, DataEngineType cloudService) {
-		computationalDAO.getComputationalResourcesWhereStatusIn(user, project, Collections.singletonList(cloudService),
-				exploratoryName, RUNNING)
+	private void saveAuditForComputational(String user, String resourceCreator, String project, String exploratoryName, AuditActionEnum action, DataEngineType cloudService,
+	                                       UserInstanceStatus... computationalStatuses) {
+		computationalDAO.getComputationalResourcesWhereStatusIn(resourceCreator, project, Collections.singletonList(cloudService),
+				exploratoryName, computationalStatuses)
 				.forEach(comp -> auditService.save(
 						AuditDTO.builder()
 								.user(user)
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImpl.java
index 5b80c42..4b64e0b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImpl.java
@@ -63,9 +63,9 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static com.epam.dlab.backendapi.domain.AuditActionEnum.CREATE;
-import static com.epam.dlab.backendapi.domain.AuditResourceTypeEnum.COMPUTATIONAL_SCHEDULER;
-import static com.epam.dlab.backendapi.domain.AuditResourceTypeEnum.NOTEBOOK_SCHEDULER;
+import static com.epam.dlab.backendapi.domain.AuditActionEnum.SET_UP_SCHEDULER;
+import static com.epam.dlab.backendapi.domain.AuditResourceTypeEnum.COMPUTE;
+import static com.epam.dlab.backendapi.domain.AuditResourceTypeEnum.NOTEBOOK;
 import static com.epam.dlab.constants.ServiceConsts.PROVISIONING_SERVICE_NAME;
 import static com.epam.dlab.dto.UserInstanceStatus.CONFIGURING;
 import static com.epam.dlab.dto.UserInstanceStatus.CREATING;
@@ -83,7 +83,7 @@ import static java.util.Date.from;
 @Singleton
 public class SchedulerJobServiceImpl implements SchedulerJobService {
 	private static final String SCHEDULER_NOT_FOUND_MSG = "Scheduler job data not found for user %s with exploratory %s";
-	private static final String AUDIT_MESSAGE = "Scheduled action";
+	private static final String AUDIT_MESSAGE = "Scheduled action, requested for notebook %s";
 	private static final long ALLOWED_INACTIVITY_MINUTES = 1L;
 
 	@Inject
@@ -129,8 +129,8 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
                         exploratoryName) + " with computational resource " + computationalName));
     }
 
-    @Audit(action = CREATE, type = NOTEBOOK_SCHEDULER)
-    @Override
+	@Audit(action = SET_UP_SCHEDULER, type = NOTEBOOK)
+	@Override
     public void updateExploratorySchedulerData(@User UserInfo user, @Project String project, @ResourceName String exploratoryName, SchedulerJobDTO dto) {
         validateExploratoryStatus(user.getName(), project, exploratoryName);
         populateDefaultSchedulerValues(dto);
@@ -145,8 +145,8 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
         }
     }
 
-    @Audit(action = CREATE, type = COMPUTATIONAL_SCHEDULER)
-    @Override
+	@Audit(action = SET_UP_SCHEDULER, type = COMPUTE)
+	@Override
     public void updateComputationalSchedulerData(@User UserInfo user, @Project String project, String exploratoryName, @ResourceName String computationalName, SchedulerJobDTO dto) {
         validateExploratoryStatus(user.getName(), project, exploratoryName);
         validateComputationalStatus(user.getName(), project, exploratoryName, computationalName);
@@ -225,8 +225,8 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
         final String expName = job.getExploratoryName();
         final String compName = job.getComputationalName();
         final String user = job.getUser();
-        log.debug("Stopping exploratory {} computational {} for user {} by scheduler", expName, compName, user);
-        computationalService.stopSparkCluster(securityService.getServiceAccountInfo(user), user, project, expName, compName, AUDIT_MESSAGE);
+		log.debug("Stopping exploratory {} computational {} for user {} by scheduler", expName, compName, user);
+		computationalService.stopSparkCluster(securityService.getServiceAccountInfo(user), user, project, expName, compName, String.format(AUDIT_MESSAGE, expName));
     }
 
 	private void terminateComputational(SchedulerJobData job) {
@@ -234,16 +234,16 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
         final String expName = job.getExploratoryName();
         final String compName = job.getComputationalName();
         final UserInfo userInfo = securityService.getServiceAccountInfo(user);
-        log.debug("Terminating exploratory {} computational {} for user {} by scheduler", expName, compName, user);
-        computationalService.terminateComputational(userInfo, user, job.getProject(), expName, compName, AUDIT_MESSAGE);
+		log.debug("Terminating exploratory {} computational {} for user {} by scheduler", expName, compName, user);
+		computationalService.terminateComputational(userInfo, user, job.getProject(), expName, compName, String.format(AUDIT_MESSAGE, expName));
     }
 
 	private void stopExploratory(SchedulerJobData job) {
         final String expName = job.getExploratoryName();
         final String user = job.getUser();
         final String project = job.getProject();
-        log.debug("Stopping exploratory {} for user {} by scheduler", expName, user);
-        exploratoryService.stop(securityService.getServiceAccountInfo(user), user, project, expName, AUDIT_MESSAGE);
+		log.debug("Stopping exploratory {} for user {} by scheduler", expName, user);
+		exploratoryService.stop(securityService.getServiceAccountInfo(user), user, project, expName, String.format(AUDIT_MESSAGE, expName));
     }
 
 	private List<SchedulerJobData> getExploratorySchedulersForTerminating(OffsetDateTime now) {
@@ -264,8 +264,8 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
         final String user = schedulerJobData.getUser();
         final String exploratoryName = schedulerJobData.getExploratoryName();
         final String project = schedulerJobData.getProject();
-        log.debug("Starting exploratory {} for user {} by scheduler", exploratoryName, user);
-        exploratoryService.start(securityService.getServiceAccountInfo(user), exploratoryName, project, AUDIT_MESSAGE);
+		log.debug("Starting exploratory {} for user {} by scheduler", exploratoryName, user);
+		exploratoryService.start(securityService.getServiceAccountInfo(user), exploratoryName, project, String.format(AUDIT_MESSAGE, exploratoryName));
         if (schedulerJobData.getJobDTO().isSyncStartRequired()) {
             log.trace("Starting computational for exploratory {} for user {} by scheduler", exploratoryName, user);
             final DataEngineType sparkCluster = DataEngineType.SPARK_STANDALONE;
@@ -283,13 +283,13 @@ public class SchedulerJobServiceImpl implements SchedulerJobService {
         final String user = job.getUser();
         final String project = job.getProject();
         final String expName = job.getExploratoryName();
-        log.debug("Terminating exploratory {} for user {} by scheduler", expName, user);
-        exploratoryService.terminate(securityService.getUserInfoOffline(user), user, project, expName, AUDIT_MESSAGE);
+		log.debug("Terminating exploratory {} for user {} by scheduler", expName, user);
+		exploratoryService.terminate(securityService.getUserInfoOffline(user), user, project, expName, String.format(AUDIT_MESSAGE, expName));
     }
 
 	private void startSpark(String user, String expName, String compName, String project) {
-        log.debug("Starting exploratory {} computational {} for user {} by scheduler", expName, compName, user);
-        computationalService.startSparkCluster(securityService.getServiceAccountInfo(user), expName, compName, project, AUDIT_MESSAGE);
+		log.debug("Starting exploratory {} computational {} for user {} by scheduler", expName, compName, user);
+		computationalService.startSparkCluster(securityService.getServiceAccountInfo(user), expName, compName, project, String.format(AUDIT_MESSAGE, expName));
     }
 
 	private boolean shouldClusterBeStarted(DataEngineType sparkCluster, UserComputationalResource compResource) {
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
index 8c71bdd..c710b3f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
@@ -221,16 +221,17 @@ export class AuditGridComponent implements OnInit {
             </mat-list>
             <ng-template #message>
               <div class="message-wrapper">
-                <p *ngIf="data.element.type !== 'COMPUTATIONAL'; else computation">
-                  <span *ngIf="data.element.info === 'Scheduled action.';else notScheduledNotebook">{{data.element.action | titlecase}} by scheduler.</span>
+                <p *ngIf="data.element.type !== 'COMPUTE'; else computation">
+                  <span *ngIf="data.element.info.indexOf('Scheduled') !== -1;else notScheduledNotebook">{{data.element.action | titlecase}} by scheduler.</span>
+
                   <ng-template #notScheduledNotebook>
                     <span>{{data.element.info}}.</span>
                   </ng-template>
                 </p>
                 <ng-template #computation>
-                  <p *ngIf="data.element.info.indexOf('Scheduled') !== -1;else notScheduled"> {{data.element.action | titlecase}} by scheduler, requested for notebook <span class="strong">{{data.element.info.split(' ')[data.element.info.split(' ').length - 1] }}</span></p>
+                  <p *ngIf="data.element.info.indexOf('Scheduled') !== -1;else notScheduled"> {{data.element.action | titlecase}} by scheduler, requested for notebook <span class="strong">{{data.element.info.split(' ')[data.element.info.split(' ').length - 1] }}.</span></p>
                     <ng-template #notScheduled>
-                      <p> {{data.element.action | titlecase}} computational resource <span class="strong">{{data.element.resourceName}}</span>, requested for notebook <span class="strong">{{data.element.info.split(' ')[data.element.info.split(' ').length - 1] }}</span></p>
+                      <p> {{data.element.action | titlecase}} computational resource <span class="strong">{{data.element.resourceName}}</span>, requested for notebook <span class="strong">{{data.element.info.split(' ')[data.element.info.split(' ').length - 1] }}.</span></p>
                     </ng-template>
                 </ng-template>
               </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
index b026fb4..b6d32aa 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
@@ -119,6 +119,6 @@ export class DetailComputationalResourcesComponent implements OnInit {
   }
 
   private logAction(name: any, description: string) {
-    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`}).subscribe();
+    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`, type: 'COMPUTE'}).subscribe();
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
index 0c9d4ad..89a4e29 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
@@ -161,6 +161,6 @@ export class DetailDialogComponent implements OnInit {
   }
 
   private logAction(name: any, description: string) {
-    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`}).subscribe();
+    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`, type: 'NOTEBOOK'}).subscribe();
   }
 }
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 657b47f..43688cf 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
@@ -39,8 +39,8 @@ import {Endpoint} from '../../../administration/project/project.component';
             </div>
               <div *ngIf="data.type === 'list'" class="info">
                   <div *ngIf="data.template.notebook.length > 0">
-                      Following notebook server<span *ngIf="data.template.notebook.length>1">s </span>
-                      <span *ngFor="let item of data.template.notebook">
+                      Following notebook server<span *ngIf="data.template.notebook.length>1">s</span>
+                    <span *ngFor="let item of data.template.notebook">&nbsp;
                         <span class="strong">{{ item.exploratory_name }}</span>
                         <span *ngIf="data.template.notebook.length > 1">, </span>
                       </span> will be stopped and all computational resources will be stopped/terminated
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImplTest.java
index 04b4c01..a4412af 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImplTest.java
@@ -399,18 +399,18 @@ public class ExploratoryServiceImplTest {
 				anyString(), any(UserInstanceStatus.class), any(UserInstanceStatus.class), anyVararg());
 
 		exploratoryService.updateProjectExploratoryStatuses(userInfo, "project",
-				"endpoint", UserInstanceStatus.TERMINATED);
-		statusEnvBaseDTO = getStatusEnvBaseDTOWithStatus("terminated");
+				"endpoint", UserInstanceStatus.TERMINATING);
+		statusEnvBaseDTO = getStatusEnvBaseDTOWithStatus("terminating");
 
 		verify(exploratoryDAO).fetchProjectExploratoriesWhereStatusNotIn("project", "endpoint",
 				UserInstanceStatus.TERMINATED, UserInstanceStatus.FAILED);
 		verify(exploratoryDAO).updateExploratoryStatus(refEq(statusEnvBaseDTO, "self"));
 		verify(computationalDAO).updateComputationalStatusesForExploratory(USER, PROJECT,
-				EXPLORATORY_NAME, UserInstanceStatus.TERMINATED, UserInstanceStatus.TERMINATED,
+				EXPLORATORY_NAME, UserInstanceStatus.TERMINATING, UserInstanceStatus.TERMINATING,
 				UserInstanceStatus.TERMINATED, UserInstanceStatus.FAILED);
 
 		verifyNoMoreInteractions(exploratoryDAO, computationalDAO);
-    }
+	}
 
 	@Test
 	public void getUserInstance() {
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImplTest.java
index c66ba83..2721a51 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/SchedulerJobServiceImplTest.java
@@ -80,7 +80,7 @@ import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class SchedulerJobServiceImplTest {
-	private static final String AUDIT_MESSAGE = "Scheduled action";
+	private static final String AUDIT_MESSAGE = "Scheduled action, requested for notebook %s";
 	private final String USER = "test";
 	private final String EXPLORATORY_NAME = "explName";
 	private final String COMPUTATIONAL_NAME = "compName";
@@ -416,10 +416,10 @@ public class SchedulerJobServiceImplTest {
 
 		verify(securityService).getServiceAccountInfo(USER);
 		verify(schedulerJobDAO)
-                .getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, STOPPED);
-        verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME),
-                eq(COMPUTATIONAL_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
+				.getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, STOPPED);
+		verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME),
+				eq(COMPUTATIONAL_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
 	}
 
 	@Test
@@ -516,11 +516,11 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.stopComputationalByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO)
-                .getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, RUNNING);
-        verify(computationalService).stopSparkCluster(refEq(userInfo), eq(userInfo.getName()), eq(PROJECT),
-                eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
+		verify(schedulerJobDAO)
+				.getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, RUNNING);
+		verify(computationalService).stopSparkCluster(refEq(userInfo), eq(userInfo.getName()), eq(PROJECT),
+				eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
     }
 
 	@Test
@@ -615,10 +615,10 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.stopExploratoryByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerWithStatusAndClusterLastActivityLessThan(eq(RUNNING),
-                any(Date.class));
-        verify(exploratoryService).stop(refEq(userInfo), eq(USER), eq(PROJECT), eq(EXPLORATORY_NAME), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService);
+		verify(schedulerJobDAO).getExploratorySchedulerWithStatusAndClusterLastActivityLessThan(eq(RUNNING),
+				any(Date.class));
+		verify(exploratoryService).stop(refEq(userInfo), eq(USER), eq(PROJECT), eq(EXPLORATORY_NAME), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService);
     }
 
 	@Test
@@ -710,11 +710,11 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.startExploratoryByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
-        verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService);
-        verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(schedulerJobDAO, exploratoryService);
+		verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
+		verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService);
+		verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(schedulerJobDAO, exploratoryService);
         verifyZeroInteractions(computationalService, computationalDAO);
     }
 
@@ -736,13 +736,13 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.startExploratoryByScheduler();
 
         verify(securityService, times(2)).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
-        verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
-        verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME),
-                eq(PROJECT), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalService,
-                computationalDAO);
+		verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
+		verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
+		verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME),
+				eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalService,
+				computationalDAO);
     }
 
 	@Test
@@ -763,9 +763,9 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.startExploratoryByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
-        verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
+		verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
+		verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
         verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalDAO);
         verifyZeroInteractions(computationalService);
     }
@@ -788,9 +788,9 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.startExploratoryByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
-        verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(AUDIT_MESSAGE));
-        verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
+		verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED);
+		verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED);
         verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalDAO);
         verifyZeroInteractions(computationalService);
     }
@@ -880,11 +880,11 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.terminateComputationalByScheduler();
 
         verify(securityService).getServiceAccountInfo(USER);
-        verify(schedulerJobDAO)
-                .getComputationalSchedulerDataWithOneOfStatus(RUNNING, STOPPED, RUNNING);
-        verify(computationalService).terminateComputational(refEq(userInfo), eq(userInfo.getName()), eq(PROJECT), eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME),
-                eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
+		verify(schedulerJobDAO)
+				.getComputationalSchedulerDataWithOneOfStatus(RUNNING, STOPPED, RUNNING);
+		verify(computationalService).terminateComputational(refEq(userInfo), eq(userInfo.getName()), eq(PROJECT), eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME),
+				eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService);
     }
 
 	@Test
@@ -974,9 +974,9 @@ public class SchedulerJobServiceImplTest {
         schedulerJobService.terminateExploratoryByScheduler();
 
         verify(securityService).getUserInfoOffline(USER);
-        verify(schedulerJobDAO).getExploratorySchedulerDataWithOneOfStatus(RUNNING, STOPPED);
-        verify(exploratoryService).terminate(refEq(getUserInfo()), eq(USER), eq(PROJECT), eq(EXPLORATORY_NAME), eq(AUDIT_MESSAGE));
-        verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService, exploratoryService);
+		verify(schedulerJobDAO).getExploratorySchedulerDataWithOneOfStatus(RUNNING, STOPPED);
+		verify(exploratoryService).terminate(refEq(getUserInfo()), eq(USER), eq(PROJECT), eq(EXPLORATORY_NAME), eq(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME)));
+		verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService, exploratoryService);
     }
 
 	@Test


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org