diff --git a/docker/README.md b/docker/README.md index 5d523406839cba97ac0df926752a81074409893d..419dd079818055f01a0e70f781e42d5221d80268 100644 --- a/docker/README.md +++ b/docker/README.md @@ -52,9 +52,8 @@ To use this image, you need a running instance of PostgreSQL and to configure th ### ENDPOINTS -* WOKEN_URL: URL to woken machine learning server, default value is "http://172.22.0.1:8087". -* WOKEN_HOST: default value is "woken". -* WOKEN_AKKA_PORT default value is "8088". +* WOKEN_PORT_8088_TCP_ADDR: default value is "woken". +* WOKEN_PORT_8088_TCP_PORT default value is "8088". * WOKEN_AKKA_PATH default value is "/user/entrypoint". * EXAREME_URL: URL to Exareme server, default value is "http://hbps2.chuv.ch:9090". diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index 345cfdd1c890abd2cb2e87eb4392d459de503f82..16a901f6b08c45917d5764a813c78a91a7952f69 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -82,14 +82,11 @@ endpoints: sentitive: false services: - woken: - experimentUrl: {{ default .Env.WOKEN_URL "http://172.22.0.1:8087" }}/experiment - listMethodsUrl: {{ default .Env.WOKEN_URL "http://172.22.0.1:8087" }}/list-methods exareme: miningExaremeUrl: {{ default .Env.EXAREME_URL "http://hbps2.chuv.ch:9090" }}/mining/query akka: woken: - host: {{ default .Env.WOKEN_HOST "woken" }} - port: {{ default .Env.WOKEN_AKKA_PORT "8088" }} + host: {{ default .Env.WOKEN_PORT_8088_TCP_ADDR "woken" }} + port: {{ default .Env.WOKEN_PORT_8088_TCP_PORT "8088" }} path: {{ default .Env.WOKEN_AKKA_PATH "/user/entrypoint" }} diff --git a/pom.xml b/pom.xml index 483704b6beb6f7e4f77a78da04a2d30dfe7e0608..95a350b908473c2c5131a40368a368b9574f2a12 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ <spring-data-jpa.version>1.10.11.RELEASE</spring-data-jpa.version> <spring-boot-starter-actuator.version>1.4.7.RELEASE</spring-boot-starter-actuator.version> <aspectjweaver.version>1.8.9</aspectjweaver.version> - <woken-messages.version>2.3.0</woken-messages.version> + <woken-messages.version>2.3.1</woken-messages.version> <javax-inject.version>1</javax-inject.version> <akka.version>2.5.9</akka.version> <spring-context.version>4.3.4.RELEASE</spring-context.version> @@ -73,6 +73,10 @@ </repositories> <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-logging</artifactId> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> @@ -217,6 +221,11 @@ <artifactId>akka-cluster-tools_2.11</artifactId> <version>${akka.version}</version> </dependency> + <dependency> + <groupId>com.typesafe.akka</groupId> + <artifactId>akka-slf4j_2.11</artifactId> + <version>${akka.version}</version> + </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index 1a63229034ea9edc8f6c5fc75f53a3c8514b73fb..d0e0db36aa029c95bebed143ff9755682dba899e 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -201,10 +201,10 @@ public class ExperimentApi extends WokenClientController { @ApiOperation(value = "List available methods and validations", response = String.class) @Cacheable(value = "methods", unless = "#result.getStatusCode().value()!=200") @RequestMapping(path = "/methods", method = RequestMethod.GET) - public ResponseEntity listAvailableMethodsAndValidations() throws IOException { + public ResponseEntity listAvailableMethodsAndValidations() { LOGGER.info("List available methods and validations"); - return askWoken(MethodsQuery$.MODULE$, 5, r -> { + return askWoken(MethodsQuery$.MODULE$, 10, r -> { MethodsResponse result = (MethodsResponse) r; // >> Temporary : should return result.methods() in the future diff --git a/src/main/java/eu/hbp/mip/controllers/MiningApi.java b/src/main/java/eu/hbp/mip/controllers/MiningApi.java index 3d3cd0c6a8ffae7224a37084f5279e8d13a3cad4..5b784fba15f1d93de20c5199112f9e34834070e7 100644 --- a/src/main/java/eu/hbp/mip/controllers/MiningApi.java +++ b/src/main/java/eu/hbp/mip/controllers/MiningApi.java @@ -2,11 +2,14 @@ package eu.hbp.mip.controllers; import com.google.gson.Gson; import eu.hbp.mip.akka.WokenClientController; +import eu.hbp.mip.configuration.SecurityConfiguration; import eu.hbp.mip.model.Mining; +import eu.hbp.mip.model.User; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import java.io.IOException; import java.sql.Date; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -31,13 +33,17 @@ public class MiningApi extends WokenClientController { private static final Logger LOGGER = LoggerFactory.getLogger(MiningApi.class); private static final Gson gson = new Gson(); + @Autowired + private SecurityConfiguration securityConfiguration; + @ApiOperation(value = "Run an algorithm", response = String.class) - @Cacheable(value = "mining", condition = "#query.getAlgorithm().getCode() == 'histograms'", key = "#query.toString()", unless = "#result.getStatusCode().value()!=200") + @Cacheable(value = "mining", condition = "#query != null and #query.getAlgorithm().getCode() == 'histograms'", key = "#query.toString()", unless = "#result.getStatusCode().value()!=200") @RequestMapping(method = RequestMethod.POST) - public ResponseEntity runAlgorithm(@RequestBody eu.hbp.mip.model.MiningQuery query) throws IOException { + public ResponseEntity runAlgorithm(@RequestBody eu.hbp.mip.model.MiningQuery query) { LOGGER.info("Run an algorithm"); + User user = securityConfiguration.getUser(); - return askWokenQuery(query.prepareQuery(), 120, + return askWokenQuery(query.prepareQuery(user.getUsername()), 120, result -> { if (result.error().nonEmpty()) { LOGGER.error(result.error().get()); diff --git a/src/main/java/eu/hbp/mip/controllers/VariablesApi.java b/src/main/java/eu/hbp/mip/controllers/VariablesApi.java index 8278bef8af34f5861e2569dcb3fc5bf255a09a98..c55cec4b05e2334b45df5e946ce96f598a8f1672 100644 --- a/src/main/java/eu/hbp/mip/controllers/VariablesApi.java +++ b/src/main/java/eu/hbp/mip/controllers/VariablesApi.java @@ -9,10 +9,8 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import eu.hbp.mip.configuration.SecurityConfiguration; import eu.hbp.mip.model.Algorithm; import eu.hbp.mip.model.MiningQuery; -import eu.hbp.mip.model.User; import eu.hbp.mip.model.Variable; import io.swagger.annotations.*; import org.postgresql.util.PGobject; @@ -50,9 +48,6 @@ public class VariablesApi { @Value("#{'${spring.featuresDatasource.main-table:features}'}") private String featuresMainTable; - @Autowired - private SecurityConfiguration securityConfiguration; - @ApiOperation(value = "Get variables", response = List.class, responseContainer = "List") @Cacheable("variables") @RequestMapping(method = RequestMethod.GET) @@ -153,15 +148,13 @@ public class VariablesApi { ) { LOGGER.info("Get query for histograms"); - User user = securityConfiguration.getUser(); - String sqlQuery = String.format( "SELECT histogram_groupings FROM meta_variables where upper(target_table)='%s'", featuresMainTable.toUpperCase()); SqlRowSet data = metaJdbcTemplate.queryForRowSet(sqlQuery); data.next(); String histogramGroupings = data.getString("histogram_groupings"); - MiningQuery query = new MiningQuery(user.getUsername()); + MiningQuery query = new MiningQuery(); query.addVariable(new Variable(code)); List<String> newGroups = Arrays.asList(histogramGroupings.split(",")); List<Variable> groupings = query.getGrouping(); diff --git a/src/main/java/eu/hbp/mip/model/MiningQuery.java b/src/main/java/eu/hbp/mip/model/MiningQuery.java index 09bd4a576449a8397d5b7fb81a98801d4d2e6725..1b03306c3c048901c411309cdb3c59f15fe66d60 100644 --- a/src/main/java/eu/hbp/mip/model/MiningQuery.java +++ b/src/main/java/eu/hbp/mip/model/MiningQuery.java @@ -4,6 +4,7 @@ import ch.chuv.lren.mip.portal.WokenConversions; import com.google.gson.Gson; import eu.hbp.mip.utils.TypesConvert; import eu.hbp.mip.woken.messages.datasets.DatasetId; +import eu.hbp.mip.woken.messages.query.ExecutionPlan; import eu.hbp.mip.woken.messages.query.UserId; import eu.hbp.mip.woken.messages.query.filters.FilterRule; import eu.hbp.mip.woken.messages.variables.FeatureIdentifier; @@ -17,25 +18,19 @@ import java.util.List; */ public class MiningQuery { - private String user; private List<Variable> variables; private List<Variable> covariables; private List<Variable> grouping; private String filters; private Algorithm algorithm; - public MiningQuery(String user) { - this.user = user; + public MiningQuery() { this.variables = new LinkedList<>(); this.covariables = new LinkedList<>(); this.grouping = new LinkedList<>(); this.filters = ""; } - public String getUser() { - return user; - } - public List<Variable> getVariables() { return variables; } @@ -82,7 +77,7 @@ public class MiningQuery { this.algorithm = algorithm; } - public eu.hbp.mip.woken.messages.query.MiningQuery prepareQuery() { + public eu.hbp.mip.woken.messages.query.MiningQuery prepareQuery(String user) { eu.hbp.mip.woken.messages.query.AlgorithmSpec scalaAlgorithm = new eu.hbp.mip.woken.messages.query.AlgorithmSpec( algorithm.getCode(), TypesConvert.algoParamsToScala(algorithm.getParameters())); @@ -102,7 +97,7 @@ public class MiningQuery { Option<FilterRule> filters = conv.toFilterRule(filtersJson); return new eu.hbp.mip.woken.messages.query.MiningQuery(userId, - variablesSeq, covariablesSeq, groupingSeq, filters, datasets, scalaAlgorithm); + variablesSeq, covariablesSeq, groupingSeq, filters, datasets, scalaAlgorithm, Option.<ExecutionPlan>empty()); } @Override diff --git a/src/main/java/eu/hbp/mip/utils/TypesConvert.java b/src/main/java/eu/hbp/mip/utils/TypesConvert.java index b4270bde5666fb60f7feeafc85829b604ee8093e..d00d026761855011b7a97d5848ecdca7d5b87a2c 100644 --- a/src/main/java/eu/hbp/mip/utils/TypesConvert.java +++ b/src/main/java/eu/hbp/mip/utils/TypesConvert.java @@ -19,7 +19,9 @@ public class TypesConvert { public static scala.collection.immutable.List<FeatureIdentifier> variablesToIdentifiers(List<Variable> vars) { List<FeatureIdentifier> varIds = new LinkedList<>(); for (Variable v: vars) { - varIds.add(new VariableId(v.getCode())); + if (!v.getCode().isEmpty()) { + varIds.add(new VariableId(v.getCode())); + } } return JavaConversions.asScalaBuffer(varIds).toList(); } diff --git a/src/main/scala/ch.chuv.lren/mip/portal/WokenConversions.scala b/src/main/scala/ch.chuv.lren/mip/portal/WokenConversions.scala index 0e90d1f3b512fd3f4f4cd931d216464b308d669e..5960326ec8df4f3596aacdcc7cf60ef14e138726 100644 --- a/src/main/scala/ch.chuv.lren/mip/portal/WokenConversions.scala +++ b/src/main/scala/ch.chuv.lren/mip/portal/WokenConversions.scala @@ -9,7 +9,10 @@ import spray.json._ @Component class WokenConversions { - def toFilterRule(json: String): Option[FilterRule] = Some(json).map(_.parseJson.convertTo[FilterRule]) + def toFilterRule(json: String): Option[FilterRule] = json match { + case "" => None + case _ => Some(json).map(_.parseJson.convertTo[FilterRule]) + } def toDatasets(commaSeparatedSets: String): Set[DatasetId] = commaSeparatedSets match { case "" => Set()