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

Reply via email to