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]
