This is an automated email from the ASF dual-hosted git repository. ofuks pushed a commit to branch audit in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
The following commit(s) were added to refs/heads/audit by this push: new c66d6c4 Added audit for computational resources c66d6c4 is described below commit c66d6c44488d17064b78b6ae973305396069cbec Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Wed Jun 10 15:09:12 2020 +0300 Added audit for computational resources --- .../dlab/backendapi/domain/AuditActionEnum.java | 2 +- .../resources/aws/ComputationalResourceAws.java | 84 ++++++++++----------- .../azure/ComputationalResourceAzure.java | 72 +++++++++--------- .../resources/gcp/ComputationalResourceGcp.java | 88 +++++++++++----------- .../backendapi/service/ComputationalService.java | 30 ++++---- .../service/impl/ComputationalServiceImpl.java | 59 +++++++-------- .../service/impl/EnvironmentServiceImpl.java | 11 ++- .../service/impl/SchedulerJobServiceImpl.java | 20 ++--- .../epam/dlab/backendapi/util/RequestBuilder.java | 20 ++--- .../service/impl/ComputationalServiceImplTest.java | 12 +-- .../service/impl/EnvironmentServiceImplTest.java | 13 ++-- .../service/impl/SchedulerJobServiceImplTest.java | 69 ++++++++--------- 12 files changed, 238 insertions(+), 242 deletions(-) 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 315925c..749885f 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 @@ -22,6 +22,6 @@ package com.epam.dlab.backendapi.domain; public enum AuditActionEnum { CREATE_PROJECT, START_PROJECT, STOP_PROJECT, TERMINATE_PROJECT, UPDATE_PROJECT, CREATE_NOTEBOOK, START_NOTEBOOK, STOP_NOTEBOOK, TERMINATE_NOTEBOOK, UPDATE_CLUSTER_CONFIG, - CREATE_DATA_ENGINE, CREATE_DATA_ENGINE_SERVICE, TERMINATE_COMPUTATIONAL, + CREATE_DATA_ENGINE, CREATE_DATA_ENGINE_SERVICE, START_COMPUTATIONAL, STOP_COMPUTATIONAL, TERMINATE_COMPUTATIONAL, UPDATE_DATA_ENGINE_CONFIG, FOLLOW_NOTEBOOK_LINK } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/aws/ComputationalResourceAws.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/aws/ComputationalResourceAws.java index d6ab4f4..a6f2f97 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/aws/ComputationalResourceAws.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/aws/ComputationalResourceAws.java @@ -98,17 +98,17 @@ public class ComputationalResourceAws implements ComputationalAPI { .computationalName(form.getName()) .imageName(form.getImage()) .templateName(form.getTemplateName()) - .status(CREATING.toString()) - .masterShape(form.getMasterInstanceType()) - .slaveShape(form.getSlaveInstanceType()) - .slaveSpot(form.getSlaveInstanceSpot()) - .slaveSpotPctPrice(form.getSlaveInstanceSpotPctPrice()) - .slaveNumber(form.getInstanceCount()) - .config(form.getConfig()) - .version(form.getVersion()) - .build(); - boolean resourceAdded = computationalService.createDataEngineService(userInfo, form.getName(), form, awsComputationalResource, - form.getProject(), Collections.singletonList(String.format(AUDIT_MESSAGE, form.getNotebookName()))); + .status(CREATING.toString()) + .masterShape(form.getMasterInstanceType()) + .slaveShape(form.getSlaveInstanceType()) + .slaveSpot(form.getSlaveInstanceSpot()) + .slaveSpotPctPrice(form.getSlaveInstanceSpotPctPrice()) + .slaveNumber(form.getInstanceCount()) + .config(form.getConfig()) + .version(form.getVersion()) + .build(); + boolean resourceAdded = computationalService.createDataEngineService(userInfo, form.getName(), form, awsComputationalResource, + form.getProject(), getAuditInfo(form.getNotebookName())); return resourceAdded ? Response.ok().build() : Response.status(Response.Status.FOUND).build(); } @@ -127,13 +127,13 @@ public class ComputationalResourceAws implements ComputationalAPI { @Path("dataengine") public Response createDataEngine(@Auth UserInfo userInfo, @Valid @NotNull SparkStandaloneClusterCreateForm form) { - log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); + log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); - validate(form); - return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), Collections.singletonList(String.format(AUDIT_MESSAGE, form.getNotebookName()))) - ? Response.ok().build() - : Response.status(Response.Status.FOUND).build(); - } + validate(form); + return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), getAuditInfo(form.getNotebookName())) + ? Response.ok().build() + : Response.status(Response.Status.FOUND).build(); + } /** * Sends request to provisioning service for termination the computational resource for user. @@ -149,13 +149,12 @@ public class ComputationalResourceAws implements ComputationalAPI { @PathParam("projectName") String projectName, @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); + log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); - computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, - computationalName, Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName))); + computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, computationalName, getAuditInfo(exploratoryName)); - return Response.ok().build(); - } + return Response.ok().build(); + } /** * Sends request to provisioning service for stopping the computational resource for user. @@ -171,11 +170,10 @@ public class ComputationalResourceAws implements ComputationalAPI { @PathParam("project") String project, @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); - - computationalService.stopSparkCluster(userInfo, project, exploratoryName, computationalName); + log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); - return Response.ok().build(); + computationalService.stopSparkCluster(userInfo, userInfo.getName(), project, exploratoryName, computationalName, getAuditInfo(exploratoryName)); + return Response.ok().build(); } /** @@ -192,12 +190,11 @@ public class ComputationalResourceAws implements ComputationalAPI { @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName, @PathParam("project") String project) { - log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); - - computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project); + log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); - return Response.ok().build(); - } + computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } @PUT @Path("dataengine/{projectName}/{exploratoryName}/{computationalName}/config") @@ -206,7 +203,6 @@ public class ComputationalResourceAws implements ComputationalAPI { @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName, @Valid @NotNull List<ClusterConfig> config) { - computationalService.updateSparkClusterConfig(userInfo, projectName, exploratoryName, computationalName, config); return Response.ok().build(); } @@ -258,14 +254,18 @@ public class ComputationalResourceAws implements ComputationalAPI { if (formDTO.getSlaveInstanceSpot() && (slaveSpotInstanceBidPct < configuration.getMinEmrSpotInstanceBidPct() || slaveSpotInstanceBidPct > configuration.getMaxEmrSpotInstanceBidPct())) { log.debug("Creating computational resource {} for user {} fail: Spot instances bidding percentage " + - "value " + - "out of the boundaries. Minimum is {}, maximum is {}", - formDTO.getName(), userInfo.getName(), configuration.getMinEmrSpotInstanceBidPct(), - configuration.getMaxEmrSpotInstanceBidPct()); - throw new DlabException("Spot instances bidding percentage value out of the boundaries. Minimum is " + - configuration.getMinEmrSpotInstanceBidPct() + ", maximum is " + - configuration.getMaxEmrSpotInstanceBidPct() + "."); - } - } - } + "value " + + "out of the boundaries. Minimum is {}, maximum is {}", + formDTO.getName(), userInfo.getName(), configuration.getMinEmrSpotInstanceBidPct(), + configuration.getMaxEmrSpotInstanceBidPct()); + throw new DlabException("Spot instances bidding percentage value out of the boundaries. Minimum is " + + configuration.getMinEmrSpotInstanceBidPct() + ", maximum is " + + configuration.getMaxEmrSpotInstanceBidPct() + "."); + } + } + } + + private List<String> getAuditInfo(String exploratoryName) { + return Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName)); + } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/azure/ComputationalResourceAzure.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/azure/ComputationalResourceAzure.java index 922260b..e063d26 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/azure/ComputationalResourceAzure.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/azure/ComputationalResourceAzure.java @@ -81,16 +81,16 @@ public class ComputationalResourceAzure { @Path("dataengine") public Response createDataEngine(@Auth UserInfo userInfo, @Valid @NotNull SparkStandaloneClusterCreateForm form) { - log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); - if (!UserRoles.checkAccess(userInfo, RoleType.COMPUTATIONAL, form.getImage(), userInfo.getRoles())) { - log.warn("Unauthorized attempt to create a {} by user {}", form.getImage(), userInfo.getName()); - throw new DlabException("You do not have the privileges to create a " + form.getTemplateName()); - } - - return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), Collections.singletonList(String.format(AUDIT_MESSAGE, form.getNotebookName()))) - ? Response.ok().build() - : Response.status(Response.Status.FOUND).build(); - } + log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); + if (!UserRoles.checkAccess(userInfo, RoleType.COMPUTATIONAL, form.getImage(), userInfo.getRoles())) { + log.warn("Unauthorized attempt to create a {} by user {}", form.getImage(), userInfo.getName()); + throw new DlabException("You do not have the privileges to create a " + form.getTemplateName()); + } + + return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), getAuditInfo(form.getNotebookName())) + ? Response.ok().build() + : Response.status(Response.Status.FOUND).build(); + } /** * Sends request to provisioning service for termination the computational resource for user. @@ -107,13 +107,11 @@ public class ComputationalResourceAzure { @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); + log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); - computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, - computationalName, Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName))); - - return Response.ok().build(); - } + computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, computationalName, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } /** * Sends request to provisioning service for stopping the computational resource for user. @@ -129,12 +127,11 @@ public class ComputationalResourceAzure { @PathParam("project") String project, @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); - - computationalService.stopSparkCluster(userInfo, project, exploratoryName, computationalName); + log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); - return Response.ok().build(); - } + computationalService.stopSparkCluster(userInfo, userInfo.getName(), project, exploratoryName, computationalName, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } /** * Sends request to provisioning service for starting the computational resource for user. @@ -150,12 +147,11 @@ public class ComputationalResourceAzure { @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName, @PathParam("project") String project) { - log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); + log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); - computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project); - - return Response.ok().build(); - } + computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } @PUT @Path("dataengine/{projectName}/{exploratoryName}/{computationalName}/config") @@ -167,14 +163,18 @@ public class ComputationalResourceAzure { computationalService.updateSparkClusterConfig(userInfo, projectName, exploratoryName, computationalName, config); return Response.ok().build(); - } - - @GET - @Path("/{projectName}/{exploratoryName}/{computationalName}/config") - public Response getClusterConfig(@Auth UserInfo userInfo, - @PathParam("projectName") String projectName, - @PathParam("exploratoryName") String exploratoryName, - @PathParam("computationalName") String computationalName) { - return Response.ok(computationalService.getClusterConfig(userInfo, projectName, exploratoryName, computationalName)).build(); - } + } + + @GET + @Path("/{projectName}/{exploratoryName}/{computationalName}/config") + public Response getClusterConfig(@Auth UserInfo userInfo, + @PathParam("projectName") String projectName, + @PathParam("exploratoryName") String exploratoryName, + @PathParam("computationalName") String computationalName) { + return Response.ok(computationalService.getClusterConfig(userInfo, projectName, exploratoryName, computationalName)).build(); + } + + private List<String> getAuditInfo(String exploratoryName) { + return Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName)); + } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/ComputationalResourceGcp.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/ComputationalResourceGcp.java index 71eaf35..336629b 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/ComputationalResourceGcp.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/ComputationalResourceGcp.java @@ -100,17 +100,17 @@ public class ComputationalResourceGcp implements ComputationalAPI { GcpComputationalResource gcpComputationalResource = GcpComputationalResource.builder().computationalName (form.getName()) .imageName(form.getImage()) - .templateName(form.getTemplateName()) - .status(CREATING.toString()) - .masterShape(form.getMasterInstanceType()) - .slaveShape(form.getSlaveInstanceType()) - .slaveNumber(form.getSlaveInstanceCount()) - .masterNumber(form.getMasterInstanceCount()) - .preemptibleNumber(form.getPreemptibleCount()) - .version(form.getVersion()) - .build(); - boolean resourceAdded = computationalService.createDataEngineService(userInfo, form.getName(), form, gcpComputationalResource, - form.getProject(), Collections.singletonList(String.format(AUDIT_MESSAGE, form.getNotebookName()))); + .templateName(form.getTemplateName()) + .status(CREATING.toString()) + .masterShape(form.getMasterInstanceType()) + .slaveShape(form.getSlaveInstanceType()) + .slaveNumber(form.getSlaveInstanceCount()) + .masterNumber(form.getMasterInstanceCount()) + .preemptibleNumber(form.getPreemptibleCount()) + .version(form.getVersion()) + .build(); + boolean resourceAdded = computationalService.createDataEngineService(userInfo, form.getName(), form, gcpComputationalResource, + form.getProject(), getAuditInfo(form.getNotebookName())); return resourceAdded ? Response.ok().build() : Response.status(Response.Status.FOUND).build(); } @@ -129,17 +129,17 @@ public class ComputationalResourceGcp implements ComputationalAPI { @Path("dataengine") public Response createDataEngine(@Auth UserInfo userInfo, @Valid @NotNull SparkStandaloneClusterCreateForm form) { - log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); + log.debug("Create computational resources for {} | form is {}", userInfo.getName(), form); - if (!UserRoles.checkAccess(userInfo, RoleType.COMPUTATIONAL, form.getImage(), userInfo.getRoles())) { - log.warn("Unauthorized attempt to create a {} by user {}", form.getImage(), userInfo.getName()); - throw new DlabException("You do not have the privileges to create a " + form.getTemplateName()); - } + if (!UserRoles.checkAccess(userInfo, RoleType.COMPUTATIONAL, form.getImage(), userInfo.getRoles())) { + log.warn("Unauthorized attempt to create a {} by user {}", form.getImage(), userInfo.getName()); + throw new DlabException("You do not have the privileges to create a " + form.getTemplateName()); + } - return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), Collections.singletonList(String.format(AUDIT_MESSAGE, form.getNotebookName()))) - ? Response.ok().build() - : Response.status(Response.Status.FOUND).build(); - } + return computationalService.createSparkCluster(userInfo, form.getName(), form, form.getProject(), getAuditInfo(form.getNotebookName())) + ? Response.ok().build() + : Response.status(Response.Status.FOUND).build(); + } /** @@ -156,13 +156,11 @@ public class ComputationalResourceGcp implements ComputationalAPI { @PathParam("projectName") String projectName, @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); - - computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, - computationalName, Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName))); + log.debug("Terminating computational resource {} for user {}", computationalName, userInfo.getName()); - return Response.ok().build(); - } + computationalService.terminateComputational(userInfo, userInfo.getName(), projectName, exploratoryName, computationalName, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } /** * Sends request to provisioning service for stopping the computational resource for user. @@ -178,11 +176,10 @@ public class ComputationalResourceGcp implements ComputationalAPI { @PathParam("project") String project, @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName) { - log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); + log.debug("Stopping computational resource {} for user {}", computationalName, userInfo.getName()); - computationalService.stopSparkCluster(userInfo, project, exploratoryName, computationalName); - - return Response.ok().build(); + computationalService.stopSparkCluster(userInfo, userInfo.getName(), project, exploratoryName, computationalName, getAuditInfo(exploratoryName)); + return Response.ok().build(); } /** @@ -199,12 +196,11 @@ public class ComputationalResourceGcp implements ComputationalAPI { @PathParam("exploratoryName") String exploratoryName, @PathParam("computationalName") String computationalName, @PathParam("project") String project) { - log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); + log.debug("Starting computational resource {} for user {}", computationalName, userInfo.getName()); - computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project); - - return Response.ok().build(); - } + computationalService.startSparkCluster(userInfo, exploratoryName, computationalName, project, getAuditInfo(exploratoryName)); + return Response.ok().build(); + } @PUT @Path("dataengine/{projectName}/{exploratoryName}/{computationalName}/config") @@ -245,14 +241,18 @@ public class ComputationalResourceGcp implements ComputationalAPI { .getMinInstanceCount() + ", maximum is " + configuration.getMaxInstanceCount()); } - final int preemptibleInstanceCount = Integer.parseInt(formDTO.getPreemptibleCount()); - if (preemptibleInstanceCount < configuration.getMinDataprocPreemptibleCount()) { - log.debug("Creating computational resource {} for user {} fail: Limit exceeded to creation preemptible " + - "instances. Minimum is {}", - formDTO.getName(), userInfo.getName(), configuration.getMinDataprocPreemptibleCount()); - throw new DlabException("Limit exceeded to creation preemptible instances. " + - "Minimum is " + configuration.getMinDataprocPreemptibleCount()); + final int preemptibleInstanceCount = Integer.parseInt(formDTO.getPreemptibleCount()); + if (preemptibleInstanceCount < configuration.getMinDataprocPreemptibleCount()) { + log.debug("Creating computational resource {} for user {} fail: Limit exceeded to creation preemptible " + + "instances. Minimum is {}", + formDTO.getName(), userInfo.getName(), configuration.getMinDataprocPreemptibleCount()); + throw new DlabException("Limit exceeded to creation preemptible instances. " + + "Minimum is " + configuration.getMinDataprocPreemptibleCount()); - } - } + } + } + + private List<String> getAuditInfo(String exploratoryName) { + return Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName)); + } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ComputationalService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ComputationalService.java index 135657f..b9071b9 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ComputationalService.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ComputationalService.java @@ -50,25 +50,25 @@ public interface ComputationalService { * * @param userInfo user info of authenticated user * @param resourceCreator username of resource creator - * @param project project name - * @param exploratoryName name of exploratory where to terminate computational resources with <code>computationalName</code> - * @param computationalName computational name - * @param auditInfo additional info for audit - */ - void terminateComputational(UserInfo userInfo, String resourceCreator, String project, String exploratoryName, String computationalName, List<String> auditInfo); + * @param project project name + * @param exploratoryName name of exploratory where to terminate computational resources with <code>computationalName</code> + * @param computationalName computational name + * @param auditInfo additional info for audit + */ + void terminateComputational(UserInfo userInfo, String resourceCreator, String project, String exploratoryName, String computationalName, List<String> auditInfo); - boolean createDataEngineService(UserInfo userInfo, String resourceName, ComputationalCreateFormDTO formDTO, UserComputationalResource - computationalResource, String project, List<String> auditInfo); + boolean createDataEngineService(UserInfo userInfo, String resourceName, ComputationalCreateFormDTO formDTO, UserComputationalResource + computationalResource, String project, List<String> auditInfo); - void stopSparkCluster(UserInfo userInfo, String project, String exploratoryName, String computationalName); + void stopSparkCluster(UserInfo userInfo, String resourceCreator, String project, String exploratoryName, String computationalName, List<String> auditInfo); - void startSparkCluster(UserInfo userInfo, String exploratoryName, String computationalName, String project); + void startSparkCluster(UserInfo userInfo, String exploratoryName, String computationalName, String project, List<String> auditInfo); - void updateSparkClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName, - List<ClusterConfig> config); + void updateSparkClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName, + List<ClusterConfig> config); - Optional<UserComputationalResource> getComputationalResource(String user, String project, String exploratoryName, - String computationalName); + Optional<UserComputationalResource> getComputationalResource(String user, String project, String exploratoryName, + String computationalName); - List<ClusterConfig> getClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName); + List<ClusterConfig> getClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName); } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java index d13fd6a..0206a1e 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java @@ -71,7 +71,10 @@ import java.util.stream.Collectors; import static com.epam.dlab.backendapi.domain.AuditActionEnum.CREATE_DATA_ENGINE; import static com.epam.dlab.backendapi.domain.AuditActionEnum.CREATE_DATA_ENGINE_SERVICE; +import static com.epam.dlab.backendapi.domain.AuditActionEnum.START_COMPUTATIONAL; +import static com.epam.dlab.backendapi.domain.AuditActionEnum.STOP_COMPUTATIONAL; import static com.epam.dlab.backendapi.domain.AuditActionEnum.TERMINATE_COMPUTATIONAL; +import static com.epam.dlab.backendapi.domain.AuditActionEnum.UPDATE_DATA_ENGINE_CONFIG; import static com.epam.dlab.dto.UserInstanceStatus.CREATING; import static com.epam.dlab.dto.UserInstanceStatus.FAILED; import static com.epam.dlab.dto.UserInstanceStatus.RECONFIGURING; @@ -252,52 +255,49 @@ public class ComputationalServiceImpl implements ComputationalService { } } + @Audit(action = STOP_COMPUTATIONAL) @Override - public void stopSparkCluster(UserInfo userInfo, String project, String expName, String compName) { - final UserInstanceDTO userInstance = exploratoryDAO.fetchExploratoryFields(userInfo.getName(), project, expName, true); + public void stopSparkCluster(@User UserInfo userInfo, String resourceCreator, String project, String expName, @ResourceName String compName, @Info List<String> auditInfo) { + final UserInstanceDTO userInstance = exploratoryDAO.fetchExploratoryFields(resourceCreator, project, expName, true); final UserInstanceStatus requiredStatus = UserInstanceStatus.RUNNING; if (computationalWithStatusResourceExist(compName, userInstance, requiredStatus)) { log.debug("{} spark cluster {} for userInstance {}", STOPPING.toString(), compName, expName); - updateComputationalStatus(userInfo.getName(), project, expName, compName, STOPPING); + updateComputationalStatus(resourceCreator, project, expName, compName, STOPPING); EndpointDTO endpointDTO = endpointService.get(userInstance.getEndpoint()); - final String uuid = - provisioningService.post(endpointDTO.getUrl() + ComputationalAPI.COMPUTATIONAL_STOP_SPARK, - userInfo.getAccessToken(), - requestBuilder.newComputationalStop(userInfo, userInstance, compName, endpointDTO), - String.class); - requestId.put(userInfo.getName(), uuid); + final String uuid = provisioningService.post(endpointDTO.getUrl() + ComputationalAPI.COMPUTATIONAL_STOP_SPARK, + userInfo.getAccessToken(), + requestBuilder.newComputationalStop(resourceCreator, userInstance, compName, endpointDTO), + String.class); + requestId.put(resourceCreator, uuid); } else { - throw new IllegalStateException(String.format(DATAENGINE_NOT_PRESENT_FORMAT, - requiredStatus.toString(), compName, expName)); + throw new IllegalStateException(String.format(DATAENGINE_NOT_PRESENT_FORMAT, requiredStatus.toString(), compName, expName)); } } @BudgetLimited + @Audit(action = START_COMPUTATIONAL) @Override - public void startSparkCluster(UserInfo userInfo, String expName, String compName, @Project String project) { - final UserInstanceDTO userInstance = - exploratoryDAO.fetchExploratoryFields(userInfo.getName(), project, expName, true); + public void startSparkCluster(@User UserInfo userInfo, String expName, @ResourceName String compName, @Project String project, @Info List<String> auditInfo) { + final UserInstanceDTO userInstance = exploratoryDAO.fetchExploratoryFields(userInfo.getName(), project, expName, true); final UserInstanceStatus requiredStatus = UserInstanceStatus.STOPPED; if (computationalWithStatusResourceExist(compName, userInstance, requiredStatus)) { log.debug("{} spark cluster {} for userInstance {}", STARTING.toString(), compName, expName); updateComputationalStatus(userInfo.getName(), project, expName, compName, STARTING); EndpointDTO endpointDTO = endpointService.get(userInstance.getEndpoint()); - final String uuid = - provisioningService.post(endpointDTO.getUrl() + ComputationalAPI.COMPUTATIONAL_START_SPARK, - userInfo.getAccessToken(), - requestBuilder.newComputationalStart(userInfo, userInstance, compName, endpointDTO), - String.class); + final String uuid = provisioningService.post(endpointDTO.getUrl() + ComputationalAPI.COMPUTATIONAL_START_SPARK, + userInfo.getAccessToken(), + requestBuilder.newComputationalStart(userInfo, userInstance, compName, endpointDTO), + String.class); requestId.put(userInfo.getName(), uuid); } else { - throw new IllegalStateException(String.format(DATAENGINE_NOT_PRESENT_FORMAT, - requiredStatus.toString(), compName, expName)); + throw new IllegalStateException(String.format(DATAENGINE_NOT_PRESENT_FORMAT, requiredStatus.toString(), compName, expName)); } } + @Audit(action = UPDATE_DATA_ENGINE_CONFIG) @Override - public void updateSparkClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName, - List<ClusterConfig> config) { + public void updateSparkClusterConfig(@User UserInfo userInfo, String project, String exploratoryName, @ResourceName String computationalName, List<ClusterConfig> config) { final String userName = userInfo.getName(); final String token = userInfo.getAccessToken(); final UserInstanceDTO userInstanceDTO = exploratoryDAO @@ -336,8 +336,7 @@ public class ComputationalServiceImpl implements ComputationalService { * @return corresponding computational resource's data or empty data if resource doesn't exist. */ @Override - public Optional<UserComputationalResource> getComputationalResource(String user, String project, String exploratoryName, - String computationalName) { + public Optional<UserComputationalResource> getComputationalResource(String user, String project, String exploratoryName, String computationalName) { try { return Optional.of(computationalDAO.fetchComputationalFields(user, project, exploratoryName, computationalName)); } catch (DlabException e) { @@ -361,8 +360,7 @@ public class ComputationalServiceImpl implements ComputationalService { * @param computationalName name of computational resource. * @param status status */ - private void updateComputationalStatus(String user, String project, String exploratoryName, String computationalName, - UserInstanceStatus status) { + private void updateComputationalStatus(String user, String project, String exploratoryName, String computationalName, UserInstanceStatus status) { ComputationalStatusDTO computationalStatus = new ComputationalStatusDTO() .withUser(user) .withProject(project) @@ -374,7 +372,6 @@ public class ComputationalServiceImpl implements ComputationalService { } private SparkStandaloneClusterResource createInitialComputationalResource(SparkStandaloneClusterCreateForm form) { - return SparkStandaloneClusterResource.builder() .computationalName(form.getName()) .imageName(form.getImage()) @@ -386,15 +383,13 @@ public class ComputationalServiceImpl implements ComputationalService { .build(); } - private boolean computationalWithStatusResourceExist(String compName, - UserInstanceDTO ui, UserInstanceStatus status) { + private boolean computationalWithStatusResourceExist(String compName, UserInstanceDTO ui, UserInstanceStatus status) { return ui.getResources() .stream() .anyMatch(c -> computationalWithNameAndStatus(compName, c, status)); } - private boolean computationalWithNameAndStatus(String computationalName, UserComputationalResource compResource, - UserInstanceStatus status) { + private boolean computationalWithNameAndStatus(String computationalName, UserComputationalResource compResource, UserInstanceStatus status) { return compResource.getStatus().equals(status.toString()) && compResource.getDataEngineType() == SPARK_STANDALONE && compResource.getComputationalName().equals(computationalName); diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImpl.java index a396859..70c18e7 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImpl.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImpl.java @@ -147,12 +147,11 @@ public class EnvironmentServiceImpl implements EnvironmentService { } @ProjectAdmin - @Override - public void stopComputational(@User UserInfo userInfo, String user, @Project String project, String exploratoryName, - String computationalName) { - computationalService.stopSparkCluster(new UserInfo(user, userInfo.getAccessToken()), project, exploratoryName, - computationalName); - } + @Override + public void stopComputational(@User UserInfo userInfo, String user, @Project String project, String exploratoryName, String computationalName) { + computationalService.stopSparkCluster(userInfo, user, project, exploratoryName, computationalName, + Collections.singletonList(String.format(AUDIT_MESSAGE, exploratoryName))); + } @ProjectAdmin @Override 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 37deea6..6033576 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 @@ -214,13 +214,13 @@ public class SchedulerJobServiceImpl implements SchedulerJobService { } private void stopComputational(SchedulerJobData job) { - final String project = job.getProject(); - 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), project, expName, compName); - } + final String project = job.getProject(); + 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, Collections.singletonList(AUDIT_MESSAGE)); + } private void terminateComputational(SchedulerJobData job) { final String user = job.getUser(); @@ -281,9 +281,9 @@ public class SchedulerJobServiceImpl implements SchedulerJobService { } 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); - } + log.debug("Starting exploratory {} computational {} for user {} by scheduler", expName, compName, user); + computationalService.startSparkCluster(securityService.getServiceAccountInfo(user), expName, compName, project, Collections.singletonList(AUDIT_MESSAGE)); + } private boolean shouldClusterBeStarted(DataEngineType sparkCluster, UserComputationalResource compResource) { return Objects.nonNull(compResource.getSchedulerData()) && compResource.getSchedulerData().isSyncStartRequired() diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/RequestBuilder.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/RequestBuilder.java index a72db8d..228f868 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/RequestBuilder.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/RequestBuilder.java @@ -484,16 +484,16 @@ public class RequestBuilder { } @SuppressWarnings("unchecked") - public <T extends ComputationalBase<T>> T newComputationalStop(UserInfo userInfo, UserInstanceDTO exploratory, - String computationalName, EndpointDTO endpointDTO) { - return (T) newResourceSysBaseDTO(userInfo.getName(), endpointDTO.getCloudProvider(), ComputationalStopDTO.class) - .withExploratoryName(exploratory.getExploratoryName()) - .withComputationalName(computationalName) - .withNotebookInstanceName(exploratory.getExploratoryId()) - .withApplicationName(getApplicationNameFromImage(exploratory.getImageName())) - .withProject(exploratory.getProject()) - .withEndpoint(endpointDTO.getName()); - } + public <T extends ComputationalBase<T>> T newComputationalStop(String resourceCreator, UserInstanceDTO exploratory, + String computationalName, EndpointDTO endpointDTO) { + return (T) newResourceSysBaseDTO(resourceCreator, endpointDTO.getCloudProvider(), ComputationalStopDTO.class) + .withExploratoryName(exploratory.getExploratoryName()) + .withComputationalName(computationalName) + .withNotebookInstanceName(exploratory.getExploratoryId()) + .withApplicationName(getApplicationNameFromImage(exploratory.getImageName())) + .withProject(exploratory.getProject()) + .withEndpoint(endpointDTO.getName()); + } @SuppressWarnings("unchecked") public <T extends ComputationalBase<T>> T newComputationalStart(UserInfo userInfo, UserInstanceDTO exploratory, diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImplTest.java index 1238e51..fb44f30 100644 --- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImplTest.java +++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImplTest.java @@ -505,17 +505,17 @@ public class ComputationalServiceImplTest { .thenReturn(mock(UpdateResult.class)); ComputationalStopDTO computationalStopDTO = new ComputationalStopDTO(); - when(requestBuilder.newComputationalStop(any(UserInfo.class), any(UserInstanceDTO.class), anyString(), + when(requestBuilder.newComputationalStop(anyString(), any(UserInstanceDTO.class), anyString(), any(EndpointDTO.class))).thenReturn(computationalStopDTO); when(provisioningService.post(anyString(), anyString(), any(ComputationalBase.class), any())) .thenReturn("someUuid"); when(requestId.put(anyString(), anyString())).thenReturn("someUuid"); - computationalService.stopSparkCluster(userInfo, PROJECT, EXPLORATORY_NAME, COMP_NAME); + computationalService.stopSparkCluster(userInfo, userInfo.getName(), PROJECT, EXPLORATORY_NAME, COMP_NAME, Collections.singletonList(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME))); verify(computationalDAO).updateComputationalStatus(refEq(computationalStatusDTOWithStatusStopping, "self")); verify(exploratoryDAO).fetchExploratoryFields(USER, PROJECT, EXPLORATORY_NAME, true); - verify(requestBuilder).newComputationalStop(refEq(userInfo), refEq(exploratory), eq(COMP_NAME), refEq(endpointDTO())); + verify(requestBuilder).newComputationalStop(eq(userInfo.getName()), refEq(exploratory), eq(COMP_NAME), refEq(endpointDTO())); verify(provisioningService) .post(eq(endpointDTO().getUrl() + "computational/stop/spark"), eq(TOKEN), refEq(computationalStopDTO), eq(String.class)); @@ -532,7 +532,7 @@ public class ComputationalServiceImplTest { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("There is no running dataengine compName for exploratory expName"); - computationalService.stopSparkCluster(userInfo, PROJECT, EXPLORATORY_NAME, COMP_NAME); + computationalService.stopSparkCluster(userInfo, userInfo.getName(), PROJECT, EXPLORATORY_NAME, COMP_NAME, Collections.singletonList(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME))); } @Test @@ -551,7 +551,7 @@ public class ComputationalServiceImplTest { .thenReturn("someUuid"); when(requestId.put(anyString(), anyString())).thenReturn("someUuid"); - computationalService.startSparkCluster(userInfo, EXPLORATORY_NAME, COMP_NAME, PROJECT); + computationalService.startSparkCluster(userInfo, EXPLORATORY_NAME, COMP_NAME, PROJECT, Collections.singletonList(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME))); verify(computationalDAO).updateComputationalStatus(refEq(computationalStatusDTOWithStatusStarting, "self")); verify(exploratoryDAO).fetchExploratoryFields(USER, PROJECT, EXPLORATORY_NAME, true); @@ -575,7 +575,7 @@ public class ComputationalServiceImplTest { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("There is no stopped dataengine compName for exploratory expName"); - computationalService.startSparkCluster(userInfo, EXPLORATORY_NAME, COMP_NAME, PROJECT); + computationalService.startSparkCluster(userInfo, EXPLORATORY_NAME, COMP_NAME, PROJECT, Collections.singletonList(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME))); } @Test diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImplTest.java index ce80c08..c32bcf5 100644 --- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImplTest.java +++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/EnvironmentServiceImplTest.java @@ -164,14 +164,15 @@ public class EnvironmentServiceImplTest { @Test public void stopComputational() { - final UserInfo userInfo = getUserInfo(); - doNothing().when(computationalService).stopSparkCluster(any(UserInfo.class), anyString(), anyString(), anyString()); + final UserInfo userInfo = getUserInfo(); + doNothing().when(computationalService).stopSparkCluster(any(UserInfo.class), anyString(), anyString(), anyString(), anyString(), anyList()); - environmentService.stopComputational(userInfo, USER, PROJECT_NAME, EXPLORATORY_NAME_1, "compName"); + environmentService.stopComputational(userInfo, USER, PROJECT_NAME, EXPLORATORY_NAME_1, "compName"); - verify(computationalService).stopSparkCluster(refEq(userInfo), eq(PROJECT_NAME), eq(EXPLORATORY_NAME_1), eq("compName")); - verifyNoMoreInteractions(securityService, computationalService); - } + verify(computationalService).stopSparkCluster(refEq(userInfo), eq(userInfo.getName()), eq(PROJECT_NAME), eq(EXPLORATORY_NAME_1), eq("compName"), + eq(Collections.singletonList(String.format(AUDIT_MESSAGE, EXPLORATORY_NAME_1)))); + verifyNoMoreInteractions(securityService, computationalService); + } @Test public void terminateExploratory() { 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 5b9b738..c8e9035 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 @@ -418,10 +418,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)); - verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService); + .getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, STOPPED); + verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME), + eq(COMPUTATIONAL_NAME), eq(PROJECT), eq(Collections.singletonList(AUDIT_MESSAGE))); + verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService); } @Test @@ -506,23 +506,24 @@ public class SchedulerJobServiceImplTest { @Test public void testStopComputationalByScheduler() { - when(schedulerJobDAO.getComputationalSchedulerDataWithOneOfStatus(any(UserInstanceStatus.class), - any(DataEngineType.class), anyVararg())).thenReturn(singletonList(getSchedulerJobData(LocalDate.now(), - LocalDate.now().plusDays(1), Arrays.asList(DayOfWeek.values()), Arrays.asList(DayOfWeek.values()), - LocalDateTime.of(LocalDate.now(), - LocalTime.now().truncatedTo(ChronoUnit.MINUTES)), false, USER, - LocalTime.now().truncatedTo(ChronoUnit.MINUTES)))); - when(securityService.getServiceAccountInfo(anyString())).thenReturn(getUserInfo()); + UserInfo userInfo = getUserInfo(); + when(schedulerJobDAO.getComputationalSchedulerDataWithOneOfStatus(any(UserInstanceStatus.class), + any(DataEngineType.class), anyVararg())).thenReturn(singletonList(getSchedulerJobData(LocalDate.now(), + LocalDate.now().plusDays(1), Arrays.asList(DayOfWeek.values()), Arrays.asList(DayOfWeek.values()), + LocalDateTime.of(LocalDate.now(), + LocalTime.now().truncatedTo(ChronoUnit.MINUTES)), false, USER, + LocalTime.now().truncatedTo(ChronoUnit.MINUTES)))); + when(securityService.getServiceAccountInfo(anyString())).thenReturn(userInfo); - schedulerJobService.stopComputationalByScheduler(); + schedulerJobService.stopComputationalByScheduler(); - verify(securityService).getServiceAccountInfo(USER); - verify(schedulerJobDAO) - .getComputationalSchedulerDataWithOneOfStatus(RUNNING, DataEngineType.SPARK_STANDALONE, RUNNING); - verify(computationalService).stopSparkCluster(refEq(getUserInfo()), eq(PROJECT), eq(EXPLORATORY_NAME), - eq(COMPUTATIONAL_NAME)); - verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService); - } + 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(Collections.singletonList(AUDIT_MESSAGE))); + verifyNoMoreInteractions(securityService, schedulerJobDAO, computationalService); + } @Test public void testStopComputationalBySchedulerWhenSchedulerIsNotConfigured() { @@ -731,21 +732,21 @@ public class SchedulerJobServiceImplTest { LocalTime.now().truncatedTo(ChronoUnit.MINUTES) ))); when(securityService.getServiceAccountInfo(anyString())).thenReturn(getUserInfo()); - when(computationalDAO.findComputationalResourcesWithStatus(anyString(), anyString(), - anyString(), any(UserInstanceStatus.class))).thenReturn(singletonList(getComputationalResource( - DataEngineType.SPARK_STANDALONE, true))); - - schedulerJobService.startExploratoryByScheduler(); - - verify(securityService, times(2)).getServiceAccountInfo(USER); - verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED); - verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(Collections.singletonList(AUDIT_MESSAGE))); - verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED); - verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME), - eq(COMPUTATIONAL_NAME), eq(PROJECT)); - verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalService, - computationalDAO); - } + when(computationalDAO.findComputationalResourcesWithStatus(anyString(), anyString(), + anyString(), any(UserInstanceStatus.class))).thenReturn(singletonList(getComputationalResource( + DataEngineType.SPARK_STANDALONE, true))); + + schedulerJobService.startExploratoryByScheduler(); + + verify(securityService, times(2)).getServiceAccountInfo(USER); + verify(schedulerJobDAO).getExploratorySchedulerDataWithStatus(STOPPED); + verify(exploratoryService).start(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(PROJECT), eq(Collections.singletonList(AUDIT_MESSAGE))); + verify(computationalDAO).findComputationalResourcesWithStatus(USER, PROJECT, EXPLORATORY_NAME, STOPPED); + verify(computationalService).startSparkCluster(refEq(getUserInfo()), eq(EXPLORATORY_NAME), eq(COMPUTATIONAL_NAME), + eq(PROJECT), eq(Collections.singletonList(AUDIT_MESSAGE))); + verifyNoMoreInteractions(securityService, schedulerJobDAO, exploratoryService, computationalService, + computationalDAO); + } @Test public void testStartExploratoryBySchedulerWithSyncComputationalStartDataEngine() { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org