This is an automated email from the ASF dual-hosted git repository. bhliva pushed a commit to branch feature/projects in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 22583969384fe31db44f434b14a3753a91673b4f Author: bhliva <bohdan_hl...@epam.com> AuthorDate: Mon Jun 24 15:17:07 2019 +0300 DLAB-745, 746 introduced edge per project --- .../java/com/epam/dlab/dto/ProjectCreateDTO.java | 15 ++++++ .../dlab/dto/base/project/CreateProjectResult.java | 15 ++++++ .../dlab/dto/base/project/ProjectEdgeInfo.java | 28 ++++++++++ .../backendapi/ProvisioningServiceApplication.java | 1 + .../core/commands/CommandExecutorMockAsync.java | 4 +- .../response/handlers/ProjectCallbackHandler.java | 45 +++++++++++++++++ .../backendapi/modules/ProvisioningDevModule.java | 3 ++ .../dlab/backendapi/resources/ProjectResource.java | 31 ++++++++++++ .../dlab/backendapi/service/ProjectService.java | 9 ++++ .../service/impl/ProjectServiceImpl.java | 59 ++++++++++++++++++++++ .../mock_response/gcp/project_create.json | 56 ++++++++++++++++++++ .../dlab/backendapi/SelfServiceApplication.java | 4 +- .../com/epam/dlab/backendapi/dao/ProjectDAO.java | 5 ++ .../epam/dlab/backendapi/dao/ProjectDAOImpl.java | 21 ++++++++ .../epam/dlab/backendapi/domain/ProjectDTO.java | 10 ++++ .../dlab/backendapi/resources/ProjectResource.java | 5 +- .../resources/callback/ProjectCallback.java | 46 +++++++++++++++++ .../dlab/backendapi/service/ProjectService.java | 2 +- .../service/impl/ProjectServiceImpl.java | 34 ++++++++++++- .../InfrastructureTemplateServiceBaseTest.java | 6 +-- 20 files changed, 388 insertions(+), 11 deletions(-) diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/ProjectCreateDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/ProjectCreateDTO.java new file mode 100644 index 0000000..a5ec693 --- /dev/null +++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/ProjectCreateDTO.java @@ -0,0 +1,15 @@ +package com.epam.dlab.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ProjectCreateDTO extends ResourceBaseDTO<ProjectCreateDTO> { + private final String key; + @JsonProperty("project_name") + private final String name; + @JsonProperty("project_tag") + private final String tag; +} diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/CreateProjectResult.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/CreateProjectResult.java new file mode 100644 index 0000000..3059b0e --- /dev/null +++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/CreateProjectResult.java @@ -0,0 +1,15 @@ +package com.epam.dlab.dto.base.project; + +import com.epam.dlab.dto.StatusBaseDTO; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class CreateProjectResult extends StatusBaseDTO<CreateProjectResult> { + private ProjectEdgeInfo edgeInfo; + @JsonProperty("project_name") + private String projectName; + +} diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectEdgeInfo.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectEdgeInfo.java new file mode 100644 index 0000000..0bf1c20 --- /dev/null +++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectEdgeInfo.java @@ -0,0 +1,28 @@ +package com.epam.dlab.dto.base.project; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProjectEdgeInfo { + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private String id; + + @JsonProperty("instance_id") + private String instanceId; + + @JsonProperty + private String hostname; + + @JsonProperty("public_ip") + private String publicIp; + + @JsonProperty + private String ip; + + @JsonProperty("key_name") + private String keyName; +} diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplication.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplication.java index 4f063c6..2353f2d 100644 --- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplication.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplication.java @@ -102,6 +102,7 @@ public class ProvisioningServiceApplication extends Application<ProvisioningServ jersey.register(injector.getInstance(BackupResource.class)); jersey.register(injector.getInstance(KeyResource.class)); jersey.register(injector.getInstance(CallbackHandlerResource.class)); + jersey.register(injector.getInstance(ProjectResource.class)); } } diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java index 5af48e3..7277961 100644 --- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java @@ -294,8 +294,8 @@ public class CommandExecutorMockAsync implements Supplier<Boolean> { private void action(String user, DockerAction action) { String resourceType = parser.getResourceType(); - String prefixFileName = (Lists.newArrayList("edge", "dataengine", "dataengine-service").contains - (resourceType) ? resourceType : "notebook") + "_"; + String prefixFileName = (Lists.newArrayList("project", "edge", "dataengine", "dataengine-service") + .contains(resourceType) ? resourceType : "notebook") + "_"; String templateFileName = "mock_response/" + cloudProvider.getName() + '/' + prefixFileName + action.toString() + JSON_FILE_ENDING; responseFileName = getAbsolutePath(parser.getResponsePath(), prefixFileName + user + "_" + diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java new file mode 100644 index 0000000..6f7f9eb --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java @@ -0,0 +1,45 @@ +package com.epam.dlab.backendapi.core.response.handlers; + +import com.epam.dlab.auth.SystemUserInfoService; +import com.epam.dlab.backendapi.core.commands.DockerAction; +import com.epam.dlab.dto.UserInstanceStatus; +import com.epam.dlab.dto.base.project.CreateProjectResult; +import com.epam.dlab.dto.base.project.ProjectEdgeInfo; +import com.epam.dlab.exceptions.DlabException; +import com.epam.dlab.rest.client.RESTService; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; + +public class ProjectCallbackHandler extends ResourceCallbackHandler<CreateProjectResult> { + + + private final String callbackUri; + + public ProjectCallbackHandler(SystemUserInfoService systemUserInfoService, RESTService selfService, String user, + String uuid, DockerAction action, String callbackUri) { + super(systemUserInfoService, selfService, user, uuid, action); + this.callbackUri = callbackUri; + } + + @Override + protected String getCallbackURI() { + return callbackUri; + } + + @Override + protected CreateProjectResult parseOutResponse(JsonNode resultNode, CreateProjectResult baseStatus) { + if (resultNode != null && getAction() == DockerAction.CREATE + && UserInstanceStatus.of(baseStatus.getStatus()) != UserInstanceStatus.FAILED) { + try { + final ProjectEdgeInfo projectEdgeInfo = mapper.readValue(resultNode.toString(), ProjectEdgeInfo.class); + baseStatus.setEdgeInfo(projectEdgeInfo); + baseStatus.setProjectName(resultNode.get("project_name").asText()); + } catch (IOException e) { + throw new DlabException("Cannot parse the EDGE info in JSON: " + e.getLocalizedMessage(), e); + } + } + + return baseStatus; + } +} diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProvisioningDevModule.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProvisioningDevModule.java index 3ec1035..9817a65 100644 --- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProvisioningDevModule.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProvisioningDevModule.java @@ -31,9 +31,11 @@ import com.epam.dlab.backendapi.core.commands.CommandExecutorMock; import com.epam.dlab.backendapi.core.commands.ICommandExecutor; import com.epam.dlab.backendapi.core.response.handlers.dao.CallbackHandlerDao; import com.epam.dlab.backendapi.core.response.handlers.dao.FileSystemCallbackHandlerDao; +import com.epam.dlab.backendapi.service.ProjectService; import com.epam.dlab.backendapi.service.RestoreCallbackHandlerService; import com.epam.dlab.backendapi.service.CheckInactivityService; import com.epam.dlab.backendapi.service.impl.CheckInactivityServiceImpl; +import com.epam.dlab.backendapi.service.impl.ProjectServiceImpl; import com.epam.dlab.backendapi.service.impl.RestoreCallbackHandlerServiceImpl; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.mongo.MongoService; @@ -91,6 +93,7 @@ public class ProvisioningDevModule extends ModuleBase<ProvisioningServiceApplica bind(CallbackHandlerDao.class).to(FileSystemCallbackHandlerDao.class); bind(RestoreCallbackHandlerService.class).to(RestoreCallbackHandlerServiceImpl.class); bind(CheckInactivityService.class).to(CheckInactivityServiceImpl.class); + bind(ProjectService.class).to(ProjectServiceImpl.class); } /** diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java new file mode 100644 index 0000000..6bb8826 --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java @@ -0,0 +1,31 @@ +package com.epam.dlab.backendapi.resources; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.service.ProjectService; +import com.epam.dlab.dto.ProjectCreateDTO; +import com.google.inject.Inject; +import io.dropwizard.auth.Auth; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("infrastructure/project") +public class ProjectResource { + private final ProjectService projectService; + + @Inject + public ProjectResource(ProjectService projectService) { + this.projectService = projectService; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createProject(@Auth UserInfo userInfo, ProjectCreateDTO dto) { + return Response.ok(projectService.create(userInfo, dto)).build(); + } +} diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java new file mode 100644 index 0000000..60656f4 --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java @@ -0,0 +1,9 @@ +package com.epam.dlab.backendapi.service; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.dto.ProjectCreateDTO; + +public interface ProjectService { + + String create(UserInfo userInfo, ProjectCreateDTO projectCreateDTO); +} diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java new file mode 100644 index 0000000..dc6401a --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java @@ -0,0 +1,59 @@ +package com.epam.dlab.backendapi.service.impl; + +import com.epam.dlab.auth.SystemUserInfoService; +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.ProvisioningServiceApplicationConfiguration; +import com.epam.dlab.backendapi.core.commands.*; +import com.epam.dlab.backendapi.core.response.folderlistener.FolderListenerExecutor; +import com.epam.dlab.backendapi.core.response.handlers.ProjectCallbackHandler; +import com.epam.dlab.backendapi.service.ProjectService; +import com.epam.dlab.dto.ProjectCreateDTO; +import com.epam.dlab.rest.client.RESTService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ProjectServiceImpl implements ProjectService { + @Inject + protected RESTService selfService; + @Inject + protected SystemUserInfoService systemUserInfoService; + @Inject + private ProvisioningServiceApplicationConfiguration configuration; + @Inject + private FolderListenerExecutor folderListenerExecutor; + @Inject + private ICommandExecutor commandExecutor; + @Inject + private CommandBuilder commandBuilder; + + @Override + public String create(UserInfo userInfo, ProjectCreateDTO dto) { + String uuid = DockerCommands.generateUUID(); + + folderListenerExecutor.start(configuration.getKeyLoaderDirectory(), + configuration.getKeyLoaderPollTimeout(), + new ProjectCallbackHandler(systemUserInfoService, selfService, userInfo.getName(), uuid, + DockerAction.CREATE, "/api/project/status")); + + RunDockerCommand runDockerCommand = new RunDockerCommand() + .withInteractive() + .withName(String.join("_", dto.getName(), "project")) + .withVolumeForRootKeys(configuration.getKeyDirectory()) + .withVolumeForResponse(configuration.getKeyLoaderDirectory()) + .withVolumeForLog(configuration.getDockerLogDirectory(), "project") + .withResource("project") + .withRequestId(uuid) + .withConfKeyName(configuration.getAdminKey()) + .withImage("docker.dlab-project") + .withAction(DockerAction.CREATE); + + try { + commandExecutor.executeAsync(userInfo.getName(), uuid, commandBuilder.buildCommand(runDockerCommand, dto)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return uuid; + } +} diff --git a/services/provisioning-service/src/main/resources/mock_response/gcp/project_create.json b/services/provisioning-service/src/main/resources/mock_response/gcp/project_create.json new file mode 100644 index 0000000..9f59b6d --- /dev/null +++ b/services/provisioning-service/src/main/resources/mock_response/gcp/project_create.json @@ -0,0 +1,56 @@ +{ + "status": "ok", + "response": { + "result": { + "tunnel_port": "22", + "full_edge_conf": { + "edge_service_account_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge", + "fw_edge_egress_internal": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge-egress-internal", + "dlab_ssh_user": "dlab-user", + "ps_role_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps", + "fw_ps_egress_public": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps-egress-public", + "private_ip": "10.10.0.3", + "fw_ps_ingress": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps-ingress", + "ssh_key_path": "/root/keys/BDCC-DSS-POC.pem", + "zone": "us-west1-a ", + "fw_edge_egress_public": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge-egress-public", + "ami_name": "/projects/ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20170721", + "edge_role_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge", + "private_subnet_prefix": "24", + "subnet_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-subnet", + "vpc_cidr": "10.10.0.0/16", + "key_name": "${CONF_KEY_NAME}", + "service_base_name": "${CONF_SERVICE_BASE_NAME}", + "static_address_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ip", + "fw_ps_egress_private": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps-egress-private", + "vpc_name": "${CONF_SERVICE_BASE_NAME}-ssn-vpc", + "static_ip": "104.198.5.3", + "bucket_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-bucket", + "fw_edge_ingress_public": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge-ingress-public", + "ps_service_account_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps", + "firewall_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge-firewall", + "region": "us-west1", + "fw_common_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-ps", + "instance_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge", + "user_keyname": "${EDGE_USER_NAME}", + "edge_user_name": "${EDGE_USER_NAME}", + "private_subnet_cidr": "10.10.16.0/24", + "fw_edge_ingress_internal": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-edge-ingress-internal", + "vpc_selflink": "https://www.googleapis.com/compute/v1/projects/or2-msq-epmc-dlab-t1iylu/global/networks/${CONF_SERVICE_BASE_NAME}-ssn-vpc", + "instance_size": "n1-standard-1", + "notebook_firewall_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-nb-firewall" + }, + "key_name": "BDCC-DSS-POC", + "hostname": "104.198.5.3", + "public_ip": "104.198.5.3", + "ip": "10.10.0.3", + "Action": "Create new EDGE server", + "user_own_bucket_name": "${CONF_SERVICE_BASE_NAME}-${EDGE_USER_NAME}-bucket", + "socks_port": "1080", + "notebook_subnet": "10.10.16.0/24", + "project_name" : "${PROJECT_NAME}" + }, + "log": "/var/log/dlab/edge/edge_${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/dlab/backendapi/SelfServiceApplication.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java index 8271fb2..8cc143e 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java @@ -100,7 +100,8 @@ public class SelfServiceApplication extends Application<SelfServiceApplicationCo /*bootstrap.addBundle(new SwaggerBundle<SelfServiceApplicationConfiguration>() { @Override - protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(SelfServiceApplicationConfiguration configuration) { + protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(SelfServiceApplicationConfiguration + configuration) { return configuration.getSwaggerConfiguration(); } });*/ @@ -181,6 +182,7 @@ public class SelfServiceApplication extends Application<SelfServiceApplicationCo jersey.register(injector.getInstance(ApplicationSettingResource.class)); jersey.register(injector.getInstance(EndpointResource.class)); jersey.register(injector.getInstance(ProjectResource.class)); + jersey.register(injector.getInstance(ProjectCallback.class)); OpenAPI oas = new OpenAPI(); Info info = new Info() .title("Hello World API") diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java index 9939bc5..35cfd1b 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java @@ -1,6 +1,7 @@ package com.epam.dlab.backendapi.dao; import com.epam.dlab.backendapi.domain.ProjectDTO; +import com.epam.dlab.dto.base.project.ProjectEdgeInfo; import java.util.List; import java.util.Optional; @@ -11,6 +12,10 @@ public interface ProjectDAO { void create(ProjectDTO projectDTO); + void updateStatus(String projectName, ProjectDTO.Status status); + + void updateEdgeInfoAndStatus(String projectName, ProjectEdgeInfo edgeInfo, ProjectDTO.Status status); + Optional<ProjectDTO> get(String name); boolean update(ProjectDTO projectDTO); diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java index 3fd5e6b..c3a6752 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java @@ -1,7 +1,10 @@ package com.epam.dlab.backendapi.dao; import com.epam.dlab.backendapi.domain.ProjectDTO; +import com.epam.dlab.dto.base.project.ProjectEdgeInfo; import com.google.common.collect.Iterables; +import com.mongodb.BasicDBObject; +import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.bson.conversions.Bson; @@ -16,6 +19,8 @@ public class ProjectDAOImpl extends BaseDAO implements ProjectDAO { private static final String PROJECTS_COLLECTION = "Projects"; private static final String GROUPS = "groups"; + private static final String STATUS_FIELD = "status"; + private static final String EDGE_INFO_FIELD = "edgeInfo"; @Override public List<ProjectDTO> getProjects() { @@ -28,6 +33,22 @@ public class ProjectDAOImpl extends BaseDAO implements ProjectDAO { } @Override + public void updateStatus(String projectName, ProjectDTO.Status status) { + updateOne(PROJECTS_COLLECTION, projectCondition(projectName), + new Document(SET, new Document(STATUS_FIELD, status.toString()))); + } + + @Override + public void updateEdgeInfoAndStatus(String projectName, ProjectEdgeInfo edgeInfo, ProjectDTO.Status status) { + BasicDBObject dbObject = new BasicDBObject(); + dbObject.put(STATUS_FIELD, status.toString()); + dbObject.put(EDGE_INFO_FIELD, convertToBson(edgeInfo)); + final UpdateResult updateResult = updateOne(PROJECTS_COLLECTION, projectCondition(projectName), + new Document(SET, dbObject)); + System.out.println(updateResult); + } + + @Override public Optional<ProjectDTO> get(String name) { return findOne(PROJECTS_COLLECTION, projectCondition(name), ProjectDTO.class); } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java index 07b281f..ac47bd8 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java @@ -16,6 +16,16 @@ public class ProjectDTO { @NotNull private final Set<String> groups; @NotNull + private final String key; + @NotNull private final String tag; private final Integer budget; + private final Status status = Status.CREATING; + + + public enum Status { + CREATING, + CREATED, + FAILED + } } 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 85029dd..36d078c 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 @@ -16,6 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import javax.annotation.security.RolesAllowed; +import javax.validation.Valid; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; @@ -51,8 +52,8 @@ public class ProjectResource { }) @POST @Consumes(MediaType.APPLICATION_JSON) - public Response createProject(@Parameter(hidden = true) @Auth UserInfo userInfo, ProjectDTO projectDTO) { - projectService.create(projectDTO); + public Response createProject(@Parameter(hidden = true) @Auth UserInfo userInfo, @Valid ProjectDTO projectDTO) { + projectService.create(userInfo, projectDTO); final URI uri = uriInfo.getRequestUriBuilder().path(projectDTO.getName()).build(); return Response .ok() diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java new file mode 100644 index 0000000..9807119 --- /dev/null +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java @@ -0,0 +1,46 @@ +package com.epam.dlab.backendapi.resources.callback; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.dao.ProjectDAO; +import com.epam.dlab.backendapi.domain.ProjectDTO; +import com.epam.dlab.backendapi.domain.RequestId; +import com.epam.dlab.dto.UserInstanceStatus; +import com.epam.dlab.dto.base.project.CreateProjectResult; +import com.google.inject.Inject; +import io.dropwizard.auth.Auth; +import lombok.extern.slf4j.Slf4j; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/project/status") +@Consumes(MediaType.APPLICATION_JSON) +@Slf4j +public class ProjectCallback { + + private final ProjectDAO projectDAO; + private final RequestId requestId; + + @Inject + public ProjectCallback(ProjectDAO projectDAO, RequestId requestId) { + this.projectDAO = projectDAO; + this.requestId = requestId; + } + + + @POST + public Response updateProjectStatus(@Auth UserInfo userInfo, CreateProjectResult projectResult) { + requestId.checkAndRemove(projectResult.getRequestId()); + if (UserInstanceStatus.of(projectResult.getStatus()) == UserInstanceStatus.FAILED) { + projectDAO.updateStatus(projectResult.getProjectName(), ProjectDTO.Status.FAILED); + } else { + projectDAO.updateEdgeInfoAndStatus(projectResult.getProjectName(), projectResult.getEdgeInfo(), + ProjectDTO.Status.CREATED); + } + return Response.ok().build(); + } +} 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 bde43b2..03c979c 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 @@ -8,7 +8,7 @@ import java.util.List; public interface ProjectService { List<ProjectDTO> getProjects(); - void create(ProjectDTO projectDTO); + void create(UserInfo userInfo, ProjectDTO projectDTO); ProjectDTO get(String name); 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 d118844..0343583 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 @@ -4,11 +4,17 @@ import com.epam.dlab.auth.UserInfo; 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.RequestId; import com.epam.dlab.backendapi.service.EnvironmentService; import com.epam.dlab.backendapi.service.ProjectService; +import com.epam.dlab.constants.ServiceConsts; +import com.epam.dlab.dto.ProjectCreateDTO; import com.epam.dlab.exceptions.ResourceConflictException; import com.epam.dlab.exceptions.ResourceNotFoundException; +import com.epam.dlab.rest.client.RESTService; import com.google.inject.Inject; +import com.google.inject.name.Named; +import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Set; @@ -17,18 +23,26 @@ import java.util.function.Supplier; import static java.util.stream.Collectors.toSet; import static java.util.stream.Stream.concat; +@Slf4j public class ProjectServiceImpl implements ProjectService { + private static final String CREATE_PRJ_API = "infrastructure/project"; private final ProjectDAO projectDAO; private final EnvironmentService environmentService; private final UserGroupDao userGroupDao; + private final RESTService provisioningService; + private final RequestId requestId; @Inject public ProjectServiceImpl(ProjectDAO projectDAO, EnvironmentService environmentService, - UserGroupDao userGroupDao) { + UserGroupDao userGroupDao, + @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService, + RequestId requestId) { this.projectDAO = projectDAO; this.environmentService = environmentService; this.userGroupDao = userGroupDao; + this.provisioningService = provisioningService; + this.requestId = requestId; } @Override @@ -37,9 +51,10 @@ public class ProjectServiceImpl implements ProjectService { } @Override - public void create(ProjectDTO projectDTO) { + public void create(UserInfo user, ProjectDTO projectDTO) { if (!projectDAO.get(projectDTO.getName()).isPresent()) { projectDAO.create(projectDTO); + createProjectOnCloud(user, projectDTO); } else { throw new ResourceConflictException("Project with passed name already exist in system"); } @@ -77,6 +92,21 @@ public class ProjectServiceImpl implements ProjectService { return projectDAO.isAnyProjectAssigned(userGroups); } + private void createProjectOnCloud(UserInfo user, ProjectDTO projectDTO) { + try { + final ProjectCreateDTO projectDto = ProjectCreateDTO.builder() + .key(projectDTO.getKey()) + .name(projectDTO.getName()) + .tag(projectDTO.getTag()) + .build(); + String uuid = provisioningService.post(CREATE_PRJ_API, user.getAccessToken(), projectDto, String.class); + requestId.put(user.getName(), uuid); + } catch (Exception e) { + log.error("Can not create project due to: {}", e.getMessage()); + projectDAO.updateStatus(projectDTO.getName(), ProjectDTO.Status.FAILED); + } + } + private Supplier<ResourceNotFoundException> projectNotFound() { return () -> new ResourceNotFoundException("Project with passed name not found"); } diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java index b2979fa..834f2f1 100644 --- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java +++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java @@ -77,7 +77,7 @@ public class InfrastructureTemplateServiceBaseTest { emDto2.setExploratoryEnvironmentShapes(shapes2); List<ExploratoryMetadataDTO> expectedEmdDtoList = Arrays.asList(emDto1, emDto2); when(projectDAO.get(anyString())).thenReturn(Optional.of(new ProjectDTO("project", Collections.emptySet(), - Collections.singleton("project"), null, null))); + Collections.singleton("project"), null, null, null))); when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedEmdDtoList.toArray()); when(settingsDAO.getConfOsFamily()).thenReturn("someConfOsFamily"); @@ -116,7 +116,7 @@ public class InfrastructureTemplateServiceBaseTest { computationalMetadataDTO ); when(projectDAO.get(anyString())).thenReturn(Optional.of(new ProjectDTO("project", Collections.emptySet(), - Collections.singleton("project"), null, null))); + Collections.singleton("project"), null, null, null))); when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); List<FullComputationalTemplate> expectedFullCmdDtoList = expectedCmdDtoList.stream() @@ -158,7 +158,7 @@ public class InfrastructureTemplateServiceBaseTest { List<ComputationalMetadataDTO> expectedCmdDtoList = Collections.singletonList(computationalMetadataDTO); when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); when(projectDAO.get(anyString())).thenReturn(Optional.of(new ProjectDTO("project", Collections.emptySet(), - Collections.singleton("project"), null, null))); + Collections.singleton("project"), null, null,null))); UserInfo userInfo = new UserInfo("test", "token"); try { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org