diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index 4f74bc820c8d0834eeaba088d778faf5dc7f88bc..0507c49cb97f264e89ffeb146b549fefed93d6f2 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -25,18 +25,14 @@ import scala.concurrent.ExecutionContext; import scala.concurrent.Future; import java.io.IOException; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; - +import java.util.*; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; /** * Created by habfast on 21/04/16. */ @RestController -@RequestMapping(value = "/experiments", produces = {APPLICATION_JSON_VALUE}) +@RequestMapping(value = "/experiments", produces = { APPLICATION_JSON_VALUE }) @Api(value = "/experiments", description = "the experiments API") public class ExperimentApi extends WokenClientController { @@ -44,11 +40,8 @@ public class ExperimentApi extends WokenClientController { 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(); + 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; @@ -76,25 +69,41 @@ public class ExperimentApi extends WokenClientController { experiment.setName(expQuery.getName()); experiment.setCreatedBy(user); experiment.setModel(modelRepository.findOne(expQuery.getModel())); - experiment.setSource(expQuery.getSource()); experimentRepository.save(experiment); LOGGER.info("Experiment saved"); + sendExperiment(experiment); - if (experiment.getSource() != "exareme") { - sendExperiment(experiment); - } else { - String algoCode = expQuery.getAlgorithms().get(0).getCode(); - List<AlgorithmParam> params = expQuery.getAlgorithms().get(0).getParameters(); - sendExaremeExperiment(experiment, algoCode, params); - } + return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); + } + + @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("sendExaremeExperiment"); + + Experiment experiment = new Experiment(); + experiment.setUuid(UUID.randomUUID()); + User user = userInfo.getUser(); + + 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())); + experimentRepository.save(experiment); + + String algoCode = expQuery.getAlgorithms().get(0).getCode(); + List<AlgorithmParam> params = expQuery.getAlgorithms().get(0).getParameters(); + sendExaremeExperiment(experiment, algoCode, params); return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK); } @ApiOperation(value = "get an experiment", response = Experiment.class) @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - public ResponseEntity<String> getExperiment(@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { + public ResponseEntity<String> getExperiment( + @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { LOGGER.info("Get an experiment"); Experiment experiment; @@ -118,7 +127,8 @@ public class ExperimentApi extends WokenClientController { @ApiOperation(value = "Mark an experiment as viewed", response = Experiment.class) @RequestMapping(value = "/{uuid}/markAsViewed", method = RequestMethod.GET) - public ResponseEntity<String> markExperimentAsViewed(@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { + public ResponseEntity<String> markExperimentAsViewed( + @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { LOGGER.info("Mark an experiment as viewed"); Experiment experiment; @@ -145,7 +155,8 @@ public class ExperimentApi extends WokenClientController { @ApiOperation(value = "Mark an experiment as shared", response = Experiment.class) @RequestMapping(value = "/{uuid}/markAsShared", method = RequestMethod.GET) - public ResponseEntity<String> markExperimentAsShared(@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { + public ResponseEntity<String> markExperimentAsShared( + @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { LOGGER.info("Mark an experiment as shared"); return doMarkExperimentAsShared(uuid, true); @@ -153,72 +164,62 @@ public class ExperimentApi extends WokenClientController { @ApiOperation(value = "Mark an experiment as unshared", response = Experiment.class) @RequestMapping(value = "/{uuid}/markAsUnshared", method = RequestMethod.GET) - public ResponseEntity<String> markExperimentAsUnshared(@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { + public ResponseEntity<String> markExperimentAsUnshared( + @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { LOGGER.info("Mark an experiment as unshared"); return doMarkExperimentAsShared(uuid, false); } @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") - @RequestMapping(method = RequestMethod.GET, params = {"maxResultCount"}) + @RequestMapping(method = RequestMethod.GET, params = { "maxResultCount" }) public ResponseEntity<String> listExperiments( - @ApiParam(value = "maxResultCount") @RequestParam int maxResultCount - ) { + @ApiParam(value = "maxResultCount") @RequestParam int maxResultCount) { LOGGER.info("List experiments"); return doListExperiments(false, null); } @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") - @RequestMapping(method = RequestMethod.GET, params = {"slug", "maxResultCount"}) - public ResponseEntity<String> listExperiments( - @ApiParam(value = "slug") @RequestParam("slug") String modelSlug, - @ApiParam(value = "maxResultCount") @RequestParam("maxResultCount") int maxResultCount - ) { + @RequestMapping(method = RequestMethod.GET, params = { "slug", "maxResultCount" }) + public ResponseEntity<String> listExperiments(@ApiParam(value = "slug") @RequestParam("slug") String modelSlug, + @ApiParam(value = "maxResultCount") @RequestParam("maxResultCount") int maxResultCount) { LOGGER.info("List experiments"); if (maxResultCount <= 0 && (modelSlug == null || "".equals(modelSlug))) { - return new ResponseEntity<>("You must provide at least a slug or a limit of result", HttpStatus.BAD_REQUEST); + return new ResponseEntity<>("You must provide at least a slug or a limit of result", + HttpStatus.BAD_REQUEST); } return doListExperiments(false, modelSlug); } @ApiOperation(value = "list my experiments", response = Experiment.class, responseContainer = "List") - @RequestMapping(method = RequestMethod.GET, params = {"mine"}) - public ResponseEntity<String> listMyExperiments( - @ApiParam(value = "mine") @RequestParam("mine") boolean mine - ) { + @RequestMapping(method = RequestMethod.GET, params = { "mine" }) + public ResponseEntity<String> listMyExperiments(@ApiParam(value = "mine") @RequestParam("mine") boolean mine) { LOGGER.info("List my experiments"); return doListExperiments(true, null); } - - private ResponseEntity<String> doListExperiments( - boolean mine, - String modelSlug - ) { + private ResponseEntity<String> doListExperiments(boolean mine, String modelSlug) { User user = userInfo.getUser(); Iterable<Experiment> myExperiments = experimentRepository.findByCreatedBy(user); List<Experiment> expList = Lists.newLinkedList(myExperiments); - if(!mine) - { + if (!mine) { Iterable<Experiment> sharedExperiments = experimentRepository.findByShared(true); List<Experiment> sharedExpList = Lists.newLinkedList(sharedExperiments); expList.addAll(sharedExpList); } if (modelSlug != null && !"".equals(modelSlug)) { - for(Iterator<Experiment> it = expList.iterator(); it.hasNext();) - { + for (Iterator<Experiment> it = expList.iterator(); it.hasNext();) { Experiment e = it.next(); e.setResult(null); e.setAlgorithms(null); e.setValidations(null); - if(!e.getModel().getSlug().equals(modelSlug)) - { + if (!e.getModel().getSlug().equals(modelSlug)) { it.remove(); } } @@ -256,10 +257,11 @@ public class ExperimentApi extends WokenClientController { User user = userInfo.getUser(); // this runs in the background. For future optimization: use a thread pool - final ch.chuv.lren.woken.messages.query.ExperimentQuery experimentQuery = experiment.prepareQuery(user.getUsername()); + final ch.chuv.lren.woken.messages.query.ExperimentQuery experimentQuery = experiment + .prepareQuery(user.getUsername()); final ExecutionContext ec = getExecutor(); - Future<Object> response = sendWokenQuery(experimentQuery, 24*3600); + Future<Object> response = sendWokenQuery(experimentQuery, 24 * 3600); response.onSuccess(new OnSuccess<Object>() { public void onSuccess(Object result) { QueryResult queryResult = (QueryResult) result; @@ -283,11 +285,27 @@ public class ExperimentApi extends WokenClientController { }, ec); } - private void sendExaremeExperiment(Experiment experiment, String algoCode, List <AlgorithmParam> params) { - // >> Temporary: we should integrate exareme in a proper way in the future + private void sendExaremeExperiment(Experiment experiment, String algoCode, List<AlgorithmParam> params) { // this runs in the background. For future optimization: use a thread pool new Thread(() -> { - String query = ""; //experiment.computeExaremeQuery(params); + List<HashMap<String, String>> queryList = new ArrayList<HashMap<String, String>>(); + + Query modelQuery = experiment.getModel().getQuery(); + queryList.add(makeObject("x", Variable.stringFromVariables(modelQuery.getVariables(), ","))); + + List<Variable> mergedCovariables = new ArrayList<Variable>(modelQuery.getCovariables()); + queryList.add(makeObject("y", Variable.stringFromVariables(mergedCovariables, ","))); + + List<Variable> mergedDatasets = new ArrayList<Variable>(modelQuery.getTrainingDatasets()); + queryList.add(makeObject("dataset", Variable.stringFromVariables(mergedDatasets, ","))); + + 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 @@ -306,14 +324,21 @@ public class ExperimentApi extends WokenClientController { } finishExperiment(experiment); }).start(); - // << Temporary } - private void finishExperiment(Experiment experiment) - { + private void finishExperiment(Experiment experiment) { experiment.setFinished(new Date()); experimentRepository.save(experiment); LOGGER.info("Experiment updated (finished)"); } + + 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; + } + } diff --git a/src/main/java/eu/hbp/mip/controllers/MiningApi.java b/src/main/java/eu/hbp/mip/controllers/MiningApi.java index bf89261eb14fab25a0adf5bf7dd3e07ff43235e6..24356234ea7467c873b902830f37fa46b78a5c17 100644 --- a/src/main/java/eu/hbp/mip/controllers/MiningApi.java +++ b/src/main/java/eu/hbp/mip/controllers/MiningApi.java @@ -38,9 +38,6 @@ public class MiningApi extends WokenClientController { @Autowired private UserInfo userInfo; - @Value("#{'${services.query.miningExaremeUrl:http://localhost:9090/mining/query}'}") - public String queryUrl; - @ApiOperation(value = "Run an algorithm", response = String.class) @Cacheable(value = "mining", condition = "#query != null and (#query.getAlgorithm().getCode() == 'histograms' or #query.getAlgorithm().getCode() == 'histograms')", diff --git a/src/main/java/eu/hbp/mip/model/AlgorithmParam.java b/src/main/java/eu/hbp/mip/model/AlgorithmParam.java index e4e5eac8ddcb77ea6e5c4af7837af547c2ba6efd..62c48ba13b4cffcf647d4da97a0509735f18cac4 100644 --- a/src/main/java/eu/hbp/mip/model/AlgorithmParam.java +++ b/src/main/java/eu/hbp/mip/model/AlgorithmParam.java @@ -11,6 +11,15 @@ public class AlgorithmParam { public String getCode() { return code; + + } + + public void setName(String name) { + this.code = name; + } + + public String getName() { + return this.code; } public void setCode(String code) { diff --git a/src/main/java/eu/hbp/mip/model/ExaremeQueryElement.java b/src/main/java/eu/hbp/mip/model/ExaremeQueryElement.java deleted file mode 100644 index 0b7005c19dd985d4ae639768053df2c61f836ac7..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/model/ExaremeQueryElement.java +++ /dev/null @@ -1,43 +0,0 @@ -package eu.hbp.mip.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.swagger.annotations.ApiModel; - -/** - * Created by mirco on 20.06.16. - */ - -@ApiModel -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ExaremeQueryElement { - - private String name; - - private String desc; - - private String value; - - 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 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 c0a1799097a3aff5ffba52bf24c5708c780f27c5..c84ec57ed37bfd699ad167c361cceaa241ba88fc 100644 --- a/src/main/java/eu/hbp/mip/model/Experiment.java +++ b/src/main/java/eu/hbp/mip/model/Experiment.java @@ -137,7 +137,6 @@ public class Experiment { public JsonObject jsonify() { JsonObject exp = gson.toJsonTree(this).getAsJsonObject(); JsonParser parser = new JsonParser(); - Boolean isExaremeAlgorithm = this.getSource() == "exareme"; if (this.algorithms != null) { @@ -156,33 +155,9 @@ public class Experiment { if (this.result != null && !this.hasServerError) { exp.remove("result"); - if (!isExaremeAlgorithm) { - JsonElement jsonResult = parser.parse(this.result); - exp.add("result", jsonResult); - } else { - JsonArray jsonArrayResult = new JsonArray(); - JsonObject jsonObjectResult = new JsonObject(); - - JsonObject algoObject = parser.parse(this.algorithms).getAsJsonArray().get(0).getAsJsonObject(); - jsonObjectResult.add("algorithm", algoObject.get("name")); - jsonObjectResult.add("code", algoObject.get("code")); - - exp.remove("result"); - JsonObject tryJson; - try { - tryJson = parser.parse(this.result).getAsJsonArray().get(0).getAsJsonObject(); - } catch(JsonParseException e) { - tryJson = new JsonObject(); - tryJson.add("result", new JsonPrimitive(this.result)); - } - - JsonObject jsonData = tryJson; - jsonObjectResult.add("data", jsonData); - - jsonArrayResult.add(jsonObjectResult); - - exp.add("result", jsonArrayResult); - } + JsonElement jsonResult = parser.parse(this.result); + exp.add("result", jsonResult); + } return exp; @@ -291,12 +266,4 @@ public class Experiment { public void setShared(boolean shared) { this.shared = shared; } - - public String getSource() { - return this.source; - } - - public void setSource(String source) { - this.source = source; - } } diff --git a/src/main/java/eu/hbp/mip/model/Variable.java b/src/main/java/eu/hbp/mip/model/Variable.java index 0947cdd7db753d27741a2e0b32fb4239c166cbac..1fcce2e48e89dc8e94a935bfc803ada086cd53f5 100644 --- a/src/main/java/eu/hbp/mip/model/Variable.java +++ b/src/main/java/eu/hbp/mip/model/Variable.java @@ -12,6 +12,7 @@ import io.swagger.annotations.ApiModel; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; +import java.util.List; @Entity @Table(name = "`variable`") @@ -42,6 +43,17 @@ public class Variable { this.code = code; } - + public static String stringFromVariables(List<Variable> variables, String operator) { + StringBuilder sb = new StringBuilder(); + int i = 0; + for (Variable s : variables) { + i++; + sb.append(s.getCode()); + if (i < variables.size()) { + sb.append(operator); + } + } + return sb.toString(); + } }