Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • hbp-mip/portal-backend
1 result
Show changes
Commits on Source (16)
Showing
with 89 additions and 1579 deletions
#######################################################
# Build the spring boot maven project
#######################################################
FROM maven:3.8.5-openjdk-11 as mvn-build-env
FROM maven:3.9.3-amazoncorretto-17 as mvn-build-env
MAINTAINER Thanasis Karampatsis <tkarabatsis@athenarc.gr>
ENV CODE_PATH="/opt/code"
WORKDIR $CODE_PATH
......@@ -17,8 +18,7 @@ RUN mvn clean package
#######################################################
# Setup the running container
#######################################################
FROM openjdk:11.0.15-jdk
MAINTAINER Thanasis Karampatsis <tkarabatsis@athenarc.gr>
FROM amazoncorretto:17.0.8-alpine3.18
#######################################################
# Setting up timezone
......@@ -27,7 +27,7 @@ ENV TZ=Etc/GMT
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#######################################################
# Setting up env variables and workdir
# Setting up environment
#######################################################
ENV APP_CONFIG_TEMPLATE="/opt/config/application.tmpl"
ENV APP_CONFIG_LOCATION="/opt/config/application.yml"
......@@ -35,6 +35,7 @@ ENV SPRING_CONFIG_LOCATION="file:/opt/config/application.yml"
WORKDIR /opt
RUN apk add --no-cache curl
#######################################################
# Install dockerize
......
......@@ -7,7 +7,7 @@
To run the backend using an IDE for development, such as IntelliJ, you need a running instance of PostgreSQL.
## Deployment (using a Docker image)
Build the image: ` docker build -t hbpmip/portal-backend:latest .`
Build the image: `docker build -t hbpmip/portal-backend:testing .`
To use this image, you need a running instance of PostgreSQL and to configure the software using the following environment variables.
......@@ -27,10 +27,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th
#### EXTERNAL SERVICES ###
* EXAREME_URL: URL to Exareme server. Default is "http://localhost:9090" .
* EXAREME2_URL: URL to Exareme2 server. Default is "http://localhost:5000" .
* GALAXY_URL: URL to Workflow server. Default is "http://localhost:8090/" .
* GALAXY_API_KEY: The api key to authorize galaxy requests.
* GALAXY_USERNAME: The username of galaxy user to be able to embed the frame.
* GALAXY_PASSWORD: The password of galaxy user.
#### KEYCLOAK ###
* KEYCLOAK_AUTH_URL: Keycloak authentication URL.
......
# Configuration template for the portal running inside a Docker container
### EMBEDDED SERVER CONFIGURATION ###
server:
servlet:
contextPath: "/services"
port: 8080
forward-headers-strategy: native
### LOG LEVELS ###
logging:
level:
root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
eu:
hbp: {{ default .Env.LOG_LEVEL "INFO" }}
### AUTHENTICATION ###
authentication:
enabled: {{ default .Env.AUTHENTICATION "true" }}
### DATABASE CONFIGURATION ###
spring:
portal-datasource:
url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://88.197.53.106:5432/portal" }}
schema: {{ default .Env.PORTAL_DB_SCHEMA "public" }}
username: {{ default .Env.PORTAL_DB_USER "postgres" }}
password: {{ .Env.PORTAL_DB_PASSWORD }}
datasource:
url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://172.17.0.1:5433/portal" }}
username: {{ default .Env.PORTAL_DB_USER "portal" }}
password: {{ default .Env.PORTAL_DB_PASSWORD "portalpwd" }}
driver-class-name: org.postgresql.Driver
data:
jpa:
......@@ -28,8 +30,35 @@ spring:
bootstrap-mode: default
jpa:
hibernate:
dialect: org.hibernate.dialect.PostgreSQL9Dialect
ddl-auto: validate
mvc:
pathmatch:
matching-strategy: ant_path_matcher
jackson:
default-property-inclusion: non_null
security:
oauth2:
client:
registration:
keycloak:
authorization-grant-type: authorization_code
client-id: {{ .Env.KEYCLOAK_REALM }}
client-secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
provider: keycloak
scope: openid
redirect-uri: http://172.17.0.1/${server.servlet.contextPath}/login/oauth2/code/{{ .Env.KEYCLOAK_REALM }}
provider:
keycloak:
issuer-uri: http://172.17.0.1/auth/realms/{{ .Env.KEYCLOAK_REALM }}
user-name-attribute: preferred_username
### AUTHENTICATION ###
authentication:
enabled: {{ default .Env.AUTHENTICATION "1" }}
all_datasets_allowed_claim: research_dataset_all
all_experiments_allowed_claim: research_experiment_all
dataset_claim_prefix: research_dataset_
### EXTERNAL SERVICES ###
......@@ -40,50 +69,9 @@ services:
attributesUrl: {{ .Env.EXAREME2_URL}}/data_models_attributes
cdesMetadataUrl: {{ .Env.EXAREME2_URL}}/cdes_metadata
exareme:
queryExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query
algorithmsUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/algorithms.json
galaxy:
galaxyUrl: {{ default .Env.GALAXY_URL "http://localhost:8090/" }}
galaxyContext: "nativeGalaxy/workflows/list"
galaxyApiKey: {{ .Env.GALAXY_API_KEY }}
galaxyUsername: {{ default .Env.GALAXY_USERNAME "admin" }}
galaxyPassword: {{ default .Env.GALAXY_PASSWORD "password" }}
### KEYCLOAK ###
keycloak:
enabled: true
auth-server-url: {{ .Env.KEYCLOAK_AUTH_URL }}
realm: {{ .Env.KEYCLOAK_REALM }}
resource: {{ .Env.KEYCLOAK_CLIENT_ID }}
use-resource-role-mappings: true
enable-basic-auth: true
credentials:
secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
principal-attribute: "preferred_username"
ssl-required: {{ .Env.KEYCLOAK_SSL_REQUIRED }}
### EXTERNAL FILES ###
# Files are imported when building the docker image
files:
pathologies_json: "file:/opt/portal/api/pathologies.json"
disabledAlgorithms_json: "file:{{ .Env.DISABLED_ALGORITHMS_CONFIG_PATH}}"
### EMBEDDED SERVER CONFIGURATION ###
server:
servlet:
contextPath: "/services"
port: 8080
forward-headers-strategy: native
### ENDPOINTS ###
endpoints:
enabled: true
health:
enabled: true
endpoint: /health
sensitive: false
......@@ -3,65 +3,43 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.hbp.mip</groupId>
<artifactId>portal-backend</artifactId>
<version>4.0.0</version><!-- BUMP_VERSION -->
<packaging>jar</packaging>
<name>portal-backend</name>
<description>Medical Informatics Platform - portal-backend</description>
<groupId>hbp.mip</groupId>
<artifactId>portal-backend</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<version>3.1.2</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<keycloak-spring.version>11.0.2</keycloak-spring.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>
<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>2.2.220</h2.version>
<postgresql.version>42.3.8</postgresql.version>
<gson.version>2.8.9</gson.version>
<slugify.version>2.1.5</slugify.version>
<maven-resources-plugin.version>3.0.1</maven-resources-plugin.version>
<sonar-maven-plugin.version>3.0.2</sonar-maven-plugin.version>
<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>
<java.version>17</java.version>
<spring-context.version>6.0.11</spring-context.version>
<postgresql.version>42.6.0</postgresql.version>
<jakarta.version>3.1.0</jakarta.version>
<hibernate.version>6.2.7.Final</hibernate.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>5.4.24.Final</hibernate.version>
<hibernate-validator.version>6.1.0.Final</hibernate-validator.version>
<aspectjweaver.version>1.8.9</aspectjweaver.version>
<javax-inject.version>1</javax-inject.version>
<protobuf-java.version>3.16.3</protobuf-java.version>
<gson.version>2.10.1</gson.version>
<commons-dbcp.version>2.9.0</commons-dbcp.version>
<lombok.version>1.18.28</lombok.version>
</properties>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>bintray-hbpmedical-maven</id>
<name>bintray</name>
<url>https://dl.bintray.com/hbpmedical/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-context.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-context.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
......@@ -72,187 +50,59 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>${keycloak-spring.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>${keycloak-spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>${angularjs.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>${jquery.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>${webjars-locator.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>${hibernate-jpa-2.1-api.version}</version>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox-boot-starter.version}</version>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway-core.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.github.slugify</groupId>
<artifactId>slugify</artifactId>
<version>${slugify.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons-dbcp.version}</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway-core.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax-inject.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-context.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.0-M4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.jmchilton.blend4j/blend4j -->
<dependency>
<groupId>com.github.jmchilton.blend4j</groupId>
<artifactId>blend4j</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>com.google.code.svenson</groupId>
<artifactId>svenson</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
<version>${lombok.version}</version>
</dependency>
</dependencies>
<build>
......@@ -270,90 +120,12 @@
</includes>
<filtering>true</filtering>
</resource>
<!-- Used for development. Docker/config folder files added as resources -->
<resource>
<directory>config</directory>
<includes>
<include>*.json</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<configuration>
<!-- specify UTF-8, ISO-8859-1 or any other file encoding -->
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>de.juplo</groupId>
<artifactId>hibernate4-maven-plugin</artifactId>
<version>${hibernate4-maven-plugin.version}</version>
<executions>
<execution>
<phase>compile</phase>
</execution>
</executions>
</plugin>
<!-- Disable default compiler. -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>${swagger2markup-maven-plugin.version}</version>
<configuration>
<swaggerInput>http://localhost:8080/services/v2/api-docs</swaggerInput>
<outputFile>${project.build.directory}/asciidoc/api</outputFile>
<config>
<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
</config>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${asciidoctor.maven.plugin.version}</version>
<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>${asciidoctorj.pdf.version}</version>
</dependency>
</dependencies>
<configuration>
<sourceDirectory>${project.build.directory}/asciidoc</sourceDirectory>
<backend>pdf</backend>
<attributes>
<toc/>
<idseparator>-</idseparator>
</attributes>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>${sonar-maven-plugin.version}</version>
</plugin>
</plugins>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package eu.hbp.mip.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
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.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class APIMetadataConfiguration {
@Bean
public Docket swaggerDocumentation() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("eu.hbp.mip.controllers"))
.build()
.pathMapping("/")
.apiInfo(metadata());
}
private ApiInfo metadata() {
return new ApiInfoBuilder()
.title("Medical Informatics Platform API")
.description("Serving the MIP Frontend")
.contact(new Contact("Kostas Filippopolitis", "https://github.com/KFilippopolitis", "kostasfilippop@gmail.com"))
.build();
}
}
package eu.hbp.mip.configurations;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import eu.hbp.mip.services.ActiveUserService;
import eu.hbp.mip.utils.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import java.util.Base64;
@RestController
public class GalaxyAuthentication {
private final ActiveUserService activeUserService;
@Value("#{'${services.galaxy.galaxyUsername:admin}'}")
private String galaxyUsername;
@Value("#{'${services.galaxy.galaxyPassword:password}'}")
private String galaxyPassword;
@Value("#{'${services.galaxy.galaxpathoyContext:nativeGalaxy}'}")
private String galaxyContext;
public GalaxyAuthentication(ActiveUserService activeUserService) {
this.activeUserService = activeUserService;
}
/**
* Get Galaxy Reverse Proxy basic access token.
*
* @return Return a @{@link ResponseEntity} with the token.
*/
@RequestMapping(path = "/galaxy", method = RequestMethod.GET, produces = "application/json")
@PreAuthorize("hasRole('WORKFLOW_ADMIN')")
@ResponseStatus(value = HttpStatus.OK)
public ResponseEntity getGalaxyConfiguration() {
Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /user/galaxy");
String stringEncoded = Base64.getEncoder().encodeToString((galaxyUsername + ":" + galaxyPassword).getBytes());
JsonObject object = new JsonObject();
object.addProperty("authorization", stringEncoded);
object.addProperty("context", galaxyContext);
logger.LogUserAction("Successfully Loaded galaxy information.");
return ResponseEntity.ok(new Gson().toJson(object));
}
}
package eu.hbp.mip.configurations;
import eu.hbp.mip.utils.CORSFilter;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
@KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
// Upon logout, redirect to login page url
private static final String logoutRedirectURL = "/sso/login";
@Value("#{'${authentication.enabled}'}")
private boolean authenticationEnabled;
public SecurityConfiguration(HttpServletRequest request) {
this.request = request;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
if (authenticationEnabled) {
http.authorizeRequests()
.antMatchers(
"/sso/login", "/actuator/**",
"/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**" // Swagger URLs
).permitAll()
.antMatchers("/galaxy*", "/galaxy/*").hasRole("WORKFLOW_ADMIN")
.antMatchers("/**").authenticated()
.and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
} else {
http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/**").permitAll()
.and().csrf().disable();
}
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
private final HttpServletRequest request;
@GetMapping(value = "/logout")
public String logout() throws ServletException {
request.logout();
return String.format("redirect:%s", logoutRedirectURL);
}
@Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setConvertToUpperCase(true);
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
}
package eu.hbp.mip.controllers;
import eu.hbp.mip.models.DAOs.UserDAO;
import eu.hbp.mip.services.ActiveUserService;
import eu.hbp.mip.utils.Logger;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequestMapping(value = "/activeUser", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/activeUser")
public class ActiveUserAPI {
private final ActiveUserService activeUserService;
public ActiveUserAPI(ActiveUserService activeUserService) {
this.activeUserService = activeUserService;
}
@ApiOperation(value = "Get the active user", response = UserDAO.class)
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<UserDAO> getTheActiveUser(HttpServletResponse response) {
Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser");
logger.LogUserAction("Loading the details of the activeUser");
return ResponseEntity.ok(activeUserService.getActiveUser());
}
@ApiOperation(value = "The active user agrees to the NDA", response = UserDAO.class)
@RequestMapping(value = "/agreeNDA", method = RequestMethod.POST)
public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(@RequestBody(required = false) UserDAO userDAO) {
Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser/agreeNDA");
logger.LogUserAction("The user agreed to the NDA");
return ResponseEntity.ok(activeUserService.agreeToNDA());
}
}
package eu.hbp.mip.controllers;
import eu.hbp.mip.models.DTOs.ExperimentDTO;
import eu.hbp.mip.services.ActiveUserService;
import eu.hbp.mip.services.ExperimentService;
import eu.hbp.mip.utils.JsonConverters;
import eu.hbp.mip.utils.Logger;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
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.Map;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/*
This api is creating experiments and running it's algorithm on the
exareme or galaxy clients.
*/
@RestController
@RequestMapping(value = "/experiments", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/experiments")
public class ExperimentAPI {
private final ExperimentService experimentService;
private final ActiveUserService activeUserService;
public ExperimentAPI(
ExperimentService experimentService,
ActiveUserService activeUserService
) {
this.experimentService = experimentService;
this.activeUserService = activeUserService;
}
@ApiOperation(value = "Get experiments", response = Map.class, responseContainer = "List")
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> getExperiments(Authentication authentication,
@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,
@RequestParam(name = "includeShared", required = false, defaultValue = "true") boolean includeShared,
@RequestParam(name = "orderBy", required = false, defaultValue = "created") String orderBy,
@RequestParam(name = "descending", required = false, defaultValue = "true") Boolean descending,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
Map experiments = experimentService.getExperiments(authentication,
name,
algorithm,
shared,
viewed,
includeShared,
page,
size,
orderBy,
descending,
new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments"));
return new ResponseEntity(experiments, HttpStatus.OK);
}
@ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
@RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
public ResponseEntity<String> getExperiment(Authentication authentication,
@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
ExperimentDTO experimentDTO = experimentService.getExperiment(authentication, uuid, new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments/{uuid}"));
return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
}
@ApiOperation(value = "Create an experiment", response = ExperimentDTO.class)
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
experimentDTO = experimentService.createExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(POST) /experiments"));
return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
}
@ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
@RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO, @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(PATCH) /experiments/{uuid}"));
return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
}
@ApiOperation(value = "Delete an experiment", response = boolean.class)
@RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
public ResponseEntity<String> deleteExperiment(
@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
experimentService.deleteExperiment(uuid, new Logger(activeUserService.getActiveUser().getUsername(), "(DELETE) /experiments/{uuid}"));
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
@RequestMapping(value = "/transient", method = RequestMethod.POST)
public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
experimentDTO = experimentService.
runTransientExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(), "(POST) /experiments/transient"));
return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
}
}
\ No newline at end of file
package eu.hbp.mip.controllers;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import eu.hbp.mip.models.DTOs.Exareme2AttributesDTO;
import eu.hbp.mip.models.DTOs.Exareme2CommonDataElement;
import eu.hbp.mip.models.DTOs.PathologyDTO;
import eu.hbp.mip.services.ActiveUserService;
import eu.hbp.mip.utils.*;
import eu.hbp.mip.utils.Exceptions.InternalServerError;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequestMapping(value = "/pathologies", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/pathologies")
public class PathologiesAPI {
private static final Gson gson = new Gson();
// Enable HBP collab authentication (1) or disable it (0). Default is 1
@Value("#{'${authentication.enabled}'}")
private boolean authenticationIsEnabled;
@Value("#{'${services.exareme2.attributesUrl}'}")
private String exareme2AttributesUrl;
@Value("#{'${services.exareme2.cdesMetadataUrl}'}")
private String exareme2CDEsMetadataUrl;
private final ActiveUserService activeUserService;
public PathologiesAPI(ActiveUserService activeUserService) {
this.activeUserService = activeUserService;
}
@RequestMapping(name = "/pathologies", method = RequestMethod.GET)
public ResponseEntity<String> getPathologies(Authentication authentication) {
Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies");
logger.LogUserAction("Loading pathologies ...");
Map<String, List<PathologyDTO.EnumerationDTO>> datasetsPerPathology = getExareme2DatasetsPerPathology(logger);
Map<String, Exareme2AttributesDTO> exareme2PathologyAttributes = getExareme2PathologyAttributes(logger);
List<PathologyDTO> pathologyDTOS = new ArrayList<>();
for (String pathology : exareme2PathologyAttributes.keySet()) {
PathologyDTO newPathology;
try {
newPathology = new PathologyDTO(pathology, exareme2PathologyAttributes.get(pathology), datasetsPerPathology.get(pathology));
}
catch(InternalServerError e) {
logger.LogUserAction(e.getMessage());
continue;
}
pathologyDTOS.add(newPathology);
}
// If authentication is disabled return everything
if (!authenticationIsEnabled) {
logger.LogUserAction("Successfully loaded " + pathologyDTOS.size() + " pathologies");
return ResponseEntity.ok().body(gson.toJson(pathologyDTOS));
}
logger.LogUserAction("Successfully loaded all authorized pathologies");
return ResponseEntity.ok().body(gson.toJson(ClaimUtils.getAuthorizedPathologies(logger, authentication, pathologyDTOS)));
}
public Map<String, List<PathologyDTO.EnumerationDTO>> getExareme2DatasetsPerPathology(Logger logger) {
Map<String, Map<String, Exareme2CommonDataElement>> exareme2CDEsMetadata;
// Get Exareme2 algorithms
try {
StringBuilder response = new StringBuilder();
HTTPUtil.sendGet(exareme2CDEsMetadataUrl, response);
exareme2CDEsMetadata = gson.fromJson(
response.toString(),
new TypeToken<HashMap<String, Map<String, Exareme2CommonDataElement>>>() {
}.getType()
);
} catch (Exception e) {
logger.LogUserAction("An exception occurred: " + e.getMessage());
return null;
}
Map<String, List<PathologyDTO.EnumerationDTO>> datasetsPerPathology = new HashMap<>();
exareme2CDEsMetadata.forEach( (pathology, cdePerDataset) -> {
List<PathologyDTO.EnumerationDTO> pathologyDatasetDTOS = new ArrayList<>();
Map datasetEnumerations = (Map) cdePerDataset.get("dataset").getEnumerations();
datasetEnumerations.forEach((code, label) -> pathologyDatasetDTOS.add(new PathologyDTO.EnumerationDTO((String) code, (String) label)));
datasetsPerPathology.put(pathology, pathologyDatasetDTOS);
});
return datasetsPerPathology;
}
public Map<String, Exareme2AttributesDTO> getExareme2PathologyAttributes(Logger logger) {
Map<String, Exareme2AttributesDTO> exareme2PathologyAttributes;
// Get Exareme2 algorithms
try {
StringBuilder response = new StringBuilder();
HTTPUtil.sendGet(exareme2AttributesUrl, response);
exareme2PathologyAttributes = gson.fromJson(
response.toString(),
new TypeToken<HashMap<String, Exareme2AttributesDTO>>() {
}.getType()
);
} catch (Exception e) {
logger.LogUserAction("An exception occurred: " + e.getMessage());
return null;
}
return exareme2PathologyAttributes;
}
}
package eu.hbp.mip.controllers.galaxy.retrofit;
import com.google.gson.JsonObject;
import eu.hbp.mip.models.galaxy.GalaxyWorkflowResult;
import eu.hbp.mip.models.galaxy.PostWorkflowToGalaxyDtoResponse;
import eu.hbp.mip.models.galaxy.WorkflowDTO;
import retrofit2.Call;
import retrofit2.http.*;
import java.util.List;
public interface RetroFitGalaxyClients {
@GET("workflows/{workflowId}")
Call<WorkflowDTO> getWorkflowFromGalaxy(@Path("workflowId") String workflowId, @Query("key") String key);
@POST("workflows/{workflowId}/invocations")
Call<PostWorkflowToGalaxyDtoResponse> postWorkflowToGalaxy(@Path("workflowId") String workflowId, @Query("key") String key, @Body JsonObject body);
@GET("histories/{historyId}")
Call<Object> getWorkflowStatusFromGalaxy(@Path("historyId") String historyId, @Query("key") String key);
@GET("histories/{historyId}/contents")
Call<List<GalaxyWorkflowResult>> getWorkflowResultsFromGalaxy(@Path("historyId") String historyId, @Query("key") String key);
@GET("histories/{historyId}/contents/{contentId}/display")
Call<Object> getWorkflowResultsBodyFromGalaxy(@Path("historyId") String historyId, @Path("contentId") String contentId, @Query("key") String key);
@GET("jobs/{jobId}?full=true")
Call<Object> getErrorMessageOfWorkflowFromGalaxy(@Path("jobId") String jobId, @Query("key") String key);
}
\ No newline at end of file
package eu.hbp.mip.controllers.galaxy.retrofit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import javax.annotation.PostConstruct;
@Component
public class RetrofitClientInstance {
private static Retrofit retrofit;
@Value("#{'${services.galaxy.galaxyUrl}'}")
private String galaxyUrl;
private static String BASE_URL;
@PostConstruct
public void init() {
BASE_URL = galaxyUrl + "/api/";
}
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
\ No newline at end of file
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Hashtable;
import java.util.List;
import java.util.Optional;
@Data
@AllArgsConstructor
public class Exareme2AlgorithmDTO {
@SerializedName("name")
private String name;
@SerializedName("desc")
private String desc;
@SerializedName("label")
private String label;
@SerializedName("type")
private String type;
@SerializedName("parameters")
private Hashtable<String, Exareme2AlgorithmParameterDTO> parameters;
@SerializedName("crossvalidation")
private String crossvalidation;
@SerializedName("inputdata")
private Exareme2AlgorithmInputdataDTO inputdata;
public Optional<Hashtable<String, Exareme2AlgorithmParameterDTO>> getParameters() {
return Optional.ofNullable(parameters);
}
@SerializedName("preprocessing")
private List<Exareme2TransformerDTO> preprocessing;
public Optional<List<Exareme2TransformerDTO>> getPreprocessing() {
return Optional.ofNullable(preprocessing);
}
@Data
@AllArgsConstructor
public static class Exareme2AlgorithmParameterDTO {
@SerializedName("label")
private String label;
@SerializedName("notblank")
private String notblank;
@SerializedName("multiple")
private String multiple;
@SerializedName("types")
private List<String> types;
@SerializedName("desc")
private String desc;
@SerializedName("min")
private String min;
@SerializedName("max")
private String max;
@SerializedName("default")
private String default_value;
@SerializedName("enums")
private Exareme2AlgorithmEnumDTO enums;
@SerializedName("dict_keys_enums")
private Exareme2AlgorithmEnumDTO dict_keys_enums;
@SerializedName("dict_values_enums")
private Exareme2AlgorithmEnumDTO dict_values_enums;
public Optional<Exareme2AlgorithmEnumDTO> getEnums() {
return Optional.ofNullable(enums);
}
@Data
@AllArgsConstructor
public static class Exareme2AlgorithmEnumDTO {
@SerializedName("type")
private String type;
@SerializedName("source")
private List<String> source;
}
}
@Data
@AllArgsConstructor
public static class Exareme2AlgorithmInputdataDTO {
@SerializedName("x")
private Exareme2AlgorithmInputDataDetailDTO x;
@SerializedName("y")
private Exareme2AlgorithmInputDataDetailDTO y;
@SerializedName("data_model")
private Exareme2AlgorithmInputDataDetailDTO data_model;
@SerializedName("datasets")
private Exareme2AlgorithmInputDataDetailDTO datasets;
@SerializedName("filter")
private Exareme2AlgorithmInputDataDetailDTO filter;
public Optional<Exareme2AlgorithmInputDataDetailDTO> getY() {
return Optional.ofNullable(y);
}
public Optional<Exareme2AlgorithmInputDataDetailDTO> getX() {
return Optional.ofNullable(x);
}
}
@Data
@AllArgsConstructor
public static class Exareme2AlgorithmInputDataDetailDTO {
@SerializedName("stattypes")
private List<String> stattypes;
@SerializedName("label")
private String label;
@SerializedName("notblank")
private String notblank;
@SerializedName("enumslen")
private Integer enumslen;
@SerializedName("multiple")
private String multiple;
@SerializedName("types")
private List<String> types;
@SerializedName("desc")
private String desc;
}
@Data
@AllArgsConstructor
public static class Exareme2TransformerDTO {
@SerializedName("name")
private String name;
@SerializedName("desc")
private String desc;
@SerializedName("label")
private String label;
@SerializedName("parameters")
private Hashtable<String, Exareme2AlgorithmParameterDTO> parameters;
}
}
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import eu.hbp.mip.utils.JsonConverters;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.*;
@Data
@AllArgsConstructor
public class Exareme2AlgorithmRequestDTO {
@SerializedName("request_id")
private String request_id;
@SerializedName("inputdata")
private InputData inputdata;
@SerializedName("parameters")
private HashMap<String, Object> parameters;
@SerializedName("preprocessing")
private HashMap<String, Object> preprocessing;
public Exareme2AlgorithmRequestDTO(UUID experimentUUID, List<ExaremeAlgorithmRequestParamDTO> exaremeAlgorithmRequestParamDTOs, List<ExaremeAlgorithmDTO.ExaremeTransformerDTO> exaremeTransformers) {
this.request_id = experimentUUID.toString();
Exareme2AlgorithmRequestDTO.InputData inputData = new Exareme2AlgorithmRequestDTO.InputData();
HashMap<String, Object> exareme2Parameters = new HashMap<>();
HashMap<String, Object> exareme2Preprocessing = new HashMap<>();
exaremeAlgorithmRequestParamDTOs.forEach(parameter -> {
switch (parameter.getName()) {
case "x":
List<String> x = Arrays.asList(parameter.getValue().split(","));
inputData.setX(x);
break;
case "y":
List<String> y = Arrays.asList(parameter.getValue().split(","));
inputData.setY(y);
break;
case "dataset":
List<String> datasets = Arrays.asList(parameter.getValue().split(","));
inputData.setDatasets(datasets);
break;
case "pathology":
inputData.setData_model(parameter.getValue());
break;
case "filter":
if (parameter.getValue() != null && !parameter.getValue().equals(""))
inputData.setFilters(JsonConverters.convertJsonStringToObject(parameter.getValue(), Exareme2AlgorithmRequestDTO.Filter.class));
break;
default:
exareme2Parameters.put(parameter.getName(), convertStringToMultipleValues(parameter.getValue()));
}
});
if (exaremeTransformers != null) {
exaremeTransformers.forEach(transformer -> {
HashMap<String, Object> transformerParameterDTOs = new HashMap<>();
for (ExaremeAlgorithmRequestParamDTO parameter : transformer.getParameters()) {
if (parameter.getName().equals("strategies")){
transformerParameterDTOs.put(parameter.getName(),
JsonConverters.convertJsonStringToObject(parameter.getValue(), HashMap.class)
);
}
else {
transformerParameterDTOs.put(parameter.getName(), convertStringToMultipleValues(parameter.getValue()));
}
}
exareme2Preprocessing.put(transformer.getName(), transformerParameterDTOs);
});
}
this.inputdata = inputData;
this.parameters = exareme2Parameters;
this.preprocessing = exareme2Preprocessing;
}
private static Object convertStringToMultipleValues(String str) {
String[] stringValues = str.split(",");
if (stringValues.length == 0)
return "";
if (stringValues.length == 1)
return convertStringToNumeric(stringValues[0]);
List<Object> values = new ArrayList<>();
for (String value : stringValues) {
values.add(convertStringToNumeric(value));
}
return values;
}
private static Object convertStringToNumeric(String str) {
if (isInteger(str))
return Integer.parseInt(str);
else if (isFloat(str))
return Double.parseDouble(str);
else
return str;
}
private static boolean isFloat(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
private static boolean isInteger(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Integer.parseInt(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
@Data
@AllArgsConstructor
public static class InputData {
@SerializedName("data_model")
private String data_model;
@SerializedName("datasets")
private List<String> datasets;
@SerializedName("filters")
private Filter filters;
@SerializedName("x")
private List<String> x;
@SerializedName("y")
private List<String> y;
public InputData() {
}
}
@Data
@AllArgsConstructor
public static class Filter {
@SerializedName("condition")
private String condition;
@SerializedName("rules")
private List<Object> rules;
}
}
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
public class Exareme2AttributesDTO {
@SerializedName("properties")
private Map<String, List<MetadataHierarchyDTO>> properties;
@SerializedName("tags")
private Object tags;
}
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Exareme2CommonDataElement {
@SerializedName("is_categorical")
private Boolean is_categorical;
@SerializedName("code")
private String code;
@SerializedName("sql_type")
private String sql_type;
@SerializedName("description")
private String description;
@SerializedName("enumerations")
private Object enumerations;
@SerializedName("label")
private String label;
@SerializedName("units")
private String units;
@SerializedName("type")
private String type;
@SerializedName("methodology")
private String methodology;
@SerializedName("min")
private String min;
@SerializedName("max")
private String max;
}
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@AllArgsConstructor
public class ExaremeAlgorithmDTO {
@SerializedName("name")
private String name;
@SerializedName("desc")
private String desc;
@SerializedName("label")
private String label;
@SerializedName("type")
private String type;
@SerializedName("parameters")
private List<ExaremeAlgorithmRequestParamDTO> parameters;
@SerializedName("preprocessing")
private List<ExaremeTransformerDTO> preprocessing;
public ExaremeAlgorithmDTO() {
}
public ExaremeAlgorithmDTO(Exareme2AlgorithmDTO exareme2Algorithm) {
this.name = exareme2Algorithm.getName().toUpperCase();
this.label = exareme2Algorithm.getLabel();
this.desc = exareme2Algorithm.getDesc();
this.type = "exareme2";
List<ExaremeAlgorithmRequestParamDTO> parameters = new ArrayList<>();
if (exareme2Algorithm.getInputdata().getY().isPresent()) {
parameters.add(new ExaremeAlgorithmRequestParamDTO("y", exareme2Algorithm.getInputdata().getY().get()));
}
if (exareme2Algorithm.getInputdata().getX().isPresent()) {
parameters.add(new ExaremeAlgorithmRequestParamDTO("x", exareme2Algorithm.getInputdata().getX().get()));
}
parameters.add(new ExaremeAlgorithmRequestParamDTO("pathology", exareme2Algorithm.getInputdata().getData_model()));
parameters.add(new ExaremeAlgorithmRequestParamDTO("dataset", exareme2Algorithm.getInputdata().getDatasets()));
parameters.add(new ExaremeAlgorithmRequestParamDTO("filter", exareme2Algorithm.getInputdata().getFilter()));
if (exareme2Algorithm.getParameters().isPresent()) {
exareme2Algorithm.getParameters().get().forEach((name, parameterDTO) -> {
ExaremeAlgorithmRequestParamDTO parameter = new ExaremeAlgorithmRequestParamDTO(name, parameterDTO);
parameters.add(parameter);
});
}
this.parameters = parameters;
List<ExaremeTransformerDTO> preprocessing = new ArrayList<>();
if (exareme2Algorithm.getPreprocessing().isPresent()) {
exareme2Algorithm.getPreprocessing().get().forEach(exareme2TransformerDTO -> {
ExaremeTransformerDTO transformer = new ExaremeTransformerDTO(exareme2TransformerDTO);
preprocessing.add(transformer);
});
this.preprocessing = preprocessing;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ExaremeTransformerDTO {
@SerializedName("name")
private String name;
@SerializedName("desc")
private String desc;
@SerializedName("label")
private String label;
@SerializedName("parameters")
private List<ExaremeAlgorithmRequestParamDTO> parameters;
public ExaremeTransformerDTO(Exareme2AlgorithmDTO.Exareme2TransformerDTO transformerDTO) {
this.name = transformerDTO.getName().toUpperCase();
this.label = transformerDTO.getLabel();
this.desc = transformerDTO.getDesc();
List<ExaremeAlgorithmRequestParamDTO> parameters = new ArrayList<>();
transformerDTO.getParameters().forEach((name, parameterDTO) -> {
ExaremeAlgorithmRequestParamDTO parameter = new ExaremeAlgorithmRequestParamDTO(name, parameterDTO);
parameters.add(parameter);
});
this.parameters = parameters;
}
}
@Data
@AllArgsConstructor
static class Rule {
@SerializedName("id")
private String id;
@SerializedName("type")
private String type;
@SerializedName("operator")
private String operator;
@SerializedName("value")
private Object value;
}
}
package eu.hbp.mip.models.DTOs;
import com.google.gson.annotations.SerializedName;
import eu.hbp.mip.utils.Exceptions.InternalServerError;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.List;
//The request of an exareme algorithm is a list of ExaremeAlgorithmRequestParamDTOs.
@Data
@AllArgsConstructor
public class ExaremeAlgorithmRequestParamDTO {
@SerializedName("name")
private String name;
@SerializedName("desc")
private String desc;
@SerializedName("label")
private String label;
@SerializedName("type")
private String type;
@SerializedName("columnValuesSQLType")
private String columnValuesSQLType;
@SerializedName("columnValuesIsCategorical")
private String columnValuesIsCategorical;
@SerializedName("value")
private String value;
@SerializedName("defaultValue")
private String defaultValue;
@SerializedName("valueType")
private String valueType;
@SerializedName("valueNotBlank")
private String valueNotBlank;
@SerializedName("valueMultiple")
private String valueMultiple;
@SerializedName("valueMin")
private String valueMin;
@SerializedName("valueMax")
private String valueMax;
@SerializedName("valueEnumerations")
private List<String> valueEnumerations;
public ExaremeAlgorithmRequestParamDTO (){}
public ExaremeAlgorithmRequestParamDTO (String name, Exareme2AlgorithmDTO.Exareme2AlgorithmParameterDTO parameter){
this.name = name;
this.desc = parameter.getDesc();
this.valueType = parameter.getTypes().get(0);
this.type = "other";
this.defaultValue = parameter.getDefault_value();
this.valueNotBlank = parameter.getNotblank();
this.label = parameter.getLabel();
this.valueEnumerations = parameter.getEnums().isPresent()? parameter.getEnums().get().getSource():null;
this.valueMultiple = parameter.getMultiple();
this.valueMax = parameter.getMax();
this.valueMin = parameter.getMin();
}
public ExaremeAlgorithmRequestParamDTO (String name, Exareme2AlgorithmDTO.Exareme2AlgorithmInputDataDetailDTO inputDataDetail){
this.name = name;
this.desc = inputDataDetail.getDesc();
this.value = "";
this.valueNotBlank = inputDataDetail.getNotblank();
this.valueMultiple = inputDataDetail.getMultiple();
String[] hidden = {"x","y","dataset", "filter","pathology","centers","formula"};
this.label = (Arrays.asList(hidden).contains(this.name) ? this.name : inputDataDetail.getLabel());
if(name.equals("dataset") || name.equals("filter") || name.equals("pathology")){
this.valueType = inputDataDetail.getTypes().get(0);
this.type = this.name;
}
else{
this.type = "column";
this.columnValuesSQLType = String.join(", ", inputDataDetail.getTypes());
this.columnValuesIsCategorical = getColumnValuesIsCategorical(inputDataDetail.getStattypes());
}
}
private String getColumnValuesIsCategorical(List<String> stattypes){
if (stattypes.contains("nominal") && stattypes.contains("numerical")){
return "";
}
else if (stattypes.contains("nominal")){
return "true";
}
else if (stattypes.contains("numerical")){
return "false";
}
else{
throw new InternalServerError("Invalid stattypes");
}
}
}
package eu.hbp.mip.models.DTOs;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class ExaremeAlgorithmResultDTO {
private int code;
private List<Object> result;
}
package eu.hbp.mip.models.DTOs;
import com.fasterxml.jackson.annotation.JsonInclude;
import eu.hbp.mip.models.DAOs.ExperimentDAO;
import eu.hbp.mip.utils.JsonConverters;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ExperimentDTO {
private UUID uuid;
private String name;
private UserDTO createdBy;
private Date created;
private Date updated;
private Date finished;
private Boolean shared;
private Boolean viewed;
// Result is a list of objects because there is a limitation that java has in types.
// Exareme has result in the type of List<HashMap<String, Object>>
// Galaxy has result in the type of List<HashMap<String, List<Object>>>
//And there is no generic type that describes either an object or a list of objects
private List<Object> result;
private ExperimentDAO.Status status;
private ExaremeAlgorithmDTO algorithm;
public ExperimentDTO(){
}
public ExperimentDTO(boolean includeResult, ExperimentDAO experimentDAO)
{
this.algorithm = JsonConverters.convertJsonStringToObject(experimentDAO.getAlgorithm(), ExaremeAlgorithmDTO.class);
this.created = experimentDAO.getCreated();
this.updated = experimentDAO.getUpdated();
this.finished = experimentDAO.getFinished();
this.createdBy = new UserDTO(experimentDAO.getCreatedBy());
this.name = experimentDAO.getName();
if(includeResult){
this.result = JsonConverters.convertJsonStringToObject(String.valueOf(experimentDAO.getResult()), new ArrayList<>().getClass());
}
this.status = experimentDAO.getStatus();
this.uuid = experimentDAO.getUuid();
this.shared = experimentDAO.isShared();
this.viewed = experimentDAO.isViewed();
}
}