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

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

commit 13594f7847044a907ebe45f358fdacc588e60f24
Author: ofuks <[email protected]>
AuthorDate: Mon Sep 30 19:39:38 2019 +0300

    [DLAB-1075]: Added possibility to stop project with related instances on 
Manage environment popup
---
 .../dlab/backendapi/domain/ProjectManagingDTO.java | 16 +++++++
 .../dlab/backendapi/resources/ProjectResource.java | 36 +++++++++++++++
 .../dlab/backendapi/service/ProjectService.java    |  5 ++
 .../service/impl/ProjectServiceImpl.java           | 54 +++++++++++++++++++++-
 4 files changed, 110 insertions(+), 1 deletion(-)

diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectManagingDTO.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectManagingDTO.java
new file mode 100644
index 0000000..167128e
--- /dev/null
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectManagingDTO.java
@@ -0,0 +1,16 @@
+package com.epam.dlab.backendapi.domain;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+@AllArgsConstructor
+public class ProjectManagingDTO {
+    private String name;
+    private final Integer budget;
+    private boolean canBeStopped;
+    private boolean canBeTerminated;
+}
\ No newline at end of file
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 3d618e3..c361b1b 100644
--- 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -110,6 +110,26 @@ public class ProjectResource {
                                .build();
        }
 
