This is an automated email from the ASF dual-hosted git repository. ofuks pushed a commit to branch bucket-browser-gcp in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 6c28123370488f391010405aa105a6d8d8239c8e Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Mon Apr 13 18:48:54 2020 +0300 gcp bucket browser --- .../src/ssn/templates/ssn.yml | 5 + .../java/com/epam/dlab/dto/bucket/BucketDTO.java} | 22 ++-- .../epam/dlab/dto/bucket/BucketDownloadDTO.java} | 21 ++-- services/dlab-webapp-common/pom.xml | 5 + .../java/com/epam/dlab/ServiceConfiguration.java | 9 ++ .../com/epam/dlab/constants/ServiceConsts.java | 1 + .../com/epam/dlab/rest/client/RESTService.java | 78 ++++++++++--- .../epam/dlab/rest/client/RESTServiceFactory.java | 5 +- services/provisioning-service/pom.xml | 27 +++++ .../backendapi/ProvisioningServiceApplication.java | 34 ++++-- .../backendapi/modules/GcpProvisioningModule.java | 1 + .../dlab/backendapi/modules/ProductionModule.java | 26 +++-- .../backendapi/modules/ProvisioningDevModule.java | 31 ++--- .../dlab/backendapi/resources/BucketResource.java | 101 ++++++++++++++++ .../dlab/backendapi/service/BucketService.java} | 23 ++-- .../service/impl/gcp/BucketServiceGcpImpl.java | 109 +++++++++++++++++ .../backendapi/modules/CloudProviderModule.java | 2 + .../epam/dlab/backendapi/modules/DevModule.java | 89 +++++++++++--- .../dlab/backendapi/modules/ProductionModule.java | 93 ++++++++++++--- .../dlab/backendapi/resources/BucketResource.java | 101 ++++++++++++++++ .../resources/dto/BucketDownloadDTO.java} | 23 ++-- .../dlab/backendapi/service/BucketService.java} | 24 ++-- .../backendapi/service/impl/BucketServiceImpl.java | 129 +++++++++++++++++++++ .../InfrastructureTemplateServiceBaseTest.java | 28 +++-- 24 files changed, 848 insertions(+), 139 deletions(-) diff --git a/infrastructure-provisioning/src/ssn/templates/ssn.yml b/infrastructure-provisioning/src/ssn/templates/ssn.yml index fffa7d2..949ddf9 100644 --- a/infrastructure-provisioning/src/ssn/templates/ssn.yml +++ b/infrastructure-provisioning/src/ssn/templates/ssn.yml @@ -62,5 +62,10 @@ provisioningService: timeout: 3s connectionTimeout: 3s +bucketService: + jerseyClient: + timeout: 5m + connectionTimeout: 3s + # Log out user on inactivity inactiveUserTimeoutMillSec: 7200000 diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDTO.java similarity index 61% copy from services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java copy to services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDTO.java index d376665..5f260b7 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDTO.java @@ -17,16 +17,18 @@ * under the License. */ -package com.epam.dlab.constants; +package com.epam.dlab.dto.bucket; -public final class ServiceConsts { - public static final String MONGO_NAME = "mongo"; - public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; - public static final String MAVEN_SEARCH_API = "mavenSearchService"; - public static final String SECURITY_SERVICE_NAME = "securityService"; - public static final String SELF_SERVICE_NAME = "selfService"; - public static final String PROVISIONING_USER_AGENT = "provisioning-service"; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Builder; +import lombok.Data; - private ServiceConsts() { - } +@Data +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class BucketDTO { + private final String bucket; + private final String object; + private final String size; + private final String creationDate; } diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDownloadDTO.java similarity index 61% copy from services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java copy to services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDownloadDTO.java index d376665..b1201e6 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/bucket/BucketDownloadDTO.java @@ -17,16 +17,17 @@ * under the License. */ -package com.epam.dlab.constants; +package com.epam.dlab.dto.bucket; -public final class ServiceConsts { - public static final String MONGO_NAME = "mongo"; - public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; - public static final String MAVEN_SEARCH_API = "mavenSearchService"; - public static final String SECURITY_SERVICE_NAME = "securityService"; - public static final String SELF_SERVICE_NAME = "selfService"; - public static final String PROVISIONING_USER_AGENT = "provisioning-service"; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import org.hibernate.validator.constraints.NotBlank; - private ServiceConsts() { - } +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class BucketDownloadDTO { + @NotBlank(message = "field cannot be empty") + private final String bucket; + @NotBlank(message = "field cannot be empty") + private final String object; } diff --git a/services/dlab-webapp-common/pom.xml b/services/dlab-webapp-common/pom.xml index 6c846d6..2e7ad5c 100644 --- a/services/dlab-webapp-common/pom.xml +++ b/services/dlab-webapp-common/pom.xml @@ -57,6 +57,11 @@ <version>${io.dropwizard.version}</version> </dependency> <dependency> + <groupId>io.dropwizard</groupId> + <artifactId>dropwizard-forms</artifactId> + <version>${io.dropwizard.version}</version> + </dependency> + <dependency> <groupId>com.epam.dlab</groupId> <artifactId>common</artifactId> </dependency> diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ServiceConfiguration.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ServiceConfiguration.java index 85d4318..51b0779 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ServiceConfiguration.java +++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ServiceConfiguration.java @@ -54,6 +54,11 @@ public class ServiceConfiguration extends Configuration { @Valid @NotNull + @JsonProperty(ServiceConsts.BUCKET_SERVICE_NAME) + private RESTServiceFactory bucketFactory = new RESTServiceFactory(); + + @Valid + @NotNull @JsonProperty(ServiceConsts.SECURITY_SERVICE_NAME) private RESTServiceFactory securityFactory; @@ -85,6 +90,10 @@ public class ServiceConfiguration extends Configuration { return provisioningFactory; } + public RESTServiceFactory getBucketFactory() { + return bucketFactory; + } + public RESTServiceFactory getSecurityFactory() { return securityFactory; } diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java index d376665..d7d7208 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java @@ -22,6 +22,7 @@ package com.epam.dlab.constants; public final class ServiceConsts { public static final String MONGO_NAME = "mongo"; public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; + public static final String BUCKET_SERVICE_NAME = "bucketService"; public static final String MAVEN_SEARCH_API = "mavenSearchService"; public static final String SECURITY_SERVICE_NAME = "securityService"; public static final String SELF_SERVICE_NAME = "selfService"; diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTService.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTService.java index ab1d29e..924862c 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTService.java +++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTService.java @@ -19,21 +19,24 @@ package com.epam.dlab.rest.client; -import com.epam.dlab.exceptions.DlabException; import lombok.extern.slf4j.Slf4j; +import org.glassfish.jersey.media.multipart.Boundary; +import org.glassfish.jersey.media.multipart.FormDataMultiPart; -import javax.ws.rs.ProcessingException; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; -import java.net.ConnectException; import java.net.URI; import java.util.Collections; import java.util.Map; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA_TYPE; + @Slf4j public class RESTService { private Client client; @@ -65,42 +68,75 @@ public class RESTService { .get(clazz); } + public <T> T getWithMediaTypes(String path, String accessToken, Class<T> clazz, String requestMediaType, String acceptMediaType) { + return get(path, accessToken, clazz, requestMediaType, acceptMediaType); + } + public <T> T get(String path, String accessToken, Class<T> clazz) { - Invocation.Builder builder = getBuilder(path, accessToken, Collections.emptyMap()); + return get(path, accessToken, clazz, APPLICATION_JSON, APPLICATION_JSON); + } + + private <T> T get(String path, String accessToken, Class<T> clazz, String requestMediaType, String acceptMediaType) { + Invocation.Builder builder = getBuilder(path, accessToken, Collections.emptyMap(), requestMediaType, acceptMediaType); log.debug("REST get secured {} {}", path, accessToken); return builder.get(clazz); } + public <T> T get(String path, GenericType<T> genericType) { + return get(path, null, genericType); + } + + public <T> T get(String path, String accessToken, GenericType<T> genericType) { + return get(path, accessToken, genericType, Collections.emptyMap()); + } + + public <T> T get(String path, String accessToken, GenericType<T> genericType, Map<String, Object> queryParams) { + Invocation.Builder builder = getBuilder(path, accessToken, queryParams, APPLICATION_JSON, APPLICATION_JSON); + log.debug("REST get secured {} {}", path, accessToken); + return builder.get(genericType); + } + public <T> T post(String path, Object parameter, Class<T> clazz) { return post(path, null, parameter, clazz); } public <T> T post(String path, String accessToken, Object parameter, Class<T> clazz) { - return post(path, accessToken, parameter, clazz, Collections.emptyMap()); + return post(path, accessToken, parameter, clazz, Collections.emptyMap(), APPLICATION_JSON, APPLICATION_JSON); + } + + public <T> T delete(String path, String accessToken, Class<T> clazz, String requestMediaType, String acceptMediaType) { + return delete(path, accessToken, clazz, Collections.emptyMap(), requestMediaType, acceptMediaType); } - public <T> T post(String path, String accessToken, Object parameter, Class<T> clazz, - Map<String, Object> queryParams) { - Invocation.Builder builder = getBuilder(path, accessToken, queryParams); + private <T> T delete(String path, String accessToken, Class<T> clazz, Map<String, Object> queryParams, + String requestMediaType, String acceptMediaType) { + Invocation.Builder builder = getBuilder(path, accessToken, queryParams, requestMediaType, acceptMediaType); + log.debug("REST delete secured {} {}", path, accessToken); + return builder.delete(clazz); + } + + private <T> T post(String path, String accessToken, Object parameter, Class<T> clazz, Map<String, Object> queryParams, + String requestMediaType, String acceptMediaType) { + Invocation.Builder builder = getBuilder(path, accessToken, queryParams, requestMediaType, acceptMediaType); log.debug("REST post secured {} {}", path, accessToken); return builder.post(Entity.json(parameter), clazz); } - private Invocation.Builder getBuilder(String path, String token, Map<String, Object> queryParams) { + private Invocation.Builder getBuilder(String path, String token, Map<String, Object> queryParams, + String requestMediaType, String acceptMediaType) { WebTarget webTarget = getWebTarget(path); for (Map.Entry<String, Object> entry : queryParams.entrySet()) { webTarget = webTarget.queryParam(entry.getKey(), entry.getValue()); } Invocation.Builder builder = webTarget - .request(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON); + .request(requestMediaType) + .accept(acceptMediaType); if (token != null) { builder.header(HttpHeaders.AUTHORIZATION, "Bearer " + token); } - if (userAgent != null) { builder.header(HttpHeaders.USER_AGENT, userAgent); } @@ -108,8 +144,22 @@ public class RESTService { return builder; } + public <T> T postForm(String path, String token, FormDataMultiPart form, Class<T> clazz) { + WebTarget webTarget = getWebTarget(path); + Invocation.Builder builder = webTarget.request(); + if (token != null) { + builder.header(HttpHeaders.AUTHORIZATION, "Bearer " + token); + } + if (userAgent != null) { + builder.header(HttpHeaders.USER_AGENT, userAgent); + } + + MediaType mediaType = Boundary.addBoundary(MULTIPART_FORM_DATA_TYPE); + return builder.post(Entity.entity(form, mediaType), clazz); + } + + private WebTarget getWebTarget(String path) { - return url != null ? - client.target(url).path(path) : client.target(path); + return url != null ? client.target(url).path(path) : client.target(path); } } diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTServiceFactory.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTServiceFactory.java index a7aa942..aeb0ad1 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTServiceFactory.java +++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/client/RESTServiceFactory.java @@ -24,10 +24,9 @@ import io.dropwizard.client.JerseyClientBuilder; import io.dropwizard.client.JerseyClientConfiguration; import io.dropwizard.setup.Environment; import org.apache.commons.lang3.StringUtils; +import org.glassfish.jersey.media.multipart.MultiPartFeature; import javax.validation.Valid; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.ws.rs.client.Client; @@ -51,7 +50,7 @@ public class RESTServiceFactory { } public RESTService build(Environment environment, String name, String userAgent) { - Client client = new JerseyClientBuilder(environment).using(jerseyClientConfiguration).build(name); + Client client = new JerseyClientBuilder(environment).using(jerseyClientConfiguration).build(name).register(MultiPartFeature.class); return StringUtils.isNotEmpty(host) ? new RESTService(client, getURL(), userAgent) : new RESTService(client, userAgent); } diff --git a/services/provisioning-service/pom.xml b/services/provisioning-service/pom.xml index 1a6548e..78bc19b 100644 --- a/services/provisioning-service/pom.xml +++ b/services/provisioning-service/pom.xml @@ -29,6 +29,18 @@ <artifactId>provisioning-service</artifactId> + <dependencyManagement> + <dependencies> + <dependency> + <groupId>com.google.cloud</groupId> + <artifactId>libraries-bom</artifactId> + <version>3.3.0</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> <dependency> <groupId>com.epam.dlab</groupId> @@ -63,8 +75,23 @@ <artifactId>conveyor</artifactId> <version>${com.aegisql.conveyor.version}</version> </dependency> + <dependency> + <groupId>io.dropwizard</groupId> + <artifactId>dropwizard-forms</artifactId> + <version>${io.dropwizard.version}</version> + </dependency> + <dependency> + <groupId>com.google.cloud</groupId> + <artifactId>google-cloud-storage</artifactId> + <version>1.106.0</version> + </dependency> <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.6</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/dlab/backendapi/ProvisioningServiceApplication.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplication.java index 6f1047b..fbb5f5a 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 @@ -26,7 +26,16 @@ import com.epam.dlab.backendapi.core.DockerWarmuper; import com.epam.dlab.backendapi.core.response.handlers.ComputationalConfigure; import com.epam.dlab.backendapi.modules.CloudModuleConfigurator; import com.epam.dlab.backendapi.modules.ModuleFactory; -import com.epam.dlab.backendapi.resources.*; +import com.epam.dlab.backendapi.resources.BackupResource; +import com.epam.dlab.backendapi.resources.BucketResource; +import com.epam.dlab.backendapi.resources.CallbackHandlerResource; +import com.epam.dlab.backendapi.resources.DockerResource; +import com.epam.dlab.backendapi.resources.GitExploratoryResource; +import com.epam.dlab.backendapi.resources.ImageResource; +import com.epam.dlab.backendapi.resources.InfrastructureResource; +import com.epam.dlab.backendapi.resources.LibraryResource; +import com.epam.dlab.backendapi.resources.ProjectResource; +import com.epam.dlab.backendapi.resources.ProvisioningHealthCheckResource; import com.epam.dlab.backendapi.resources.base.KeyResource; import com.epam.dlab.backendapi.service.impl.RestoreCallbackHandlerServiceImpl; import com.epam.dlab.cloud.CloudModule; @@ -47,6 +56,7 @@ import de.thomaskrille.dropwizard_template_config.TemplateConfigBundleConfigurat import io.dropwizard.Application; import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.Authorizer; +import io.dropwizard.forms.MultiPartBundle; import io.dropwizard.jersey.setup.JerseyEnvironment; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; @@ -66,16 +76,17 @@ public class ProvisioningServiceApplication extends Application<ProvisioningServ @Override public void initialize(Bootstrap<ProvisioningServiceApplicationConfiguration> bootstrap) { - bootstrap.addBundle(new TemplateConfigBundle( - new TemplateConfigBundleConfiguration().fileIncludePath(ServiceUtils.getConfPath()) - )); - bootstrap.addBundle(new KeycloakBundle<ProvisioningServiceApplicationConfiguration>() { - @Override - protected KeycloakConfiguration getKeycloakConfiguration(ProvisioningServiceApplicationConfiguration configuration) { - return configuration.getKeycloakConfiguration(); - } - - @Override + bootstrap.addBundle(new MultiPartBundle()); + bootstrap.addBundle(new TemplateConfigBundle( + new TemplateConfigBundleConfiguration().fileIncludePath(ServiceUtils.getConfPath()) + )); + bootstrap.addBundle(new KeycloakBundle<ProvisioningServiceApplicationConfiguration>() { + @Override + protected KeycloakConfiguration getKeycloakConfiguration(ProvisioningServiceApplicationConfiguration configuration) { + return configuration.getKeycloakConfiguration(); + } + + @Override protected Class<? extends Principal> getUserClass() { return UserInfo.class; } @@ -145,5 +156,6 @@ public class ProvisioningServiceApplication extends Application<ProvisioningServ jersey.register(injector.getInstance(CallbackHandlerResource.class)); jersey.register(injector.getInstance(ProjectResource.class)); jersey.register(injector.getInstance(ProvisioningHealthCheckResource.class)); + environment.jersey().register(injector.getInstance(BucketResource.class)); } } diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/GcpProvisioningModule.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/GcpProvisioningModule.java index 4553592..1365c33 100644 --- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/GcpProvisioningModule.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/GcpProvisioningModule.java @@ -19,6 +19,7 @@ package com.epam.dlab.backendapi.modules; +import com.epam.dlab.backendapi.resources.BucketResource; import com.epam.dlab.backendapi.resources.gcp.ComputationalResourceGcp; import com.epam.dlab.backendapi.resources.gcp.EdgeResourceGcp; import com.epam.dlab.backendapi.resources.gcp.ExploratoryResourceGcp; diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java index 40744fa..d01ebc5 100644 --- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java @@ -27,12 +27,15 @@ import com.epam.dlab.backendapi.core.commands.CommandExecutor; 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.BucketService; import com.epam.dlab.backendapi.service.CheckInactivityService; import com.epam.dlab.backendapi.service.ProjectService; import com.epam.dlab.backendapi.service.RestoreCallbackHandlerService; 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.backendapi.service.impl.gcp.BucketServiceGcpImpl; +import com.epam.dlab.cloud.CloudProvider; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.rest.client.RESTService; import com.fasterxml.jackson.core.JsonParser; @@ -64,14 +67,17 @@ public class ProductionModule extends ModuleBase<ProvisioningServiceApplicationC .build(environment, ServiceConsts.SECURITY_SERVICE_NAME, ServiceConsts .PROVISIONING_USER_AGENT)); - bind(RESTService.class).toInstance(configuration.getSelfFactory().build(environment, ServiceConsts - .SELF_SERVICE_NAME)); - bind(MetadataHolder.class).to(DockerWarmuper.class); - bind(ICommandExecutor.class).to(CommandExecutor.class).asEagerSingleton(); - bind(ObjectMapper.class).toInstance(new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true)); - bind(CallbackHandlerDao.class).to(FileSystemCallbackHandlerDao.class); - bind(RestoreCallbackHandlerService.class).to(RestoreCallbackHandlerServiceImpl.class); - bind(CheckInactivityService.class).to(CheckInactivityServiceImpl.class); - bind(ProjectService.class).to(ProjectServiceImpl.class); - } + bind(RESTService.class).toInstance(configuration.getSelfFactory().build(environment, ServiceConsts + .SELF_SERVICE_NAME)); + bind(MetadataHolder.class).to(DockerWarmuper.class); + bind(ICommandExecutor.class).to(CommandExecutor.class).asEagerSingleton(); + bind(ObjectMapper.class).toInstance(new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true)); + bind(CallbackHandlerDao.class).to(FileSystemCallbackHandlerDao.class); + bind(RestoreCallbackHandlerService.class).to(RestoreCallbackHandlerServiceImpl.class); + bind(CheckInactivityService.class).to(CheckInactivityServiceImpl.class); + bind(ProjectService.class).to(ProjectServiceImpl.class); + if (configuration.getCloudProvider() == CloudProvider.GCP) { + bind(BucketService.class).to(BucketServiceGcpImpl.class); + } + } } 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 73d333f..43685a6 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 @@ -30,13 +30,15 @@ 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.BucketService; import com.epam.dlab.backendapi.service.CheckInactivityService; +import com.epam.dlab.backendapi.service.ProjectService; import com.epam.dlab.backendapi.service.RestoreCallbackHandlerService; 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.backendapi.service.impl.gcp.BucketServiceGcpImpl; +import com.epam.dlab.cloud.CloudProvider; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.rest.client.RESTService; import com.epam.dlab.rest.contracts.DockerAPI; @@ -70,17 +72,20 @@ public class ProvisioningDevModule extends ModuleBase<ProvisioningServiceApplica protected void configure() { bind(ProvisioningServiceApplicationConfiguration.class).toInstance(configuration); bind(RESTService.class).annotatedWith(Names.named(ServiceConsts.SECURITY_SERVICE_NAME)).toInstance - (createAuthenticationService()); - bind(RESTService.class).toInstance(configuration.getSelfFactory().build(environment, ServiceConsts - .SELF_SERVICE_NAME)); - bind(MetadataHolder.class).to(DockerWarmuper.class); - bind(ICommandExecutor.class).toInstance(new CommandExecutorMock(configuration.getCloudProvider())); - bind(ObjectMapper.class).toInstance(new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true)); - bind(CallbackHandlerDao.class).to(FileSystemCallbackHandlerDao.class); - bind(RestoreCallbackHandlerService.class).to(RestoreCallbackHandlerServiceImpl.class); - bind(CheckInactivityService.class).to(CheckInactivityServiceImpl.class); - bind(ProjectService.class).to(ProjectServiceImpl.class); - } + (createAuthenticationService()); + bind(RESTService.class).toInstance(configuration.getSelfFactory().build(environment, ServiceConsts + .SELF_SERVICE_NAME)); + bind(MetadataHolder.class).to(DockerWarmuper.class); + bind(ICommandExecutor.class).toInstance(new CommandExecutorMock(configuration.getCloudProvider())); + bind(ObjectMapper.class).toInstance(new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true)); + bind(CallbackHandlerDao.class).to(FileSystemCallbackHandlerDao.class); + bind(RestoreCallbackHandlerService.class).to(RestoreCallbackHandlerServiceImpl.class); + bind(CheckInactivityService.class).to(CheckInactivityServiceImpl.class); + bind(ProjectService.class).to(ProjectServiceImpl.class); + if (configuration.getCloudProvider() == CloudProvider.GCP) { + bind(BucketService.class).to(BucketServiceGcpImpl.class); + } + } /** * Creates and returns the mock object for authentication service. diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java new file mode 100644 index 0000000..7859a0a --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.epam.dlab.backendapi.resources; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.service.BucketService; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import com.google.inject.Inject; +import io.dropwizard.auth.Auth; +import lombok.extern.slf4j.Slf4j; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; + +@Slf4j +@Path("/bucket") +public class BucketResource { + private final BucketService bucketService; + + @Inject + public BucketResource(BucketService bucketService) { + this.bucketService = bucketService; + } + + @GET + @Path("/{bucket}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getListOfObjects(@Auth UserInfo userInfo, + @PathParam("bucket") String bucket) { + return Response.ok(bucketService.getObjects(bucket)).build(); + } + + @POST + @Path("/upload") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + public Response uploadObject(@Auth UserInfo userInfo, + @FormDataParam("object") String object, + @FormDataParam("bucket") String bucket, + @FormDataParam("file") InputStream inputStream, + @FormDataParam("file") FormDataContentDisposition fileMetaData) { + bucketService.uploadObject(bucket, object, inputStream); + return Response.ok().build(); + } + + @GET + @Path("/{bucket}/object/{object}/download") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response downloadObject(@Auth UserInfo userInfo, + @PathParam("object") String object, + @PathParam("bucket") String bucket) { + return Response.ok(bucketService.downloadObject(bucket, object)).build(); + } + + @DELETE + @Path("/{bucket}/object/{object}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response uploadObject(@Auth UserInfo userInfo, + @PathParam("bucket") String bucket, + @PathParam("object") String object) { + bucketService.deleteObject(bucket, object); + return Response.ok().build(); + } + + public static void main(String[] args) { + Storage storage = StorageOptions.getDefaultInstance().getService(); + String bucketName = "ofuks-1304-prj1-local-bucket"; + storage.delete(bucketName, "1.txt"); + } +} diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java similarity index 61% copy from services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java copy to services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java index d376665..772fd0d 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java @@ -17,16 +17,19 @@ * under the License. */ -package com.epam.dlab.constants; +package com.epam.dlab.backendapi.service; -public final class ServiceConsts { - public static final String MONGO_NAME = "mongo"; - public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; - public static final String MAVEN_SEARCH_API = "mavenSearchService"; - public static final String SECURITY_SERVICE_NAME = "securityService"; - public static final String SELF_SERVICE_NAME = "selfService"; - public static final String PROVISIONING_USER_AGENT = "provisioning-service"; +import com.epam.dlab.dto.bucket.BucketDTO; - private ServiceConsts() { - } +import java.io.InputStream; +import java.util.List; + +public interface BucketService { + List<BucketDTO> getObjects(String bucket); + + void uploadObject(String bucket, String object, InputStream stream); + + byte[] downloadObject(String bucket, String object); + + void deleteObject(String bucket, String object); } diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java new file mode 100644 index 0000000..6bc0a8d --- /dev/null +++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.epam.dlab.backendapi.service.impl.gcp; + +import com.epam.dlab.backendapi.service.BucketService; +import com.epam.dlab.dto.bucket.BucketDTO; +import com.epam.dlab.exceptions.DlabException; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +@Slf4j +public class BucketServiceGcpImpl implements BucketService { + + @Override + public List<BucketDTO> getObjects(String bucket) { + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + Bucket gcpBucket = storage.get(bucket); + return StreamSupport.stream(gcpBucket.list().getValues().spliterator(), false) + .map(this::toBucketDTO) + .collect(Collectors.toList()); + } catch (Exception e) { + log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage()); + throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage())); + } + } + + @Override + public void uploadObject(String bucket, String object, InputStream stream) { + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + BlobId blobId = BlobId.of(bucket, object); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build(); + storage.create(blobInfo, IOUtils.toByteArray(stream)); + } catch (Exception e) { + log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage()); + throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage())); + } + } + + @Override + public byte[] downloadObject(String bucket, String object) { + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + Blob blob = storage.get(BlobId.of(bucket, object)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + blob.downloadTo(outputStream); //todo add check for blob != null and throw exception + return outputStream.toByteArray(); + } catch (Exception e) { + log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage()); + throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage())); + } + } + + @Override + public void deleteObject(String bucket, String object) { + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + storage.delete(bucket, object); + } catch (Exception e) { + log.error("Cannot delete object {} from bucket {}. Reason: {}", object, bucket, e.getMessage()); + throw new DlabException(String.format("Cannot delete object %s from bucket %s. Reason: %s", object, bucket, e.getMessage())); + } + } + + private BucketDTO toBucketDTO(BlobInfo blobInfo) { + final String size = FileUtils.byteCountToDisplaySize(blobInfo.getSize()); + Date date = new Date(blobInfo.getCreateTime()); + SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss"); + return BucketDTO.builder() + .bucket(blobInfo.getBucket()) + .object(blobInfo.getName()) + .size(size) + .creationDate(formatter.format(date)) + .build(); + } +} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java index 7ea2739..c4c771d 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java @@ -28,6 +28,7 @@ import com.epam.dlab.backendapi.dao.azure.AzureBillingDAO; import com.epam.dlab.backendapi.dao.gcp.GcpBillingDao; import com.epam.dlab.backendapi.interceptor.BudgetLimitInterceptor; import com.epam.dlab.backendapi.resources.BillingResource; +import com.epam.dlab.backendapi.resources.BucketResource; import com.epam.dlab.backendapi.resources.aws.ComputationalResourceAws; import com.epam.dlab.backendapi.resources.azure.ComputationalResourceAzure; import com.epam.dlab.backendapi.resources.gcp.ComputationalResourceGcp; @@ -85,6 +86,7 @@ public class CloudProviderModule extends CloudModule { environment.jersey().register(injector.getInstance(ComputationalResourceAws.class)); environment.jersey().register(injector.getInstance(ComputationalResourceAzure.class)); environment.jersey().register(injector.getInstance(ComputationalResourceGcp.class)); + environment.jersey().register(injector.getInstance(BucketResource.class)); if (injector.getInstance(SelfServiceApplicationConfiguration.class).isGcpOuauth2AuthenticationEnabled()) { environment.jersey().register(injector.getInstance(GcpOauthResource.class)); } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java index cf08d12..f8de46d 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java @@ -23,9 +23,66 @@ import com.epam.dlab.ModuleBase; import com.epam.dlab.auth.contract.SecurityAPI; import com.epam.dlab.backendapi.auth.SelfServiceSecurityAuthorizer; import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.backendapi.dao.*; -import com.epam.dlab.backendapi.service.*; -import com.epam.dlab.backendapi.service.impl.*; +import com.epam.dlab.backendapi.dao.BackupDao; +import com.epam.dlab.backendapi.dao.BackupDaoImpl; +import com.epam.dlab.backendapi.dao.EndpointDAO; +import com.epam.dlab.backendapi.dao.EndpointDAOImpl; +import com.epam.dlab.backendapi.dao.ImageExploratoryDao; +import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl; +import com.epam.dlab.backendapi.dao.ProjectDAO; +import com.epam.dlab.backendapi.dao.ProjectDAOImpl; +import com.epam.dlab.backendapi.dao.UserGroupDao; +import com.epam.dlab.backendapi.dao.UserGroupDaoImpl; +import com.epam.dlab.backendapi.dao.UserRoleDao; +import com.epam.dlab.backendapi.dao.UserRoleDaoImpl; +import com.epam.dlab.backendapi.service.AccessKeyService; +import com.epam.dlab.backendapi.service.ApplicationSettingService; +import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl; +import com.epam.dlab.backendapi.service.BackupService; +import com.epam.dlab.backendapi.service.BucketService; +import com.epam.dlab.backendapi.service.ComputationalService; +import com.epam.dlab.backendapi.service.EndpointService; +import com.epam.dlab.backendapi.service.EnvironmentService; +import com.epam.dlab.backendapi.service.ExploratoryService; +import com.epam.dlab.backendapi.service.ExternalLibraryService; +import com.epam.dlab.backendapi.service.GitCredentialService; +import com.epam.dlab.backendapi.service.GuacamoleService; +import com.epam.dlab.backendapi.service.ImageExploratoryService; +import com.epam.dlab.backendapi.service.InactivityService; +import com.epam.dlab.backendapi.service.KeycloakService; +import com.epam.dlab.backendapi.service.KeycloakServiceImpl; +import com.epam.dlab.backendapi.service.LibraryService; +import com.epam.dlab.backendapi.service.ProjectService; +import com.epam.dlab.backendapi.service.ReuploadKeyService; +import com.epam.dlab.backendapi.service.SchedulerJobService; +import com.epam.dlab.backendapi.service.SecurityService; +import com.epam.dlab.backendapi.service.SecurityServiceImpl; +import com.epam.dlab.backendapi.service.SystemInfoService; +import com.epam.dlab.backendapi.service.TagService; +import com.epam.dlab.backendapi.service.TagServiceImpl; +import com.epam.dlab.backendapi.service.UserGroupService; +import com.epam.dlab.backendapi.service.UserRoleService; +import com.epam.dlab.backendapi.service.UserRoleServiceImpl; +import com.epam.dlab.backendapi.service.UserSettingService; +import com.epam.dlab.backendapi.service.UserSettingServiceImpl; +import com.epam.dlab.backendapi.service.impl.AccessKeyServiceImpl; +import com.epam.dlab.backendapi.service.impl.BackupServiceImpl; +import com.epam.dlab.backendapi.service.impl.BucketServiceImpl; +import com.epam.dlab.backendapi.service.impl.ComputationalServiceImpl; +import com.epam.dlab.backendapi.service.impl.EndpointServiceImpl; +import com.epam.dlab.backendapi.service.impl.EnvironmentServiceImpl; +import com.epam.dlab.backendapi.service.impl.ExploratoryServiceImpl; +import com.epam.dlab.backendapi.service.impl.GitCredentialServiceImpl; +import com.epam.dlab.backendapi.service.impl.GuacamoleServiceImpl; +import com.epam.dlab.backendapi.service.impl.ImageExploratoryServiceImpl; +import com.epam.dlab.backendapi.service.impl.InactivityServiceImpl; +import com.epam.dlab.backendapi.service.impl.LibraryServiceImpl; +import com.epam.dlab.backendapi.service.impl.MavenCentralLibraryService; +import com.epam.dlab.backendapi.service.impl.ProjectServiceImpl; +import com.epam.dlab.backendapi.service.impl.ReuploadKeyServiceImpl; +import com.epam.dlab.backendapi.service.impl.SchedulerJobServiceImpl; +import com.epam.dlab.backendapi.service.impl.SystemInfoServiceImpl; +import com.epam.dlab.backendapi.service.impl.UserGroupServiceImpl; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.mongo.MongoService; import com.epam.dlab.rest.client.RESTService; @@ -75,6 +132,9 @@ public class DevModule extends ModuleBase<SelfServiceApplicationConfiguration> i bind(RESTService.class).annotatedWith(Names.named(ServiceConsts.PROVISIONING_SERVICE_NAME)) .toInstance(configuration.getProvisioningFactory() .build(environment, ServiceConsts.PROVISIONING_SERVICE_NAME)); + bind(RESTService.class).annotatedWith(Names.named(ServiceConsts.BUCKET_SERVICE_NAME)) + .toInstance(configuration.getBucketFactory() + .build(environment, ServiceConsts.BUCKET_SERVICE_NAME)); bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class); bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class); bind(BackupService.class).to(BackupServiceImpl.class); @@ -96,17 +156,18 @@ public class DevModule extends ModuleBase<SelfServiceApplicationConfiguration> i bind(ExternalLibraryService.class).to(MavenCentralLibraryService.class); bind(SystemInfoService.class).to(SystemInfoServiceImpl.class); bind(UserGroupService.class).to(UserGroupServiceImpl.class); - bind(UserRoleService.class).to(UserRoleServiceImpl.class); - bind(UserRoleDao.class).to(UserRoleDaoImpl.class); - bind(UserGroupDao.class).to(UserGroupDaoImpl.class); - bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class); - bind(UserSettingService.class).to(UserSettingServiceImpl.class); - bind(GuacamoleService.class).to(GuacamoleServiceImpl.class); - bind(EndpointService.class).to(EndpointServiceImpl.class); - bind(EndpointDAO.class).to(EndpointDAOImpl.class); - bind(ProjectService.class).to(ProjectServiceImpl.class); - bind(ProjectDAO.class).to(ProjectDAOImpl.class); - } + bind(UserRoleService.class).to(UserRoleServiceImpl.class); + bind(UserRoleDao.class).to(UserRoleDaoImpl.class); + bind(UserGroupDao.class).to(UserGroupDaoImpl.class); + bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class); + bind(UserSettingService.class).to(UserSettingServiceImpl.class); + bind(GuacamoleService.class).to(GuacamoleServiceImpl.class); + bind(EndpointService.class).to(EndpointServiceImpl.class); + bind(EndpointDAO.class).to(EndpointDAOImpl.class); + bind(ProjectService.class).to(ProjectServiceImpl.class); + bind(ProjectDAO.class).to(ProjectDAOImpl.class); + bind(BucketService.class).to(BucketServiceImpl.class); + } private void configureCors(Environment environment) { final FilterRegistration.Dynamic cors = diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java index 0d0ae1d..6896ee7 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java @@ -20,11 +20,68 @@ package com.epam.dlab.backendapi.modules; import com.epam.dlab.ModuleBase; -import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; import com.epam.dlab.backendapi.auth.SelfServiceSecurityAuthorizer; -import com.epam.dlab.backendapi.dao.*; -import com.epam.dlab.backendapi.service.*; -import com.epam.dlab.backendapi.service.impl.*; +import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; +import com.epam.dlab.backendapi.dao.BackupDao; +import com.epam.dlab.backendapi.dao.BackupDaoImpl; +import com.epam.dlab.backendapi.dao.EndpointDAO; +import com.epam.dlab.backendapi.dao.EndpointDAOImpl; +import com.epam.dlab.backendapi.dao.ImageExploratoryDao; +import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl; +import com.epam.dlab.backendapi.dao.ProjectDAO; +import com.epam.dlab.backendapi.dao.ProjectDAOImpl; +import com.epam.dlab.backendapi.dao.UserGroupDao; +import com.epam.dlab.backendapi.dao.UserGroupDaoImpl; +import com.epam.dlab.backendapi.dao.UserRoleDao; +import com.epam.dlab.backendapi.dao.UserRoleDaoImpl; +import com.epam.dlab.backendapi.service.AccessKeyService; +import com.epam.dlab.backendapi.service.ApplicationSettingService; +import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl; +import com.epam.dlab.backendapi.service.BackupService; +import com.epam.dlab.backendapi.service.BucketService; +import com.epam.dlab.backendapi.service.ComputationalService; +import com.epam.dlab.backendapi.service.EndpointService; +import com.epam.dlab.backendapi.service.EnvironmentService; +import com.epam.dlab.backendapi.service.ExploratoryService; +import com.epam.dlab.backendapi.service.ExternalLibraryService; +import com.epam.dlab.backendapi.service.GitCredentialService; +import com.epam.dlab.backendapi.service.GuacamoleService; +import com.epam.dlab.backendapi.service.ImageExploratoryService; +import com.epam.dlab.backendapi.service.InactivityService; +import com.epam.dlab.backendapi.service.KeycloakService; +import com.epam.dlab.backendapi.service.KeycloakServiceImpl; +import com.epam.dlab.backendapi.service.LibraryService; +import com.epam.dlab.backendapi.service.ProjectService; +import com.epam.dlab.backendapi.service.ReuploadKeyService; +import com.epam.dlab.backendapi.service.SchedulerJobService; +import com.epam.dlab.backendapi.service.SecurityService; +import com.epam.dlab.backendapi.service.SecurityServiceImpl; +import com.epam.dlab.backendapi.service.SystemInfoService; +import com.epam.dlab.backendapi.service.TagService; +import com.epam.dlab.backendapi.service.TagServiceImpl; +import com.epam.dlab.backendapi.service.UserGroupService; +import com.epam.dlab.backendapi.service.UserRoleService; +import com.epam.dlab.backendapi.service.UserRoleServiceImpl; +import com.epam.dlab.backendapi.service.UserSettingService; +import com.epam.dlab.backendapi.service.UserSettingServiceImpl; +import com.epam.dlab.backendapi.service.impl.AccessKeyServiceImpl; +import com.epam.dlab.backendapi.service.impl.BackupServiceImpl; +import com.epam.dlab.backendapi.service.impl.BucketServiceImpl; +import com.epam.dlab.backendapi.service.impl.ComputationalServiceImpl; +import com.epam.dlab.backendapi.service.impl.EndpointServiceImpl; +import com.epam.dlab.backendapi.service.impl.EnvironmentServiceImpl; +import com.epam.dlab.backendapi.service.impl.ExploratoryServiceImpl; +import com.epam.dlab.backendapi.service.impl.GitCredentialServiceImpl; +import com.epam.dlab.backendapi.service.impl.GuacamoleServiceImpl; +import com.epam.dlab.backendapi.service.impl.ImageExploratoryServiceImpl; +import com.epam.dlab.backendapi.service.impl.InactivityServiceImpl; +import com.epam.dlab.backendapi.service.impl.LibraryServiceImpl; +import com.epam.dlab.backendapi.service.impl.MavenCentralLibraryService; +import com.epam.dlab.backendapi.service.impl.ProjectServiceImpl; +import com.epam.dlab.backendapi.service.impl.ReuploadKeyServiceImpl; +import com.epam.dlab.backendapi.service.impl.SchedulerJobServiceImpl; +import com.epam.dlab.backendapi.service.impl.SystemInfoServiceImpl; +import com.epam.dlab.backendapi.service.impl.UserGroupServiceImpl; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.mongo.MongoService; import com.epam.dlab.rest.client.RESTService; @@ -66,6 +123,9 @@ public class ProductionModule extends ModuleBase<SelfServiceApplicationConfigura bind(RESTService.class).annotatedWith(Names.named(ServiceConsts.PROVISIONING_SERVICE_NAME)) .toInstance(configuration.getProvisioningFactory().build(environment, ServiceConsts .PROVISIONING_SERVICE_NAME)); + bind(RESTService.class).annotatedWith(Names.named(ServiceConsts.BUCKET_SERVICE_NAME)) + .toInstance(configuration.getBucketFactory().build(environment, ServiceConsts + .BUCKET_SERVICE_NAME)); bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class); bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class); bind(BackupService.class).to(BackupServiceImpl.class); @@ -88,16 +148,17 @@ public class ProductionModule extends ModuleBase<SelfServiceApplicationConfigura bind(UserRoleDao.class).to(UserRoleDaoImpl.class); bind(UserGroupDao.class).to(UserGroupDaoImpl.class); bind(InactivityService.class).to(InactivityServiceImpl.class); - bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class); - bind(UserSettingService.class).to(UserSettingServiceImpl.class); - bind(GuacamoleService.class).to(GuacamoleServiceImpl.class); - bind(EndpointService.class).to(EndpointServiceImpl.class); - bind(EndpointDAO.class).to(EndpointDAOImpl.class); - bind(ProjectService.class).to(ProjectServiceImpl.class); - bind(ProjectDAO.class).to(ProjectDAOImpl.class); - bind(TagService.class).to(TagServiceImpl.class); - bind(SecurityService.class).to(SecurityServiceImpl.class); - bind(KeycloakService.class).to(KeycloakServiceImpl.class); - bind(Client.class).toInstance(httpClient); - } + bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class); + bind(UserSettingService.class).to(UserSettingServiceImpl.class); + bind(GuacamoleService.class).to(GuacamoleServiceImpl.class); + bind(EndpointService.class).to(EndpointServiceImpl.class); + bind(EndpointDAO.class).to(EndpointDAOImpl.class); + bind(ProjectService.class).to(ProjectServiceImpl.class); + bind(ProjectDAO.class).to(ProjectDAOImpl.class); + bind(TagService.class).to(TagServiceImpl.class); + bind(SecurityService.class).to(SecurityServiceImpl.class); + bind(KeycloakService.class).to(KeycloakServiceImpl.class); + bind(BucketService.class).to(BucketServiceImpl.class); + bind(Client.class).toInstance(httpClient); + } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java new file mode 100644 index 0000000..a98daa2 --- /dev/null +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BucketResource.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.epam.dlab.backendapi.resources; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.service.BucketService; +import com.google.inject.Inject; +import io.dropwizard.auth.Auth; +import lombok.extern.slf4j.Slf4j; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; +import java.nio.file.Paths; + +@Path("/bucket") +@Slf4j +public class BucketResource { + private final BucketService bucketService; + + @Inject + public BucketResource(BucketService bucketService) { + this.bucketService = bucketService; + } + + @GET + @Path("/{bucket}/endpoint/{endpoint}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getListOfObjects(@Auth UserInfo userInfo, + @PathParam("bucket") String bucket, + @PathParam("endpoint") String endpoint) { + return Response.ok(bucketService.getObjects(userInfo, bucket, endpoint)).build(); + } + + @POST + @Path("/upload") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + public Response uploadObject(@Auth UserInfo userInfo, + @FormDataParam("object") String object, + @FormDataParam("bucket") String bucket, + @FormDataParam("endpoint") String endpoint, + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition fileMetaData) { + bucketService.uploadObjects(userInfo, bucket, object, endpoint, fileInputStream); + return Response.ok().build(); + } + + @GET + @Path("/{bucket}/object/{object}/endpoint/{endpoint}/download") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response downloadObject(@Auth UserInfo userInfo, + @PathParam("bucket") String bucket, + @PathParam("object") String object, + @PathParam("endpoint") String endpoint) { + return Response.ok(bucketService.downloadObject(userInfo, bucket, object, endpoint)) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + Paths.get(object).getFileName() + "\"") + .build(); + } + + @DELETE + @Path("/{bucket}/object/{object}/endpoint/{endpoint}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteObject(@Auth UserInfo userInfo, + @PathParam("bucket") String bucket, + @PathParam("object") String object, + @PathParam("endpoint") String endpoint) { + bucketService.deleteObject(userInfo, bucket, object, endpoint); + return Response.ok().build(); + } +} diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/BucketDownloadDTO.java similarity index 61% copy from services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java copy to services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/BucketDownloadDTO.java index d376665..eb26202 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/BucketDownloadDTO.java @@ -17,16 +17,19 @@ * under the License. */ -package com.epam.dlab.constants; +package com.epam.dlab.backendapi.resources.dto; -public final class ServiceConsts { - public static final String MONGO_NAME = "mongo"; - public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; - public static final String MAVEN_SEARCH_API = "mavenSearchService"; - public static final String SECURITY_SERVICE_NAME = "securityService"; - public static final String SELF_SERVICE_NAME = "selfService"; - public static final String PROVISIONING_USER_AGENT = "provisioning-service"; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import org.hibernate.validator.constraints.NotBlank; - private ServiceConsts() { - } +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class BucketDownloadDTO { + @NotBlank(message = "field cannot be empty") + private final String bucket; + @NotBlank(message = "field cannot be empty") + private final String object; + @NotBlank(message = "field cannot be empty") + private final String endpoint; } diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java similarity index 57% copy from services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java copy to services/self-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java index d376665..0377969 100644 --- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/constants/ServiceConsts.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BucketService.java @@ -17,16 +17,20 @@ * under the License. */ -package com.epam.dlab.constants; +package com.epam.dlab.backendapi.service; -public final class ServiceConsts { - public static final String MONGO_NAME = "mongo"; - public static final String PROVISIONING_SERVICE_NAME = "provisioningService"; - public static final String MAVEN_SEARCH_API = "mavenSearchService"; - public static final String SECURITY_SERVICE_NAME = "securityService"; - public static final String SELF_SERVICE_NAME = "selfService"; - public static final String PROVISIONING_USER_AGENT = "provisioning-service"; +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.dto.bucket.BucketDTO; - private ServiceConsts() { - } +import java.io.InputStream; +import java.util.List; + +public interface BucketService { + List<BucketDTO> getObjects(UserInfo userInfo, String bucket, String endpoint); + + void uploadObjects(UserInfo userInfo, String bucket, String object, String endpoint, InputStream inputStream); + + byte[] downloadObject(UserInfo userInfo, String bucket, String object, String endpoint); + + void deleteObject(UserInfo userInfo, String bucket, String object, String endpoint); } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java new file mode 100644 index 0000000..ce72a6f --- /dev/null +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.epam.dlab.backendapi.service.impl; + +import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.domain.EndpointDTO; +import com.epam.dlab.backendapi.service.BucketService; +import com.epam.dlab.backendapi.service.EndpointService; +import com.epam.dlab.constants.ServiceConsts; +import com.epam.dlab.dto.bucket.BucketDTO; +import com.epam.dlab.exceptions.DlabException; +import com.epam.dlab.rest.client.RESTService; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpStatus; +import org.glassfish.jersey.media.multipart.FormDataMultiPart; + +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; + +@Slf4j +public class BucketServiceImpl implements BucketService { + private static final String BUCKET_GET_OBJECTS = "%sbucket/%s"; + private static final String BUCKET_UPLOAD_OBJECT = "%sbucket/upload"; + private static final String BUCKET_DOWNLOAD_OBJECT = "%sbucket/%s/object/%s/download"; + private static final String BUCKET_DELETE_OBJECT = "%sbucket/%s/object/%s"; + + private final EndpointService endpointService; + private final RESTService provisioningService; + + @Inject + public BucketServiceImpl(EndpointService endpointService, @Named(ServiceConsts.BUCKET_SERVICE_NAME) RESTService provisioningService) { + this.endpointService = endpointService; + this.provisioningService = provisioningService; + } + + @Override + public List<BucketDTO> getObjects(UserInfo userInfo, String bucket, String endpoint) { + try { + EndpointDTO endpointDTO = endpointService.get(endpoint); + return provisioningService.get(String.format(BUCKET_GET_OBJECTS, endpointDTO.getUrl(), bucket), userInfo.getAccessToken(), new GenericType<List<BucketDTO>>() { + }); + } catch (Exception e) { + log.error("Cannot get objects from bucket {} for user {}, endpoint {}. Reason {}", bucket, userInfo.getName(), endpoint, e.getMessage()); + throw new DlabException(String.format("Cannot get objects from bucket %s for user %s, endpoint %s. Reason %s", bucket, userInfo.getName(), endpoint, e.getMessage())); + } + } + + @Override + public void uploadObjects(UserInfo userInfo, String bucket, String object, String endpoint, InputStream inputStream) { + try { + EndpointDTO endpointDTO = endpointService.get(endpoint); + FormDataMultiPart formData = getFormDataMultiPart(bucket, object, inputStream); + Response response = provisioningService.postForm(String.format(BUCKET_UPLOAD_OBJECT, endpointDTO.getUrl()), userInfo.getAccessToken(), formData, Response.class); + if (response.getStatus() != HttpStatus.SC_OK) { + throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus())); + } + } catch (Exception e) { + log.error("Cannot upload object {} to bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage()); + throw new DlabException(String.format("Cannot upload object %s to bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage())); + } + } + + @Override + public byte[] downloadObject(UserInfo userInfo, String bucket, String object, String endpoint) { + try { + EndpointDTO endpointDTO = endpointService.get(endpoint); + return provisioningService.getWithMediaTypes(String.format(BUCKET_DOWNLOAD_OBJECT, endpointDTO.getUrl(), bucket, encodeObject(object)), userInfo.getAccessToken(), byte[].class, + APPLICATION_JSON, APPLICATION_OCTET_STREAM); + } catch (Exception e) { + log.error("Cannot upload object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage()); + throw new DlabException(String.format("Cannot download object %s from bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage())); + } + } + + @Override + public void deleteObject(UserInfo userInfo, String bucket, String object, String endpoint) { + try { + EndpointDTO endpointDTO = endpointService.get(endpoint); + Response response = provisioningService.delete(String.format(BUCKET_DELETE_OBJECT, endpointDTO.getUrl(), bucket, encodeObject(object)), userInfo.getAccessToken(), Response.class, + APPLICATION_JSON, APPLICATION_JSON); + if (response.getStatus() != HttpStatus.SC_OK) { + throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus())); + } + } catch (Exception e) { + log.error("Cannot delete object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage()); + throw new DlabException(String.format("Cannot delete object %s from bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage())); + } + } + + private String encodeObject(String object) throws UnsupportedEncodingException { + return URLEncoder.encode(object, StandardCharsets.UTF_8.toString()); + } + + private FormDataMultiPart getFormDataMultiPart(String bucket, String object, InputStream inputStream) { + FormDataMultiPart formData = new FormDataMultiPart(); + formData.field("file", inputStream, MediaType.valueOf(APPLICATION_OCTET_STREAM)); + formData.field("bucket", bucket); + formData.field("object", object); + return formData; + } +} 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 e53b78c..97079e3 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 @@ -41,11 +41,23 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.lang.reflect.Field; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class InfrastructureTemplateServiceBaseTest { @@ -89,7 +101,7 @@ public class InfrastructureTemplateServiceBaseTest { emDto2.setExploratoryEnvironmentShapes(shapes2); List<ExploratoryMetadataDTO> expectedEmdDtoList = Arrays.asList(emDto1, emDto2); when(userGroupDao.getUserGroups(anyString())).thenReturn(Collections.emptySet()); - when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedEmdDtoList.toArray()); + when(provisioningService.get(anyString(), anyString(), any(Class.class))).thenReturn(expectedEmdDtoList.toArray()); when(settingsDAO.getConfOsFamily()).thenReturn("someConfOsFamily"); UserInfo userInfo = new UserInfo("test", "token"); @@ -108,7 +120,7 @@ public class InfrastructureTemplateServiceBaseTest { public void getExploratoryTemplatesWithException() { when(endpointService.get(anyString())).thenReturn(endpointDTO()); doThrow(new DlabException("Could not load list of exploratory templates for user")) - .when(provisioningService).get(anyString(), anyString(), any()); + .when(provisioningService).get(anyString(), anyString(), any(Class.class)); UserInfo userInfo = new UserInfo("test", "token"); try { @@ -131,7 +143,7 @@ public class InfrastructureTemplateServiceBaseTest { ); when(projectDAO.get(anyString())).thenReturn(Optional.of(new ProjectDTO("project", Collections.emptySet(), null, null, null, null, true))); - when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); + when(provisioningService.get(anyString(), anyString(), any(Class.class))).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); List<FullComputationalTemplate> expectedFullCmdDtoList = expectedCmdDtoList.stream() .map(e -> infrastructureTemplateServiceBaseChild.getCloudFullComputationalTemplate(e)) @@ -154,7 +166,7 @@ public class InfrastructureTemplateServiceBaseTest { public void getComputationalTemplatesWhenMethodThrowsException() { when(endpointService.get(anyString())).thenReturn(endpointDTO()); doThrow(new DlabException("Could not load list of computational templates for user")) - .when(provisioningService).get(anyString(), anyString(), any()); + .when(provisioningService).get(anyString(), anyString(), any(Class.class)); UserInfo userInfo = new UserInfo("test", "token"); try { @@ -173,7 +185,7 @@ public class InfrastructureTemplateServiceBaseTest { final ComputationalMetadataDTO computationalMetadataDTO = new ComputationalMetadataDTO("dataengine-service"); computationalMetadataDTO.setComputationResourceShapes(Collections.emptyMap()); List<ComputationalMetadataDTO> expectedCmdDtoList = Collections.singletonList(computationalMetadataDTO); - when(provisioningService.get(anyString(), anyString(), any())).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); + when(provisioningService.get(anyString(), anyString(), any(Class.class))).thenReturn(expectedCmdDtoList.toArray(new ComputationalMetadataDTO[]{})); when(projectDAO.get(anyString())).thenReturn(Optional.of(new ProjectDTO("project", Collections.emptySet(), null, null, null, null, true))); when(configuration.getMinEmrInstanceCount()).thenReturn(1); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org