From 30c06d2e0d526257f70ee9e8bcde3c1da2e3db6f Mon Sep 17 00:00:00 2001 From: kfilippopolitis <kostasfilippop@gmail.com> Date: Fri, 4 Jun 2021 03:28:08 -0700 Subject: [PATCH] Mip engine integration first touce --- docker/README.md | 2 + docker/config/application.tmpl | 3 + .../eu/hbp/mip/controllers/AlgorithmsAPI.java | 50 ++++++- .../models/DTOs/MIPEngineAlgorithmDTO.java | 119 +++++++++++++++++ .../hbp/mip/services/ExperimentService.java | 123 ++++++++++++------ src/main/resources/application.yml | 2 + 6 files changed, 254 insertions(+), 45 deletions(-) create mode 100644 src/main/java/eu/hbp/mip/models/DTOs/MIPEngineAlgorithmDTO.java diff --git a/docker/README.md b/docker/README.md index 9636ff324..8693aad09 100644 --- a/docker/README.md +++ b/docker/README.md @@ -24,6 +24,8 @@ To use this image, you need a running instance of PostgreSQL and to configure th ### EXTERNAL SERVICES ### +* MIPENGINE_URL: URL to MIPENGINE server. Default is "http://localhost:5000" . + * EXAREME_URL: URL to Exareme server. Default is "http://localhost:9090" . * GALAXY_URL: URL to Workflow server. Default is "http://localhost:8090/" . diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index ae10744aa..0913c99e7 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -34,6 +34,9 @@ spring: ### EXTERNAL SERVICES ### services: + mipengine: + algorithmsUrl: {{ default .Env.MIPENGINE_URL "http://localhost:5000" }}/algorithms + exareme: queryExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query algorithmsUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/algorithms.json diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java index 48500bb10..1ca68f13b 100644 --- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java +++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java @@ -9,6 +9,7 @@ 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.AlgorithmDTO; +import eu.hbp.mip.models.DTOs.MIPEngineAlgorithmDTO; import eu.hbp.mip.models.galaxy.WorkflowDTO; import eu.hbp.mip.services.ActiveUserService; import eu.hbp.mip.utils.CustomResourceLoader; @@ -42,6 +43,9 @@ public class AlgorithmsAPI { private final ActiveUserService activeUserService; + @Value("#{'${services.mipengine.algorithmsUrl}'}") + private String mipengineAlgorithmsUrl; + @Value("#{'${services.exareme.algorithmsUrl}'}") private String exaremeAlgorithmsUrl; @@ -64,8 +68,9 @@ public class AlgorithmsAPI { public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() { Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms"); - logger.LogUserAction("Executing..."); - +// logger.LogUserAction("Executing..."); + LinkedList<AlgorithmDTO> mipengineAlgorithms = getMIPEngineAlgorithms(logger); + logger.LogUserAction("Loaded " + mipengineAlgorithms.size() + " mipengine algorithms"); LinkedList<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms(logger); logger.LogUserAction("Loaded " + exaremeAlgorithms.size() + " exareme algorithms"); LinkedList<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows(logger); @@ -73,12 +78,17 @@ public class AlgorithmsAPI { LinkedList<AlgorithmDTO> algorithms = new LinkedList<>(); if (exaremeAlgorithms != null) { - algorithms.addAll(exaremeAlgorithms); +// algorithms.addAll(exaremeAlgorithms); } else { logger.LogUserAction("Getting exareme algorithms failed and returned null"); } + if (mipengineAlgorithms != null) { + algorithms.addAll(mipengineAlgorithms); + } else { + logger.LogUserAction("Getting mipengine algorithms failed and returned null"); + } if (galaxyAlgorithms != null) { - algorithms.addAll(galaxyAlgorithms); +// algorithms.addAll(galaxyAlgorithms); } else { logger.LogUserAction("Getting galaxy workflows failed and returned null"); } @@ -112,7 +122,6 @@ public class AlgorithmsAPI { try { StringBuilder response = new StringBuilder(); HTTPUtil.sendGet(exaremeAlgorithmsUrl, response); - algorithms = gson.fromJson( response.toString(), new TypeToken<LinkedList<AlgorithmDTO>>() { @@ -127,6 +136,37 @@ public class AlgorithmsAPI { return algorithms; } + /** + * This method gets all the available mipengine algorithms and + * + * @return a list of AlgorithmDTOs or null if something fails + */ + public LinkedList<AlgorithmDTO> getMIPEngineAlgorithms(Logger logger) { + LinkedList<MIPEngineAlgorithmDTO> mipEngineAlgorithms; + // Get MIPEngine algorithms + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendGet(mipengineAlgorithmsUrl, response); + logger.LogUserAction(response.toString()); + + mipEngineAlgorithms = gson.fromJson( + response.toString(), + new TypeToken<LinkedList<MIPEngineAlgorithmDTO>>() { + }.getType() + ); + } catch (IOException e) { + logger.LogUserAction("An exception occurred: " + e.getMessage()); + return null; + } + + + LinkedList<AlgorithmDTO> algorithms = new LinkedList<>(); + mipEngineAlgorithms.forEach(mipEngineAlgorithm -> algorithms.add(mipEngineAlgorithm.convertToAlgorithmDTO())); + + logger.LogUserAction("Completed, returned " + algorithms.size() + " algorithms."); + return algorithms; + } + /** * This method gets all the available galaxy workflows, converts them into algorithms and * diff --git a/src/main/java/eu/hbp/mip/models/DTOs/MIPEngineAlgorithmDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/MIPEngineAlgorithmDTO.java new file mode 100644 index 000000000..a250e4249 --- /dev/null +++ b/src/main/java/eu/hbp/mip/models/DTOs/MIPEngineAlgorithmDTO.java @@ -0,0 +1,119 @@ +package eu.hbp.mip.models.DTOs; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +@Getter +@Setter +public class MIPEngineAlgorithmDTO { + + @SerializedName("name") + private String name; + + @SerializedName("desc") + private String desc; + + @SerializedName("label") + private String label; + + @SerializedName("type") + private String type; + + @SerializedName("parameters") + private Object parameters; + + @SerializedName("crossvalidation") + private String crossvalidation; + + @SerializedName("inputdata") + private Hashtable<String, InputDataParamDTO> inputdata; + + @Getter + @Setter + public static class InputDataParamDTO { + + @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; + public AlgorithmDTO.AlgorithmParamDTO convertToAlgorithmParamDTO(String name) throws Exception { + AlgorithmDTO.AlgorithmParamDTO algorithmParamDTO = new AlgorithmDTO.AlgorithmParamDTO(); + algorithmParamDTO.setName(name); + algorithmParamDTO.setDesc(this.desc); + algorithmParamDTO.setLabel(this.label); + if(name.equals("datasets") || name.equals("filter") || name.equals("pathology")){ + algorithmParamDTO.setType(name.equals("datasets")? "dataset":name); + algorithmParamDTO.setValueType(this.types.get(0)); + } + else{ + if(stattypes == null){ + System.out.println("Dsafasfads------------------------->>>>>>>>>>>>>>>"); + System.out.println(name); + } + algorithmParamDTO.setType("column"); + algorithmParamDTO.setColumnValuesSQLType(String.join(", ", this.types)); + algorithmParamDTO.setColumnValuesIsCategorical(getColumnValuesIsCategorical(this.stattypes)); + } + algorithmParamDTO.setValue(""); + algorithmParamDTO.setValueNotBlank(this.notblank); + algorithmParamDTO.setValueMultiple(this.multiple); + return algorithmParamDTO; + } + private String getColumnValuesIsCategorical(List<String> stattypes) throws Exception { + + 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 Exception("Invalid stattypes"); + } + } + } + + public AlgorithmDTO convertToAlgorithmDTO() + { + AlgorithmDTO algorithmDTO = new AlgorithmDTO(); + algorithmDTO.setName(this.name); + algorithmDTO.setLabel(this.label); + algorithmDTO.setDesc(this.desc); + algorithmDTO.setType("mipengine"); + List<AlgorithmDTO.AlgorithmParamDTO> parameters = new ArrayList<>(); + this.inputdata.forEach((name, inputDataParamDTO) -> { + try { + AlgorithmDTO.AlgorithmParamDTO parameter = inputDataParamDTO.convertToAlgorithmParamDTO(name); + parameters.add(parameter); + } catch (Exception e) { + e.printStackTrace(); + } + }); + algorithmDTO.setParameters(parameters); + return algorithmDTO; + } +} diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java index 45345c8a5..a8b176d76 100644 --- a/src/main/java/eu/hbp/mip/services/ExperimentService.java +++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java @@ -50,6 +50,9 @@ public class ExperimentService { @Value("#{'${services.exareme.queryExaremeUrl}'}") private String queryExaremeUrl; + @Value("#{'${services.mipengine.algorithmsUrl}'}") + private String mipengineAlgorithmsUrl; + @Value("#{'${services.galaxy.galaxyUrl}'}") private String galaxyUrl; @@ -194,7 +197,7 @@ public class ExperimentService { return runGalaxyWorkflow(experimentDTO, logger); } else { logger.LogUserAction("Algorithm runs on Exareme."); - return createExaremeExperiment(experimentDTO, logger); + return createExperiment(experimentDTO, logger); } } @@ -219,13 +222,6 @@ public class ExperimentService { throw new BadRequestException("You can not run workflow algorithms transiently."); } - // Get the parameters - List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters - = experimentDTO.getAlgorithm().getParameters(); - - // Get the type and name of algorithm - String algorithmName = experimentDTO.getAlgorithm().getName(); - algorithmParametersLogging(experimentDTO, logger); if (authenticationIsEnabled) { @@ -233,19 +229,15 @@ public class ExperimentService { ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger); } - String body = gson.toJson(algorithmParameters); - String url = queryExaremeUrl + "/" + algorithmName; - logger.LogUserAction("url: " + url + ", body: " + body); - - logger.LogUserAction("Completed, returning: " + experimentDTO.toString()); + logger.LogUserAction("Completed, returning: " + experimentDTO); // Results are stored in the experiment object - ExaremeResult exaremeResult = runExaremeExperiment(url, body, experimentDTO); + ExperimentResult experimentResult = runExperiment(experimentDTO, logger); - logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults()); + logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + experimentResult.getCode() + " and result: " + experimentResult.getResults()); - experimentDTO.setResult((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults()); - experimentDTO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success); + experimentDTO.setResult((experimentResult.getCode() >= 400) ? null : experimentResult.getResults()); + experimentDTO.setStatus((experimentResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success); return experimentDTO; } @@ -514,15 +506,52 @@ public class ExperimentService { return JsonConverters.convertObjectToJsonString(finalJsonObject); } + /** + * The runExperiment will run the experiment to exareme or MIPEngine. + * + * @param experimentDTO is the request with the experiment information + * @return the result of experiment as well as the http status that was retrieved + */ + public ExperimentResult runExperiment(ExperimentDTO experimentDTO, Logger logger) { + + // Algorithm type + String algorithmType = experimentDTO.getAlgorithm().getType(); + + // Run the 1st algorithm from the list + String algorithmName = experimentDTO.getAlgorithm().getName(); + + // Get the parameters + List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters + = experimentDTO.getAlgorithm().getParameters(); + + String body = gson.toJson(algorithmParameters); + + logger.LogUserAction("Completed, returning: " + experimentDTO); + + + // Run with the appropriate engine + if (algorithmType.equals("mipengine")) { + String url = mipengineAlgorithmsUrl + "/" + algorithmName; + logger.LogUserAction("url: " + url + ", body: " + body); + logger.LogUserAction("Algorithm runs on MIPEngine."); + return runMIPEngineExperiment(url, body); + } else { + String url = queryExaremeUrl + "/" + algorithmName; + logger.LogUserAction("url: " + url + ", body: " + body); + logger.LogUserAction("Algorithm runs on Exareme."); + return runExaremeExperiment(url, body); + } + } + + /** * The runExaremeExperiment will run to exareme the experiment * * @param url is the url that contain the results of the experiment * @param body is the parameters of the algorithm - * @param experimentDTO is the experiment information to be executed in the exareme * @return the result of exareme as well as the http status that was retrieved */ - public ExaremeResult runExaremeExperiment(String url, String body, ExperimentDTO experimentDTO) { + public ExperimentResult runExaremeExperiment(String url, String body) { StringBuilder results = new StringBuilder(); int code; @@ -536,7 +565,32 @@ public class ExperimentService { ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class); List<Object> resultDTOS = experimentDTOWithOnlyResult.getResult(); - return new ExaremeResult(code, resultDTOS); + return new ExperimentResult(code, resultDTOS); + } + + /** + * The runExaremeExperiment will run to exareme the experiment + * + * @param url is the url that contain the results of the experiment + * @param body is the parameters of the algorithm + * @return the result of exareme as well as the http status that was retrieved + */ + public ExperimentResult runMIPEngineExperiment(String url, String body) { + + StringBuilder results = new StringBuilder(); + int code; + try { + code = HTTPUtil.sendPost(url, body, results); + } catch (Exception e) { + throw new InternalServerError("Error occurred : " + e.getMessage()); + } + System.out.println("----------------------------------->>>>>>>>>>>>>>>>>>>>>>"); + System.out.println(results); + // Results are stored in the experiment object + ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class); + List<Object> resultDTOS = experimentDTOWithOnlyResult.getResult(); + + return new ExperimentResult(code, resultDTOS); } /* -------------------------------------- EXAREME CALLS ---------------------------------------------------------*/ @@ -548,27 +602,15 @@ public class ExperimentService { * @param logger contains username and the endpoint. * @return the experiment information that was retrieved from exareme */ - public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, Logger logger) { + public ExperimentDTO createExperiment(ExperimentDTO experimentDTO, Logger logger) { logger.LogUserAction("Running the algorithm..."); ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, logger); logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid()); - // Run the 1st algorithm from the list - String algorithmName = experimentDTO.getAlgorithm().getName(); - - // Get the parameters - List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters - = experimentDTO.getAlgorithm().getParameters(); - - String body = gson.toJson(algorithmParameters); - String url = queryExaremeUrl + "/" + algorithmName; - logger.LogUserAction("url: " + url + ", body: " + body); - - logger.LogUserAction("Completed, returning: " + experimentDTO.toString()); - logger.LogUserAction("Starting exareme execution thread"); + logger.LogUserAction("Starting execution in thread"); ExperimentDTO finalExperimentDTO = experimentDTO; new Thread(() -> { @@ -576,13 +618,14 @@ public class ExperimentService { Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!"); try { + // Results are stored in the experiment object - ExaremeResult exaremeResult = runExaremeExperiment(url, body, finalExperimentDTO); + ExperimentResult experimentResult = runExperiment(finalExperimentDTO, logger); - Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults()); + Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + experimentResult.getCode() + " and result: " + experimentResult.getResults()); - experimentDAO.setResult((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(exaremeResult.getResults())); - experimentDAO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success); + experimentDAO.setResult((experimentResult.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(experimentResult.getResults())); + experimentDAO.setStatus((experimentResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success); } catch (Exception e) { Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage()); @@ -988,11 +1031,11 @@ public class ExperimentService { return returnError; } - static class ExaremeResult { + static class ExperimentResult { private final int code; private final List<Object> results; - public ExaremeResult(int code, List<Object> results) { + public ExperimentResult(int code, List<Object> results) { this.code = code; this.results = results; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 345fc4bfa..d8d542b6b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -34,6 +34,8 @@ spring: ### EXTERNAL SERVICES ### services: + mipengine: + algorithmsUrl: "http://127.0.0.1:5000/algorithms" exareme: queryExaremeUrl: "http://127.0.0.1:9090/mining/query" algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json" -- GitLab