+       @Operation(summary = "Stop project on Manage environment popup", tags = 
"project")
+       @ApiResponses({
+                       @ApiResponse(responseCode = "202", description = 
"Project is stopping"),
+                       @ApiResponse(responseCode = "400", description = 
"Validation error", content = @Content(mediaType =
+                                       MediaType.APPLICATION_JSON,
+                                       schema = @Schema(implementation = 
ErrorDTO.class)))
+       })
+       @Path("managing/stop/{name}")
+       @POST
+       @Consumes(MediaType.APPLICATION_JSON)
+       @RolesAllowed("/api/project")
+       public Response stopProjectWithResources(@Parameter(hidden = true) 
@Auth UserInfo userInfo,
+                                                                               
         @Parameter(description = "Project name")
+                                                                               
         @PathParam("name") String name) {
+               projectService.stopWithResources(userInfo, name);
+               return Response
+                               .accepted()
+                               .build();
+       }
+
 
        @Operation(summary = "Get project info", tags = "project")
        @ApiResponses({
@@ -149,6 +169,22 @@ public class ProjectResource {
                                .build();
        }
 
+       @Operation(summary = "Get available projects for managing", tags = 
"project")
+       @ApiResponses({
+                       @ApiResponse(responseCode = "200", description = 
"Return information about projects",
+                                       content = @Content(mediaType = 
MediaType.APPLICATION_JSON, schema =
+                                       @Schema(implementation = 
ProjectManagingDTO.class))),
+       })
+       @GET
+       @Path("managing")
+       @Produces(MediaType.APPLICATION_JSON)
+       @RolesAllowed("/api/project")
+       public Response getProjectsForManaging(@Parameter(hidden = true) @Auth 
UserInfo userInfo) {
+               return Response
+                               .ok(projectService.getProjectsForManaging())
+                               .build();
+       }
+
        @Operation(summary = "Get projects assigned to user", tags = "project")
        @ApiResponses({
                        @ApiResponse(responseCode = "200", description = 
"Return information about projects",
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index 2823eb7..1a94259 100644
--- 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -2,6 +2,7 @@ package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
+import com.epam.dlab.backendapi.domain.ProjectManagingDTO;
 import com.epam.dlab.backendapi.domain.UpdateProjectDTO;
 
 import java.util.List;
@@ -9,6 +10,8 @@ import java.util.List;
 public interface ProjectService {
        List<ProjectDTO> getProjects();
 
+       List<ProjectManagingDTO> getProjectsForManaging();
+
        List<ProjectDTO> getUserActiveProjects(UserInfo userInfo);
 
        List<ProjectDTO> getProjectsWithStatus(ProjectDTO.Status status);
@@ -25,6 +28,8 @@ public interface ProjectService {
 
        void stop(UserInfo userInfo, String endpoint, String name);
 
+       void stopWithResources(UserInfo userInfo, String projectName);
+
        void update(UserInfo userInfo, UpdateProjectDTO projectDTO);
 
        void updateBudget(String project, Integer budget);
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index de5ecfa..7b44d0f 100644
--- 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -3,17 +3,21 @@ package com.epam.dlab.backendapi.service.impl;
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.annotation.BudgetLimited;
 import com.epam.dlab.backendapi.annotation.Project;
+import com.epam.dlab.backendapi.dao.ExploratoryDAO;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.dao.UserGroupDao;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.domain.ProjectEndpointDTO;
+import com.epam.dlab.backendapi.domain.ProjectManagingDTO;
 import com.epam.dlab.backendapi.domain.RequestId;
 import com.epam.dlab.backendapi.domain.UpdateProjectDTO;
 import com.epam.dlab.backendapi.service.EndpointService;
 import com.epam.dlab.backendapi.service.ExploratoryService;
 import com.epam.dlab.backendapi.service.ProjectService;
+import com.epam.dlab.backendapi.service.SecurityService;
 import com.epam.dlab.backendapi.util.RequestBuilder;
 import com.epam.dlab.constants.ServiceConsts;
+import com.epam.dlab.dto.UserInstanceDTO;
 import com.epam.dlab.dto.UserInstanceStatus;
 import com.epam.dlab.exceptions.ResourceConflictException;
 import com.epam.dlab.exceptions.ResourceNotFoundException;
@@ -22,6 +26,8 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import lombok.extern.slf4j.Slf4j;
 
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -39,6 +45,9 @@ public class ProjectServiceImpl implements ProjectService {
        private static final String START_PRJ_API = 
"infrastructure/project/start";
        private static final String STOP_PRJ_API = 
"infrastructure/project/stop";
        private static final String ANY_USER_ROLE = "$anyuser";
+       private static final String STOP_ACTION = "stop";
+       private static final String TERMINATE_ACTION = "terminate";
+
        private final ProjectDAO projectDAO;
        private final ExploratoryService exploratoryService;
        private final UserGroupDao userGroupDao;
@@ -46,12 +55,15 @@ public class ProjectServiceImpl implements ProjectService {
        private final RequestId requestId;
        private final RequestBuilder requestBuilder;
        private final EndpointService endpointService;
+       private final ExploratoryDAO exploratoryDAO;
+       private final SecurityService securityService;
 
        @Inject
        public ProjectServiceImpl(ProjectDAO projectDAO, ExploratoryService 
exploratoryService,
                                                          UserGroupDao 
userGroupDao,
                                                          
@Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
-                                                         RequestId requestId, 
RequestBuilder requestBuilder, EndpointService endpointService) {
+                                                         RequestId requestId, 
RequestBuilder requestBuilder, EndpointService endpointService,
+                                                         ExploratoryDAO 
exploratoryDAO, SecurityService securityService) {
                this.projectDAO = projectDAO;
                this.exploratoryService = exploratoryService;
                this.userGroupDao = userGroupDao;
@@ -59,6 +71,8 @@ public class ProjectServiceImpl implements ProjectService {
                this.requestId = requestId;
                this.requestBuilder = requestBuilder;
                this.endpointService = endpointService;
+               this.exploratoryDAO = exploratoryDAO;
+               this.securityService = securityService;
        }
 
        @Override
@@ -67,6 +81,16 @@ public class ProjectServiceImpl implements ProjectService {
        }
 
        @Override
+       public List<ProjectManagingDTO> getProjectsForManaging() {
+               return projectDAO.getProjects().stream().map(p -> new 
ProjectManagingDTO(
+                               p.getName(), p.getBudget(), 
!exploratoryDAO.fetchProjectExploratoriesWhereStatusIn(p.getName(),
+                               
Collections.singletonList(UserInstanceStatus.RUNNING), 
UserInstanceStatus.RUNNING).isEmpty(),
+                               !p.getEndpoints().stream().allMatch(e -> 
Arrays.asList(UserInstanceStatus.STARTING,
+                                               UserInstanceStatus.TERMINATED, 
UserInstanceStatus.TERMINATING).contains(e.getStatus()))))
+                               .collect(Collectors.toList());
+       }
+
+       @Override
        public List<ProjectDTO> getUserActiveProjects(UserInfo userInfo) {
                userInfo.getRoles().add(ANY_USER_ROLE);
                return projectDAO.getUserProjects(userInfo);
@@ -103,6 +127,7 @@ public class ProjectServiceImpl implements ProjectService {
 
        @Override
        public void terminateProject(UserInfo userInfo, String name) {
+               checkProjectRelatedResourcesInProgress(name, TERMINATE_ACTION);
                get(name).getEndpoints()
                                .stream()
                                .map(ProjectEndpointDTO::getName)
@@ -123,6 +148,16 @@ public class ProjectServiceImpl implements ProjectService {
        }
 
        @Override
+       public void stopWithResources(UserInfo userInfo, String projectName) {
+               ProjectDTO project = get(projectName);
+               checkProjectRelatedResourcesInProgress(projectName, 
STOP_ACTION);
+               
exploratoryDAO.fetchRunningExploratoryFieldsForProject(projectName).forEach(this::stopNotebook);
+               project.getEndpoints().stream().filter(e -> 
!Arrays.asList(UserInstanceStatus.TERMINATED,
+                               
UserInstanceStatus.TERMINATING).contains(e.getStatus())).
+                               forEach(e -> stop(userInfo, e.getName(), 
projectName));
+       }
+
+       @Override
        public void update(UserInfo userInfo, UpdateProjectDTO projectDTO) {
                final ProjectDTO project = 
projectDAO.get(projectDTO.getName()).orElseThrow(projectNotFound());
                final Set<String> endpoints = project.getEndpoints()
@@ -189,6 +224,23 @@ public class ProjectServiceImpl implements ProjectService {
                }
        }
 
+       private void checkProjectRelatedResourcesInProgress(String projectName, 
String action) {
+               List<UserInstanceDTO> userInstanceDTOs = 
exploratoryDAO.fetchProjectExploratoriesWhereStatusIn(projectName,
+                               Arrays.asList(UserInstanceStatus.CREATING, 
UserInstanceStatus.STARTING,
+                                               
UserInstanceStatus.CREATING_IMAGE), UserInstanceStatus.CREATING,
+                               UserInstanceStatus.CONFIGURING, 
UserInstanceStatus.STARTING, UserInstanceStatus.RECONFIGURING,
+                               UserInstanceStatus.CREATING_IMAGE);
+               if (!userInstanceDTOs.isEmpty()) {
+                       throw new ResourceConflictException((String.format("Can 
not %s environment because on of user resource " +
+                                       "is in status CREATING or STARTING", 
action)));
+               }
+       }
+
+       private void stopNotebook(UserInstanceDTO instance) {
+               final UserInfo userInfo = 
securityService.getUserInfoOffline(instance.getUser());
+               exploratoryService.stop(userInfo, 
instance.getExploratoryName());
+       }
+
        private Supplier<ResourceNotFoundException> projectNotFound() {
                return () -> new ResourceNotFoundException("Project with passed 
name not found");
        }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to