diff --git a/README.md b/README.md index e1b55c95eb3e2a1e86fd3e116b352a14b4f84f96..5fd32af2cda37ba123c5cc16a779caddc558ac73 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/config/application.tmpl b/config/application.tmpl index f47ee3ca603d3be190a94898432fec108009185e..053f28947172e5f4404fbbcada65f157f5f6bf01 100644 --- a/config/application.tmpl +++ b/config/application.tmpl @@ -48,13 +48,6 @@ services: 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: diff --git a/pom.xml b/pom.xml index 7a5b8a9d7401cfc26907fcaf9d15d62a92be30b8..6a2af84f2426d56e685302a94afe0011227b09c3 100644 --- a/pom.xml +++ b/pom.xml @@ -26,9 +26,6 @@ <keycloak-spring.version>11.0.2</keycloak-spring.version> <gson.version>2.10.1</gson.version> <commons-dbcp.version>2.9.0</commons-dbcp.version> - <blend4j.version>0.2.0</blend4j.version> - <retrofit2.version>2.9.0</retrofit2.version> - <logging-interceptor.version>4.11.0</logging-interceptor.version> <lombok.version>1.18.28</lombok.version> </properties> @@ -87,6 +84,11 @@ <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> </dependency> + <dependency> + <groupId>org.flywaydb</groupId> + <artifactId>flyway-core</artifactId> + <version>${flyway-core.version}</version> + </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> @@ -97,31 +99,6 @@ <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>com.github.jmchilton.blend4j</groupId> - <artifactId>blend4j</artifactId> - <version>${blend4j.version}</version> - </dependency> - <dependency> - <groupId>com.squareup.retrofit2</groupId> - <artifactId>retrofit</artifactId> - <version>${retrofit2.version}</version> - </dependency> - <dependency> - <groupId>com.squareup.retrofit2</groupId> - <artifactId>converter-gson</artifactId> - <version>${retrofit2.version}</version> - </dependency> - <dependency> - <groupId>com.squareup.okhttp3</groupId> - <artifactId>logging-interceptor</artifactId> - <version>${logging-interceptor.version}</version> - </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> diff --git a/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java b/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java deleted file mode 100644 index e8a5df4bc7311cc86683c546f27de0208a850d20..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java +++ /dev/null @@ -1,54 +0,0 @@ -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)); - } -} diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java index c7c30ab55ce60a58f1da79e358ffbc0637f6ec45..733eb1dcf8a538c745c0ec64bc339b686f677805 100644 --- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java @@ -1,7 +1,6 @@ package eu.hbp.mip.configurations; import eu.hbp.mip.utils.CORSFilter; -import org.jetbrains.annotations.NotNull; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; @@ -23,7 +22,9 @@ 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.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -36,7 +37,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter // Upon logout, redirect to login page url private static final String logoutRedirectURL = "/sso/login"; - + private final HttpServletRequest request; @Value("#{'${authentication.enabled}'}") private boolean authenticationEnabled; @@ -51,10 +52,8 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter if (authenticationEnabled) { http.authorizeRequests() .antMatchers( - "/sso/login", "/actuator/**", - "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**" // Swagger URLs + "/sso/login", "/actuator/**" ).permitAll() - .antMatchers("/galaxy*", "/galaxy/*").hasRole("WORKFLOW_ADMIN") .antMatchers("/**").authenticated() .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository()) .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class); @@ -70,8 +69,8 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter private Filter csrfHeaderFilter() { return new OncePerRequestFilter() { @Override - protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, - @NotNull FilterChain filterChain) throws ServletException, IOException { + 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"); @@ -93,8 +92,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter return repository; } - private final HttpServletRequest request; - @GetMapping(value = "/logout") public String logout() throws ServletException { request.logout(); diff --git a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java b/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java deleted file mode 100644 index 609163e8920ad3443e908c36aea6143ba69533c1..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java +++ /dev/null @@ -1,31 +0,0 @@ -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 diff --git a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetrofitClientInstance.java b/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetrofitClientInstance.java deleted file mode 100644 index 6aa218902ebd724518d56d8cca8b0c5e77aa2893..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetrofitClientInstance.java +++ /dev/null @@ -1,42 +0,0 @@ -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 diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java index d872975913b9d5937173b137282440b4e09d48bb..461df982261e01043d59d632db5b0f55c9ffb304 100644 --- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java +++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java @@ -5,6 +5,7 @@ import eu.hbp.mip.models.DAOs.ExperimentDAO; import eu.hbp.mip.utils.JsonConverters; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Date; @@ -12,6 +13,7 @@ import java.util.List; import java.util.UUID; @Data +@NoArgsConstructor @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class ExperimentDTO { @@ -26,25 +28,21 @@ public class ExperimentDTO { 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) - { + 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()); + if (includeResult) { + this.result = JsonConverters.convertJsonStringToObject(String.valueOf(experimentDAO.getResult()), ArrayList.class); } this.status = experimentDAO.getStatus(); this.uuid = experimentDAO.getUuid(); diff --git a/src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java b/src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java deleted file mode 100644 index 2703e742541faf9f715ed19485076d397697059e..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Developed by Kechagias Konstantinos. - * Copyright (c) 2019. MIT License - */ - -package eu.hbp.mip.models.galaxy; - -import com.google.gson.annotations.SerializedName; - -import java.util.ArrayList; -import java.util.List; - -public class ErrorResponse { - - @SerializedName("result") - List<ErrorMessage> result; - - public ErrorResponse() { - } - - public ErrorResponse(String errMsg) { - this.result = new ArrayList<>(); - this.result.add(new ErrorMessage(errMsg)); - } - - public static class ErrorMessage { - - @SerializedName("data") - String errMsg; - - @SerializedName("type") - String errType; - - public ErrorMessage() { - } - - public ErrorMessage(String errMsg) { - this.errMsg = errMsg; - this.errType = "text/plain+error"; - } - - public String getErrMsg() { - return errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - } -} diff --git a/src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java b/src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java deleted file mode 100644 index ca7d98fe51e55cd60914893283f2c30b6fcf90be..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Developed by Kechagias Konstantinos. - * Copyright (c) 2019. MIT License - */ - -package eu.hbp.mip.models.galaxy; - -import com.google.gson.annotations.SerializedName; - -import java.util.List; - -public class GalaxyWorkflowResult { - - @SerializedName("history_content_type") - private String historyContentType; - @SerializedName("update_time") - private String updateTime; - @SerializedName("name") - private String name; - @SerializedName("extension") - private String extension; - @SerializedName("type_id") - private String typeId; - @SerializedName("deleted") - private Boolean deleted; - @SerializedName("history_id") - private String historyId; - @SerializedName("tags") - private List<Object> tags = null; - @SerializedName("id") - private String id; - @SerializedName("visible") - private Boolean visible; - @SerializedName("state") - private String state; - @SerializedName("create_time") - private String createTime; - @SerializedName("hid") - private Integer hid; - @SerializedName("url") - private String url; - @SerializedName("dataset_id") - private String datasetId; - @SerializedName("type") - private String type; - @SerializedName("purged") - private Boolean purged; - - public GalaxyWorkflowResult() { - } - - public GalaxyWorkflowResult(String historyContentType, String updateTime, String name, String extension, String typeId, Boolean deleted, String historyId, List<Object> tags, String id, Boolean visible, String state, String createTime, Integer hid, String url, String datasetId, String type, Boolean purged) { - this.historyContentType = historyContentType; - this.updateTime = updateTime; - this.name = name; - this.extension = extension; - this.typeId = typeId; - this.deleted = deleted; - this.historyId = historyId; - this.tags = tags; - this.id = id; - this.visible = visible; - this.state = state; - this.createTime = createTime; - this.hid = hid; - this.url = url; - this.datasetId = datasetId; - this.type = type; - this.purged = purged; - } - - public String getHistoryContentType() { - return historyContentType; - } - - public void setHistoryContentType(String historyContentType) { - this.historyContentType = historyContentType; - } - - public String getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(String updateTime) { - this.updateTime = updateTime; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getExtension() { - return extension; - } - - public void setExtension(String extension) { - this.extension = extension; - } - - public String getTypeId() { - return typeId; - } - - public void setTypeId(String typeId) { - this.typeId = typeId; - } - - public Boolean getDeleted() { - return deleted; - } - - public void setDeleted(Boolean deleted) { - this.deleted = deleted; - } - - public String getHistoryId() { - return historyId; - } - - public void setHistoryId(String historyId) { - this.historyId = historyId; - } - - public List<Object> getTags() { - return tags; - } - - public void setTags(List<Object> tags) { - this.tags = tags; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Boolean getVisible() { - return visible; - } - - public void setVisible(Boolean visible) { - this.visible = visible; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - public String getCreateTime() { - return createTime; - } - - public void setCreateTime(String createTime) { - this.createTime = createTime; - } - - public Integer getHid() { - return hid; - } - - public void setHid(Integer hid) { - this.hid = hid; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getDatasetId() { - return datasetId; - } - - public void setDatasetId(String datasetId) { - this.datasetId = datasetId; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Boolean getPurged() { - return purged; - } - - public void setPurged(Boolean purged) { - this.purged = purged; - } -} - diff --git a/src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java b/src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java deleted file mode 100644 index 96d8aa8efa089599093fed13ac8e0d0a4be81f42..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Developed by Kechagias Konstantinos. - * Copyright (c) 2019. MIT License - */ - -package eu.hbp.mip.models.galaxy; - -import com.google.gson.annotations.SerializedName; - -public class PostWorkflowToGalaxyDtoResponse { - - - @SerializedName("update_time") - String updateTime; - String uuid; - @SerializedName("history_id") - String historyId; - String stake; - @SerializedName("workflow_id") - String workflowId; - @SerializedName("model_class") - String modelClass; - String id; - - public PostWorkflowToGalaxyDtoResponse() { - } - - public PostWorkflowToGalaxyDtoResponse(String updateTime, String uuid, String historyId, String stake, String workflowId, String modelClass, String id) { - this.updateTime = updateTime; - this.uuid = uuid; - this.historyId = historyId; - this.stake = stake; - this.workflowId = workflowId; - this.modelClass = modelClass; - this.id = id; - } - - public String getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(String updateTime) { - this.updateTime = updateTime; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public String getHistoryId() { - return historyId; - } - - public void setHistoryId(String historyId) { - this.historyId = historyId; - } - - public String getStake() { - return stake; - } - - public void setStake(String stake) { - this.stake = stake; - } - - public String getWorkflowId() { - return workflowId; - } - - public void setWorkflowId(String workflowId) { - this.workflowId = workflowId; - } - - public String getModelClass() { - return modelClass; - } - - public void setModelClass(String modelClass) { - this.modelClass = modelClass; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } -} diff --git a/src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java b/src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java deleted file mode 100644 index eae07531e6f126aa69465a9fcdf6c6cf44c1d267..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java +++ /dev/null @@ -1,163 +0,0 @@ -package eu.hbp.mip.models.galaxy; - -import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; -import eu.hbp.mip.models.DTOs.ExaremeAlgorithmDTO; -import eu.hbp.mip.models.DTOs.ExaremeAlgorithmRequestParamDTO; - -import java.util.*; - -public class WorkflowDTO { - - @SerializedName("id") - private String id; - - @SerializedName("name") - private String name; - - @SerializedName("inputs") - private HashMap<String, WorkflowInputDTO> inputs; - - @SerializedName("steps") - private HashMap<String, WorkflowStepDTO> steps; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public HashMap<String, WorkflowInputDTO> getInputs() { - return inputs; - } - - public void setInputs(HashMap<String, WorkflowInputDTO> inputs) { - this.inputs = inputs; - } - - public HashMap<String, WorkflowStepDTO> getSteps() { - return steps; - } - - public void setSteps(HashMap<String, WorkflowStepDTO> steps) { - this.steps = steps; - } - - public class WorkflowInputDTO { - @SerializedName("uuid") - private String uuid; - - @SerializedName("label") - private String label; - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - } - - public class WorkflowStepDTO { - @SerializedName("id") - private int id; - - @SerializedName("type") - private String type; - - @SerializedName("annotation") - private String annotation; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getAnnotation() { - return annotation; - } - - public void setAnnotation(String annotation) { - this.annotation = annotation; - } - } - - public ExaremeAlgorithmDTO convertToAlgorithmDTO() { - - ExaremeAlgorithmDTO exaremeAlgorithmDTO = new ExaremeAlgorithmDTO(); - - // Transfer workflow information - exaremeAlgorithmDTO.setName(id); - exaremeAlgorithmDTO.setDesc(""); - exaremeAlgorithmDTO.setLabel(name); - exaremeAlgorithmDTO.setType("workflow"); - - // Transfer workflow parameters information - List<ExaremeAlgorithmRequestParamDTO> algorithmParams = new LinkedList<>(); - Gson gson = new Gson(); - for (Map.Entry<String, WorkflowInputDTO> workflowInput : getInputs().entrySet()) { - - // Convert the annotation to algorithm Parameter - ExaremeAlgorithmRequestParamDTO algorithmParam; - if (steps.get(workflowInput.getKey()).getAnnotation() != null) { - algorithmParam = gson.fromJson(steps.get(workflowInput.getKey()).getAnnotation(), - ExaremeAlgorithmRequestParamDTO.class); - } else { - // If annotation is not provided, auto-fill some information - algorithmParam = new ExaremeAlgorithmRequestParamDTO(); - // When the constraints are not known, set the most relaxed constraints - algorithmParam.setDesc(""); - algorithmParam.setValue(""); - algorithmParam.setValueType("string"); - algorithmParam.setValueNotBlank("false"); - algorithmParam.setDefaultValue(""); - algorithmParam.setDefaultValue("true"); - // If label is dataset/pathology/filter/formula the type should be the same - if (workflowInput.getValue().getLabel().equals("dataset") || - workflowInput.getValue().getLabel().equals("pathology") || - workflowInput.getValue().getLabel().equals("filter") || - workflowInput.getValue().getLabel().equals("formula")) { - algorithmParam.setType(workflowInput.getValue().getLabel()); - } else if (workflowInput.getValue().getLabel().equals("x") || - workflowInput.getValue().getLabel().equals("y")) { - algorithmParam.setType("column"); - algorithmParam.setColumnValuesSQLType("text,real,integer"); - algorithmParam.setColumnValuesIsCategorical(""); - } else { - algorithmParam.setType("other"); - } - } - // Set the name to the workflow id - algorithmParam.setName(workflowInput.getValue().getUuid()); - algorithmParam.setLabel(workflowInput.getValue().getLabel()); - - algorithmParams.add(algorithmParam); - } - exaremeAlgorithmDTO.setParameters(algorithmParams); - - return exaremeAlgorithmDTO; - } - -} diff --git a/src/main/java/eu/hbp/mip/services/AlgorithmService.java b/src/main/java/eu/hbp/mip/services/AlgorithmService.java index 93e22a297f33404c6aa1ee66e677ee34ca42ad5a..87aeca1cf33c12e245bc98b28e9dad3803117352 100644 --- a/src/main/java/eu/hbp/mip/services/AlgorithmService.java +++ b/src/main/java/eu/hbp/mip/services/AlgorithmService.java @@ -1,16 +1,9 @@ package eu.hbp.mip.services; -import com.github.jmchilton.blend4j.galaxy.GalaxyInstance; -import com.github.jmchilton.blend4j.galaxy.GalaxyInstanceFactory; -import com.github.jmchilton.blend4j.galaxy.WorkflowsClient; -import com.github.jmchilton.blend4j.galaxy.beans.Workflow; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients; -import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance; -import eu.hbp.mip.models.DTOs.ExaremeAlgorithmDTO; import eu.hbp.mip.models.DTOs.Exareme2AlgorithmDTO; -import eu.hbp.mip.models.galaxy.WorkflowDTO; +import eu.hbp.mip.models.DTOs.ExaremeAlgorithmDTO; import eu.hbp.mip.utils.CustomResourceLoader; import eu.hbp.mip.utils.Exceptions.BadRequestException; import eu.hbp.mip.utils.HTTPUtil; @@ -22,11 +15,12 @@ import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import retrofit2.Call; -import retrofit2.Response; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import static eu.hbp.mip.utils.InputStreamConverter.convertInputStreamToString; @@ -35,27 +29,19 @@ import static eu.hbp.mip.utils.InputStreamConverter.convertInputStreamToString; public class AlgorithmService { private static final Gson gson = new Gson(); - + private final CustomResourceLoader resourceLoader; private ArrayList<ExaremeAlgorithmDTO> algorithmDTOS = new ArrayList<>(); - @Value("#{'${services.exareme2.algorithmsUrl}'}") private String exareme2AlgorithmsUrl; - @Value("#{'${services.exareme.algorithmsUrl}'}") private String exaremeAlgorithmsUrl; - - @Value("#{'${services.galaxy.galaxyUrl}'}") - private String galaxyUrl; - - @Value("#{'${services.galaxy.galaxyApiKey}'}") - private String galaxyApiKey; - @Value("#{'${files.disabledAlgorithms_json}'}") private String disabledAlgorithmsFilePath; public AlgorithmService(CustomResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } + public ArrayList<ExaremeAlgorithmDTO> getAlgorithms() { return this.algorithmDTOS; @@ -64,17 +50,16 @@ public class AlgorithmService { public void update(Logger logger) { ArrayList<ExaremeAlgorithmDTO> exareme2Algorithms = getExareme2Algorithms(logger); ArrayList<ExaremeAlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms(logger); - ArrayList<ExaremeAlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows(logger); ArrayList<ExaremeAlgorithmDTO> algorithms = new ArrayList<>(); // Remove Exareme algorithms that exist in the Exareme2 - if (exareme2Algorithms != null && exaremeAlgorithms != null){ + if (exareme2Algorithms != null && exaremeAlgorithms != null) { int old_exareme_algorithm_size = exaremeAlgorithms.size(); for (ExaremeAlgorithmDTO algorithm : exareme2Algorithms) { exaremeAlgorithms.removeIf(obj -> Objects.equals(obj.getName(), algorithm.getName())); } - logger.LogUserAction("Removed "+ (old_exareme_algorithm_size - exaremeAlgorithms.size()) +" deprecated exareme algorithms"); + logger.LogUserAction("Removed " + (old_exareme_algorithm_size - exaremeAlgorithms.size()) + " deprecated exareme algorithms"); } if (exaremeAlgorithms != null) { @@ -89,12 +74,6 @@ public class AlgorithmService { } else { logger.LogUserAction("Fetching exareme2 algorithms failed"); } - if (galaxyAlgorithms != null) { - algorithms.addAll(galaxyAlgorithms); - logger.LogUserAction("Loaded " + galaxyAlgorithms.size() + " galaxy algorithms"); - } else { - logger.LogUserAction("Fetching galaxy workflows failed"); - } List<String> disabledAlgorithms = new ArrayList<>(); try { @@ -112,44 +91,24 @@ public class AlgorithmService { } int algorithmsRemoved = algorithms.size() - allowedAlgorithms.size(); - if (algorithmsRemoved > 0){ - logger.LogUserAction("Removed "+ (algorithmsRemoved) +" disabled algorithms"); + if (algorithmsRemoved > 0) { + logger.LogUserAction("Removed " + (algorithmsRemoved) + " disabled algorithms"); } this.algorithmDTOS = allowedAlgorithms; } - - @EnableAsync - public static class AlgorithmAggregator { - - private final AlgorithmService algorithmService; - - public AlgorithmAggregator(AlgorithmService algorithmService){ - this.algorithmService = algorithmService; - } - @Async - @Scheduled(fixedDelayString = "${services.algorithmsUpdateInterval}000") - public void scheduleFixedRateTaskAsync() throws InterruptedException { - algorithmService.update(new Logger("AlgorithmAggregator","(GET) /algorithms")); - } - } - - public String getAlgorithmEngineType(String algorithmName){ - Optional<ExaremeAlgorithmDTO> exaremeAlgorithmDTO = this.algorithmDTOS.stream().filter(algorithmDTO -> algorithmDTO.getName().equals(algorithmName)).findAny(); + public String getAlgorithmEngineType(String algorithmName) { + Optional<ExaremeAlgorithmDTO> exaremeAlgorithmDTO = this.algorithmDTOS.stream().filter(algorithmDTO -> algorithmDTO.getName().equals(algorithmName)).findAny(); if (exaremeAlgorithmDTO.isPresent()) return getAlgorithmEngineType(exaremeAlgorithmDTO.get()); else throw new BadRequestException("Algorithm: " + algorithmName + " does not exist."); } - private String getAlgorithmEngineType(ExaremeAlgorithmDTO algorithmDTO){ - switch (algorithmDTO.getType()) { - case "exareme2": - return "Exareme2"; - case "workflow": - return "Galaxy"; - default: - return "Exareme"; + private String getAlgorithmEngineType(ExaremeAlgorithmDTO algorithmDTO) { + if (algorithmDTO.getType().equals("exareme2")) { + return "Exareme2"; } + return "Exareme"; } /** @@ -205,65 +164,6 @@ public class AlgorithmService { return algorithms; } - /** - * This method gets all the available galaxy workflows, converts them into algorithms and - * - * @return a list of AlgorithmDTOs or null if something fails - */ - public ArrayList<ExaremeAlgorithmDTO> getGalaxyWorkflows(Logger logger) { - List<Workflow> workflowList; - try { - // Get all the workflows with the galaxy client - final GalaxyInstance instance = GalaxyInstanceFactory.get(galaxyUrl, galaxyApiKey); - final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); - - workflowList = new ArrayList<>(workflowsClient.getWorkflows()); - } catch (Exception e) { - logger.LogUserAction("Error when calling list galaxy workflows: " + e.getMessage()); - return null; - } - - // Get the workflow details with the custom client to receive them as a WorkflowDTO - List<WorkflowDTO> workflows = new ArrayList<>(); - // Create the request client - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - for (Workflow workflow : workflowList) { - // Call Galaxy to run the workflow - Call<WorkflowDTO> call = service.getWorkflowFromGalaxy(workflow.getId(), galaxyApiKey); - try { - Response<WorkflowDTO> response = call.execute(); - - if (response.code() == 200) { // Call succeeded - workflows.add(response.body()); - - } else { // Something unexpected happened - String msgErr = gson.toJson(response.errorBody()); - logger.LogUserAction("Error Response: " + msgErr); - return null; - } - } catch (Exception e) { - logger.LogUserAction("An exception occurred: " + e.getMessage()); - return null; - } - } - logger.LogUserAction("Workflows fetched: " + workflows.size()); - - // Convert the workflows to algorithms - ArrayList<ExaremeAlgorithmDTO> algorithms = new ArrayList<>(); - for (WorkflowDTO workflow : workflows) { - logger.LogUserAction("Converting workflow: " + workflow); - - algorithms.add(workflow.convertToAlgorithmDTO()); - - logger.LogUserAction("Converted algorithm: " + algorithms.get(algorithms.size() - 1)); - } - - logger.LogUserAction("Completed!"); - return algorithms; - } - - private final CustomResourceLoader resourceLoader; - /** * Fetches the disabled algorithms from a .json file * @@ -280,4 +180,20 @@ public class AlgorithmService { }.getType() ); } + + @EnableAsync + public static class AlgorithmAggregator { + + private final AlgorithmService algorithmService; + + public AlgorithmAggregator(AlgorithmService algorithmService) { + this.algorithmService = algorithmService; + } + + @Async + @Scheduled(fixedDelayString = "${services.algorithmsUpdateInterval}000") + public void scheduleFixedRateTaskAsync() { + algorithmService.update(new Logger("AlgorithmAggregator", "(GET) /algorithms")); + } + } } diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java index a7097e817249c1b713439a5145ce867129fa4879..081f44ea979571add6e1fdbf99f70067f1b83ead 100644 --- a/src/main/java/eu/hbp/mip/services/ExperimentService.java +++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java @@ -3,7 +3,10 @@ package eu.hbp.mip.services; import com.google.gson.Gson; import eu.hbp.mip.models.DAOs.ExperimentDAO; import eu.hbp.mip.models.DAOs.UserDAO; -import eu.hbp.mip.models.DTOs.*; +import eu.hbp.mip.models.DTOs.Exareme2AlgorithmRequestDTO; +import eu.hbp.mip.models.DTOs.ExaremeAlgorithmRequestParamDTO; +import eu.hbp.mip.models.DTOs.ExaremeAlgorithmResultDTO; +import eu.hbp.mip.models.DTOs.ExperimentDTO; import eu.hbp.mip.repositories.ExperimentRepository; import eu.hbp.mip.repositories.ExperimentSpecifications; import eu.hbp.mip.utils.ClaimUtils; @@ -29,26 +32,20 @@ import java.util.*; public class ExperimentService { + private static final Gson gson = new Gson(); + private final ActiveUserService activeUserService; + private final AlgorithmService algorithmService; + private final ExperimentRepository experimentRepository; @Value("#{'${services.exareme.queryExaremeUrl}'}") private String queryExaremeUrl; - @Value("#{'${services.exareme2.algorithmsUrl}'}") private String exareme2AlgorithmsUrl; - @Value("#{'${authentication.enabled}'}") private boolean authenticationIsEnabled; - private static final Gson gson = new Gson(); - - private final ActiveUserService activeUserService; - private final AlgorithmService algorithmService; - private final GalaxyService galaxyService; - private final ExperimentRepository experimentRepository; - - public ExperimentService(ActiveUserService activeUserService, AlgorithmService algorithmService, GalaxyService galaxyService, ExperimentRepository experimentRepository) { + public ExperimentService(ActiveUserService activeUserService, AlgorithmService algorithmService, ExperimentRepository experimentRepository) { this.algorithmService = algorithmService; this.activeUserService = activeUserService; - this.galaxyService = galaxyService; this.experimentRepository = experimentRepository; } @@ -65,7 +62,7 @@ public class ExperimentService { * @param orderBy is the column that is required to ordered by * @param descending is a boolean to determine if the experiments will be order by descending or ascending * @param logger contains username and the endpoint. - * @return a list of mapped experiments + * @return a map experiments */ public Map getExperiments(Authentication authentication, String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, Logger logger) { @@ -127,10 +124,10 @@ public class ExperimentService { experimentDAO = experimentRepository.loadExperiment(uuid, logger); if ( - authenticationIsEnabled - && !experimentDAO.isShared() - && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) - && !ClaimUtils.validateAccessRightsOnExperiments(authentication, logger) + authenticationIsEnabled + && !experimentDAO.isShared() + && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) + && !ClaimUtils.validateAccessRightsOnExperiments(authentication, logger) ) { logger.LogUserAction("Accessing Experiment is unauthorized."); throw new UnauthorizedException("You don't have access to the experiment."); @@ -151,10 +148,9 @@ public class ExperimentService { */ public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) { - //Checking if check (POST) /experiments has proper input. + // TODO ExperimentRequestDTO should be different than ExperimentResponseDTO checkPostExperimentProperInput(experimentDTO, logger); - // Get the engine name from algorithmService String algorithmEngineName = algorithmService.getAlgorithmEngineType(experimentDTO.getAlgorithm().getName().toUpperCase()); logger.LogUserAction("Algorithm runs on " + algorithmEngineName + "."); @@ -166,12 +162,8 @@ public class ExperimentService { ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger); } - // Run with the appropriate engine - if (algorithmEngineName.equals("Galaxy")) { - return galaxyService.createGalaxyExperiment(experimentDTO, logger); - } else { - return createSynchronousExperiment(experimentDTO, algorithmEngineName, logger); - } + return createSynchronousExperiment(experimentDTO, algorithmEngineName, logger); + } /** @@ -193,11 +185,6 @@ public class ExperimentService { experimentDTO.setUuid(UUID.randomUUID()); - if (algorithmEngineName.equals("Galaxy")) { - logger.LogUserAction("You can not run workflow algorithms transiently."); - throw new BadRequestException("You can not run workflow algorithms transiently."); - } - algorithmParametersLogging(experimentDTO, logger); if (authenticationIsEnabled) { @@ -295,7 +282,6 @@ public class ExperimentService { // /* ------------------------------- PRIVATE METHODS ----------------------------------------------------*/ private void checkPostExperimentProperInput(ExperimentDTO experimentDTO, Logger logger) { - boolean properInput = experimentDTO.getShared() == null && experimentDTO.getViewed() == null @@ -356,7 +342,7 @@ public class ExperimentService { private void algorithmParametersLogging(ExperimentDTO experimentDTO, Logger logger) { String algorithmName = experimentDTO.getAlgorithm().getName(); StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n"); - if (experimentDTO.getAlgorithm().getParameters() != null){ + if (experimentDTO.getAlgorithm().getParameters() != null) { experimentDTO.getAlgorithm().getParameters().forEach( params -> parametersLogMessage .append(" ") @@ -466,7 +452,7 @@ public class ExperimentService { * @param experimentDTO is the request with the experiment information * @return the result of experiment as well as the http status that was retrieved */ - private ExaremeAlgorithmResultDTO runSynchronousExperiment(ExperimentDTO experimentDTO, String algorithmEngineName, Logger logger) { + private ExaremeAlgorithmResultDTO runSynchronousExperiment(ExperimentDTO experimentDTO, String algorithmEngineName, Logger logger) { if (algorithmEngineName.equals("Exareme2")) { return runExareme2Experiment(experimentDTO, logger); } else { @@ -490,8 +476,7 @@ public class ExperimentService { = experimentDTO.getAlgorithm().getParameters(); List<ExaremeAlgorithmRequestParamDTO> algorithmParametersWithoutPathologyVersion = new ArrayList<>(); - for (ExaremeAlgorithmRequestParamDTO algorithmParameter : algorithmParameters) - { + for (ExaremeAlgorithmRequestParamDTO algorithmParameter : algorithmParameters) { if (algorithmParameter.getName().equals("pathology")) { List<String> pathology_info = Arrays.asList(algorithmParameter.getValue().split(":", 2)); String pathology_code = pathology_info.get(0); diff --git a/src/main/java/eu/hbp/mip/services/GalaxyService.java b/src/main/java/eu/hbp/mip/services/GalaxyService.java deleted file mode 100644 index 23c15d710a1a5c3725080f977e28b0a54b3be00c..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/services/GalaxyService.java +++ /dev/null @@ -1,456 +0,0 @@ -package eu.hbp.mip.services; - -import com.github.jmchilton.blend4j.galaxy.GalaxyInstance; -import com.github.jmchilton.blend4j.galaxy.GalaxyInstanceFactory; -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.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.internal.LinkedTreeMap; -import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients; -import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance; -import eu.hbp.mip.models.DAOs.ExperimentDAO; -import eu.hbp.mip.models.DTOs.ExaremeAlgorithmRequestParamDTO; -import eu.hbp.mip.models.DTOs.ExperimentDTO; -import eu.hbp.mip.models.galaxy.GalaxyWorkflowResult; -import eu.hbp.mip.models.galaxy.PostWorkflowToGalaxyDtoResponse; -import eu.hbp.mip.repositories.ExperimentRepository; -import eu.hbp.mip.utils.Exceptions.BadRequestException; -import eu.hbp.mip.utils.Exceptions.InternalServerError; -import eu.hbp.mip.utils.JsonConverters; -import eu.hbp.mip.utils.Logger; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import retrofit2.Call; -import retrofit2.Response; - -import java.io.IOException; -import java.util.*; - -import static java.lang.Thread.sleep; - -@Service -public class GalaxyService { - - private final ActiveUserService activeUserService; - private final ExperimentRepository experimentRepository; - public GalaxyService( - ActiveUserService activeUserService, - ExperimentRepository experimentRepository - ) { - this.activeUserService = activeUserService; - this.experimentRepository = experimentRepository; - } - @Value("#{'${services.galaxy.galaxyUrl}'}") - private String galaxyUrl; - - @Value("#{'${services.galaxy.galaxyApiKey}'}") - private String galaxyApiKey; - - private static final Gson gson = new Gson(); - - /** - * Creates an experiment and runs it on Galaxy - * - * @param experimentDTO is the request with the experiment information - * @return the response to be returned - */ - public ExperimentDTO createGalaxyExperiment(ExperimentDTO experimentDTO, Logger logger) { - logger.LogUserAction("Running a workflow..."); - - ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(), logger); - logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid()); - - - // Run the 1st algorithm from the list - String workflowId = experimentDTO.getAlgorithm().getName(); - - // Get the parameters - List<ExaremeAlgorithmRequestParamDTO> algorithmParameters - = experimentDTO.getAlgorithm().getParameters(); - - // Convert the parameters to workflow parameters - HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>(); - if (algorithmParameters != null) { - for (ExaremeAlgorithmRequestParamDTO param : algorithmParameters) { - algorithmParamsIncludingEmpty.put(param.getName(), param.getValue()); - } - } - - // Get all the algorithm parameters because the frontend provides only the non-null - final GalaxyInstance instance = GalaxyInstanceFactory.get(galaxyUrl, galaxyApiKey); - final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); - Workflow workflow = null; - for (Workflow curWorkflow : workflowsClient.getWorkflows()) { - if (curWorkflow.getId().equals(workflowId)) { - workflow = curWorkflow; - break; - } - } - if (workflow == null) { - logger.LogUserAction("Could not find algorithm code: " + workflowId); - throw new BadRequestException("Could not find galaxy algorithm."); - } - final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId()); - for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) { - if (!(algorithmParamsIncludingEmpty.containsKey(workflowParameter.getValue().getUuid()))) { - algorithmParamsIncludingEmpty.put(workflowParameter.getValue().getUuid(), ""); - } - } - - // Create the body of the request - HashMap<String, HashMap<String, String>> requestBody = new HashMap<>(); - requestBody.put("inputs", algorithmParamsIncludingEmpty); - JsonObject requestBodyJson = new JsonParser().parse(gson.toJson(requestBody)).getAsJsonObject(); - - // Create the request client - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - logger.LogUserAction("Running Galaxy workflow with id: " + workflow.getId()); - - // Call Galaxy to run the workflow - Call<PostWorkflowToGalaxyDtoResponse> call = service.postWorkflowToGalaxy(workflow.getId(), galaxyApiKey, requestBodyJson); - try { - Response<PostWorkflowToGalaxyDtoResponse> response = call.execute(); - - if (response.code() == 200) { // Call succeeded - String responseBody = gson.toJson(response.body()); - logger.LogUserAction("Response: " + responseBody); - - String historyId = (String) new JSONObject(responseBody).get("history_id"); - experimentDAO.setWorkflowHistoryId(historyId); - experimentDAO.setStatus(ExperimentDAO.Status.success); - - } else { // Something unexpected happened - String msgErr = gson.toJson(response.errorBody()); - logger.LogUserAction("Error Response: " + msgErr); - experimentDTO.setStatus((response.code() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success); - } - - } catch (Exception e) { - logger.LogUserAction("An exception occurred: " + e.getMessage()); - experimentDAO.setStatus(ExperimentDAO.Status.error); - } - experimentRepository.saveExperiment(experimentDAO, logger); - - // Start the process of fetching the status - updateWorkflowExperiment(experimentDAO, logger); - - logger.LogUserAction("Run workflow completed!"); - - experimentDTO = new ExperimentDTO(true, experimentDAO); - return experimentDTO; - } - - - - /** - * @param experimentDAO The experiment of the workflow - * @return "pending" -> When the workflow is still running - * "internalError" -> When an exception or a bad request occurred - * "error" -> When the workflow produced an error - * "success" -> When the workflow completed successfully - */ - public String getWorkflowStatus(ExperimentDAO experimentDAO) { - String historyId = experimentDAO.getWorkflowHistoryId(); - String experimentName = experimentDAO.getName(); - UUID experimentId = experimentDAO.getUuid(); - - // ATTENTION: This function is used from a Thread. Only LogBackgroundAction should be used, not LogUserAction! - Logger.LogBackgroundAction(experimentName, experimentId, " History Id : " + historyId); - - // Create the request client - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - Call<Object> call = service.getWorkflowStatusFromGalaxy(historyId, galaxyApiKey); - - String result; - try { - Response<Object> response = call.execute(); - if (response.code() >= 400) { - Logger.LogBackgroundAction(experimentName, experimentId, " Response code: " - + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " ")); - return "internalError"; - } - result = new Gson().toJson(response.body()); - Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + result); - - } catch (IOException e) { - Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage()); - return "internalError"; - } - - String state; - try { - JSONObject resultJson = new JSONObject(result); - state = resultJson.getString("state"); - } catch (JSONException e) { - Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage()); - return "internalError"; - } - - Logger.LogBackgroundAction(experimentName, experimentId, " Completed!"); - switch (state) { - case "ok": - return "success"; - case "error": - return "error"; - case "pending": - case "new": - case "waiting": - case "queued": - return "pending"; - default: - return "internalError"; - } - } - - /** - * @param experimentDAO The experiment of the workflow - * @return a List<GalaxyWorkflowResult> or null when an error occurred - */ - public List<GalaxyWorkflowResult> getWorkflowResults(ExperimentDAO experimentDAO) { - - String historyId = experimentDAO.getWorkflowHistoryId(); - String experimentName = experimentDAO.getName(); - UUID experimentId = experimentDAO.getUuid(); - Logger.LogBackgroundAction(experimentName, experimentId, " historyId : " + historyId); - - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey); - - List<GalaxyWorkflowResult> getGalaxyWorkflowResultList; - try { - Response<List<GalaxyWorkflowResult>> response = call.execute(); - if (response.code() >= 400) { - Logger.LogBackgroundAction(experimentName, experimentId, " Response code: " - + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " ")); - return null; - } - getGalaxyWorkflowResultList = response.body(); - Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + response.body()); - - } catch (IOException e) { - Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage()); - return null; - } - - Logger.LogBackgroundAction(experimentName, experimentId, " Completed!"); - return getGalaxyWorkflowResultList; - - } - - /** - * @param experimentDAO The experiment of the workflow - * @param contentId the id of the job result that we want - * @return the result of the specific workflow job, null if there was an error - */ - public String getWorkflowResultBody(ExperimentDAO experimentDAO, String contentId) { - - String historyId = experimentDAO.getWorkflowHistoryId(); - String experimentName = experimentDAO.getName(); - UUID experimentId = experimentDAO.getUuid(); - - Logger.LogBackgroundAction(experimentName, experimentId, " historyId : " + historyId); - - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - Call<Object> call = - service.getWorkflowResultsBodyFromGalaxy(historyId, contentId, galaxyApiKey); - - String resultJson; - try { - Response<Object> response = call.execute(); - if (response.code() >= 400) { - Logger.LogBackgroundAction(experimentName, experimentId, " Response code: " - + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " ")); - return null; - } - resultJson = new Gson().toJson(response.body()); - Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + resultJson); - - } catch (IOException e) { - Logger.LogBackgroundAction(experimentName, experimentId, - " An exception happened: " + e.getMessage()); - return null; - } - - Logger.LogBackgroundAction(experimentName, experimentId, " Completed!"); - return formattingGalaxyResult(resultJson); - } - - private String formattingGalaxyResult(String result) { - List<LinkedTreeMap<String,Object>> jsonObject = JsonConverters.convertJsonStringToObject(result, new ArrayList<ArrayList<Object>>().getClass()); - LinkedTreeMap<String,Object> firstResult = jsonObject.get(0); - jsonObject = (List<LinkedTreeMap<String, Object>>) firstResult.get("result"); - List<LinkedTreeMap<String,Object>> finalJsonObject = new ArrayList<>(); - finalJsonObject.add(jsonObject.get(0)); - return JsonConverters.convertObjectToJsonString(finalJsonObject); - } - - - /** - * @param jobId the id of the workflow job that failed - * @return the error that was produced or null if an error occurred - */ - public String getWorkflowJobError(String jobId, ExperimentDAO experimentDAO) { - String experimentName = experimentDAO.getName(); - UUID experimentId = experimentDAO.getUuid(); - - Logger.LogBackgroundAction(experimentName, experimentId, " jobId : " + jobId); - RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); - Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey); - - String fullError; - String returnError; - try { - Response<Object> response = callError.execute(); - if (response.code() >= 400) { - Logger.LogBackgroundAction(experimentName, experimentId, "Response code: " - + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " ")); - return null; - } - - // Parsing the stderr of the job that failed - String jsonString = new Gson().toJson(response.body()); - JsonElement jsonElement = new JsonParser().parse(jsonString); - JsonObject rootObject = jsonElement.getAsJsonObject(); - fullError = rootObject.get("stderr").getAsString(); - Logger.LogBackgroundAction(experimentName, experimentId, "Error: " + fullError); - - String[] arrOfStr = fullError.split("ValueError", 0); - String specError = arrOfStr[arrOfStr.length - 1]; - returnError = specError.substring(1); - Logger.LogBackgroundAction(experimentName, experimentId, "Parsed Error: " + returnError); - - } catch (IOException e) { - Logger.LogBackgroundAction(experimentName, experimentId, "Exception: " + e.getMessage()); - return null; - } - - Logger.LogBackgroundAction(experimentName, experimentId, "Completed successfully!"); - - return returnError; - } - - /** - * This method creates a thread that will fetch the workflow result when it is ready - * - * @param experimentDAO will be used to fetch it's workflow status, it should have the workflowHistoryId initialized - * and the result should not already be fetched - */ - public void updateWorkflowExperiment(ExperimentDAO experimentDAO, Logger logger) { - - if (experimentDAO == null) { - logger.LogUserAction("The experiment does not exist."); - return; - } - - logger.LogUserAction(" Experiment id : " + experimentDAO.getUuid()); - if (experimentDAO.getWorkflowHistoryId() == null) { - logger.LogUserAction("History Id does not exist."); - return; - } - - logger.LogUserAction("Starting Thread..."); - new Thread(() -> { - while (true) { - // ATTENTION: Inside the Thread only LogBackgroundAction should be used, not LogUserAction! - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running..."); - - try { - sleep(2000); - } catch (InterruptedException e) { - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage()); - throw new InternalServerError(e.getMessage()); - } - - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid()); - - String state = getWorkflowStatus(experimentDAO); - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state); - - switch (state) { - case "pending": - // Do nothing, when the experiment is created the status is set to running - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running."); - break; - - case "success": - // Get only the job result that is visible - List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experimentDAO); - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString()); - - boolean resultFound = false; - for (GalaxyWorkflowResult jobResult : workflowJobsResults) { - if (jobResult.getVisible()) { - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId()); - - String result = getWorkflowResultBody(experimentDAO, jobResult.getId()); - - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result); - if (result == null) { - experimentDAO.setStatus(ExperimentDAO.Status.error); - } else { - experimentDAO.setResult(result); - experimentDAO.setStatus(ExperimentDAO.Status.success); - resultFound = true; - } - } - } - - if (!resultFound) { // If there is no visible result - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result"); - experimentDAO.setStatus(ExperimentDAO.Status.error); - } - - experimentRepository.finishExperiment(experimentDAO, logger); - break; - - case "error": - // Get the job result that failed - workflowJobsResults = getWorkflowResults(experimentDAO); - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString()); - - boolean failedJobFound = false; - for (GalaxyWorkflowResult jobResult : workflowJobsResults) { - if (jobResult.getState().equals("error")) { - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId()); - - String result = getWorkflowJobError(jobResult.getId(), experimentDAO); - - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result); - if (result == null) { - experimentDAO.setStatus(ExperimentDAO.Status.error); - } - experimentDAO.setStatus(ExperimentDAO.Status.error); - failedJobFound = true; - } - } - - if (!failedJobFound) { // If there is no visible failed job - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result"); - experimentDAO.setStatus(ExperimentDAO.Status.error); - } - experimentRepository.finishExperiment(experimentDAO, logger); - break; - - default: // InternalError or unexpected result - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred."); - experimentDAO.setStatus(ExperimentDAO.Status.error); - experimentRepository.finishExperiment(experimentDAO, logger); - break; - } - - // If result exists return - if (experimentDAO.getResult() != null) { - Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult()); - return; - } - } - }).start(); - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7f64c8f92155979b72148a472b35285098d4e419..89fb72844192a95de2b4d216623980224eb3fa97 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -46,12 +46,6 @@ services: exareme: queryExaremeUrl: "http://127.0.0.1:9090/mining/query" algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json" - galaxy: - galaxyUrl: "http://127.0.0.1:8090" - galaxyContext: "nativeGalaxy/workflows/list" - galaxyApiKey: "d14a4cc5eebf805eb2ff261374ed08a2" - galaxyUsername: "admin" - galaxyPassword: "password" ### KEYCLOAK ###