Skip to content
Snippets Groups Projects
Commit c9c43887 authored by Ludovic Claude's avatar Ludovic Claude
Browse files

Update woken-messages to 2.5.2, /datasets return [{code,label}] from Woken

parent 06dc9885
No related branches found
No related tags found
No related merge requests found
...@@ -24,7 +24,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th ...@@ -24,7 +24,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th
* FEATURES_DB_USER: User to use when connecting to the science database, default value is "postgres". * FEATURES_DB_USER: User to use when connecting to the science database, default value is "postgres".
* FEATURES_DB_PASSWORD: Password to use when connecting to the science database. * FEATURES_DB_PASSWORD: Password to use when connecting to the science database.
* FEATURES_DB_MAIN_TABLE: Table that contains the scientific data to use, default value is "features". * FEATURES_DB_MAIN_TABLE: Table that contains the scientific data to use, default value is "features".
* DATASETS (temporary hack): list of datasets available in the features table
### OAUTH2 LOGIN ### OAUTH2 LOGIN
......
...@@ -21,7 +21,6 @@ spring: ...@@ -21,7 +21,6 @@ spring:
username: {{ default .Env.FEATURES_DB_USER "postgres" }} username: {{ default .Env.FEATURES_DB_USER "postgres" }}
password: {{ .Env.FEATURES_DB_PASSWORD }} password: {{ .Env.FEATURES_DB_PASSWORD }}
driver-class-name: org.postgresql.Driver driver-class-name: org.postgresql.Driver
datasets: {{ .Env.DATASETS }}
jpa: jpa:
hibernate: hibernate:
dialect: org.hibernate.dialect.PostgreSQL9Dialect dialect: org.hibernate.dialect.PostgreSQL9Dialect
......
...@@ -10,4 +10,4 @@ fi ...@@ -10,4 +10,4 @@ fi
if [ ! -z "$FEATURES_DB_SERVER" ]; then if [ ! -z "$FEATURES_DB_SERVER" ]; then
OPTS="$OPTS -wait tcp://$FEATURES_DB_SERVER -timeout 60s" OPTS="$OPTS -wait tcp://$FEATURES_DB_SERVER -timeout 60s"
fi fi
dockerize $OPTS java -jar /usr/share/jars/portal-backend.jar dockerize $OPTS java ${JAVA_OPTS} -jar /usr/share/jars/portal-backend.jar
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<spring-data-jpa.version>1.10.11.RELEASE</spring-data-jpa.version> <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> <spring-boot-starter-actuator.version>1.4.7.RELEASE</spring-boot-starter-actuator.version>
<aspectjweaver.version>1.8.9</aspectjweaver.version> <aspectjweaver.version>1.8.9</aspectjweaver.version>
<woken-messages.version>2.4.9</woken-messages.version> <woken-messages.version>2.5.2</woken-messages.version>
<javax-inject.version>1</javax-inject.version> <javax-inject.version>1</javax-inject.version>
<akka.version>2.5.9</akka.version> <akka.version>2.5.9</akka.version>
<spring-context.version>4.3.4.RELEASE</spring-context.version> <spring-context.version>4.3.4.RELEASE</spring-context.version>
......
...@@ -31,7 +31,7 @@ import java.util.function.Function; ...@@ -31,7 +31,7 @@ import java.util.function.Function;
*/ */
public abstract class WokenClientController { public abstract class WokenClientController {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
@Autowired @Autowired
private ActorSystem actorSystem; private ActorSystem actorSystem;
...@@ -44,6 +44,7 @@ public abstract class WokenClientController { ...@@ -44,6 +44,7 @@ public abstract class WokenClientController {
private ActorRef wokenClient; private ActorRef wokenClient;
@SuppressWarnings("unused")
@PostConstruct @PostConstruct
public void initClusterClient() { public void initClusterClient() {
LOGGER.info("Start Woken client " + wokenReceptionistPath); LOGGER.info("Start Woken client " + wokenReceptionistPath);
...@@ -56,7 +57,8 @@ public abstract class WokenClientController { ...@@ -56,7 +57,8 @@ public abstract class WokenClientController {
return Collections.singleton(ActorPaths.fromString(wokenReceptionistPath)); return Collections.singleton(ActorPaths.fromString(wokenReceptionistPath));
} }
protected <A, B> ResponseEntity askWoken(A message, int waitInSeconds, Function<B, ResponseEntity> handleResponse) { @SuppressWarnings("unchecked")
protected <A, B> B askWoken(A message, int waitInSeconds) throws Exception {
LOGGER.info("Akka is trying to reach remote " + wokenPath); LOGGER.info("Akka is trying to reach remote " + wokenPath);
ClusterClient.Send queryMessage = new ClusterClient.Send(wokenPath, message, true); ClusterClient.Send queryMessage = new ClusterClient.Send(wokenPath, message, true);
...@@ -64,35 +66,29 @@ public abstract class WokenClientController { ...@@ -64,35 +66,29 @@ public abstract class WokenClientController {
Future<Object> future = Patterns.ask(wokenClient, queryMessage, timeout); Future<Object> future = Patterns.ask(wokenClient, queryMessage, timeout);
B result; return (B) Await.result(future, timeout.duration());
}
protected <A, B> ResponseEntity requestWoken(A message, int waitInSeconds, Function<B, ResponseEntity> handleResponse) {
try { try {
result = (B) Await.result(future, timeout.duration()); B result = askWoken(message, waitInSeconds);
return handleResponse.apply(result);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Cannot receive algorithm result from woken: " + e.getMessage(), e); final String msg = "Cannot receive result from woken: " + e.getMessage();
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build(); LOGGER.error(msg, e);
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(msg);
} }
return handleResponse.apply(result);
} }
protected <A extends Query> ResponseEntity askWokenQuery(A query, int waitInSeconds, Function<QueryResult, ResponseEntity> handleResponse) { protected <A extends Query> ResponseEntity askWokenQuery(A query, int waitInSeconds, Function<QueryResult, ResponseEntity> handleResponse) {
LOGGER.info("Akka is trying to reach remote " + wokenPath);
ClusterClient.Send queryMessage = new ClusterClient.Send(wokenPath, query, true);
Timeout timeout = new Timeout(Duration.create(waitInSeconds, "seconds"));
Future<Object> future = Patterns.ask(wokenClient, queryMessage, timeout);
QueryResult result;
try { try {
result = (QueryResult) Await.result(future, timeout.duration()); QueryResult result = askWoken(query, waitInSeconds);
return handleResponse.apply(result);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Cannot receive algorithm result from woken: " + e.getMessage(), e); final String msg = "Cannot receive algorithm result from woken: " + e.getMessage();
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build(); LOGGER.error(msg, e);
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(msg);
} }
return handleResponse.apply(result);
} }
protected <A extends Query> Future<Object> sendWokenQuery(A query, int timeout) { protected <A extends Query> Future<Object> sendWokenQuery(A query, int timeout) {
...@@ -103,11 +99,6 @@ public abstract class WokenClientController { ...@@ -103,11 +99,6 @@ public abstract class WokenClientController {
return Patterns.ask(wokenClient, queryMessage, timeout); return Patterns.ask(wokenClient, queryMessage, timeout);
} }
protected ActorRef createActor(String actorBeanName, String actorName) {
return actorSystem.actorOf(SpringExtension.SPRING_EXTENSION_PROVIDER.get(actorSystem)
.props(actorBeanName), actorName);
}
protected ExecutionContext getExecutor() { protected ExecutionContext getExecutor() {
return actorSystem.dispatcher(); return actorSystem.dispatcher();
} }
......
...@@ -5,7 +5,12 @@ ...@@ -5,7 +5,12 @@
package eu.hbp.mip.controllers; package eu.hbp.mip.controllers;
import ch.chuv.lren.woken.messages.datasets.DatasetsQuery;
import ch.chuv.lren.woken.messages.datasets.DatasetsResponse;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import eu.hbp.mip.akka.WokenClientController;
import eu.hbp.mip.model.Dataset; import eu.hbp.mip.model.Dataset;
import eu.hbp.mip.model.Variable; import eu.hbp.mip.model.Variable;
import eu.hbp.mip.repositories.VariableRepository; import eu.hbp.mip.repositories.VariableRepository;
...@@ -13,21 +18,25 @@ import io.swagger.annotations.*; ...@@ -13,21 +18,25 @@ import io.swagger.annotations.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import scala.Option;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Set;
import java.util.stream.Stream;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController @RestController
@RequestMapping(value = "/datasets", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(value = "/datasets", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/datasets", description = "the datasets API") @Api(value = "/datasets", description = "the datasets API")
public class DatasetsApi { public class DatasetsApi extends WokenClientController {
private static final Logger LOGGER = LoggerFactory.getLogger(DatasetsApi.class); private static final Logger LOGGER = LoggerFactory.getLogger(DatasetsApi.class);
private static final Gson gson = new Gson(); private static final Gson gson = new Gson();
...@@ -35,15 +44,15 @@ public class DatasetsApi { ...@@ -35,15 +44,15 @@ public class DatasetsApi {
@Autowired @Autowired
private VariableRepository variableRepository; private VariableRepository variableRepository;
@Value("#{'${spring.featuresDatasource.datasets:adni,ppmi,edsd}'}")
private String datasets;
@PostConstruct @PostConstruct
public void init() { public void init() throws Exception {
for (String dataset: datasets.split(",")) { // Pre-fill the local variable repository with the list of datasets, interpreted here as variables
Variable v = variableRepository.findOne(dataset); // (a bit like a categorical variable can be split into a set of variables (a.k.a one hot encoding in Data science) )
for (ch.chuv.lren.woken.messages.datasets.Dataset dataset: fetchDatasets()) {
final String code = dataset.dataset().code();
Variable v = variableRepository.findOne(code);
if (v == null) { if (v == null) {
v = new Variable(dataset); v = new Variable(code);
variableRepository.save(v); variableRepository.save(v);
} }
} }
...@@ -55,7 +64,27 @@ public class DatasetsApi { ...@@ -55,7 +64,27 @@ public class DatasetsApi {
) { ) {
LOGGER.info("Get dataset list"); LOGGER.info("Get dataset list");
return ResponseEntity.ok(datasets.split(",")); try {
JsonArray datasets = new JsonArray();
Stream<JsonObject> values = fetchDatasets().stream().map(d -> {
JsonObject jsObject = new JsonObject();
jsObject.addProperty("code", d.dataset().code());
jsObject.addProperty("label", d.label());
datasets.add(jsObject);
return jsObject;
});
return ResponseEntity.ok(datasets);
} catch (Exception e) {
final String msg = "Cannot receive datasets from woken: " + e.getMessage();
LOGGER.error(msg, e);
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(msg);
}
} }
private Set<ch.chuv.lren.woken.messages.datasets.Dataset> fetchDatasets() throws Exception {
DatasetsResponse result = askWoken(new DatasetsQuery(Option.empty()), 30);
return scala.collection.JavaConversions.setAsJavaSet(result.datasets());
}
} }
...@@ -35,7 +35,7 @@ public class MethodsApi extends WokenClientController { ...@@ -35,7 +35,7 @@ public class MethodsApi extends WokenClientController {
public ResponseEntity listAvailableMethodsAndValidations() { public ResponseEntity listAvailableMethodsAndValidations() {
LOGGER.info("List available methods and validations"); LOGGER.info("List available methods and validations");
return askWoken(MethodsQuery$.MODULE$, 10, r -> { return requestWoken(MethodsQuery$.MODULE$, 10, r -> {
MethodsResponse result = (MethodsResponse) r; MethodsResponse result = (MethodsResponse) r;
// >> Temporary : should return result.methods() in the future // >> Temporary : should return result.methods() in the future
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment