diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java new file mode 100644 index 0000000000000000000000000000000000000000..492358c59c14801df01548032d0722a1c929a5bb --- /dev/null +++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java @@ -0,0 +1,157 @@ +package eu.hbp.mip.controllers; + +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 eu.hbp.mip.controllers.retrofit.RetroFitGalaxyClients; +import eu.hbp.mip.controllers.retrofit.RetrofitClientInstance; +import eu.hbp.mip.model.AlgorithmDTO; +import eu.hbp.mip.model.galaxy.WorkflowDTO; +import eu.hbp.mip.utils.HTTPUtil; +import eu.hbp.mip.utils.UserActionLogging; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import retrofit2.Call; +import retrofit2.Response; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +@RestController +@RequestMapping(value = "/algorithms", produces = {APPLICATION_JSON_VALUE}) +@Api(value = "/algorithms") +public class AlgorithmsApi { + + private static final Gson gson = new Gson(); + + @Value("#{'${services.exareme.algorithmsUrl}'}") + private String exaremeAlgorithmsUrl; + + @Value("#{'${services.galaxy.galaxyUrl}'}") + private String galaxyUrl; + + @Value("#{'${services.galaxy.galaxyApiKey}'}") + private String galaxyApiKey; + + @ApiOperation(value = "List all algorithms", response = String.class) + @RequestMapping(value = "/", method = RequestMethod.GET) + public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() { + UserActionLogging.LogAction("List all algorithms", ""); + + List<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms(); + List<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows(); + + List<AlgorithmDTO> algorithms = new LinkedList<>(); + if (exaremeAlgorithms != null) { + algorithms.addAll(exaremeAlgorithms); + } else { + UserActionLogging.LogAction("List all algorithms", + "Getting exareme algorithms failed and returned null"); + } + if (galaxyAlgorithms != null) { + algorithms.addAll(galaxyAlgorithms); + } else { + UserActionLogging.LogAction("List all algorithms", + "Getting galaxy workflows failed and returned null"); + } + + return ResponseEntity.ok(algorithms); + } + + /** + * This method gets all the available exareme algorithms and + * + * @return a list of AlgorithmDTOs or null if something fails + */ + public List<AlgorithmDTO> getExaremeAlgorithms() { + UserActionLogging.LogAction("List exareme algorithms", ""); + + List<AlgorithmDTO> algorithms = new LinkedList<>(); + // Get exareme algorithms + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendGet(exaremeAlgorithmsUrl, response); + + algorithms = gson.fromJson(response.toString(), algorithms.getClass()); + } catch (IOException e) { + UserActionLogging.LogAction("List exareme algorithms", "An exception occurred: " + e.getMessage()); + return null; + } + + UserActionLogging.LogAction("List exareme algorithms", + "Completed, returned " + algorithms.size() + " algorithms."); + 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 List<AlgorithmDTO> getGalaxyWorkflows() { + UserActionLogging.LogAction("List Galaxy workflows", ""); + + List<Workflow> workflowList = null; + 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) { + UserActionLogging.LogAction("List Galaxy workflows", "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 LinkedList<>(); + // 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()); + UserActionLogging.LogAction("List Galaxy workflows", "Error Response: " + msgErr); + return null; + } + } catch (Exception e) { + UserActionLogging.LogAction("List Galaxy workflows", "An exception occurred: " + e.getMessage()); + return null; + } + } + UserActionLogging.LogAction("List Galaxy workflows", "Workflows fetched: " + workflows.size()); + + // Convert the workflows to algorithms + List<AlgorithmDTO> algorithms = new LinkedList<>(); + for (WorkflowDTO workflow : workflows) { + UserActionLogging.LogAction("List Galaxy workflows", "Converting workflow: " + workflow); + + algorithms.add(workflow.convertToAlgorithmDTO()); + + UserActionLogging.LogAction("List Galaxy workflows", + "Converted algorithm: " + algorithms.get(algorithms.size() - 1)); + } + + UserActionLogging.LogAction("List Galaxy workflows", "Completed!"); + return algorithms; + } +} diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index b936cdd35a7dadb97ca7d1d95a2a0167d00527b8..927bcf8f13a23a87f816c602077bf3570277120e 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -10,10 +10,11 @@ import com.google.common.collect.Lists; import com.google.gson.*; import eu.hbp.mip.controllers.retrofit.RetroFitGalaxyClients; import eu.hbp.mip.controllers.retrofit.RetrofitClientInstance; -import eu.hbp.mip.dto.ErrorResponse; -import eu.hbp.mip.dto.GalaxyWorkflowResult; -import eu.hbp.mip.dto.PostWorkflowToGalaxyDtoResponse; import eu.hbp.mip.model.*; +import eu.hbp.mip.model.ExperimentExecutionDTO.AlgorithmExecutionDTO.AlgorithmExecutionParamDTO; +import eu.hbp.mip.model.galaxy.ErrorResponse; +import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult; +import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse; import eu.hbp.mip.repositories.ExperimentRepository; import eu.hbp.mip.repositories.ModelRepository; import eu.hbp.mip.utils.HTTPUtil; @@ -41,15 +42,13 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @Api(value = "/experiments") public class ExperimentApi { - //private static final Logger LOGGER = LoggerFactory.getLogger(ExperimentApi.class); - private static final Gson gson = new Gson(); private static final Gson gsonOnlyExposed = new GsonBuilder().serializeNulls() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").excludeFieldsWithoutExposeAnnotation().create(); - @Value("#{'${services.exareme.miningExaremeUrl:http://localhost:9090/mining/query}'}") - public String miningExaremeQueryUrl; + @Value("#{'${services.exareme.miningExaremeUrl}'}") + public String exaremeUrl; @Value("#{'${services.workflows.workflowUrl}'}") private String workflowUrl; @@ -57,6 +56,12 @@ public class ExperimentApi { @Value("#{'${services.workflows.jwtSecret}'}") private String jwtSecret; + @Value("#{'${services.galaxy.galaxyUrl}'}") + private String galaxyUrl; + + @Value("#{'${services.galaxy.galaxyApiKey}'}") + private String galaxyApiKey; + @Autowired private UserInfo userInfo; @@ -66,69 +71,110 @@ public class ExperimentApi { @Autowired private ExperimentRepository experimentRepository; - @Value("#{'${services.galaxy.galaxyUrl}'}") - private String galaxyUrl; + @ApiOperation(value = "Create an experiment", response = Experiment.class) + @RequestMapping(value = "/runAlgorithm", method = RequestMethod.POST) + public ResponseEntity<String> runExperiment(@RequestBody ExperimentExecutionDTO experimentExecutionDTO) { + UserActionLogging.LogAction("Run algorithm", "Running the algorithm..."); - @Value("#{'${services.galaxy.galaxyApiKey}'}") - private String galaxyApiKey; + // Get the type of algorithm + String algorithmType = experimentExecutionDTO.getAlgorithms().get(0).getType(); - @ApiOperation(value = "Create an experiment on Exareme", response = Experiment.class) - @RequestMapping(value = "/exareme", method = RequestMethod.POST) - public ResponseEntity<String> runExaremeExperiment(@RequestBody ExperimentQuery expQuery) { - //LOGGER.info("send ExaremeExperiment"); + if (algorithmType.equals("workflow")) { + return runGalaxyWorkflow(experimentExecutionDTO); + } else { + return runExaremeAlgorithm(experimentExecutionDTO); + } - Experiment experiment = saveExperiment(expQuery); + } - String algoCode = expQuery.getAlgorithms().get(0).getCode(); - List<AlgorithmParam> params = expQuery.getAlgorithms().get(0).getParameters(); - new Thread(() -> { - List<HashMap<String, String>> queryList = new ArrayList<HashMap<String, String>>(); + /** + * The runExaremeExperiment will POST the algorithm to the exareme client + * + * @param experimentExecutionDTO is the request with the experiment information + * @return the response to be returned + */ + public ResponseEntity<String> runExaremeAlgorithm(ExperimentExecutionDTO experimentExecutionDTO) { + UserActionLogging.LogAction("Run exareme algorithm", "Running the algorithm..."); - if (params != null) { - for (AlgorithmParam p : params) { - queryList.add(makeObject(p.getName(), p.getValue())); - } - } + Experiment experiment = createExperiment(experimentExecutionDTO); + + // Run the 1st algorithm from the list + String algorithmName = experimentExecutionDTO.getAlgorithms().get(0).getName(); + + // Get the parameters + List<AlgorithmExecutionParamDTO> algorithmParameters + = experimentExecutionDTO.getAlgorithms().get(0).getParameters(); + + String body = gson.toJson(algorithmParameters); + String url = exaremeUrl + "/" + algorithmName; + UserActionLogging.LogAction("Run exareme algorithm", "url: " + url + ", body: " + body); + + ResponseEntity<String> response = new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); + UserActionLogging.LogAction("Run exareme algorithm", + "Completed, returning: " + experiment.toString()); - String query = gson.toJson(queryList); - String url = miningExaremeQueryUrl + "/" + algoCode; + UserActionLogging.LogAction("Run exareme algorithm", + "Starting exareme execution thread"); + new Thread(() -> { + // ATTENTION: Inside the Thread only LogThreadAction should be used, not LogAction! + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "Thread started!"); - // Results are stored in the experiment object try { + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "Thread started!"); StringBuilder results = new StringBuilder(); - int code = HTTPUtil.sendPost(url, query, results); + int code = HTTPUtil.sendPost(url, body, results); + + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "Algorithm finished with code: " + code); + + // Results are stored in the experiment object experiment.setResult("[" + results.toString() + "]"); experiment.setHasError(code >= 400); experiment.setHasServerError(code >= 500); - } catch (IOException e) { - //LOGGER.trace("Invalid UUID", e); - //LOGGER.warn("Exareme experiment failed to run properly !"); + } catch (Exception e) { + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "There was an exception: " + e.getMessage()); + experiment.setHasError(true); experiment.setHasServerError(true); experiment.setResult(e.getMessage()); } + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "Finished the experiment: " + experiment.toString()); finishExperiment(experiment); - }).start(); - UserActionLogging.LogAction("create ExaremeExperiment", "no info"); + UserActionLogging.LogThreadAction("Thread, Run exareme algorithm", + "Finished!"); + }).start(); - return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); + return response; } - @ApiOperation(value = "Create a workflow", response = Experiment.class) - @RequestMapping(value = "/workflow", method = RequestMethod.POST) - public ResponseEntity runWorkflow(@RequestBody ExperimentQuery expQuery) { + /** + * The runWorkflow will POST the algorithm to the galaxy client + * + * @param experimentExecutionDTO is the request with the experiment information + * @return the response to be returned + */ + public ResponseEntity<String> runGalaxyWorkflow(ExperimentExecutionDTO experimentExecutionDTO) { UserActionLogging.LogAction("Run workflow", "Running a workflow..."); - Experiment experiment = saveExperiment(expQuery); + Experiment experiment = createExperiment(experimentExecutionDTO); + + // Run the 1st algorithm from the list + String workflowId = experimentExecutionDTO.getAlgorithms().get(0).getName(); + + // Get the parameters + List<AlgorithmExecutionParamDTO> algorithmParameters + = experimentExecutionDTO.getAlgorithms().get(0).getParameters(); - // Get the algorithm parameters provided - String algorithmName = expQuery.getAlgorithms().get(0).getName(); - List<AlgorithmParam> algorithmParams = expQuery.getAlgorithms().get(0).getParameters(); + // Convert the parameters to workflow parameters HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>(); - if (algorithmParams != null) { - for (AlgorithmParam p : algorithmParams) { - algorithmParamsIncludingEmpty.put(p.getName(), p.getValue()); + if (algorithmParameters != null) { + for (AlgorithmExecutionParamDTO param : algorithmParameters) { + algorithmParamsIncludingEmpty.put(param.getName(), param.getValue()); } } @@ -137,14 +183,16 @@ public class ExperimentApi { final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); Workflow workflow = null; for (Workflow curWorkflow : workflowsClient.getWorkflows()) { - if (curWorkflow.getName().equals(algorithmName)) { + if (curWorkflow.getId().equals(workflowId)) { workflow = curWorkflow; break; } } if (workflow == null) { - UserActionLogging.LogAction("Run workflow", "Could not find algorithm code"); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse("Could not find galaxy algorithm.", "99")); + UserActionLogging.LogAction("Run workflow", + "Could not find algorithm code: " + workflowId); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new ErrorResponse("Could not find galaxy algorithm.", "99").toString()); } final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId()); for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) { @@ -197,7 +245,8 @@ public class ExperimentApi { experiment.setHasServerError(true); experiment.setResult(e.getMessage()); } - finishExperiment(experiment); + saveExperiment(experiment); + UserActionLogging.LogAction("Run workflow", "Run workflow completed!"); return new ResponseEntity(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); @@ -304,6 +353,8 @@ public class ExperimentApi { experiment.setHasError(true); experiment.setHasServerError(true); } + + finishExperiment(experiment); break; case "error": @@ -337,12 +388,14 @@ public class ExperimentApi { experiment.setHasError(true); experiment.setHasServerError(true); } + finishExperiment(experiment); break; default: // InternalError or unexpected result experiment.setResult(new ErrorResponse("An unexpected error occurred.", "500").toString()); experiment.setHasError(true); experiment.setHasServerError(true); + finishExperiment(experiment); break; } @@ -647,37 +700,43 @@ public class ExperimentApi { return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); } - private void finishExperiment(Experiment experiment) { - experiment.setFinished(new Date()); + private Experiment createExperiment(ExperimentExecutionDTO experimentExecutionDTO) throws NullPointerException{ + User user = userInfo.getUser(); + + Experiment experiment = new Experiment(); + experiment.setUuid(UUID.randomUUID()); + experiment.setCreatedBy(user); + experiment.setAlgorithms(gson.toJson(experimentExecutionDTO.getAlgorithms())); + Model model = modelRepository.findOne(experimentExecutionDTO.getModel()); + experiment.setModel(model); + experiment.setName(experimentExecutionDTO.getName()); experimentRepository.save(experiment); - UserActionLogging.LogAction("Experiment updated (finished)", ""); + UserActionLogging.LogAction("Created an experiment", " id : " + experiment.getUuid()); + UserActionLogging.LogAction("Created an experiment", " algorithms : " + experiment.getAlgorithms()); + UserActionLogging.LogAction("Created an experiment", " model : " + experiment.getModel().getSlug()); + UserActionLogging.LogAction("Created an experiment", " name : " + experiment.getName()); + return experiment; } - private HashMap<String, String> makeObject(String name, String value) { - HashMap<String, String> o = new HashMap<String, String>(); - o.put("name", name); - o.put("value", value); - - return o; - } + private void saveExperiment(Experiment experiment) { + UserActionLogging.LogAction("Saved an experiment", " id : " + experiment.getUuid()); + UserActionLogging.LogAction("Saved an experiment", " algorithms : " + experiment.getAlgorithms()); + UserActionLogging.LogAction("Saved an experiment", " model : " + experiment.getModel().getSlug()); + UserActionLogging.LogAction("Saved an experiment", " name : " + experiment.getName()); + UserActionLogging.LogAction("Saved an experiment", " historyId : " + experiment.getWorkflowHistoryId()); + UserActionLogging.LogAction("Saved an experiment", " status : " + experiment.getWorkflowStatus()); - private Experiment saveExperiment(ExperimentQuery expQuery) { + experimentRepository.save(experiment); - Experiment experiment = new Experiment(); - experiment.setUuid(UUID.randomUUID()); - User user = userInfo.getUser(); + UserActionLogging.LogAction("Experiment saved", ""); + } - experiment.setAlgorithms(gson.toJson(expQuery.getAlgorithms())); - experiment.setValidations(gson.toJson(expQuery.getValidations())); - experiment.setName(expQuery.getName()); - experiment.setCreatedBy(user); - experiment.setModel(modelRepository.findOne(expQuery.getModel())); + private void finishExperiment(Experiment experiment) { + experiment.setFinished(new Date()); experimentRepository.save(experiment); - UserActionLogging.LogAction("Saved an experiment", " id : " + experiment.getUuid()); - - return experiment; + UserActionLogging.LogThreadAction("Experiment finished!", ""); } } diff --git a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java b/src/main/java/eu/hbp/mip/controllers/MethodsApi.java deleted file mode 100644 index bbae570a584151e1c2cfbfe16df074bac6a30342..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java +++ /dev/null @@ -1,83 +0,0 @@ -package eu.hbp.mip.controllers; - -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.google.gson.*; -import com.sun.jersey.api.client.ClientHandlerException; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import eu.hbp.mip.model.UserInfo; -import eu.hbp.mip.utils.HTTPUtil; -import org.springframework.beans.factory.annotation.Value; -import java.io.IOException; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.List; - -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import org.springframework.beans.factory.annotation.Autowired; -import eu.hbp.mip.utils.UserActionLogging; - -@RestController -@RequestMapping(value = "/methods", produces = { APPLICATION_JSON_VALUE }) -@Api(value = "/methods") -public class MethodsApi { - - private static final Gson gson = new Gson(); - - @Value("#{'${services.exareme.algorithmsUrl:http://localhost:9090/mining/algorithms.json}'}") - private String exaremeAlgorithmsUrl; - - @Value("#{'${services.galaxy.galaxyUrl}'}") - private String galaxyUrl; - - @Value("#{'${services.galaxy.galaxyApiKey}'}") - private String galaxyApiKey; - - @ApiOperation(value = "List Exareme algorithms and validations", response = String.class) - @RequestMapping(value = "/exareme", method = RequestMethod.GET) - public ResponseEntity<Object> getExaremeAlgorithms() { - UserActionLogging.LogAction("List Exareme algorithms and validations", ""); - - try { - StringBuilder response = new StringBuilder(); - HTTPUtil.sendGet(exaremeAlgorithmsUrl, response); - JsonElement element = new JsonParser().parse(response.toString()); - - return ResponseEntity.ok(gson.toJson(element)); - } catch (IOException e) { - return ResponseEntity.status(500).body(e.getMessage()); - } - } - - @ApiOperation(value = "List Galaxy workflows", response = String.class) - @RequestMapping(value = "/workflows", method = RequestMethod.GET) - public ResponseEntity<Object> getWorkflows() { - UserActionLogging.LogAction("List Galaxy workflows", ""); - - try { - final GalaxyInstance instance = GalaxyInstanceFactory.get(galaxyUrl, galaxyApiKey); - final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); - - List<Workflow> workflowList = new ArrayList<>(workflowsClient.getWorkflows()); - - List<WorkflowDetails> workflowDetailsList = new ArrayList<>(); - for(Workflow workflow : workflowList){ - workflowDetailsList.add(workflowsClient.showWorkflow(workflow.getId())); - } - - return ResponseEntity.ok(workflowDetailsList); - } catch (Exception e) { - UserActionLogging.LogAction("List Galaxy workflows", "Error when calling list galaxy workflows: " + e.getMessage()); - - return ResponseEntity.ok(new ArrayList<>()); - } - - } - -} diff --git a/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java b/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java index 43f22af2b830639ea7c0897273184bf30a9ad7be..6acd92f0aeff3dde2a40ece432a6dc10ef86ed7c 100644 --- a/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java +++ b/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java @@ -1,8 +1,9 @@ package eu.hbp.mip.controllers.retrofit; import com.google.gson.JsonObject; -import eu.hbp.mip.dto.GalaxyWorkflowResult; -import eu.hbp.mip.dto.PostWorkflowToGalaxyDtoResponse; +import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult; +import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse; +import eu.hbp.mip.model.galaxy.WorkflowDTO; import retrofit2.Call; import retrofit2.http.*; @@ -10,6 +11,9 @@ 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); diff --git a/src/main/java/eu/hbp/mip/model/Algorithm.java b/src/main/java/eu/hbp/mip/model/Algorithm.java deleted file mode 100644 index bd08093a82e0cc7823fdc6c33c193a3feff774ba..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/model/Algorithm.java +++ /dev/null @@ -1,32 +0,0 @@ -package eu.hbp.mip.model; - -import java.util.LinkedList; - -/** - * Created by mirco on 09.11.16. - */ - -public class Algorithm extends ExperimentValidator { - - private boolean validation; - - public Algorithm() { - - } - - public Algorithm(String code, String name, boolean validation) { - this.validation = validation; - setCode(code); - setName(name); - setParameters(new LinkedList<>()); - } - - public boolean isValidation() { - return validation; - } - - public void setValidation(boolean validation) { - this.validation = validation; - } - -} diff --git a/src/main/java/eu/hbp/mip/model/AlgorithmDTO.java b/src/main/java/eu/hbp/mip/model/AlgorithmDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..ed0ef2a15606ef09f139bad65c90c3cf436c2474 --- /dev/null +++ b/src/main/java/eu/hbp/mip/model/AlgorithmDTO.java @@ -0,0 +1,220 @@ +package eu.hbp.mip.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AlgorithmDTO { + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List<AlgorithmParamDTO> getParameters() { + return parameters; + } + + public void setParameters(List<AlgorithmParamDTO> parameters) { + this.parameters = parameters; + } + + @SerializedName("name") + private String name; + + @SerializedName("desc") + private String desc; + + @SerializedName("label") + private String label; + + @SerializedName("type") + private String type; + + @SerializedName("parameters") + private List<AlgorithmParamDTO> parameters; + + public static class AlgorithmParamDTO { + @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 String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getColumnValuesSQLType() { + return columnValuesSQLType; + } + + public void setColumnValuesSQLType(String columnValuesSQLType) { + this.columnValuesSQLType = columnValuesSQLType; + } + + public String getColumnValuesIsCategorical() { + return columnValuesIsCategorical; + } + + public void setColumnValuesIsCategorical(String columnValuesIsCategorical) { + this.columnValuesIsCategorical = columnValuesIsCategorical; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public String getValueType() { + return valueType; + } + + public void setValueType(String valueType) { + this.valueType = valueType; + } + + public String getValueNotBlank() { + return valueNotBlank; + } + + public void setValueNotBlank(String valueNotBlank) { + this.valueNotBlank = valueNotBlank; + } + + public String getValueMultiple() { + return valueMultiple; + } + + public void setValueMultiple(String valueMultiple) { + this.valueMultiple = valueMultiple; + } + + public String getValueMin() { + return valueMin; + } + + public void setValueMin(String valueMin) { + this.valueMin = valueMin; + } + + public String getValueMax() { + return valueMax; + } + + public void setValueMax(String valueMax) { + this.valueMax = valueMax; + } + + public List<String> getValueEnumerations() { + return valueEnumerations; + } + + public void setValueEnumerations(List<String> valueEnumerations) { + this.valueEnumerations = valueEnumerations; + } + } + +} diff --git a/src/main/java/eu/hbp/mip/model/AlgorithmParam.java b/src/main/java/eu/hbp/mip/model/AlgorithmParam.java deleted file mode 100644 index 62c48ba13b4cffcf647d4da97a0509735f18cac4..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/model/AlgorithmParam.java +++ /dev/null @@ -1,36 +0,0 @@ -package eu.hbp.mip.model; - -/** - * Created by mirco on 09.11.16. - */ - -public class AlgorithmParam { - - private String code; - private String value; - - public String getCode() { - return code; - - } - - public void setName(String name) { - this.code = name; - } - - public String getName() { - return this.code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/src/main/java/eu/hbp/mip/model/Experiment.java b/src/main/java/eu/hbp/mip/model/Experiment.java index 3cb3a85ee74126f8da14f02f0c186f22debe06f2..25a851f0f6e32d5828ffdce68faeadefb57b2cfe 100644 --- a/src/main/java/eu/hbp/mip/model/Experiment.java +++ b/src/main/java/eu/hbp/mip/model/Experiment.java @@ -16,8 +16,6 @@ import java.util.*; @Table(name = "`experiment`") public class Experiment { - private static final Logger LOGGER = LoggerFactory.getLogger(Experiment.class); - private static final Gson gson = new Gson(); @Id diff --git a/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java b/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..a68cd9121d852503bc01eb6b2f0d23dd8af525dd --- /dev/null +++ b/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java @@ -0,0 +1,106 @@ +package eu.hbp.mip.model; + +import java.util.List; + +public class ExperimentExecutionDTO { + + private String name; + private String model; + private List<AlgorithmExecutionDTO> algorithms; + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public List<AlgorithmExecutionDTO> getAlgorithms() { + return algorithms; + } + + public void setAlgorithms(List<AlgorithmExecutionDTO> algorithms) { + this.algorithms = algorithms; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static class AlgorithmExecutionDTO { + + private String name; + private String label; + private String type; + + private List<AlgorithmExecutionParamDTO> parameters; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List<AlgorithmExecutionDTO.AlgorithmExecutionParamDTO> getParameters() { + return parameters; + } + + public void setParameters(List<AlgorithmExecutionDTO.AlgorithmExecutionParamDTO> parameters) { + this.parameters = parameters; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public static class AlgorithmExecutionParamDTO { + + private String name; + private String label; + private String value; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + } + } +} diff --git a/src/main/java/eu/hbp/mip/model/ExperimentQuery.java b/src/main/java/eu/hbp/mip/model/ExperimentQuery.java deleted file mode 100644 index 333751c438099de62942918e17f019505a800de7..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/model/ExperimentQuery.java +++ /dev/null @@ -1,46 +0,0 @@ -package eu.hbp.mip.model; - -import java.util.List; - -/** - * Created by mirco on 09.11.16. - */ -public class ExperimentQuery { - - private String name; - private String model; - private List<ExperimentValidator> validations; - private List<Algorithm> algorithms; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - public List<ExperimentValidator> getValidations() { - return validations; - } - - public void setValidations(List<ExperimentValidator> validations) { - this.validations = validations; - } - - public List<Algorithm> getAlgorithms() { - return algorithms; - } - - public void setAlgorithms(List<Algorithm> algorithms) { - this.algorithms = algorithms; - } -} diff --git a/src/main/java/eu/hbp/mip/model/ExperimentValidator.java b/src/main/java/eu/hbp/mip/model/ExperimentValidator.java deleted file mode 100644 index 208fc90fa7272779bf51e09ca7fa0b6f409c66d3..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/model/ExperimentValidator.java +++ /dev/null @@ -1,40 +0,0 @@ -package eu.hbp.mip.model; - -import java.util.List; - -/** - * Created by mirco on 09.11.16. - */ - -public class ExperimentValidator { - - private String code; - private String name; - - private List<AlgorithmParam> parameters; - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List<AlgorithmParam> getParameters() { - return parameters; - } - - public void setParameters(List<AlgorithmParam> parameters) { - this.parameters = parameters; - } - -} diff --git a/src/main/java/eu/hbp/mip/model/MiningQuery.java b/src/main/java/eu/hbp/mip/model/MiningQuery.java index 6ced265037ba4148d4f18e6ba06d9434e4610317..171c55032eee4b3c5f63d636c137d6ae41bfe051 100644 --- a/src/main/java/eu/hbp/mip/model/MiningQuery.java +++ b/src/main/java/eu/hbp/mip/model/MiningQuery.java @@ -1,6 +1,7 @@ package eu.hbp.mip.model; import com.google.gson.Gson; + import java.util.LinkedList; import java.util.List; @@ -14,7 +15,7 @@ public class MiningQuery { private List<Variable> grouping; private List<Variable> datasets; private String filters; - private Algorithm algorithm; + private ExperimentExecutionDTO.AlgorithmExecutionDTO algorithm; public MiningQuery() { this.variables = new LinkedList<>(); @@ -32,7 +33,9 @@ public class MiningQuery { this.variables = variables; } - public void addVariable(Variable variable) { this.variables.add(variable); } + public void addVariable(Variable variable) { + this.variables.add(variable); + } public List<Variable> getCovariables() { return covariables; @@ -42,7 +45,9 @@ public class MiningQuery { this.covariables = covariables; } - public void addCovariable(Variable variable) { this.covariables.add(variable); } + public void addCovariable(Variable variable) { + this.covariables.add(variable); + } public List<Variable> getGrouping() { return grouping; @@ -52,15 +57,21 @@ public class MiningQuery { this.grouping = grouping; } - public List<Variable> getDatasets() { return datasets; } + public List<Variable> getDatasets() { + return datasets; + } public void setDataset(List<Variable> datasets) { this.datasets = datasets; } - public void addDataset(Variable variable) { this.datasets.add(variable); } + public void addDataset(Variable variable) { + this.datasets.add(variable); + } - public void addGrouping(Variable variable) { this.grouping.add(variable); } + public void addGrouping(Variable variable) { + this.grouping.add(variable); + } public String getFilters() { return filters; @@ -70,11 +81,11 @@ public class MiningQuery { this.filters = filters; } - public Algorithm getAlgorithm() { + public ExperimentExecutionDTO.AlgorithmExecutionDTO getAlgorithm() { return algorithm; } - public void setAlgorithm(Algorithm algorithm) { + public void setAlgorithm(ExperimentExecutionDTO.AlgorithmExecutionDTO algorithm) { this.algorithm = algorithm; } diff --git a/src/main/java/eu/hbp/mip/dto/ErrorResponse.java b/src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java similarity index 95% rename from src/main/java/eu/hbp/mip/dto/ErrorResponse.java rename to src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java index 1051340acbb3db553173d8e5ff4a7818d2f4df7e..e4144da6502ca26cf0f2032ace1d5d19d6c65746 100644 --- a/src/main/java/eu/hbp/mip/dto/ErrorResponse.java +++ b/src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java @@ -3,7 +3,7 @@ * Copyright (c) 2019. MIT License */ -package eu.hbp.mip.dto; +package eu.hbp.mip.model.galaxy; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/eu/hbp/mip/dto/GalaxyWorkflowResult.java b/src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java similarity index 99% rename from src/main/java/eu/hbp/mip/dto/GalaxyWorkflowResult.java rename to src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java index 566910c6fda59d9acd30e06a48ccdfe1efe17f63..089a6a626ed1e0d38306c911b515edd3fa8fa5f0 100644 --- a/src/main/java/eu/hbp/mip/dto/GalaxyWorkflowResult.java +++ b/src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java @@ -3,7 +3,7 @@ * Copyright (c) 2019. MIT License */ -package eu.hbp.mip.dto; +package eu.hbp.mip.model.galaxy; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java b/src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java similarity index 98% rename from src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java rename to src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java index bc504c5f5a2894b4fb2a4a75acac56bf4f949a12..edefd63266a8d1678bf82d057882e4eccab112cc 100644 --- a/src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java +++ b/src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java @@ -3,7 +3,7 @@ * Copyright (c) 2019. MIT License */ -package eu.hbp.mip.dto; +package eu.hbp.mip.model.galaxy; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java b/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..de537a1dcc4649e0ea6b28ff967567b599c77251 --- /dev/null +++ b/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java @@ -0,0 +1,162 @@ +package eu.hbp.mip.model.galaxy; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import eu.hbp.mip.model.AlgorithmDTO; + +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 AlgorithmDTO convertToAlgorithmDTO(){ + + AlgorithmDTO algorithmDTO = new AlgorithmDTO(); + + // Transfer workflow information + algorithmDTO.setName(id); + algorithmDTO.setDesc(""); + algorithmDTO.setLabel(name); + algorithmDTO.setType("workflow"); + + // Transfer workflow parameters information + List<AlgorithmDTO.AlgorithmParamDTO> algorithmParams = new LinkedList<>(); + Gson gson = new Gson(); + for (Map.Entry<String, WorkflowInputDTO> workflowInput : getInputs().entrySet()) { + + // Convert the annotation to algorithm Parameter + AlgorithmDTO.AlgorithmParamDTO algorithmParam; + if(steps.get(workflowInput.getKey()).getAnnotation() != null) { + algorithmParam = gson.fromJson(steps.get(workflowInput.getKey()).getAnnotation(), + AlgorithmDTO.AlgorithmParamDTO.class); + }else{ + // If annotation is not provided, auto-fill some information + algorithmParam = new AlgorithmDTO.AlgorithmParamDTO(); + // 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); + } + algorithmDTO.setParameters(algorithmParams); + + return algorithmDTO; + } + +} diff --git a/src/main/java/eu/hbp/mip/utils/UserActionLogging.java b/src/main/java/eu/hbp/mip/utils/UserActionLogging.java index c1257fa537c714e34bdf989960174f97bbe39a35..2c37ccb31cfbb7922da969c7062327c65cfe8912 100644 --- a/src/main/java/eu/hbp/mip/utils/UserActionLogging.java +++ b/src/main/java/eu/hbp/mip/utils/UserActionLogging.java @@ -4,8 +4,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContextHolder; -import java.time.LocalTime; - public class UserActionLogging { @@ -19,4 +17,8 @@ public class UserActionLogging { + " info: " + actionIdInfo); } + public static void LogThreadAction(String actionName, String actionIdInfo) + { + LOGGER.info( "Called endpoint: " + actionName + " info: " + actionIdInfo); + } }