diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index 13fc6577970ede925089895265e8a3f6b0a409ae..4e723b8a3b27ed8f420e8b7f6293277ad17194f0 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -2,7 +2,7 @@ # See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html spring: - portalDatasource: + portal-datasource: url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://172.22.0.1:5432/portal" }} schema: {{ default .Env.PORTAL_DB_SCHEMA "public" }} username: {{ default .Env.PORTAL_DB_USER "postgres" }} @@ -16,6 +16,8 @@ spring: jpa: hibernate: dialect: org.hibernate.dialect.PostgreSQL9Dialect + ddl-auto: validate + # SPRING RESOURCES HANDLING resources: chain: diff --git a/pom.xml b/pom.xml index 2caa3f34994694784cfff87419af578ebb9786e0..02129ae2b41f261b610ddea13d43a978d895141c 100644 --- a/pom.xml +++ b/pom.xml @@ -14,9 +14,7 @@ <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>1.3.8.RELEASE</version> - <relativePath/> - + <version>2.3.5.RELEASE</version> </parent> <properties> @@ -25,16 +23,18 @@ <sonar.projectName>MIP portal-backend</sonar.projectName> <sonar.sources>src/main/java/</sonar.sources> <java.version>1.8</java.version> + <springfox-swagger.version>2.5.0</springfox-swagger.version> + <spring-context.version>5.2.10.RELEASE</spring-context.version> + <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version> <asciidoctor.maven.plugin.version>1.5.5</asciidoctor.maven.plugin.version> <asciidoctorj.pdf.version>1.5.0-alpha.15</asciidoctorj.pdf.version> <asciidoctorj.version>1.5.5</asciidoctorj.version> - <spring-data-commons.version>1.12.3.RELEASE</spring-data-commons.version> <angularjs.version>1.5.7</angularjs.version> <jquery.version>3.0.0</jquery.version> <bootstrap.version>3.3.7</bootstrap.version> + <webjars-locator.version>0.36</webjars-locator.version> <h2.version>1.4.192</h2.version> <postgresql.version>42.2.1</postgresql.version> - <springfox-swagger.version>2.5.0</springfox-swagger.version> <gson.version>2.7</gson.version> <slugify.version>2.1.5</slugify.version> <maven-resources-plugin.version>3.0.1</maven-resources-plugin.version> @@ -42,15 +42,12 @@ <swagger2markup-maven-plugin.version>1.0.0</swagger2markup-maven-plugin.version> <maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version> <hibernate4-maven-plugin.version>1.1.1</hibernate4-maven-plugin.version> + <commons-dbcp.version>2.7.0</commons-dbcp.version> <flyway-core.version>4.2.0</flyway-core.version> <hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version> - <hibernate.version>4.3.11.Final</hibernate.version> - <spring-data-jpa.version>1.10.11.RELEASE</spring-data-jpa.version> - <spring-boot-starter-actuator.version>1.4.7.RELEASE</spring-boot-starter-actuator.version> + <hibernate.version>5.4.10.Final</hibernate.version> <aspectjweaver.version>1.8.9</aspectjweaver.version> <javax-inject.version>1</javax-inject.version> - <akka.version>2.5.22</akka.version> - <spring-context.version>4.3.4.RELEASE</spring-context.version> <protobuf-java.version>3.1.0</protobuf-java.version> </properties> @@ -66,32 +63,39 @@ </repositories> <dependencies> - + <dependency> + <groupId>net.logstash.logback</groupId> + <artifactId>logstash-logback-encoder</artifactId> + <version>6.4</version> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> + <dependency> + <groupId>org.springframework.security.oauth.boot</groupId> + <artifactId>spring-security-oauth2-autoconfigure</artifactId> + <version>2.0.1.RELEASE</version> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> - <version>${spring-boot-starter-actuator.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> - <version>${spring-data-commons.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-oauth2-resource-server</artifactId> </dependency> <dependency> - <groupId>org.springframework.security.oauth</groupId> - <artifactId>spring-security-oauth2</artifactId> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> @@ -115,6 +119,7 @@ <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> + <version>${webjars-locator.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> @@ -148,13 +153,8 @@ </dependency> <dependency> <groupId>io.springfox</groupId> - <artifactId>springfox-swagger2</artifactId> - <version>${springfox-swagger.version}</version> - </dependency> - <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-swagger-ui</artifactId> - <version>${springfox-swagger.version}</version> + <artifactId>springfox-boot-starter</artifactId> + <version>${springfox-boot-starter.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> @@ -169,11 +169,11 @@ <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> - <version>${spring-data-jpa.version}</version> </dependency> <dependency> - <groupId>commons-dbcp</groupId> - <artifactId>commons-dbcp</artifactId> + <groupId>org.apache.commons</groupId> + <artifactId>commons-dbcp2</artifactId> + <version>${commons-dbcp.version}</version> </dependency> <dependency> <groupId>org.flywaydb</groupId> @@ -192,9 +192,9 @@ <version>${javax-inject.version}</version> </dependency> <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - <version>${spring.version}</version> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring-context.version}</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> @@ -243,6 +243,11 @@ <artifactId>java-jwt</artifactId> <version>3.11.0</version> </dependency> + <dependency> + <groupId>org.springframework.security.oauth</groupId> + <artifactId>spring-security-oauth2</artifactId> + <version>2.5.0.RELEASE</version> + </dependency> </dependencies> <build> diff --git a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java index c8024e1bffa90604da6d13712bc07cbac815b3d7..bca25598a6e59827a6a938e30fc9db1b9b5d5614 100644 --- a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java @@ -1,10 +1,12 @@ package eu.hbp.mip.configuration; import org.flywaydb.core.Flyway; -import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.orm.jpa.EntityScan; -import org.springframework.context.annotation.*; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -18,12 +20,11 @@ import javax.sql.DataSource; @Configuration @EnableJpaRepositories("eu.hbp.mip.repositories") -@EntityScan(basePackages = "eu.hbp.mip.model") public class PersistenceConfiguration { @Primary - @Bean(name = "portalDatasource") - @ConfigurationProperties(prefix = "spring.portalDatasource") + @Bean(name = "portal-datasource") + @ConfigurationProperties(prefix = "spring.portal-datasource") public DataSource portalDataSource() { return DataSourceBuilder.create().build(); } @@ -32,11 +33,12 @@ public class PersistenceConfiguration { @Bean(name = "entityManagerFactory") @DependsOn("flyway") public LocalContainerEntityManagerFactoryBean entityManagerFactory() { - LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(portalDataSource()); + LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); + emfb.setDataSource(portalDataSource()); JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - em.setJpaVendorAdapter(vendorAdapter); - return em; + emfb.setJpaVendorAdapter(vendorAdapter); + emfb.setPackagesToScan("eu.hbp.mip.model.DAOs"); + return emfb; } @Bean(name = "flyway", initMethod = "migrate") diff --git a/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java b/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java deleted file mode 100644 index 352b1d156558ef42b9862b644ed5668070899708..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java +++ /dev/null @@ -1,43 +0,0 @@ -package eu.hbp.mip.configuration; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestAttributes; - -import java.util.HashMap; -import java.util.Map; - -@Component -public class PortalErrorAttributes extends DefaultErrorAttributes { - - private static final Logger LOGGER = LoggerFactory.getLogger(PortalErrorAttributes.class); - - @Override - public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { - Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace); - - Throwable throwable = getError(requestAttributes); - StringBuilder sb = new StringBuilder("["); - for (String attr : requestAttributes.getAttributeNames(RequestAttributes.SCOPE_REQUEST)) { - Object v = requestAttributes.getAttribute(attr, RequestAttributes.SCOPE_REQUEST); - sb.append(attr).append(" = ").append(v).append('\n'); - } - sb.append("]"); - LOGGER.error("Reporting server error on request with attributes " + sb.toString(), throwable); - - if (throwable != null) { - - Throwable cause = throwable.getCause(); - if (cause != null) { - Map<String, Object> causeErrorAttributes = new HashMap<>(); - causeErrorAttributes.put("exception", cause.getClass().getName()); - causeErrorAttributes.put("message", cause.getMessage()); - errorAttributes.put("cause", causeErrorAttributes); - } - } - - return errorAttributes; - } -} diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java index 4ea52570fd3bde8c8b21253fe202aa3fc61363d4..afd3e56ed97164627dd5694e945eed97f18f9aaa 100644 --- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor; import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices; -import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java index a5b514dfb815c9df88c0475b7c3ce24df1f06803..17e38a5eea2931d756375af4420b77953d737f51 100644 --- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java @@ -2,7 +2,6 @@ package eu.hbp.mip.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.data.web.config.EnableSpringDataWebSupport; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; @@ -10,7 +9,6 @@ import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger.web.UiConfiguration; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** @@ -22,10 +20,10 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSpringDataWebSupport public class WebConfiguration { - @Bean - public UiConfiguration swaggerUiConfig() { - return UiConfiguration.DEFAULT; - } +// @Bean +// public String[] swaggerUiConfig() { +// return UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS; +// } @Bean public Docket swaggerDocumentation() { diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index d28d8aac35cf08c7be49f96e64b1bfb5410e2662..c3b93cbe14120208c6fbc40ceab186305028f348 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -1,6 +1,5 @@ package eu.hbp.mip.controllers; -import com.google.gson.Gson; import eu.hbp.mip.model.DTOs.ExperimentDTO; import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.services.ExperimentService; @@ -8,13 +7,10 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; -import java.util.List; - import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; /* @@ -35,8 +31,13 @@ public class ExperimentApi { @ApiOperation(value = "Get experiments", response = ExperimentDTO.class, responseContainer = "List") @RequestMapping(method = RequestMethod.GET) - public ResponseEntity<String> getExperiments() { - return experimentService.getExperiments("(GET) /experiments"); + public ResponseEntity<String> getExperiments( + @RequestParam(name = "name", required = false) String name, + @RequestParam(name = "algorithm", required = false) String algorithm, + @RequestParam(name = "shared", required = false) Boolean shared, + @RequestParam(name = "viewed", required = false) Boolean viewed + ) { + return experimentService.getExperiments(name, algorithm, shared, viewed, "(GET) /experiments"); } @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class) diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java index 4e412aea08da5612f47d60baafd4bac791f2fc6e..ff8d70a80405ad2e7579198c5ef4f8a9a42d38d5 100644 --- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java +++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.gson.JsonObject; import eu.hbp.mip.configuration.SecurityConfiguration; -import eu.hbp.mip.model.User; +import eu.hbp.mip.model.DAOs.UserDAO; import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.repositories.UserRepository; import eu.hbp.mip.utils.Logging; @@ -70,7 +70,7 @@ public class SecurityApi { @RequestMapping(path = "/user", method = RequestMethod.POST) public ResponseEntity<Void> postUser( @ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA") Boolean agreeNDA) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); if (user != null) { user.setAgreeNDA(agreeNDA); userRepository.save(user); diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java index b791a7858e216d8ce0f8cd36610763c5c123e66a..886ad1ac90776e3c8b66025a6f7a22c223eadb6a 100644 --- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java +++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java @@ -4,7 +4,7 @@ package eu.hbp.mip.controllers; -import eu.hbp.mip.model.User; +import eu.hbp.mip.model.DAOs.UserDAO; import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.repositories.UserRepository; import eu.hbp.mip.utils.Logging; @@ -31,13 +31,13 @@ public class UsersApi { @Autowired private UserInfo userInfo; - @ApiOperation(value = "Get a user", response = User.class) + @ApiOperation(value = "Get a user", response = UserDAO.class) @RequestMapping(value = "/{username}", method = RequestMethod.GET) - public ResponseEntity<User> getAUser( + public ResponseEntity<UserDAO> getAUser( @ApiParam(value = "username", required = true) @PathVariable("username") String username ) { Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /users/{username}", "Loaded a user with username : " + userInfo.getUser().getUsername()); - return ResponseEntity.ok(userRepository.findOne(username)); + return ResponseEntity.ok(userRepository.findByUsername(username)); } } diff --git a/src/main/java/eu/hbp/mip/model/Article.java b/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java similarity index 87% rename from src/main/java/eu/hbp/mip/model/Article.java rename to src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java index b79f2a33a8275484a0e9a680a93619dbea2ea5c2..541c50765e25e7ce68504026ed437f906104e2ce 100644 --- a/src/main/java/eu/hbp/mip/model/Article.java +++ b/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java @@ -2,7 +2,7 @@ * Created by mirco on 04.12.15. */ -package eu.hbp.mip.model; +package eu.hbp.mip.model.DAOs; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -13,15 +13,13 @@ import javax.persistence.*; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.Date; -import java.util.LinkedList; -import java.util.List; @Entity @Table(name = "`article`") @ApiModel @JsonInclude(JsonInclude.Include.NON_NULL) @Validated -public class Article { +public class ArticleDAO { @Id private String slug = null; @@ -46,13 +44,13 @@ public class Article { @ManyToOne @JoinColumn(name = "createdby_username") - private User createdBy = null; + private UserDAO createdBy = null; @ManyToOne @JoinColumn(name = "updatedby_username") - private User updatedBy = null; + private UserDAO updatedBy = null; - public Article() { + public ArticleDAO() { /* * Empty constructor is needed by Hibernate */ @@ -133,20 +131,20 @@ public class Article { } - public User getCreatedBy() { + public UserDAO getCreatedBy() { return createdBy; } - public void setCreatedBy(User createdBy) { + public void setCreatedBy(UserDAO createdBy) { this.createdBy = createdBy; } - public User getUpdatedBy() { + public UserDAO getUpdatedBy() { return updatedBy; } - public void setUpdatedBy(User updatedBy) { + public void setUpdatedBy(UserDAO updatedBy) { this.updatedBy = updatedBy; } diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java index 682f121cea95c13bf88c83c71ddcd5815ffe7884..30d6c87da9603b828fd9efe3d4d457800fc576de 100644 --- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java +++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java @@ -1,11 +1,12 @@ package eu.hbp.mip.model.DAOs; +import com.fasterxml.jackson.annotation.JsonInclude; import com.google.gson.Gson; import com.google.gson.annotations.Expose; import eu.hbp.mip.model.DTOs.AlgorithmDTO; import eu.hbp.mip.model.DTOs.ExperimentDTO; -import eu.hbp.mip.model.User; import eu.hbp.mip.utils.JsonConverters; +import io.swagger.annotations.ApiModel; import javax.persistence.*; import java.util.Date; @@ -16,51 +17,62 @@ import java.util.UUID; */ @Entity @Table(name = "`experiment`") +@ApiModel +@JsonInclude(JsonInclude.Include.NON_NULL) public class ExperimentDAO { private static final Gson gson = new Gson(); + @Expose @Id @Column(columnDefinition = "uuid", updatable = false) @org.hibernate.annotations.Type(type = "pg-uuid") - @Expose private UUID uuid; - @Column(columnDefinition = "TEXT") @Expose + @Column(columnDefinition = "TEXT") private String name; @Expose @ManyToOne - @JoinColumn(name = "created_by_username") - private User createdBy; + @JoinColumn(name = "created_by_username",columnDefinition = "CHARACTER VARYING") + private UserDAO createdBy; - @Column(name="workflow_history_id", columnDefinition = "TEXT") @Expose + @Column(name="workflow_history_id", columnDefinition = "TEXT") private String workflowHistoryId; - @Column(columnDefinition = "TEXT") @Expose + @Column(columnDefinition = "TEXT") private Status status; - @Column(columnDefinition = "TEXT") @Expose + @Column(columnDefinition = "TEXT") private String result; @Expose + @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE") private Date finished; @Expose + @Column(columnDefinition = "TEXT") + private String algorithmDetails; + + @Expose + @Column(columnDefinition = "TEXT") private String algorithm; @Expose + @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE") private Date created = new Date(); @Expose + @Column(columnDefinition = "BOOLEAN") private boolean shared = false; // whether or not the experiment's result have been viewed by its owner @Expose + @Column(columnDefinition = "BOOLEAN") private boolean viewed = false; public enum Status { @@ -102,7 +114,7 @@ public class ExperimentDAO { public ExperimentDTO convertToDTO() { ExperimentDTO experimentDTO = new ExperimentDTO(); - experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithm, AlgorithmDTO.class)); + experimentDTO.setAlgorithmDetails(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class)); experimentDTO.setCreated(this.created); experimentDTO.setCreatedBy(this.createdBy.getUsername()); experimentDTO.setName(this.name); @@ -113,6 +125,14 @@ public class ExperimentDAO { return experimentDTO; } + public String getAlgorithmDetails() { + return algorithmDetails; + } + + public void setAlgorithmDetails(String algorithmDetails) { + this.algorithmDetails = algorithmDetails; + } + public String getAlgorithm() { return algorithm; } @@ -177,11 +197,11 @@ public class ExperimentDAO { this.name = name; } - public User getCreatedBy() { + public UserDAO getCreatedBy() { return createdBy; } - public void setCreatedBy(User createdBy) { + public void setCreatedBy(UserDAO createdBy) { this.createdBy = createdBy; } diff --git a/src/main/java/eu/hbp/mip/model/User.java b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java similarity index 94% rename from src/main/java/eu/hbp/mip/model/User.java rename to src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java index f1ee34059054493bfc3c37ad7d762ffacb486c6f..1e35ac8315e000e21c6962472967b53fbdcaecf9 100644 --- a/src/main/java/eu/hbp/mip/model/User.java +++ b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java @@ -2,7 +2,7 @@ * Created by mirco on 04.12.15. */ -package eu.hbp.mip.model; +package eu.hbp.mip.model.DAOs; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -20,7 +20,7 @@ import java.util.regex.Pattern; @ApiModel @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(value = {"appsVotes"}) -public class User { +public class UserDAO { @Id @Expose @@ -35,7 +35,7 @@ public class User { private Boolean agreeNDA = null; - public User() { + public UserDAO() { /* * Empty constructor is needed by Hibernate */ @@ -47,7 +47,7 @@ public class User { * * @param userInfo info from OpenID UserInfo endpoint */ - public User(String userInfo) { + public UserDAO(String userInfo) { Pattern p; Matcher m; diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java index b4214dd0a4de6aa50fa13f7aeb91652ce2c32137..e4b9d34a5f35baf8927bd6d5e26310671aca6ae6 100644 --- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java +++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java @@ -16,16 +16,29 @@ public class ExperimentDTO { private ExperimentDTO.ResultDTO result; private ExperimentDAO.Status status; - private AlgorithmDTO algorithm; + private String algorithm; + private AlgorithmDTO algorithmDetails; - public AlgorithmDTO getAlgorithm() { + public ExperimentDTO() { + } + + public String getAlgorithm() { return algorithm; } - public void setAlgorithm(AlgorithmDTO algorithm) { + public void setAlgorithm(String algorithm) { this.algorithm = algorithm; } + public AlgorithmDTO getAlgorithmDetails() { + return algorithmDetails; + } + + public void setAlgorithmDetails(AlgorithmDTO algorithmDetails) { + this.algorithmDetails = algorithmDetails; + this.algorithm = algorithmDetails.getName(); + } + public String getUuid() { return uuid; } diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java index 7bd9a97f3a8f16847410f73afc924fd05ff905cd..cb61cfcea60c58275aaa0fac65c63a699efd58c7 100644 --- a/src/main/java/eu/hbp/mip/model/UserInfo.java +++ b/src/main/java/eu/hbp/mip/model/UserInfo.java @@ -1,5 +1,6 @@ package eu.hbp.mip.model; +import eu.hbp.mip.model.DAOs.UserDAO; import eu.hbp.mip.repositories.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -26,7 +27,7 @@ public class UserInfo { @Value("#{'${hbp.authentication.enabled:1}'}") private boolean authentication; - private User user; + private UserDAO user; /** * Set to true if using no-auth mode and user has clicked on the login button @@ -45,18 +46,18 @@ public class UserInfo { * * @return the user for the current session */ - public User getUser() { + public UserDAO getUser() { if (user == null) { if (!authentication) { - user = new User(); + user = new UserDAO(); user.setUsername("anonymous"); user.setFullname("anonymous"); user.setEmail("anonymous@anonymous.com"); } else { - user = new User(getUserInfos()); + user = new UserDAO(getUserInfos()); } - User foundUser = userRepository.findOne(user.getUsername()); + UserDAO foundUser = userRepository.findByUsername(user.getUsername()); if (foundUser != null) { user.setAgreeNDA(foundUser.getAgreeNDA()); } diff --git a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java b/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java index 1a93186ff064bf5833246d82b2cb0d35bf838312..5f6589ab5e61499aff08022ed0af52efb1e2edc0 100644 --- a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java +++ b/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java @@ -1,17 +1,17 @@ package eu.hbp.mip.repositories; -import eu.hbp.mip.model.Article; -import eu.hbp.mip.model.User; +import eu.hbp.mip.model.DAOs.ArticleDAO; +import eu.hbp.mip.model.DAOs.UserDAO; import org.springframework.data.repository.CrudRepository; /** * Created by mirco on 11.07.16. */ -public interface ArticleRepository extends CrudRepository<Article, String> { +public interface ArticleRepository extends CrudRepository<ArticleDAO, String> { Long countByTitle(String title); - Iterable<Article> findByCreatedBy(User user); + Iterable<ArticleDAO> findByCreatedBy(UserDAO user); - Iterable<Article> findByStatusOrCreatedBy(String status, User user); + Iterable<ArticleDAO> findByStatusOrCreatedBy(String status, UserDAO user); } diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java index eb1d254156e38529de29335a7f3cdfdd49cd7686..a9fb10f2785cb680a19e090b6eb2e54fd6510bb5 100644 --- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java +++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java @@ -1,7 +1,7 @@ package eu.hbp.mip.repositories; import eu.hbp.mip.model.DAOs.ExperimentDAO; -import eu.hbp.mip.model.User; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import java.util.UUID; @@ -10,8 +10,7 @@ import java.util.UUID; * Created by mirco on 11.07.16. */ -public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID> { - Iterable<ExperimentDAO> findByCreatedBy(User user); - - Iterable<ExperimentDAO> findByShared(Boolean shared); +public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID>, JpaSpecificationExecutor<ExperimentDAO> +{ + ExperimentDAO findByUuid(UUID experimentUuid); } diff --git a/src/main/java/eu/hbp/mip/repositories/UserRepository.java b/src/main/java/eu/hbp/mip/repositories/UserRepository.java index 3a0db7ee31cf9c56cdd68397d641f4a71e8c37a2..4a3a7c69893f01a20f5cf860498bdfd1173a62bf 100644 --- a/src/main/java/eu/hbp/mip/repositories/UserRepository.java +++ b/src/main/java/eu/hbp/mip/repositories/UserRepository.java @@ -1,12 +1,13 @@ package eu.hbp.mip.repositories; -import eu.hbp.mip.model.User; +import eu.hbp.mip.model.DAOs.UserDAO; import org.springframework.data.repository.CrudRepository; /** * Created by mirco on 11.07.16. */ -public interface UserRepository extends CrudRepository<User, String> { +public interface UserRepository extends CrudRepository<UserDAO, String> { + UserDAO findByUsername(String username); } diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java index bd0bed3596c6de60154cacd291e6d34e9a4a74c1..d8545b9be65c3ea612d6ec81cbeae6b5e70aa8e4 100644 --- a/src/main/java/eu/hbp/mip/services/ExperimentService.java +++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java @@ -6,14 +6,13 @@ import com.github.jmchilton.blend4j.galaxy.WorkflowsClient; import com.github.jmchilton.blend4j.galaxy.beans.Workflow; import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails; import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition; -import com.google.common.collect.Lists; import com.google.gson.*; import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients; import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance; import eu.hbp.mip.model.DAOs.ExperimentDAO; +import eu.hbp.mip.model.DAOs.UserDAO; import eu.hbp.mip.model.DTOs.AlgorithmDTO; import eu.hbp.mip.model.DTOs.ExperimentDTO; -import eu.hbp.mip.model.User; import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.model.galaxy.ErrorResponse; import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult; @@ -27,6 +26,7 @@ import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; @@ -51,12 +51,6 @@ public class ExperimentService { @Value("#{'${services.exareme.queryExaremeUrl}'}") private String queryExaremeUrl; - @Value("#{'${services.workflows.workflowUrl}'}") - private String workflowUrl; - - @Value("#{'${services.workflows.jwtSecret}'}") - private String jwtSecret; - @Value("#{'${services.galaxy.galaxyUrl}'}") private String galaxyUrl; @@ -75,7 +69,7 @@ public class ExperimentService { public ResponseEntity<String> getExperiment(String uuid, String endpoint) { ExperimentDAO experimentDAO; - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid); @@ -97,7 +91,7 @@ public class ExperimentService { } public ResponseEntity<String> createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); //Checking if check (POST) /experiments has proper input. if (checkPostExperimentProperInput(experimentDTO)){ @@ -106,11 +100,11 @@ public class ExperimentService { return ResponseEntity.badRequest().body("Please provide proper input."); } // Get the type and name of algorithm - String algorithmType = experimentDTO.getAlgorithm().getType(); - String algorithmName = experimentDTO.getAlgorithm().getName(); + String algorithmType = experimentDTO.getAlgorithmDetails().getType(); + String algorithmName = experimentDTO.getAlgorithmDetails().getName(); StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n"); - for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithm().getParameters()) { + for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithmDetails().getParameters()) { parametersLogMessage .append(" ") .append(params.getLabel()) @@ -123,7 +117,7 @@ public class ExperimentService { if (authenticationIsEnabled) { // Getting the dataset from the experiment parameters String experimentDatasets = null; - for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithm().getParameters()) { + for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) { if (parameter.getLabel().equals("dataset")) { experimentDatasets = parameter.getValue(); break; @@ -152,19 +146,18 @@ public class ExperimentService { } } - public ResponseEntity<String> getExperiments( String endpoint) { - User user = userInfo.getUser(); + public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, String endpoint) { + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments."); + Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name)) + .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm)) + .and(new ExperimentSpecifications.ExperimentWithShared(shared)) + .and(new ExperimentSpecifications.ExperimentWithViewed(viewed)); - Iterable<ExperimentDAO> myExperiments = experimentRepository.findByCreatedBy(user); - List<ExperimentDAO> expList = Lists.newLinkedList(myExperiments); - Iterable<ExperimentDAO> sharedExperiments = experimentRepository.findByShared(true); - List<ExperimentDAO> sharedExpList = Lists.newLinkedList(sharedExperiments); - expList.addAll(sharedExpList); - Logging.LogUserAction(user.getUsername(), endpoint, "Successfully listed my experiments."); - List<ExperimentDTO> experimentDTOs = new LinkedList<>(); + List<ExperimentDAO> experimentDAOs = experimentRepository.findAll(spec); - for (ExperimentDAO experimentDAO: expList){ + List<ExperimentDTO> experimentDTOs= new ArrayList<>(); + for (ExperimentDAO experimentDAO: experimentDAOs){ ExperimentDTO experimentDTO = experimentDAO.convertToDTO(); experimentDTOs.add(experimentDTO); } @@ -174,7 +167,7 @@ public class ExperimentService { public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint) { ExperimentDAO experimentDAO; - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + experimentDTO.getUuid() + "."); //Checking if check (PUT) /experiments has proper input. if (checkPutExperimentProperInput(experimentDTO)){ @@ -186,7 +179,7 @@ public class ExperimentService { if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0) && experimentDTO.getShared() == null && experimentDTO.getViewed() == null - && experimentDTO.getAlgorithm() == null) + && experimentDTO.getAlgorithmDetails() == null) { return ResponseEntity.badRequest().body("Input is required."); } @@ -222,7 +215,7 @@ public class ExperimentService { public ResponseEntity<String> deleteExperiment(String uuid, String endpoint) { ExperimentDAO experimentDAO; - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + "."); experimentDAO = loadExperiment(uuid); @@ -266,30 +259,31 @@ public class ExperimentService { return null; } - return experimentRepository.findOne(experimentUuid); + return experimentRepository.findByUuid(experimentUuid); } private ExperimentDAO createExperiment(ExperimentDTO experimentDTO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); ExperimentDAO experimentDAO = new ExperimentDAO(); experimentDAO.setUuid(UUID.randomUUID()); experimentDAO.setCreatedBy(user); - experimentDAO.setAlgorithm(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm())); + experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails())); + experimentDAO.setAlgorithm(experimentDTO.getAlgorithm()); experimentDAO.setName(experimentDTO.getName()); experimentRepository.save(experimentDAO); Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid()); - Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm()); + Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails()); Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName()); return experimentDAO; } private void saveExperiment(ExperimentDAO experimentDAO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid()); - Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm()); + Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails()); Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName()); Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId()); Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus()); @@ -313,18 +307,18 @@ public class ExperimentService { * @return the response to be returned */ public ResponseEntity<String> runExaremeAlgorithm(ExperimentDTO experimentDTO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm..."); ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint); Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid()); // Run the 1st algorithm from the list - String algorithmName = experimentDTO.getAlgorithm().getName(); + String algorithmName = experimentDTO.getAlgorithmDetails().getName(); // Get the parameters List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters - = experimentDTO.getAlgorithm().getParameters(); + = experimentDTO.getAlgorithmDetails().getParameters(); String body = gson.toJson(algorithmParameters); String url = queryExaremeUrl + "/" + algorithmName; @@ -375,7 +369,7 @@ public class ExperimentService { * @return the response to be returned */ public ResponseEntity<String> runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow..."); ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint); @@ -383,11 +377,11 @@ public class ExperimentService { // Run the 1st algorithm from the list - String workflowId = experimentDTO.getAlgorithm().getName(); + String workflowId = experimentDTO.getAlgorithmDetails().getName(); // Get the parameters List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters - = experimentDTO.getAlgorithm().getParameters(); + = experimentDTO.getAlgorithmDetails().getParameters(); // Convert the parameters to workflow parameters HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>(); @@ -481,7 +475,7 @@ public class ExperimentService { * @return nothing, just updates the experiment */ public void updateWorkflowExperiment(ExperimentDAO experimentDAO, String endpoint) { - User user = userInfo.getUser(); + UserDAO user = userInfo.getUser(); if (experimentDAO == null) { Logging.LogUserAction(user.getUsername(), endpoint, "The experiment does not exist."); diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java new file mode 100644 index 0000000000000000000000000000000000000000..6596a319ad510ed6bda468088e348ff70f618c1a --- /dev/null +++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java @@ -0,0 +1,82 @@ +package eu.hbp.mip.services; + +import eu.hbp.mip.model.DAOs.ExperimentDAO; +import org.springframework.data.jpa.domain.Specification; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +public class ExperimentSpecifications { + public static class ExperimentWithName implements Specification<ExperimentDAO> { + + private String name; + private String regExp; + + public ExperimentWithName(String name){ + this.name = name; + this.regExp = "%"+name+"%"; + } + + public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) + { + if (name == null) { + return cb.isTrue(cb.literal(true)); + } + + return cb.like( root.get( "name" ), regExp ); + } + } + public static class ExperimentWithAlgorithm implements Specification<ExperimentDAO> { + + private String algorithm; + + public ExperimentWithAlgorithm(String algorithm){ + this.algorithm = algorithm; + } + + public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) + { + if (algorithm == null) { + return cb.isTrue(cb.literal(true)); + } + + return cb.equal(root.get("algorithm"), this.algorithm); + } + } + + public static class ExperimentWithViewed implements Specification<ExperimentDAO> { + + private Boolean viewed; + + public ExperimentWithViewed(Boolean viewed){ + this.viewed = viewed; + } + + public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> query, CriteriaBuilder cb) { + if (viewed == null) { + return cb.isTrue(cb.literal(true)); // always true = no filtering + } + return cb.equal(root.get("viewed"), this.viewed); + } + } + + public static class ExperimentWithShared implements org.springframework.data.jpa.domain.Specification<ExperimentDAO> { + + private Boolean shared; + + public ExperimentWithShared(Boolean shared){ + this.shared = shared; + } + + public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { + if (shared == null) { + return cb.isTrue(cb.literal(true)); + } + return cb.equal(root.get("shared"), this.shared); + } + + } +} + diff --git a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql index b69ae2b702742e36025e99ba04ebde23610c10f4..73a15addd8f1a7cd34594b9708595f7a4447bfb8 100644 --- a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql +++ b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql @@ -5,7 +5,7 @@ DROP COLUMN validations, DROP COLUMN model_slug; ALTER TABLE experiment -RENAME algorithms TO algorithm; +RENAME algorithms TO algorithmDetails; ALTER TABLE experiment RENAME createdby_username TO created_by_username; ALTER TABLE experiment @@ -15,6 +15,9 @@ RENAME resultsviewed TO viewed; ALTER TABLE experiment RENAME workflowstatus TO status; +ALTER TABLE experiment +ADD COLUMN algorithm text; + ALTER TABLE "user" DROP COLUMN birthday, DROP COLUMN city,