[DATALAB-1895] Sync up DataLab instance statuses with cloud statuses
diff --git a/services/datalab-model/src/main/java/com/epam/datalab/dto/UserEnvironmentResources.java b/services/datalab-model/src/main/java/com/epam/datalab/dto/UserEnvironmentResources.java
index 6fc6319..3c74d45 100644
--- a/services/datalab-model/src/main/java/com/epam/datalab/dto/UserEnvironmentResources.java
+++ b/services/datalab-model/src/main/java/com/epam/datalab/dto/UserEnvironmentResources.java
@@ -22,7 +22,9 @@
import com.epam.datalab.dto.status.EnvResourceList;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects.ToStringHelper;
+import lombok.EqualsAndHashCode;
+@EqualsAndHashCode
public class UserEnvironmentResources extends ResourceSysBaseDTO<UserEnvironmentResources> {
@JsonProperty("edge_list_resources")
private EnvResourceList resourceList;
diff --git a/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResource.java b/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResource.java
index f18ebe9..10b90ac 100644
--- a/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResource.java
+++ b/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResource.java
@@ -25,6 +25,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
+import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@@ -33,6 +34,7 @@
* Describe the resource (host, cluster, storage) for check status in Cloud.
*/
@NoArgsConstructor
+@EqualsAndHashCode
public class EnvResource {
@JsonProperty
private String id;
@@ -141,15 +143,39 @@
return this;
}
+ public String getProject() {
+ return project;
+ }
+
+ public void setProject(String project) {
+ this.project = project;
+ }
+
+ public EnvResource withProject(String project) {
+ setProject(project);
+ return this;
+ }
+
public String getEndpoint() {
return endpoint;
}
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public EnvResource withEndpoint(String endpoint) {
+ setEndpoint(endpoint);
+ return this;
+ }
+
public ToStringHelper toStringHelper(Object self) {
return MoreObjects.toStringHelper(self)
.add("id", id)
.add("status", status)
.add("name", name)
+ .add("project", project)
+ .add("endpoint", endpoint)
.add("resourceType", resourceType)
.add("lastActivity", lastActivity);
}
diff --git a/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResourceList.java b/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResourceList.java
index 0a3d292..018e736 100644
--- a/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResourceList.java
+++ b/services/datalab-model/src/main/java/com/epam/datalab/dto/status/EnvResourceList.java
@@ -22,12 +22,14 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
+import lombok.EqualsAndHashCode;
import java.util.List;
/**
* Describe the lists of resources (host, cluster, storage) for check status in Cloud.
*/
+@EqualsAndHashCode
public class EnvResourceList {
@JsonProperty("host")
private List<EnvResource> hostList;
diff --git a/services/provisioning-service/pom.xml b/services/provisioning-service/pom.xml
index 055bbe7..eda6624 100644
--- a/services/provisioning-service/pom.xml
+++ b/services/provisioning-service/pom.xml
@@ -127,6 +127,11 @@
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
diff --git a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/response/handlers/ResourcesStatusCallbackHandler.java b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/response/handlers/ResourcesStatusCallbackHandler.java
index 9ca477b..347d650 100644
--- a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/response/handlers/ResourcesStatusCallbackHandler.java
+++ b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/response/handlers/ResourcesStatusCallbackHandler.java
@@ -21,6 +21,7 @@
package com.epam.datalab.backendapi.core.response.handlers;
import com.epam.datalab.backendapi.core.commands.DockerAction;
+import com.epam.datalab.dto.status.EnvResource;
import com.epam.datalab.dto.status.EnvResourceList;
import com.epam.datalab.dto.status.EnvStatusDTO;
import com.epam.datalab.exceptions.DatalabException;
@@ -30,10 +31,15 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
import java.io.IOException;
import java.time.Instant;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import static com.epam.datalab.rest.contracts.ApiCallbacks.INFRASTRUCTURE;
import static com.epam.datalab.rest.contracts.ApiCallbacks.STATUS_URI;
@@ -41,14 +47,13 @@
@Slf4j
public class ResourcesStatusCallbackHandler extends ResourceCallbackHandler<EnvStatusDTO> {
- private EnvResourceList datalabResourceList;
+ private Map<String, EnvResource> datalabHostResources;
@JsonCreator
- public ResourcesStatusCallbackHandler(
- @JacksonInject RESTService selfService, @JsonProperty("action") DockerAction action, @JsonProperty("uuid") String uuid,
- @JsonProperty("user") String user, EnvResourceList resourceList) {
+ public ResourcesStatusCallbackHandler(@JacksonInject RESTService selfService, @JsonProperty("action") DockerAction action,
+ @JsonProperty("uuid") String uuid, @JsonProperty("user") String user, EnvResourceList resourceList) {
super(selfService, user, uuid, action);
- this.datalabResourceList = resourceList;
+ this.datalabHostResources = getEnvResources(resourceList.getHostList());
}
@Override
@@ -64,8 +69,15 @@
throw new DatalabException("Docker response for UUID " + getUUID() + " not valid: " + e.getLocalizedMessage(), e);
}
+ EnvResourceList envResourceList = new EnvResourceList();
+ if (CollectionUtils.isNotEmpty(cloudResourceList.getHostList())) {
+ envResourceList.withHostList(getChangedEnvResources(cloudResourceList.getHostList()));
+ } else {
+ envResourceList.withHostList(Collections.emptyList());
+ }
+
baseStatus
- .withResourceList(cloudResourceList)
+ .withResourceList(envResourceList)
.withUptime(Date.from(Instant.now()));
log.trace("Inner status {}", baseStatus);
@@ -93,4 +105,19 @@
public void handleError(String errorMessage) {
// Nothing action for status response
}
+
+ private List<EnvResource> getChangedEnvResources(List<EnvResource> envResources) {
+ return envResources
+ .stream()
+ .filter(e -> !e.getStatus().equals(datalabHostResources.get(e.getId()).getStatus()))
+ .map(e -> datalabHostResources.get(e.getId())
+ .withStatus(e.getStatus()))
+ .collect(Collectors.toList());
+ }
+
+ private Map<String, EnvResource> getEnvResources(List<EnvResource> envResources) {
+ return envResources
+ .stream()
+ .collect(Collectors.toMap(EnvResource::getId, e -> e));
+ }
}
diff --git a/services/provisioning-service/src/main/resources/mock_response/aws/notebook_status.json b/services/provisioning-service/src/main/resources/mock_response/aws/notebook_status.json
index 7ecad18..4ede40b 100644
--- a/services/provisioning-service/src/main/resources/mock_response/aws/notebook_status.json
+++ b/services/provisioning-service/src/main/resources/mock_response/aws/notebook_status.json
@@ -1,10 +1,9 @@
{
"status": "ok",
"response": {
- "result": ${
- LIST_RESOURCES
-},
-"log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
-},
+ "result": {
+ },
+ "log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
+ },
"request_id": "${REQUEST_ID}"
}
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/resources/mock_response/azure/notebook_status.json b/services/provisioning-service/src/main/resources/mock_response/azure/notebook_status.json
index 7ecad18..5b9d881 100644
--- a/services/provisioning-service/src/main/resources/mock_response/azure/notebook_status.json
+++ b/services/provisioning-service/src/main/resources/mock_response/azure/notebook_status.json
@@ -1,10 +1,9 @@
{
"status": "ok",
"response": {
- "result": ${
- LIST_RESOURCES
-},
-"log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
-},
-"request_id": "${REQUEST_ID}"
+ "result": {
+ },
+ "log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
+ },
+ "request_id": "${REQUEST_ID}"
}
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/resources/mock_response/gcp/notebook_status.json b/services/provisioning-service/src/main/resources/mock_response/gcp/notebook_status.json
index 7ecad18..dc74f4f 100644
--- a/services/provisioning-service/src/main/resources/mock_response/gcp/notebook_status.json
+++ b/services/provisioning-service/src/main/resources/mock_response/gcp/notebook_status.json
@@ -1,10 +1,8 @@
{
"status": "ok",
"response": {
- "result": ${
- LIST_RESOURCES
-},
-"log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
-},
-"request_id": "${REQUEST_ID}"
+ "result": {},
+ "log": "/var/log/datalab/status/status_${EDGE_USER_NAME}_${REQUEST_ID}.log"
+ },
+ "request_id": "${REQUEST_ID}"
}
\ No newline at end of file
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ComputationalDAO.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ComputationalDAO.java
index 50c7a02..ef0203c 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ComputationalDAO.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ComputationalDAO.java
@@ -76,6 +76,7 @@
static final String COMPUTATIONAL_NAME = "computational_name";
static final String COMPUTATIONAL_ID = "computational_id";
static final String PROJECT = "project";
+ static final String ENDPOINT = "endpoint";
static final String IMAGE = "image";
private static final String COMPUTATIONAL_URL = "computational_url";
@@ -400,4 +401,11 @@
set(computationalFieldFilter(COMPUTATIONAL_LAST_ACTIVITY),
Date.from(lastActivity.atZone(ZoneId.systemDefault()).toInstant())));
}
+
+ public void updateComputeStatus(String project, String endpoint, String computeName, String instanceId, UserInstanceStatus status) {
+ updateOne(USER_INSTANCES,
+ and(eq(PROJECT, project), eq(ENDPOINT, endpoint), eq(COMPUTATIONAL_RESOURCES + "." + INSTANCE_ID, instanceId),
+ eq(COMPUTATIONAL_RESOURCES + "." + COMPUTATIONAL_NAME, computeName)),
+ set(computationalFieldFilter(STATUS), status.toString()));
+ }
}
\ No newline at end of file
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ExploratoryDAO.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ExploratoryDAO.java
index 0657107..b925d81 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ExploratoryDAO.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ExploratoryDAO.java
@@ -364,6 +364,12 @@
set(STATUS, newStatus.toString()));
}
+ public UpdateResult updateExploratoryStatus(String project, String endpoint, String name, String instanceId, UserInstanceStatus status) {
+ return updateOne(USER_INSTANCES,
+ and(eq(ENDPOINT, endpoint), eq(PROJECT, project), eq(EXPLORATORY_NAME, name), eq(INSTANCE_ID, instanceId)),
+ set(STATUS, status.toString()));
+ }
+
/**
* Updates the scheduler's data for exploratory in Mongo database.
*
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/EnvironmentStatusCallback.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/EnvironmentStatusCallback.java
index 7775164..c8caa0c 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/EnvironmentStatusCallback.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/EnvironmentStatusCallback.java
@@ -21,7 +21,10 @@
import com.epam.datalab.backendapi.dao.EnvDAO;
import com.epam.datalab.backendapi.domain.RequestId;
+import com.epam.datalab.backendapi.service.EnvironmentService;
+import com.epam.datalab.dto.UserInstanceStatus;
import com.epam.datalab.dto.status.EnvStatusDTO;
+import com.epam.datalab.exceptions.DatalabException;
import com.epam.datalab.rest.contracts.ApiCallbacks;
import com.google.inject.Inject;
import lombok.extern.slf4j.Slf4j;
@@ -39,10 +42,16 @@
@Slf4j
public class EnvironmentStatusCallback {
+ private final EnvDAO envDAO;
+ private final RequestId requestId;
+ private final EnvironmentService environmentService;
+
@Inject
- private EnvDAO envDAO;
- @Inject
- private RequestId requestId;
+ public EnvironmentStatusCallback(EnvDAO envDAO, RequestId requestId, EnvironmentService environmentService) {
+ this.envDAO = envDAO;
+ this.requestId = requestId;
+ this.environmentService = environmentService;
+ }
/**
* Updates the status of the resources for user.
@@ -53,18 +62,17 @@
@POST
@Path(ApiCallbacks.STATUS_URI)
public Response status(EnvStatusDTO dto) {
- log.info("EnvStatusDTO__ {} ", dto);
-// log.trace("Updating the status of resources for user {}: {}", dto.getUser(), dto);
-// requestId.checkAndRemove(dto.getRequestId());
-// try {
-// if (UserInstanceStatus.FAILED == UserInstanceStatus.of(dto.getStatus())) {
-// log.warn("Request for the status of resources for user {} fails: {}", dto.getUser(), dto.getErrorMessage());
-// } else {
-// envDAO.updateEnvStatus(dto.getUser(), null, dto.getResourceList());
-// }
-// } catch (DatalabException e) {
-// log.warn("Could not update status of resources for user {}: {}", dto.getUser(), e.getLocalizedMessage(), e);
-// }
+ requestId.checkAndRemove(dto.getRequestId());
+ log.info("Updating statuses of following resources {} ", dto.getResourceList());
+ try {
+ if (UserInstanceStatus.FAILED == UserInstanceStatus.of(dto.getStatus())) {
+ log.warn("Request for the status of resources for user {} fails: {}", dto.getUser(), dto.getErrorMessage());
+ } else {
+ environmentService.updateEnvironmentStatuses(dto.getResourceList());
+ }
+ } catch (DatalabException e) {
+ log.warn("Could not update status of resources for user {}: {}", dto.getUser(), e.getLocalizedMessage(), e);
+ }
return Response.ok().build();
}
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/schedulers/CheckInfrastructureStatusScheduler.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/schedulers/CheckInfrastructureStatusScheduler.java
index 55caf85..de56486 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/schedulers/CheckInfrastructureStatusScheduler.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/schedulers/CheckInfrastructureStatusScheduler.java
@@ -23,6 +23,7 @@
import com.epam.datalab.backendapi.dao.ExploratoryDAO;
import com.epam.datalab.backendapi.domain.EndpointDTO;
import com.epam.datalab.backendapi.domain.ProjectDTO;
+import com.epam.datalab.backendapi.domain.ProjectEndpointDTO;
import com.epam.datalab.backendapi.schedulers.internal.Scheduled;
import com.epam.datalab.backendapi.service.EndpointService;
import com.epam.datalab.backendapi.service.InfrastructureInfoService;
@@ -50,6 +51,7 @@
public class CheckInfrastructureStatusScheduler implements Job {
private static final List<UserInstanceStatus> statusesToCheck = Arrays.asList(UserInstanceStatus.RUNNING, UserInstanceStatus.STOPPED);
+
private final InfrastructureInfoService infrastructureInfoService;
private final SecurityService securityService;
private final EndpointService endpointService;
@@ -98,6 +100,8 @@
.map(r -> new EnvResource()
.withId(r.getInstanceId())
.withName(r.getComputationalName())
+ .withProject(userInstanceDTO.getProject())
+ .withEndpoint(userInstanceDTO.getEndpoint())
.withStatus(r.getStatus())
.withResourceType(ResourceType.COMPUTATIONAL))
.collect(Collectors.toList());
@@ -105,6 +109,8 @@
instances.add(new EnvResource()
.withId(userInstanceDTO.getInstanceId())
.withName(userInstanceDTO.getExploratoryName())
+ .withProject(userInstanceDTO.getProject())
+ .withEndpoint(userInstanceDTO.getEndpoint())
.withStatus(userInstanceDTO.getStatus())
.withResourceType(ResourceType.EXPLORATORY));
@@ -114,14 +120,25 @@
private List<EnvResource> getEdgeInstances(String endpoint) {
return projectService.getProjectsByEndpoint(endpoint)
.stream()
- .map(ProjectDTO::getEndpoints)
+ .collect(Collectors.toMap(ProjectDTO::getName, ProjectDTO::getEndpoints))
+ .entrySet()
+ .stream()
+ .map(entry -> getEdgeInstances(endpoint, entry))
.flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ private List<EnvResource> getEdgeInstances(String endpoint, Map.Entry<String, List<ProjectEndpointDTO>> entry) {
+ return entry.getValue()
+ .stream()
.filter(e -> statusesToCheck.contains(e.getStatus()))
.filter(e -> e.getName().equals(endpoint))
.filter(e -> Objects.nonNull(e.getEdgeInfo()))
.map(e -> new EnvResource()
.withId(e.getEdgeInfo().getInstanceId())
.withName(e.getName())
+ .withProject(entry.getKey())
+ .withEndpoint(endpoint)
.withStatus(e.getStatus().toString())
.withResourceType(ResourceType.EDGE)
)
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ComputationalService.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ComputationalService.java
index a930d9f..63e6544 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ComputationalService.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ComputationalService.java
@@ -23,6 +23,7 @@
import com.epam.datalab.backendapi.resources.dto.ComputationalCreateFormDTO;
import com.epam.datalab.backendapi.resources.dto.ComputationalTemplatesDTO;
import com.epam.datalab.backendapi.resources.dto.SparkStandaloneClusterCreateForm;
+import com.epam.datalab.dto.UserInstanceStatus;
import com.epam.datalab.dto.aws.computational.ClusterConfig;
import com.epam.datalab.dto.computational.UserComputationalResource;
@@ -71,4 +72,6 @@
String computationalName);
List<ClusterConfig> getClusterConfig(UserInfo userInfo, String project, String exploratoryName, String computationalName);
+
+ void updateAfterStatusCheck(UserInfo systemUser, String project, String endpoint, String name, String instanceID, UserInstanceStatus status, String auditInfo);
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/EnvironmentService.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/EnvironmentService.java
index 549a405..ad9fa3c 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/EnvironmentService.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/EnvironmentService.java
@@ -22,6 +22,7 @@
import com.epam.datalab.auth.UserInfo;
import com.epam.datalab.backendapi.resources.dto.UserDTO;
import com.epam.datalab.backendapi.resources.dto.UserResourceInfo;
+import com.epam.datalab.dto.status.EnvResourceList;
import java.util.List;
@@ -43,4 +44,6 @@
void terminateExploratory(UserInfo userInfo, String user, String project, String exploratoryName);
void terminateComputational(UserInfo userInfo, String user, String project, String exploratoryName, String computationalName);
+
+ void updateEnvironmentStatuses(EnvResourceList resourceList);
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ExploratoryService.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ExploratoryService.java
index f16bcfc..3711c52 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ExploratoryService.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ExploratoryService.java
@@ -59,4 +59,6 @@
List<ClusterConfig> getClusterConfig(UserInfo user, String project, String exploratoryName);
ExploratoryCreatePopUp getUserInstances(UserInfo user);
+
+ void updateAfterStatusCheck(UserInfo userInfo, String project, String endpoint, String name, String instanceID, UserInstanceStatus status, String auditInfo);
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ProjectService.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ProjectService.java
index 01b9028..4ecd014 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ProjectService.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ProjectService.java
@@ -23,6 +23,7 @@
import com.epam.datalab.backendapi.domain.ProjectDTO;
import com.epam.datalab.backendapi.domain.UpdateProjectBudgetDTO;
import com.epam.datalab.backendapi.domain.UpdateProjectDTO;
+import com.epam.datalab.dto.UserInstanceStatus;
import java.util.List;
@@ -51,13 +52,15 @@
void stop(UserInfo userInfo, String endpoint, String name, String auditInfo);
- void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
+ void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
- void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
+ void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
- void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
+ void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
- boolean isAnyProjectAssigned(UserInfo userInfo);
+ boolean isAnyProjectAssigned(UserInfo userInfo);
- boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
+ boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
+
+ void updateAfterStatusCheck(UserInfo userInfo, String project, String endpoint, String instanceID, UserInstanceStatus status, String auditInfo);
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ComputationalServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ComputationalServiceImpl.java
index 9e0e129..245f4c4 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ComputationalServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ComputationalServiceImpl.java
@@ -74,6 +74,7 @@
import static com.epam.datalab.backendapi.domain.AuditActionEnum.START;
import static com.epam.datalab.backendapi.domain.AuditActionEnum.STOP;
import static com.epam.datalab.backendapi.domain.AuditActionEnum.TERMINATE;
+import static com.epam.datalab.backendapi.domain.AuditActionEnum.UPDATE;
import static com.epam.datalab.backendapi.domain.AuditResourceTypeEnum.COMPUTE;
import static com.epam.datalab.dto.UserInstanceStatus.CREATING;
import static com.epam.datalab.dto.UserInstanceStatus.FAILED;
@@ -272,7 +273,6 @@
} else {
throw new IllegalStateException(String.format(DATAENGINE_NOT_PRESENT_FORMAT, requiredStatus.toString(), compName, expName));
}
-
}
@BudgetLimited
@@ -323,7 +323,6 @@
.withStatus(RECONFIGURING.toString())
.withUser(userName));
requestId.put(userName, uuid);
-
}
/**
@@ -350,6 +349,13 @@
return computationalDAO.getClusterConfig(userInfo.getName(), project, exploratoryName, computationalName);
}
+ @Audit(action = UPDATE, type = COMPUTE)
+ @Override
+ public void updateAfterStatusCheck(@User UserInfo systemUser, @Project String project, String endpoint, @ResourceName String name, String instanceID,
+ UserInstanceStatus status, @Info String auditInfo) {
+ computationalDAO.updateComputeStatus(project, endpoint, name, instanceID, status);
+ }
+
/**
* Updates the status of computational resource in database.
*
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImpl.java
index 628d9b6..aedf269 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImpl.java
@@ -35,6 +35,9 @@
import com.epam.datalab.backendapi.service.ProjectService;
import com.epam.datalab.backendapi.service.SecurityService;
import com.epam.datalab.dto.UserInstanceDTO;
+import com.epam.datalab.dto.UserInstanceStatus;
+import com.epam.datalab.dto.status.EnvResource;
+import com.epam.datalab.dto.status.EnvResourceList;
import com.epam.datalab.exceptions.ResourceConflictException;
import com.epam.datalab.model.ResourceEnum;
import com.google.inject.Inject;
@@ -44,6 +47,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
@@ -61,6 +65,7 @@
public class EnvironmentServiceImpl implements EnvironmentService {
private static final String ERROR_MSG_FORMAT = "Can not %s environment because on of user resource is in status CREATING or STARTING";
private static final String AUDIT_QUOTA_MESSAGE = "Billing quota reached";
+ private static final String AUDIT_UPDATE_STATUS = "Sync up with console status";
private static final String DATALAB_SYSTEM_USER = "DataLab system user";
private final EnvDAO envDAO;
@@ -167,6 +172,39 @@
computationalService.terminateComputational(userInfo, user, project, exploratoryName, computationalName, String.format(AUDIT_MESSAGE, exploratoryName));
}
+ @Override
+ public void updateEnvironmentStatuses(EnvResourceList resourceList) {
+ resourceList.getHostList()
+ .forEach(this::updateHostStatuses);
+ }
+
+ private void updateHostStatuses(EnvResource envResource) {
+ final UserInstanceStatus status = UserInstanceStatus.of(envResource.getStatus());
+ if (Objects.nonNull(status)) {
+ UserInfo systemUser = new UserInfo(DATALAB_SYSTEM_USER, null);
+ final String endpoint = envResource.getEndpoint();
+ final String instanceID = envResource.getId();
+ final String name = envResource.getName();
+ final String project = envResource.getProject();
+
+ switch (envResource.getResourceType()) {
+ case EDGE:
+ projectService.updateAfterStatusCheck(systemUser, project, endpoint, instanceID, status, AUDIT_UPDATE_STATUS);
+ break;
+ case EXPLORATORY:
+ exploratoryService.updateAfterStatusCheck(systemUser, project, endpoint, name, instanceID, status, AUDIT_UPDATE_STATUS);
+ break;
+ case COMPUTATIONAL:
+ computationalService.updateAfterStatusCheck(systemUser, project, endpoint, name, instanceID, status, AUDIT_UPDATE_STATUS);
+ break;
+ default:
+ log.warn("Resource {} has unknown resource type {}", envResource, envResource.getResourceType());
+ }
+ } else {
+ log.warn("Resource {} has unknown status {}", envResource, envResource.getStatus());
+ }
+ }
+
private UserDTO toUserDTO(String u, UserDTO.Status status) {
return new UserDTO(u, settingsDAO.getAllowedBudget(u).orElse(null), status);
}
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java
index 6ef627a..72f0801 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java
@@ -79,6 +79,7 @@
import static com.epam.datalab.backendapi.domain.AuditActionEnum.START;
import static com.epam.datalab.backendapi.domain.AuditActionEnum.STOP;
import static com.epam.datalab.backendapi.domain.AuditActionEnum.TERMINATE;
+import static com.epam.datalab.backendapi.domain.AuditActionEnum.UPDATE;
import static com.epam.datalab.backendapi.domain.AuditResourceTypeEnum.NOTEBOOK;
import static com.epam.datalab.dto.UserInstanceStatus.CREATING;
import static com.epam.datalab.dto.UserInstanceStatus.FAILED;
@@ -271,6 +272,13 @@
return new ExploratoryCreatePopUp(userProjects, collect);
}
+ @Audit(action = UPDATE, type = NOTEBOOK)
+ @Override
+ public void updateAfterStatusCheck(@User UserInfo userInfo, @Project String project, String endpoint, @ResourceName String name,
+ String instanceID, UserInstanceStatus status, @Info String auditInfo) {
+ exploratoryDAO.updateExploratoryStatus(project, endpoint, name, instanceID, status);
+ }
+
private List<String> getProjectExploratoryNames(ProjectDTO project) {
return exploratoryDAO.fetchExploratoryFieldsForProject(project.getName()).stream()
.map(UserInstanceDTO::getExploratoryName)
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
index efd4088..e0c63d0 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
@@ -68,7 +68,7 @@
private static final String PERMISSION_UPLOAD = "/api/bucket/upload";
private static final String PERMISSION_DOWNLOAD = "/api/bucket/download";
private static final String PERMISSION_DELETE = "/api/bucket/delete";
- private static final String INFRASTRUCTURE_STAUS = "infrastructure/status";
+ private static final String INFRASTRUCTURE_STATUS = "infrastructure/status";
private final ExploratoryDAO expDAO;
private final SelfServiceApplicationConfiguration configuration;
@@ -152,7 +152,7 @@
.withHostList(hostInstances);
EndpointDTO endpointDTO = endpointService.get(endpoint);
- String uuid = provisioningService.post(endpointDTO.getUrl() + INFRASTRUCTURE_STAUS, user.getAccessToken(),
+ String uuid = provisioningService.post(endpointDTO.getUrl() + INFRASTRUCTURE_STATUS, user.getAccessToken(),
requestBuilder.newInfrastructureStatus(user.getName(), endpointDTO.getCloudProvider(), envResourceList),
String.class);
requestId.put(user.getName(), uuid);
diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ProjectServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ProjectServiceImpl.java
index bc66131..1a1974c 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ProjectServiceImpl.java
@@ -283,6 +283,13 @@
UserInstanceStatus.TERMINATING).isEmpty();
}
+ @Audit(action = UPDATE, type = EDGE_NODE)
+ @Override
+ public void updateAfterStatusCheck(@User UserInfo userInfo, @Project String project, @ResourceName String endpoint, String instanceID,
+ UserInstanceStatus status, @Info String auditInfo) {
+ projectDAO.updateEdgeStatus(project, endpoint, status);
+ }
+
private void createProjectOnCloud(UserInfo user, ProjectDTO project) {
try {
project.getEndpoints().forEach(e -> createEndpoint(user, project, e.getName(), project.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
diff --git a/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImplTest.java b/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImplTest.java
index 8127874..3f35e47 100644
--- a/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/EnvironmentServiceImplTest.java
@@ -34,9 +34,12 @@
import com.epam.datalab.dto.UserInstanceDTO;
import com.epam.datalab.dto.UserInstanceStatus;
import com.epam.datalab.dto.base.edge.EdgeInfo;
+import com.epam.datalab.dto.status.EnvResource;
+import com.epam.datalab.dto.status.EnvResourceList;
import com.epam.datalab.exceptions.DatalabException;
import com.epam.datalab.exceptions.ResourceConflictException;
import com.epam.datalab.model.ResourceEnum;
+import com.epam.datalab.model.ResourceType;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -66,12 +69,14 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class EnvironmentServiceImplTest {
private static final String AUDIT_QUOTA_MESSAGE = "Billing quota reached";
+ private static final String AUDIT_UPDATE_STATUS = "Sync up with console status";
private static final String AUDIT_MESSAGE = "Notebook name %s";
private static final String DATALAB_SYSTEM_USER = "DataLab system user";
private static final String DATALAB_SYSTEM_USER_TOKEN = "token";
@@ -84,6 +89,12 @@
private static final String ENDPOINT_NAME = "endpointName";
private static final String SHAPE = "shape";
+ private static final String INSTANCE_ID = "instance_id";
+ private static final String NAME = "name";
+ private static final String PROJECT = "project";
+ private static final String ENDPOINT = "endpoint";
+ private static final String STATUS = "running";
+
@Mock
private EnvDAO envDAO;
@Mock
@@ -312,6 +323,45 @@
verifyNoMoreInteractions(securityService, computationalService);
}
+ @Test
+ public void updateEnvironmentStatuses() {
+ environmentService.updateEnvironmentStatuses(getEnvResourceList());
+
+ verify(projectService).updateAfterStatusCheck(getSystemUser(), PROJECT, ENDPOINT, INSTANCE_ID, UserInstanceStatus.of(STATUS), AUDIT_UPDATE_STATUS);
+ verify(exploratoryService).updateAfterStatusCheck(getSystemUser(), PROJECT, ENDPOINT, NAME, INSTANCE_ID, UserInstanceStatus.of(STATUS), AUDIT_UPDATE_STATUS);
+ verify(computationalService).updateAfterStatusCheck(getSystemUser(), PROJECT, ENDPOINT, NAME, INSTANCE_ID, UserInstanceStatus.of(STATUS), AUDIT_UPDATE_STATUS);
+ verifyNoMoreInteractions(projectService, exploratoryService, computationalService);
+ }
+
+ @Test
+ public void updateEnvironmentStatusesWithUnknownStatus() {
+ EnvResourceList envResourceList = new EnvResourceList().withHostList(Collections.singletonList(new EnvResource().withStatus("unknown status")));
+ environmentService.updateEnvironmentStatuses(envResourceList);
+
+ verifyZeroInteractions(projectService, exploratoryService, computationalService);
+ }
+
+ private UserInfo getSystemUser() {
+ return new UserInfo(DATALAB_SYSTEM_USER, null);
+ }
+
+ private EnvResourceList getEnvResourceList() {
+ List<EnvResource> hostList = Arrays.asList(getEnvResource(ResourceType.EDGE), getEnvResource(ResourceType.EXPLORATORY),
+ getEnvResource(ResourceType.COMPUTATIONAL));
+ return new EnvResourceList()
+ .withHostList(hostList);
+ }
+
+ private EnvResource getEnvResource(ResourceType resourceType) {
+ return new EnvResource()
+ .withId(INSTANCE_ID)
+ .withName(NAME)
+ .withProject(PROJECT)
+ .withEndpoint(ENDPOINT)
+ .withStatus(STATUS)
+ .withResourceType(resourceType);
+ }
+
private UserResourceInfo getUserResourceInfoEdge() {
return UserResourceInfo.builder()
.resourceType(ResourceEnum.EDGE_NODE)
diff --git a/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImplTest.java b/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImplTest.java
index 56e4533..85f6380 100644
--- a/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/datalab/backendapi/service/impl/InfrastructureInfoServiceImplTest.java
@@ -26,13 +26,17 @@
import com.epam.datalab.backendapi.domain.BillingReportLine;
import com.epam.datalab.backendapi.domain.ProjectDTO;
import com.epam.datalab.backendapi.domain.ProjectEndpointDTO;
+import com.epam.datalab.backendapi.domain.RequestId;
import com.epam.datalab.backendapi.resources.TestBase;
import com.epam.datalab.backendapi.resources.dto.HealthStatusPageDTO;
import com.epam.datalab.backendapi.resources.dto.ProjectInfrastructureInfo;
import com.epam.datalab.backendapi.service.BillingService;
import com.epam.datalab.backendapi.service.EndpointService;
import com.epam.datalab.backendapi.service.ProjectService;
+import com.epam.datalab.backendapi.util.RequestBuilder;
+import com.epam.datalab.cloud.CloudProvider;
import com.epam.datalab.dto.InfrastructureMetaInfoDTO;
+import com.epam.datalab.dto.UserEnvironmentResources;
import com.epam.datalab.dto.UserInstanceDTO;
import com.epam.datalab.dto.UserInstanceStatus;
import com.epam.datalab.dto.aws.edge.EdgeInfoAws;
@@ -41,6 +45,9 @@
import com.epam.datalab.dto.billing.BillingResourceType;
import com.epam.datalab.dto.computational.UserComputationalResource;
import com.epam.datalab.dto.gcp.edge.EdgeInfoGcp;
+import com.epam.datalab.dto.status.EnvResource;
+import com.epam.datalab.dto.status.EnvResourceList;
+import com.epam.datalab.rest.client.RESTService;
import com.jcabi.manifests.Manifests;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,6 +78,8 @@
private static final String EXPLORATORY_NAME = "exploratoryName";
private static final String COMPUTE_NAME = "computeName";
private static final String CURRENCY = "currency";
+ private static final String UUID = "uuid";
+ private static final String INFRASTRUCTURE_STATUS = "infrastructure/status";
@Mock
private ExploratoryDAO expDAO;
@@ -82,6 +91,12 @@
private EndpointService endpointService;
@Mock
private BillingService billingService;
+ @Mock
+ private RESTService provisioningService;
+ @Mock
+ private RequestBuilder requestBuilder;
+ @Mock
+ private RequestId requestId;
@InjectMocks
private InfrastructureInfoServiceImpl infoService;
@@ -196,6 +211,25 @@
assertEquals("InfrastructureMetaInfoDTO should be equal", getInfrastructureMetaInfoDTO(), actualInfrastructureMetaInfo);
}
+ @Test
+ public void updateInfrastructureStatuses() {
+ List<EnvResource> envResources = Collections.singletonList(new EnvResource().withId("id"));
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(UserEnvironmentResources.class), any())).thenReturn(UUID);
+ when(requestBuilder.newInfrastructureStatus(anyString(), any(CloudProvider.class), any(EnvResourceList.class))).thenReturn(
+ new UserEnvironmentResources());
+
+ infoService.updateInfrastructureStatuses(getUserInfo(), ENDPOINT_NAME, envResources, envResources);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(requestBuilder).newInfrastructureStatus(USER.toLowerCase(), CloudProvider.AWS, new EnvResourceList()
+ .withHostList(envResources)
+ .withClusterList(envResources));
+ verify(provisioningService).post(ENDPOINT_URL + INFRASTRUCTURE_STATUS, TOKEN, new UserEnvironmentResources(), String.class);
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(endpointService, provisioningService, requestBuilder, requestId);
+ }
+
private InfrastructureMetaInfoDTO getInfrastructureMetaInfoDTO() {
return InfrastructureMetaInfoDTO.builder()
.branch("branch")