diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index 5f9ea27f9885a3c518cb6fed0b418276012470ea..b4c1909d57d6f102e1e0d13d9f8982f5d34bf194 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -89,4 +89,7 @@ endpoints: services: exareme: miningExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query - algorithmsUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/algorithms.json \ No newline at end of file + algorithmsUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/algorithms.json + workflows: + workflowUrl: {{ default .Env.WORKFLOW_URL "http://localhost:9090" }} + workflowAuthorization: {{ default .Env.WORKFLOW_AUTHORIZATION "-" }} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index 1f36e87107bbd3a19311e444f5ab6d18d725b664..2c626060818dc93ee79b1029ced677ce1412e8cf 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -2,6 +2,7 @@ package eu.hbp.mip.controllers; import akka.dispatch.OnSuccess; import ch.chuv.lren.mip.portal.WokenConversions; +import com.google.gson.*; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -46,6 +47,12 @@ public class ExperimentApi extends WokenClientController { @Value("#{'${services.exareme.miningExaremeUrl:http://localhost:9090/mining/query}'}") public String miningExaremeQueryUrl; + @Value("#{'${services.workflows.workflowUrl}'}") + private String workflowUrl; + + @Value("#{'${services.workflows.workflowAuthorization}'}") + private String workflowAuthorization; + @Autowired private UserInfo userInfo; @@ -75,7 +82,34 @@ public class ExperimentApi extends WokenClientController { String algoCode = expQuery.getAlgorithms().get(0).getCode(); List<AlgorithmParam> params = expQuery.getAlgorithms().get(0).getParameters(); - sendExaremeExperiment(experiment, algoCode, params); + new Thread(() -> { + List<HashMap<String, String>> queryList = new ArrayList<HashMap<String, String>>(); + + if (params != null) { + for (AlgorithmParam p : params) { + queryList.add(makeObject(p.getName(), p.getValue())); + } + } + + String query = gson.toJson(queryList); + String url = miningExaremeQueryUrl + "/" + algoCode; + + // Results are stored in the experiment object + try { + StringBuilder results = new StringBuilder(); + int code = HTTPUtil.sendPost(url, query, results); + 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 !"); + experiment.setHasError(true); + experiment.setHasServerError(true); + experiment.setResult(e.getMessage()); + } + finishExperiment(experiment); + }).start(); return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); } @@ -89,7 +123,37 @@ public class ExperimentApi extends WokenClientController { String algoCode = expQuery.getAlgorithms().get(0).getCode(); List<AlgorithmParam> params = expQuery.getAlgorithms().get(0).getParameters(); - sendWorkflow(experiment, algoCode, params); + new Thread(() -> { + HashMap<String, String> queryMap = new HashMap<String, String>(); + + if (params != null) { + for (AlgorithmParam p : params) { + queryMap.put(p.getName(), p.getValue()); + } + } + + String query = gson.toJson(queryMap); + LOGGER.info("****************************** query"); + LOGGER.info(query); + String url = workflowUrl + "/runWorkflow/" + algoCode; + // Results are stored in the experiment object + try { + StringBuilder results = new StringBuilder(); + int code = HTTPUtil.sendAuthorizedHTTP(url, query, results, "POST", workflowAuthorization); + experiment.setResult("[" + results.toString() + "]"); + LOGGER.info("****************************** results"); + LOGGER.info(results.toString()); + experiment.setHasError(code >= 400); + experiment.setHasServerError(code >= 500); + } catch (IOException e) { + LOGGER.trace("Invalid UUID", e); + LOGGER.warn("Workflow failed to run properly !"); + experiment.setHasError(true); + experiment.setHasServerError(true); + experiment.setResult(e.getMessage()); + } + finishExperiment(experiment); + }).start(); return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); } @@ -119,6 +183,62 @@ public class ExperimentApi extends WokenClientController { return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); } + @ApiOperation(value = "get workflow status", response = String.class) + @RequestMapping(value = "/workflow/status/{historyId}", method = RequestMethod.GET) + public ResponseEntity<String> getWorkflowStatus( + @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId) { + LOGGER.info("Get a workflow status"); + + String url = workflowUrl + "/getWorkflowStatus/" + historyId; + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendAuthorizedHTTP(url, "", response, "GET", workflowAuthorization); + JsonElement element = new JsonParser().parse(response.toString()); + + return ResponseEntity.ok(gson.toJson(element)); + } catch (IOException e) { + return ResponseEntity.status(500).body(e.getMessage()); + } + } + + // TODO: factorize workflow results + @ApiOperation(value = "get workflow results", response = String.class) + @RequestMapping(value = "/workflow/results/{historyId}", method = RequestMethod.GET) + public ResponseEntity<String> getWorkflowResults( + @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId) { + LOGGER.info("Get a workflow results"); + + String url = workflowUrl + "/getWorkflowResults/" + historyId; + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendAuthorizedHTTP(url, "", response, "GET", workflowAuthorization); + 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 = "get workflow result body", response = String.class) + @RequestMapping(value = "/workflow/resultsbody/{historyId}/content/{resultId}", method = RequestMethod.GET) + public ResponseEntity<String> getWorkflowResultBody( + @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId, + @ApiParam(value = "resultId", required = true) @PathVariable("resultId") String resultId) { + LOGGER.info("Get a workflow result content"); + + String url = workflowUrl + "/getWorkflowResultsBody/" + historyId + "/contents/" + resultId; + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendAuthorizedHTTP(url, "", response, "GET", workflowAuthorization); + 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 = "Mark an experiment as viewed", response = Experiment.class) @RequestMapping(value = "/{uuid}/markAsViewed", method = RequestMethod.GET) public ResponseEntity<String> markExperimentAsViewed( @@ -279,69 +399,6 @@ public class ExperimentApi extends WokenClientController { }, ec); } - private void sendExaremeExperiment(Experiment experiment, String algoCode, List<AlgorithmParam> params) { - // this runs in the background. For future optimization: use a thread pool - new Thread(() -> { - List<HashMap<String, String>> queryList = new ArrayList<HashMap<String, String>>(); - - if (params != null) { - for (AlgorithmParam p : params) { - queryList.add(makeObject(p.getName(), p.getValue())); - } - } - - String query = gson.toJson(queryList); - String url = miningExaremeQueryUrl + "/" + algoCode; - - // Results are stored in the experiment object - try { - StringBuilder results = new StringBuilder(); - int code = HTTPUtil.sendPost(url, query, results); - 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 !"); - experiment.setHasError(true); - experiment.setHasServerError(true); - experiment.setResult(e.getMessage()); - } - finishExperiment(experiment); - }).start(); - } - - private void sendWorkflow(Experiment experiment, String algoCode, List<AlgorithmParam> params) { - // this runs in the background. For future optimization: use a thread pool - new Thread(() -> { - HashMap<String, String> queryMap = new HashMap<String, String>(); - - if (params != null) { - for (AlgorithmParam p : params) { - queryMap.put(p.getName(), p.getValue()); - } - } - - String query = gson.toJson(queryMap); - String url = "http://88.197.53.36:8080/Gateway_API-1.0.0-SNAPSHOT/api/runWorkflow/3f5830403180d620"; - // Results are stored in the experiment object - try { - StringBuilder results = new StringBuilder(); - int code = HTTPUtil.sendWorkflowHTTP(url, query, results); - 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 !"); - experiment.setHasError(true); - experiment.setHasServerError(true); - experiment.setResult(e.getMessage()); - } - finishExperiment(experiment); - }).start(); - } - private void finishExperiment(Experiment experiment) { experiment.setFinished(new Date()); experimentRepository.save(experiment); @@ -350,7 +407,7 @@ public class ExperimentApi extends WokenClientController { } private HashMap<String, String> makeObject(String name, String value) { - HashMap<String, String> o = new HashMap<String, String>(); + HashMap<String, String> o = new HashMap<String, String>(); o.put("name", name); o.put("value", value); diff --git a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java b/src/main/java/eu/hbp/mip/controllers/MethodsApi.java index 21d3b9f2f852828df49dd81c4ec85fcecbe8e80c..5eaf651b756c1536bddb6aea8431bf55eedccb7a 100644 --- a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java +++ b/src/main/java/eu/hbp/mip/controllers/MethodsApi.java @@ -30,6 +30,12 @@ public class MethodsApi extends WokenClientController { @Value("#{'${services.exareme.algorithmsUrl:http://localhost:9090/mining/algorithms.json}'}") private String exaremeAlgorithmsUrl; + @Value("#{'${services.workflows.workflowUrl}'}") + private String workflowUrl; + + @Value("#{'${services.workflows.workflowAuthorization}'}") + private String workflowAuthorization; + @ApiOperation(value = "List available methods and validations", response = String.class) @Cacheable(value = "methods", unless = "#result.getStatusCode().value()!=200") @RequestMapping(method = RequestMethod.GET) @@ -62,4 +68,25 @@ public class MethodsApi extends WokenClientController { } + @ApiOperation(value = "List Galaxy workflows", response = String.class) + @RequestMapping(value = "/workflows", method = RequestMethod.GET) + public ResponseEntity<Object> getWorkflows() { + LOGGER.info("List Galaxy workflows"); + + try { + StringBuilder response = new StringBuilder(); + HTTPUtil.sendAuthorizedHTTP(workflowUrl + "/getAllWorkflowWithDetails", "", response, "GET", workflowAuthorization); + LOGGER.info("************************************************* workflows"); + LOGGER.info(workflowUrl + "/getAllWorkflowWithDetails"); + LOGGER.info(workflowAuthorization); + LOGGER.info(response.toString()); + JsonElement element = new JsonParser().parse(response.toString()); + + return ResponseEntity.ok(gson.toJson(element)); + } catch (IOException e) { + return ResponseEntity.status(500).body(e.getMessage()); + } + + } + } diff --git a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java index e3c1de5111c762b5b23c660f8a2e4b0ca43c909a..5c5043463c546bd618aae547358c4c5b84872ba4 100644 --- a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java +++ b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java @@ -13,29 +13,37 @@ import java.nio.charset.StandardCharsets; */ public class HTTPUtil { - private HTTPUtil() - { + private HTTPUtil() { /* Hide implicit public constructor */ throw new IllegalAccessError("HTTPUtil class"); } public static int sendGet(String url, StringBuilder resp) throws IOException { - return sendHTTP(url, "", resp, "GET"); + return sendHTTP(url, "", resp, "GET", null); } public static int sendPost(String url, String query, StringBuilder resp) throws IOException { - return sendHTTP(url, query, resp, "POST"); + return sendHTTP(url, query, resp, "POST", null); } - private static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb) throws IOException { + public static int sendAuthorizedHTTP(String url, String query, StringBuilder resp, String httpVerb, + String authorization) throws IOException { + return sendHTTP(url, query, resp, httpVerb, authorization); + } + + private static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb, String authorization) + throws IOException { URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - if(!"GET".equals(httpVerb)) { + if (authorization != null) { + con.setRequestProperty("Authorization", authorization); + } + + if (!"GET".equals(httpVerb)) { con.setRequestMethod(httpVerb); - if(query != null && query.length() > 0) - { + if (query != null && query.length() > 0) { con.addRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Content-Length", Integer.toString(query.length())); @@ -50,53 +58,9 @@ public class HTTPUtil { int respCode = con.getResponseCode(); BufferedReader in; - if(respCode == 200) { + if (respCode == 200) { in = new BufferedReader(new InputStreamReader(con.getInputStream())); - } - else - { - in = new BufferedReader(new InputStreamReader(con.getErrorStream())); - } - String inputLine; - StringBuilder response = new StringBuilder(); - - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - in.close(); - resp.append(response.toString()); - - return respCode; - } - - /* FIXME: Authorization */ - public static int sendWorkflowHTTP(String url, String query, StringBuilder resp) throws IOException { - - URL obj = new URL(url); - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - - con.setRequestMethod("POST"); - if(query != null && query.length() > 0) - { - con.addRequestProperty("Content-Type", "application/json"); - con.setRequestProperty("Content-Length", Integer.toString(query.length())); - - con.setDoOutput(true); - DataOutputStream wr = new DataOutputStream(con.getOutputStream()); - wr.write(query.getBytes(StandardCharsets.UTF_8)); - wr.flush(); - wr.close(); - } - - - int respCode = con.getResponseCode(); - - BufferedReader in; - if(respCode == 200) { - in = new BufferedReader(new InputStreamReader(con.getInputStream())); - } - else - { + } else { in = new BufferedReader(new InputStreamReader(con.getErrorStream())); } String inputLine;