diff --git a/pom.xml b/pom.xml index af7c98035d8d7f354bf6730240deef5b94d9d464..a9cb39f28e7cf809c411420afed6756ec9965b9e 100644 --- a/pom.xml +++ b/pom.xml @@ -11,13 +11,6 @@ <name>backend-services</name> <description>Medical Informatics Platform : backend restful services</description> - <distributionManagement> - <repository> - <id>central</id> - <name>8a59c6752bef-releases</name> - <url>http://hbps1.chuv.ch/artifactory/libs-release-local</url> - </repository> - </distributionManagement> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> @@ -165,6 +158,33 @@ </dependency> </dependencies> + + + <pluginRepositories> + <pluginRepository> + <id>jcenter-snapshots</id> + <name>jcenter</name> + <url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url> + </pluginRepository> + <pluginRepository> + <snapshots> + <enabled>false</enabled> + </snapshots> + <id>jcenter-releases</id> + <name>jcenter</name> + <url>http://jcenter.bintray.com</url> + </pluginRepository> + </pluginRepositories> + + <properties> + <asciidoctor.maven.plugin.version>1.5.3</asciidoctor.maven.plugin.version> + <asciidoctorj.pdf.version>1.5.0-alpha.11</asciidoctorj.pdf.version> + <asciidoctorj.version>1.5.4</asciidoctorj.version> + <sonar.host.url>http://dockerhost:9000</sonar.host.url> + <sonar.projectName>MIP Backend</sonar.projectName> + <sonar.sources>src/main/java/</sonar.sources> + </properties> + <build> <resources> <resource> @@ -172,8 +192,8 @@ <includes> <include>**/*.xml</include> <include>**/*.json</include> + <include>**/*.csv</include> </includes> - <excludes><exclude>**/*.csv</exclude></excludes> <filtering>true</filtering> </resource> </resources> @@ -182,7 +202,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> - <version>2.4</version> + <version>2.3</version> <configuration> <!-- specify UTF-8, ISO-8859-1 or any other file encoding --> <encoding>UTF-8</encoding> @@ -192,28 +212,19 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> - <plugin> - <groupId>de.juplo</groupId> - <artifactId>hibernate-maven-plugin</artifactId> - <version>2.0.0</version> - <executions> - <execution> - <phase>compile</phase> - <goals> - <goal>create</goal> - </goals> - </execution> - </executions> - <configuration> - <export>false</export> - <show>true</show> - <format>true</format> - </configuration> - </plugin> <plugin> - <groupId>org.apache.maven.plugins</groupId> + <groupId>de.juplo</groupId> + <artifactId>hibernate4-maven-plugin</artifactId> + <version>1.1.0</version> + <executions> + <execution> + <phase>compile</phase> + </execution> + </executions> + </plugin> + <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.5.1</version> + <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> @@ -224,6 +235,43 @@ <artifactId>flyway-maven-plugin</artifactId> <version>4.0.1</version> </plugin> + <plugin> + <groupId>io.github.swagger2markup</groupId> + <artifactId>swagger2markup-maven-plugin</artifactId> + <version>1.0.0</version> + <configuration> + <swaggerInput>http://localhost:8080/services/v2/api-docs</swaggerInput> + <outputFile>${project.build.directory}/asciidoc/api</outputFile> + <config> + <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage> + </config> + </configuration> + </plugin> + <plugin> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctor-maven-plugin</artifactId> + <version>${asciidoctor.maven.plugin.version}</version> + <dependencies> + <dependency> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctorj-pdf</artifactId> + <version>${asciidoctorj.pdf.version}</version> + </dependency> + </dependencies> + <configuration> + <sourceDirectory>${project.build.directory}/asciidoc</sourceDirectory> + <backend>pdf</backend> + <attributes> + <toc/> + <idseparator>-</idseparator> + </attributes> + </configuration> + </plugin> + <plugin> + <groupId>org.sonarsource.scanner.maven</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>3.0.1</version> + </plugin> </plugins> </build> diff --git a/src/main/java/org/hbp/mip/MIPApplication.java b/src/main/java/org/hbp/mip/MIPApplication.java index 0c44fef61108fcd62b46653bdc996ceb42480967..f6d5aeb3d156eeac8afd31340c8bf1b190065e61 100644 --- a/src/main/java/org/hbp/mip/MIPApplication.java +++ b/src/main/java/org/hbp/mip/MIPApplication.java @@ -3,27 +3,13 @@ * Based on gregturn code at : 'https://github.com/spring-guides/tut-spring-boot-oauth2'. */ -/* - * Copyright 2012-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package org.hbp.mip; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiParam; +import org.apache.log4j.Logger; import org.hbp.mip.model.User; import org.hbp.mip.utils.CORSFilter; import org.hbp.mip.utils.HibernateUtil; @@ -92,6 +78,8 @@ import java.security.Principal; @Api(value = "/", description = "MIP API") public class MIPApplication extends WebSecurityConfigurerAdapter { + private static final Logger LOGGER = Logger.getLogger(MIPApplication.class); + @Autowired OAuth2ClientContext oauth2ClientContext; @@ -178,12 +166,11 @@ public class MIPApplication extends WebSecurityConfigurerAdapter { try { String userJSON = mapper.writeValueAsString(getUser()); Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8")); + cookie.setSecure(true); cookie.setPath("/"); response.addCookie(cookie); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + } catch (JsonProcessingException | UnsupportedEncodingException e) { + LOGGER.trace(e); } return principal; } @@ -222,7 +209,7 @@ public class MIPApplication extends WebSecurityConfigurerAdapter { http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class); http.antMatcher("/**") .authorizeRequests() - .antMatchers("/", "/frontend/**", "/webjars/**").permitAll() + .antMatchers("/", "/frontend/**", "/webjars/**", "/v2/api-docs").permitAll() .anyRequest().authenticated() .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint("/login/hbp")) .and().logout().logoutSuccessUrl("/login/hbp").permitAll() @@ -274,8 +261,7 @@ public class MIPApplication extends WebSecurityConfigurerAdapter { } private CsrfTokenRepository csrfTokenRepository() { - HttpSessionCsrfTokenRepository repository = httpSessionCsrfTokenRepository; - return repository; + return httpSessionCsrfTokenRepository; } } diff --git a/src/main/java/org/hbp/mip/controllers/AppsApi.java b/src/main/java/org/hbp/mip/controllers/AppsApi.java index aa0bd2357c08c99f8e121ccc85ecb71af9ef6f7c..b89ef31b4836ba1e52966ae8a002e341bdb13546 100644 --- a/src/main/java/org/hbp/mip/controllers/AppsApi.java +++ b/src/main/java/org/hbp/mip/controllers/AppsApi.java @@ -5,6 +5,7 @@ package org.hbp.mip.controllers; import io.swagger.annotations.*; +import org.apache.log4j.Logger; import org.hbp.mip.MIPApplication; import org.hbp.mip.model.App; import org.hbp.mip.model.User; @@ -32,6 +33,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @Api(value = "/apps", description = "the apps API") public class AppsApi { + private static final Logger LOGGER = Logger.getLogger(AppsApi.class); + @Autowired MIPApplication mipApplication; @@ -106,6 +109,7 @@ public class AppsApi { } catch (ConstraintViolationException cve) { + LOGGER.trace(cve); if(session.getTransaction() != null) { session.getTransaction().rollback(); @@ -114,6 +118,7 @@ public class AppsApi { } catch (NonUniqueObjectException nuoe) { + LOGGER.trace(nuoe); if(session.getTransaction() != null) { session.getTransaction().rollback(); diff --git a/src/main/java/org/hbp/mip/controllers/ArticlesApi.java b/src/main/java/org/hbp/mip/controllers/ArticlesApi.java index 8a0a15e52e478f36a86eb326239cfa3c7f0d7f88..99fe8334aef8fa27ba2fde647794b472b1cdb196 100644 --- a/src/main/java/org/hbp/mip/controllers/ArticlesApi.java +++ b/src/main/java/org/hbp/mip/controllers/ArticlesApi.java @@ -7,6 +7,7 @@ package org.hbp.mip.controllers; import com.github.slugify.Slugify; import io.swagger.annotations.*; +import org.apache.log4j.Logger; import org.hbp.mip.MIPApplication; import org.hbp.mip.model.Article; import org.hbp.mip.model.User; @@ -31,6 +32,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @Api(value = "/articles", description = "the articles API") public class ArticlesApi { + private static final Logger LOGGER = Logger.getLogger(ArticlesApi.class); + @Autowired MIPApplication mipApplication; @@ -57,11 +60,6 @@ public class ArticlesApi { else { queryString += " AND (status='published' or u.username= :username)"; - if(team != null && team) - { - // TODO: decide if this is needed - //queryString += " AND u.team= :team"; - } } Session session = HibernateUtil.getSessionFactory().getCurrentSession(); @@ -99,7 +97,7 @@ public class ArticlesApi { User user = mipApplication.getUser(); article.setCreatedAt(new Date()); - if (article.getStatus().equals("published")) { + if ("published".equals(article.getStatus())) { article.setPublishedAt(new Date()); } article.setCreatedBy(user); @@ -128,13 +126,7 @@ public class ArticlesApi { } } while(count > 0); - Slugify slg = null; - try { - slg = new Slugify(); - } catch (IOException e) { - e.printStackTrace(); - } - String slug = slg.slugify(article.getTitle()); + String slug = new Slugify().slugify(article.getTitle()); i = 0; do { @@ -156,8 +148,9 @@ public class ArticlesApi { session.save(article); session.getTransaction().commit(); - } catch (Exception e) - { + } catch (IOException e) { + LOGGER.trace(e); + } catch (Exception e) { if(session.getTransaction() != null) { session.getTransaction().rollback(); @@ -191,7 +184,7 @@ public class ArticlesApi { session.getTransaction().commit(); - if (!article.getStatus().equals("published") && !article.getCreatedBy().getUsername().equals(user.getUsername())) + if (!"published".equals(article.getStatus()) && !article.getCreatedBy().getUsername().equals(user.getUsername())) { return new ResponseEntity<>(HttpStatus.FORBIDDEN); } diff --git a/src/main/java/org/hbp/mip/controllers/ExperimentApi.java b/src/main/java/org/hbp/mip/controllers/ExperimentApi.java index 868b7ed860f08eb63d1bb88a572355d00f30c486..5adbdaa35ffd233717ea958b54e6a3cdfc7f78a2 100644 --- a/src/main/java/org/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/org/hbp/mip/controllers/ExperimentApi.java @@ -2,23 +2,28 @@ package org.hbp.mip.controllers; import com.google.gson.*; import io.swagger.annotations.*; +import org.apache.log4j.Logger; import org.hbp.mip.MIPApplication; -import org.hbp.mip.model.*; +import org.hbp.mip.model.Experiment; +import org.hbp.mip.model.Model; +import org.hbp.mip.model.User; import org.hbp.mip.utils.HTTPUtil; import org.hbp.mip.utils.HibernateUtil; +import org.hbp.mip.utils.JSONUtil; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.exception.DataException; 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.web.bind.annotation.*; -import java.io.*; -import java.net.*; -import java.util.Date; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -34,6 +39,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @javax.annotation.Generated(value = "class io.swagger.codegen.languages.SpringMVCServerCodegen", date = "2016-01-07T07:38:20.227Z") public class ExperimentApi { + private static final Logger LOGGER = Logger.getLogger(ExperimentApi.class); + private static final String EXAREME_ALGO_JSON_FILE="data/exareme_algorithms.json"; private static final Gson gson = new GsonBuilder() @@ -42,6 +49,8 @@ public class ExperimentApi { .excludeFieldsWithoutExposeAnnotation() .create(); + private static final String EXAREME_LR_ALGO = "WP_LINEAR_REGRESSION"; + @Value("#{'${workflow.experimentUrl:http://dockerhost:8087/experiment}'}") private String experimentUrl; @@ -54,72 +63,6 @@ public class ExperimentApi { @Autowired MIPApplication mipApplication; - private void sendPost(Experiment experiment) throws MalformedURLException { - URL obj = new URL(experimentUrl); - - // this runs in the background. For future optimization: use a thread pool - new Thread() { - public void run() { - try { - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - - String query = experiment.computeQuery(); - System.out.println("Running experiment: " + query); - - // create query - try { - con.setRequestMethod("POST"); - } catch (ProtocolException pe) {} // ignore; won't happen - con.addRequestProperty("Content-Type", "application/json"); - con.setRequestProperty("Content-Length", Integer.toString(query.length())); - con.setFollowRedirects(true); - con.setReadTimeout(3600000); // 1 hour: 60*60*1000 ms - - // write body of query - con.setDoOutput(true); - DataOutputStream wr = new DataOutputStream(con.getOutputStream()); - wr.write(query.getBytes("UTF8")); - wr.flush(); - wr.close(); - - // get response - InputStream stream = con.getResponseCode() < 400 ? con.getInputStream() : con.getErrorStream(); - BufferedReader in = new BufferedReader(new InputStreamReader(stream)); - String inputLine; - StringBuilder response = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - response.append(inputLine + '\n'); - } - in.close(); - - // write to experiment - experiment.setResult(response.toString().replace("\0", "")); - experiment.setHasError(con.getResponseCode() >= 400); - experiment.setHasServerError(con.getResponseCode() >= 500); - - } catch (IOException ioe) { - // write error to - experiment.setHasError(true); - experiment.setHasServerError(true); - experiment.setResult(ioe.getMessage()); - } - - experiment.setFinished(new Date()); - - // finally - try { - Session session = HibernateUtil.getSessionFactory().openSession(); - Transaction transaction = session.beginTransaction(); - session.update(experiment); - transaction.commit(); - session.close(); - } catch (DataException e) { - throw e; - } - - } - }.start(); - } @ApiOperation(value = "Send a request to the workflow to run an experiment", response = Experiment.class) @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) @@ -149,8 +92,12 @@ public class ExperimentApi { transaction.commit(); } catch (Exception e) { - transaction.rollback(); - e.printStackTrace(); + if(transaction != null) + { + transaction.rollback(); + } + LOGGER.trace(e); + LOGGER.warn("Cannot create experiment to run ! This is probably caused by a bad request !"); // 400 here probably return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); } @@ -158,125 +105,28 @@ public class ExperimentApi { try { if(isExaremeAlgo(experiment)) { - sendExaremePost(experiment); + sendExaremeExperiment(experiment); } else { - sendPost(experiment); + sendExperiment(experiment); } - } catch (MalformedURLException mue) {} // ignore + } catch (MalformedURLException mue) { LOGGER.trace(mue.getMessage()); } // ignore return new ResponseEntity<>(gson.toJson(experiment), HttpStatus.OK); } - private void sendExaremePost(Experiment experiment) { - - Model model = experiment.getModel(); - String algoCode = "WP_LINEAR_REGRESSION"; - - LinkedList<ExaremeQueryElement> queryElements = new LinkedList<>(); - for (Variable var : model.getQuery().getVariables()) - { - ExaremeQueryElement el = new ExaremeQueryElement(); - el.setName("variable"); - el.setDesc(""); - el.setValue(var.getCode()); - queryElements.add(el); - } - for (Variable var : model.getQuery().getCovariables()) - { - ExaremeQueryElement el = new ExaremeQueryElement(); - el.setName("covariables"); - el.setDesc(""); - el.setValue(var.getCode()); - queryElements.add(el); - } - for (Variable var : model.getQuery().getGrouping()) - { - ExaremeQueryElement el = new ExaremeQueryElement(); - el.setName("groupings"); - el.setDesc(""); - el.setValue(var.getCode()); - queryElements.add(el); - } - - ExaremeQueryElement tableEl = new ExaremeQueryElement(); - tableEl.setName("showtable"); - tableEl.setDesc(""); - tableEl.setValue("TotalResults"); - queryElements.add(tableEl); - - ExaremeQueryElement formatEl = new ExaremeQueryElement(); - formatEl.setName("format"); - formatEl.setDesc(""); - formatEl.setValue("True"); - queryElements.add(formatEl); - - String jsonQuery = new Gson().toJson(queryElements); - - new Thread() { - public void run() { - try { - String url = miningExaremeQueryUrl + "/" + algoCode; - StringBuilder results = new StringBuilder(); - int code = HTTPUtil.sendPost(url, jsonQuery, results); - - experiment.setResult(results.toString().replace("\0", "")); - experiment.setHasError(code >= 400); - experiment.setHasServerError(code >= 500); - - if(!isJSONValid(experiment.getResult())) - { - experiment.setResult("Unsupported variables !"); - } - } catch (Exception e) { - experiment.setHasError(true); - experiment.setHasServerError(true); - experiment.setResult(e.getMessage()); - } - - experiment.setFinished(new Date()); - - try { - Session session = HibernateUtil.getSessionFactory().openSession(); - Transaction transaction = session.beginTransaction(); - session.update(experiment); - transaction.commit(); - session.close(); - } catch (DataException e) { - throw e; - } - - } - }.start(); - } - - public boolean isJSONValid(String test) { - try { - new JsonParser().parse(test); - } catch (JsonParseException jpe) - { - return false; - } - return true; - } - - private boolean isExaremeAlgo(Experiment experiment) { - JsonArray algorithms = new JsonParser().parse(experiment.getAlgorithms()).getAsJsonArray(); - String algoCode = algorithms.get(0).getAsJsonObject().get("code").getAsString(); - return algoCode.equals("glm_exareme"); - } - @ApiOperation(value = "get an experiment", response = Experiment.class) @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) public ResponseEntity<String> getExperiment(@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) { - Experiment experiment; UUID experimentUuid; try { experimentUuid = UUID.fromString(uuid); } catch (IllegalArgumentException iae) { + LOGGER.trace(iae); + LOGGER.warn("An invalid Experiment UUID was received !"); return ResponseEntity.badRequest().body("Invalid Experiment UUID"); } @@ -291,7 +141,10 @@ public class ExperimentApi { session.getTransaction().commit(); } catch (Exception e) { // 404 here probably - session.getTransaction().rollback(); + if(session.getTransaction() != null) + { + session.getTransaction().rollback(); + } throw e; } @@ -312,6 +165,8 @@ public class ExperimentApi { try { experimentUuid = UUID.fromString(uuid); } catch (IllegalArgumentException iae) { + LOGGER.trace(iae); + LOGGER.warn("An invalid Experiment UUID was received !"); return ResponseEntity.badRequest().body("Invalid Experiment UUID"); } @@ -333,56 +188,16 @@ public class ExperimentApi { transaction.commit(); } catch (Exception e) { // 404 here probably - transaction.rollback(); - throw e; - } - - if (experiment == null) { - return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND); - } - return new ResponseEntity<>(gson.toJson(experiment), HttpStatus.OK); - } - - public ResponseEntity<String> doMarkExperimentAsShared(String uuid, boolean shared) { - - Experiment experiment; - UUID experimentUuid; - User user = mipApplication.getUser(); - try { - experimentUuid = UUID.fromString(uuid); - } catch (IllegalArgumentException iae) { - return ResponseEntity.badRequest().body("Invalid Experiment UUID"); - } - - Session session = HibernateUtil.getSessionFactory().getCurrentSession(); - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - Query hibernateQuery = session.createQuery("from Experiment as experiment where experiment.uuid = :uuid"); - hibernateQuery.setParameter("uuid", experimentUuid); - experiment = (Experiment) hibernateQuery.uniqueResult(); - - if (!experiment.getCreatedBy().getUsername().equals(user.getUsername())) - return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.BAD_REQUEST); - - experiment.setShared(shared); - session.update(experiment); - - transaction.commit(); - } catch (Exception e) { - // 404 here probably - transaction.rollback(); + if(transaction != null) + { + transaction.rollback(); + } throw e; } - if (experiment == null) { - return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND); - } return new ResponseEntity<>(gson.toJson(experiment), HttpStatus.OK); } - @ApiOperation(value = "get an experiment", response = Experiment.class) @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) @RequestMapping(value = "/{uuid}/markAsShared", method = RequestMethod.GET) @@ -397,7 +212,55 @@ public class ExperimentApi { return doMarkExperimentAsShared(uuid, false); } - public ResponseEntity<String> doListExperiments( + @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") + @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) + @RequestMapping(value = "/mine", method = RequestMethod.GET, params = {"maxResultCount"}) + public ResponseEntity<String> listExperiments( + @ApiParam(value = "maxResultCount", required = false) @RequestParam int maxResultCount + ) { + return doListExperiments(true, maxResultCount, null); + } + + @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") + @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) + @RequestMapping(method = RequestMethod.GET, params = {"slug", "maxResultCount"}) + public ResponseEntity<String> listExperiments( + @ApiParam(value = "slug", required = false) @RequestParam("slug") String modelSlug, + @ApiParam(value = "maxResultCount", required = false) @RequestParam("maxResultCount") int maxResultCount + ) { + + 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 doListExperiments(false, maxResultCount, modelSlug); + } + + @ApiOperation(value = "List available methods and validations", response = String.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) + @RequestMapping(path = "/methods", method = RequestMethod.GET) + public ResponseEntity<String> listAvailableMethodsAndValidations() throws IOException { + + StringBuilder response = new StringBuilder(); + + int code = HTTPUtil.sendGet(listMethodsUrl, response); + if (code < 200 || code > 299) { + return new ResponseEntity<>(response.toString(), HttpStatus.valueOf(code)); + } + + JsonObject catalog = new JsonParser().parse(response.toString()).getAsJsonObject(); + + InputStream is = ExperimentApi.class.getClassLoader().getResourceAsStream(EXAREME_ALGO_JSON_FILE); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + JsonObject exaremeAlgo = new JsonParser().parse(br).getAsJsonObject(); + + catalog.get("algorithms").getAsJsonArray().add(exaremeAlgo); + + return new ResponseEntity<>(new Gson().toJson(catalog), HttpStatus.valueOf(code)); + } + + private ResponseEntity<String> doListExperiments( boolean mine, int maxResultCount, String modelSlug @@ -415,10 +278,11 @@ public class ExperimentApi { baseQuery += mine ? "e.createdBy = :user" : "(e.createdBy = :user OR e.shared is true)"; - if (modelSlug == null || modelSlug.equals("")) { + if (modelSlug == null || "".equals(modelSlug)) { hibernateQuery = session.createQuery(baseQuery); } else { - hibernateQuery = session.createQuery(baseQuery + " AND e.model.slug = :slug"); + baseQuery += " AND e.model.slug = :slug"; + hibernateQuery = session.createQuery(baseQuery); hibernateQuery.setParameter("slug", modelSlug); } hibernateQuery.setParameter("user", user); @@ -440,59 +304,125 @@ public class ExperimentApi { } } catch (Exception e) { // 404 here probably + LOGGER.trace(e); throw e; } finally { - session.getTransaction().rollback(); + if(session.getTransaction() != null) + { + session.getTransaction().rollback(); + } } return new ResponseEntity<>(gson.toJson(experiments), HttpStatus.OK); } - @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) - @RequestMapping(value = "/mine", method = RequestMethod.GET, params = {"maxResultCount"}) - public ResponseEntity<String> listExperiments( - @ApiParam(value = "maxResultCount", required = false) @RequestParam int maxResultCount - ) { - return doListExperiments(true, maxResultCount, null); - } + private ResponseEntity<String> doMarkExperimentAsShared(String uuid, boolean shared) { + Experiment experiment; + UUID experimentUuid; + User user = mipApplication.getUser(); + try { + experimentUuid = UUID.fromString(uuid); + } catch (IllegalArgumentException iae) { + LOGGER.trace(iae); + LOGGER.warn("An invalid Experiment UUID was received !"); + return ResponseEntity.badRequest().body("Invalid Experiment UUID"); + } - @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) - @RequestMapping(method = RequestMethod.GET, params = {"slug", "maxResultCount"}) - public ResponseEntity<String> listExperiments( - @ApiParam(value = "slug", required = false) @RequestParam("slug") String modelSlug, - @ApiParam(value = "maxResultCount", required = false) @RequestParam("maxResultCount") int maxResultCount - ) { + Session session = HibernateUtil.getSessionFactory().getCurrentSession(); + Transaction transaction = null; + try { + transaction = session.beginTransaction(); - if (maxResultCount <= 0 && (modelSlug == null || modelSlug.equals(""))) { - return new ResponseEntity<>("You must provide at least a slug or a limit of result", HttpStatus.BAD_REQUEST); + Query hibernateQuery = session.createQuery("from Experiment as experiment where experiment.uuid = :uuid"); + hibernateQuery.setParameter("uuid", experimentUuid); + experiment = (Experiment) hibernateQuery.uniqueResult(); + + if (!experiment.getCreatedBy().getUsername().equals(user.getUsername())) + return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.BAD_REQUEST); + + experiment.setShared(shared); + session.update(experiment); + + transaction.commit(); + } catch (Exception e) { + // 404 here probably + if(transaction != null) + { + transaction.rollback(); + } + throw e; } - return doListExperiments(false, maxResultCount, modelSlug); + return new ResponseEntity<>(gson.toJson(experiment), HttpStatus.OK); } - @ApiOperation(value = "List available methods and validations", response = String.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success") }) - @RequestMapping(path = "/methods", method = RequestMethod.GET) - public ResponseEntity<String> listAvailableMethodsAndValidations() throws Exception { + private void sendExperiment(Experiment experiment) throws MalformedURLException { + // this runs in the background. For future optimization: use a thread pool + new Thread() { + @Override + public void run() { + String url = experimentUrl; + String query = experiment.computeQuery(); - StringBuilder response = new StringBuilder(); + // Results are stored in the experiment object + try { + executeExperiment(url, query, experiment); + } catch (IOException e) { + LOGGER.trace(e); + LOGGER.warn("Experiment failed to run properly !"); + setExperimentError(e, experiment); + } - int code = HTTPUtil.sendGet(listMethodsUrl, response); - if (code < 200 || code > 299) { - return new ResponseEntity<>(response.toString(), HttpStatus.valueOf(code)); - } + experiment.finish(); + } + }.start(); + } - JsonObject catalog = new JsonParser().parse(response.toString()).getAsJsonObject(); + private void sendExaremeExperiment(Experiment experiment) { + // this runs in the background. For future optimization: use a thread pool + new Thread() { + @Override + public void run() { + String query = experiment.computeExaremeQuery(); + String url = miningExaremeQueryUrl + "/" + EXAREME_LR_ALGO; - InputStream is = ExperimentApi.class.getClassLoader().getResourceAsStream(EXAREME_ALGO_JSON_FILE); - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - JsonObject exaremeAlgo = new JsonParser().parse(br).getAsJsonObject(); + // Results are stored in the experiment object + try { + executeExperiment(url, query, experiment); + } catch (IOException e) { + LOGGER.trace(e); + LOGGER.warn("Exareme experiment failed to run properly !"); + setExperimentError(e, experiment); + } - catalog.get("algorithms").getAsJsonArray().add(exaremeAlgo); + if(!JSONUtil.isJSONValid(experiment.getResult())) + { + experiment.setResult("Unsupported variables !"); + } - return new ResponseEntity<>(new Gson().toJson(catalog), HttpStatus.valueOf(code)); + experiment.finish(); + } + }.start(); + } + + private static void executeExperiment(String url, String query, Experiment experiment) throws IOException { + StringBuilder results = new StringBuilder(); + int code = HTTPUtil.sendPost(url, query, results); + experiment.setResult(results.toString().replace("\0", "")); + experiment.setHasError(code >= 400); + experiment.setHasServerError(code >= 500); } + + private static void setExperimentError(IOException e, Experiment experiment) { + experiment.setHasError(true); + experiment.setHasServerError(true); + experiment.setResult(e.getMessage()); + } + + private static boolean isExaremeAlgo(Experiment experiment) { + JsonArray algorithms = new JsonParser().parse(experiment.getAlgorithms()).getAsJsonArray(); + String algoCode = algorithms.get(0).getAsJsonObject().get("code").getAsString(); + return "glm_exareme".equals(algoCode); + } + } diff --git a/src/main/java/org/hbp/mip/controllers/ModelsApi.java b/src/main/java/org/hbp/mip/controllers/ModelsApi.java index 7041bbe76420928f5a0785f4301fb5fb300f681f..21b102e1858a508f92bff344a4aded93006c10f2 100644 --- a/src/main/java/org/hbp/mip/controllers/ModelsApi.java +++ b/src/main/java/org/hbp/mip/controllers/ModelsApi.java @@ -6,6 +6,7 @@ package org.hbp.mip.controllers; import com.github.slugify.Slugify; import io.swagger.annotations.*; +import org.apache.log4j.Logger; import org.hbp.mip.MIPApplication; import org.hbp.mip.model.*; import org.hbp.mip.utils.CSVUtil; @@ -28,6 +29,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @javax.annotation.Generated(value = "class io.swagger.codegen.languages.SpringMVCServerCodegen", date = "2016-01-07T07:38:20.227Z") public class ModelsApi { + private static final Logger LOGGER = Logger.getLogger(ModelsApi.class); + @Autowired MIPApplication mipApplication; @@ -57,11 +60,6 @@ public class ModelsApi { else { queryString += " AND (m.valid=true or u.username= :username)"; - if(team != null && team) - { - // TODO: decide if this is needed - //queryString += " AND u.team= :team"; - } } queryString += " ORDER BY m.createdAt DESC"; @@ -92,7 +90,7 @@ public class ModelsApi { } for(Model model:models){ - String ds_code = model.getDataset().getCode(); + String dsCode = model.getDataset().getCode(); session = HibernateUtil.getSessionFactory().getCurrentSession(); Dataset dataset = null; @@ -100,7 +98,7 @@ public class ModelsApi { session.beginTransaction(); dataset = (Dataset) session .createQuery("from Dataset where code= :code") - .setString("code", ds_code) + .setString("code", dsCode) .uniqueResult(); session.getTransaction().commit(); } catch (Exception e) @@ -160,13 +158,7 @@ public class ModelsApi { } } while(count > 0); - Slugify slg = null; - try { - slg = new Slugify(); - } catch (IOException e) { - e.printStackTrace(); - } - String slug = slg.slugify(model.getTitle()); + String slug = new Slugify().slugify(model.getTitle()); i = 0; do { @@ -192,6 +184,8 @@ public class ModelsApi { session.save(model); session.getTransaction().commit(); + } catch (IOException e) { + LOGGER.trace(e); } catch (Exception e) { if(session.getTransaction() != null) @@ -215,7 +209,6 @@ public class ModelsApi { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); Model model = null; - Query query; try { session.beginTransaction(); @@ -260,45 +253,48 @@ public class ModelsApi { } } - List<Variable> vars = new LinkedList<>(); - for (Variable var : q.getVariables()) { - Variable v = new Variable(); - v.setCode(var.getCode()); - vars.add(v); - } + if(q != null) { - List<Variable> covs = new LinkedList<>(); - for (Variable cov : q.getCovariables()) { - Variable v = new Variable(); - v.setCode(cov.getCode()); - covs.add(v); - } + List<Variable> vars = new LinkedList<>(); + for (Variable var : q.getVariables()) { + Variable v = new Variable(); + v.setCode(var.getCode()); + vars.add(v); + } - List<Variable> grps = new LinkedList<>(); - for (Variable grp : q.getGrouping()) { - Variable v = new Variable(); - v.setCode(grp.getCode()); - grps.add(v); - } + List<Variable> covs = new LinkedList<>(); + for (Variable cov : q.getCovariables()) { + Variable v = new Variable(); + v.setCode(cov.getCode()); + covs.add(v); + } - List<Filter> fltrs = new LinkedList<>(); - for (Filter fltr : q.getFilters()) { - Filter f = new Filter(); - f.setId(fltr.getId()); - f.setOperator(fltr.getOperator()); - f.setValues(fltr.getValues()); - f.setVariable(fltr.getVariable()); - fltrs.add(f); - } + List<Variable> grps = new LinkedList<>(); + for (Variable grp : q.getGrouping()) { + Variable v = new Variable(); + v.setCode(grp.getCode()); + grps.add(v); + } - org.hbp.mip.model.Query myQuery = new org.hbp.mip.model.Query(); - myQuery.setId(q.getId()); - myQuery.setVariables(vars); - myQuery.setCovariables(covs); - myQuery.setGrouping(grps); - myQuery.setFilters(fltrs); + List<Filter> fltrs = new LinkedList<>(); + for (Filter fltr : q.getFilters()) { + Filter f = new Filter(); + f.setId(fltr.getId()); + f.setOperator(fltr.getOperator()); + f.setValues(fltr.getValues()); + f.setVariable(fltr.getVariable()); + fltrs.add(f); + } - model.setQuery(myQuery); + org.hbp.mip.model.Query myQuery = new org.hbp.mip.model.Query(); + myQuery.setId(q.getId()); + myQuery.setVariables(vars); + myQuery.setCovariables(covs); + myQuery.setGrouping(grps); + myQuery.setFilters(fltrs); + + model.setQuery(myQuery); + } Dataset ds = CSVUtil.parseValues(DATA_FILE, model.getQuery()); model.setDataset(ds); @@ -380,41 +376,7 @@ public class ModelsApi { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - @ApiOperation(value = "Copy a model", response = Model.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Model copied"), @ApiResponse(code = 404, message = "Not found") }) - @RequestMapping(value = "/{slug}/copies", method = RequestMethod.POST) - public ResponseEntity<Model> copyAModel( - @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug, - @RequestBody @ApiParam(value = "Model to update", required = true) Model model - ) { - - User user = mipApplication.getUser(); - - String originalSlug = model.getSlug(); - String copySlug; - do { - copySlug = originalSlug+" copy_"+randomStr(20); - } while (getAModel(copySlug) == null); - model.setSlug(copySlug); - - Session session = HibernateUtil.getSessionFactory().getCurrentSession(); - try{ - session.beginTransaction(); - session.save(model); - session.getTransaction().commit(); - } catch (Exception e) - { - if(session.getTransaction() != null) - { - session.getTransaction().rollback(); - throw e; - } - } - - return new ResponseEntity<>(HttpStatus.CREATED).ok(model); - } - - private String randomStr(int length) { + private static String randomStr(int length) { char[] chars = "abcdefghijklmnopqrstuvwxyz0123456789".toCharArray(); StringBuilder sb = new StringBuilder(); Random random = new Random(); diff --git a/src/main/java/org/hbp/mip/model/App.java b/src/main/java/org/hbp/mip/model/App.java index 38450ade304847675a0f02966eb79d0fef9e54b7..c328c36ca8330b538d66028cd085407959a4b5ca 100644 --- a/src/main/java/org/hbp/mip/model/App.java +++ b/src/main/java/org/hbp/mip/model/App.java @@ -44,6 +44,9 @@ public class App { public App() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Article.java b/src/main/java/org/hbp/mip/model/Article.java index 49e0fc8171d7d4ea26401312d708cc77c5689b34..b7821db0ca22566bb2aff06a847d566fff0a40e7 100644 --- a/src/main/java/org/hbp/mip/model/Article.java +++ b/src/main/java/org/hbp/mip/model/Article.java @@ -26,12 +26,12 @@ public class Article { @NotNull @Size(min = 1, max = 255) - private String title = null; + private String title; private String status = null; - @Column(columnDefinition = "text") - private String _abstract = null; + @Column(columnDefinition = "text", name = "abstract") + private String abstractText = null; @Column(columnDefinition = "text") private String content = null; @@ -55,6 +55,10 @@ public class Article { public Article() { + /* + * Empty constructor is needed by Hibernate + */ + title = ""; } @@ -87,11 +91,11 @@ public class Article { @JsonProperty("abstract") public String getAbstract() { - return _abstract; + return abstractText; } - public void setAbstract(String _abstract) { - this._abstract = _abstract; + public void setAbstract(String abstractText) { + this.abstractText = abstractText; } diff --git a/src/main/java/org/hbp/mip/model/Config.java b/src/main/java/org/hbp/mip/model/Config.java index 555d7cece4fc591d29792f9ffdcbb5e30a67c1a7..08bed89798cda8f97015ae62717a7a2300b7126d 100644 --- a/src/main/java/org/hbp/mip/model/Config.java +++ b/src/main/java/org/hbp/mip/model/Config.java @@ -41,6 +41,9 @@ public class Config { public Config() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Dataset.java b/src/main/java/org/hbp/mip/model/Dataset.java index 61b5a5316cebdd78d10b4bb63045bffeb4541c35..023cecf06d6738dc31f7cfde5edb2dccf2dbd09f 100644 --- a/src/main/java/org/hbp/mip/model/Dataset.java +++ b/src/main/java/org/hbp/mip/model/Dataset.java @@ -39,6 +39,9 @@ public class Dataset { public Dataset() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Experiment.java b/src/main/java/org/hbp/mip/model/Experiment.java index a569c9719231a54e50f66f4d1b71a7421b1fdd32..d87949be04dc8da5d7080d4e20ace726e22ff267 100644 --- a/src/main/java/org/hbp/mip/model/Experiment.java +++ b/src/main/java/org/hbp/mip/model/Experiment.java @@ -5,12 +5,19 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; +import org.apache.log4j.Logger; +import org.hbp.mip.utils.HibernateUtil; +import org.hibernate.Session; +import org.hibernate.Transaction; import org.hibernate.annotations.*; +import org.hibernate.exception.DataException; import javax.persistence.*; import javax.persistence.Entity; import javax.persistence.Table; import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.UUID; /** @@ -20,6 +27,8 @@ import java.util.UUID; @Table(name = "`experiment`") public class Experiment { + private static final Logger LOGGER = Logger.getLogger(Experiment.class); + private static final Gson gson = new GsonBuilder() .serializeNulls() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") @@ -78,6 +87,9 @@ public class Experiment { private boolean resultsViewed = false; public Experiment() { + /* + * Empty constructor is needed by Hibernate + */ } public String computeQuery() { @@ -91,6 +103,63 @@ public class Experiment { return outgoingQuery.toString(); } + public String computeExaremeQuery() { + List<ExaremeQueryElement> queryElements = new LinkedList<>(); + for (Variable var : model.getQuery().getVariables()) + { + ExaremeQueryElement el = new ExaremeQueryElement(); + el.setName("variable"); + el.setDesc(""); + el.setValue(var.getCode()); + queryElements.add(el); + } + for (Variable var : model.getQuery().getCovariables()) + { + ExaremeQueryElement el = new ExaremeQueryElement(); + el.setName("covariables"); + el.setDesc(""); + el.setValue(var.getCode()); + queryElements.add(el); + } + for (Variable var : model.getQuery().getGrouping()) + { + ExaremeQueryElement el = new ExaremeQueryElement(); + el.setName("groupings"); + el.setDesc(""); + el.setValue(var.getCode()); + queryElements.add(el); + } + + ExaremeQueryElement tableEl = new ExaremeQueryElement(); + tableEl.setName("showtable"); + tableEl.setDesc(""); + tableEl.setValue("TotalResults"); + queryElements.add(tableEl); + + ExaremeQueryElement formatEl = new ExaremeQueryElement(); + formatEl.setName("format"); + formatEl.setDesc(""); + formatEl.setValue("True"); + queryElements.add(formatEl); + + return new Gson().toJson(queryElements); + } + + public void finish() { + this.setFinished(new Date()); + + try { + Session session = HibernateUtil.getSessionFactory().openSession(); + Transaction transaction = session.beginTransaction(); + session.update(this); + transaction.commit(); + session.close(); + } catch (DataException e) { + LOGGER.trace(e); + throw e; + } + } + public String getValidations() { return validations; } diff --git a/src/main/java/org/hbp/mip/model/Filter.java b/src/main/java/org/hbp/mip/model/Filter.java index c85bc140a47ab0bcef46c795ad9160a60edac1c1..27af1d69c9b26fd1475d1395f1e3a6432c86bf81 100644 --- a/src/main/java/org/hbp/mip/model/Filter.java +++ b/src/main/java/org/hbp/mip/model/Filter.java @@ -34,6 +34,9 @@ public class Filter { public Filter() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/GeneralStats.java b/src/main/java/org/hbp/mip/model/GeneralStats.java index 94b3b62b28b5dea3b2d727c66042272401827858..b9366c013e3e2913a220e598cfe6c3264d231b6a 100644 --- a/src/main/java/org/hbp/mip/model/GeneralStats.java +++ b/src/main/java/org/hbp/mip/model/GeneralStats.java @@ -17,6 +17,9 @@ public class GeneralStats { public GeneralStats() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Group.java b/src/main/java/org/hbp/mip/model/Group.java index 066f3f94905128fdb961b1d473b0d878948814ad..32cf44f662107d113c214901ee77113d6e434d85 100644 --- a/src/main/java/org/hbp/mip/model/Group.java +++ b/src/main/java/org/hbp/mip/model/Group.java @@ -32,6 +32,9 @@ public class Group { public Group() { + /* + * Empty constructor is needed by Hibernate + */ } @@ -70,15 +73,4 @@ public class Group { this.groups = groups; } - - public Group clone() - { - Group g = new Group(); - g.setCode(this.getCode()); - g.setLabel(this.getLabel()); - g.setParent(this.getParent()); - g.setGroups(this.getGroups()); - return g; - } - } diff --git a/src/main/java/org/hbp/mip/model/Model.java b/src/main/java/org/hbp/mip/model/Model.java index 774b8e0cf75833d659a06a75a637c3d7e84b19cb..fb871152fe562a4fab41a0b7def52123cd26394b 100644 --- a/src/main/java/org/hbp/mip/model/Model.java +++ b/src/main/java/org/hbp/mip/model/Model.java @@ -59,6 +59,9 @@ public class Model { public Model() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Query.java b/src/main/java/org/hbp/mip/model/Query.java index ebcce263bb75713c521f0e34b25f1264038b3724..fddb0c7a7c68ffb5a79c733032d9a36c4564008b 100644 --- a/src/main/java/org/hbp/mip/model/Query.java +++ b/src/main/java/org/hbp/mip/model/Query.java @@ -52,6 +52,9 @@ public class Query { public Query() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Tag.java b/src/main/java/org/hbp/mip/model/Tag.java index e4c34e30bb9ca12ee306455e755018033ab928f7..6619bd75f57a66dfe66446e4f710b4d515663199 100644 --- a/src/main/java/org/hbp/mip/model/Tag.java +++ b/src/main/java/org/hbp/mip/model/Tag.java @@ -22,6 +22,9 @@ public class Tag { public Tag() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/User.java b/src/main/java/org/hbp/mip/model/User.java index f013859e96b02d12adeada9cbadf250b4429d9e9..7d12a47f5265f9f4aebd58463b7dcde0c93140b1 100644 --- a/src/main/java/org/hbp/mip/model/User.java +++ b/src/main/java/org/hbp/mip/model/User.java @@ -88,6 +88,9 @@ public class User { public User() { + /* + * Empty constructor is needed by Hibernate + */ } @@ -133,7 +136,7 @@ public class User { p = Pattern.compile("title=([\\w ]+)"); m = p.matcher(userInfo); if (m.find()) { - if (m.group(1).equals("Mr")) { + if ("Mr".equals(m.group(1))) { this.gender = "Male"; } else { this.gender = "Female"; diff --git a/src/main/java/org/hbp/mip/model/Variable.java b/src/main/java/org/hbp/mip/model/Variable.java index e651105c6f525d13345daf6a6b7f04b56d4f4fbf..2bc6a37c8637930c0ea1466633250bfb467ac9b2 100644 --- a/src/main/java/org/hbp/mip/model/Variable.java +++ b/src/main/java/org/hbp/mip/model/Variable.java @@ -59,6 +59,9 @@ public class Variable { public Variable() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/model/Vote.java b/src/main/java/org/hbp/mip/model/Vote.java index 91ce0b055d21cfd9dd65a9066d34dea1f9aa93db..b9981a8e92a96092b8c0fa8e4e833f70846dedfd 100644 --- a/src/main/java/org/hbp/mip/model/Vote.java +++ b/src/main/java/org/hbp/mip/model/Vote.java @@ -33,6 +33,9 @@ public class Vote { public Vote() { + /* + * Empty constructor is needed by Hibernate + */ } diff --git a/src/main/java/org/hbp/mip/utils/CORSFilter.java b/src/main/java/org/hbp/mip/utils/CORSFilter.java index 30bea8de4bc436b3a9aa685424e89d7f6f7c92ab..9feb2895dd7af50acfcb61e0e35810e3a71d2ebe 100644 --- a/src/main/java/org/hbp/mip/utils/CORSFilter.java +++ b/src/main/java/org/hbp/mip/utils/CORSFilter.java @@ -9,6 +9,7 @@ import java.io.IOException; */ public class CORSFilter implements Filter { + @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); @@ -18,7 +19,13 @@ public class CORSFilter implements Filter { chain.doFilter(req, res); } - public void init(FilterConfig filterConfig) {} + @Override + public void init(FilterConfig filterConfig) { + /* Nothing to do */ + } - public void destroy() {} + @Override + public void destroy() { + /* Nothing to do */ + } } diff --git a/src/main/java/org/hbp/mip/utils/CSVUtil.java b/src/main/java/org/hbp/mip/utils/CSVUtil.java index 4ac7fd269d736166e12daf3fdd5716ad115a398a..b3f6850be795983ec8728624da7dfcf733369dfe 100644 --- a/src/main/java/org/hbp/mip/utils/CSVUtil.java +++ b/src/main/java/org/hbp/mip/utils/CSVUtil.java @@ -1,5 +1,6 @@ package org.hbp.mip.utils; +import org.apache.log4j.Logger; import org.hbp.mip.model.Dataset; import org.hbp.mip.model.Query; import org.hbp.mip.model.Variable; @@ -19,14 +20,22 @@ import java.util.stream.Collectors; */ public class CSVUtil { + private static final Logger LOGGER = Logger.getLogger(CSVUtil.class); + private static final String SEPARATOR = ","; + private CSVUtil() + { + /* Hide implicit public constructor */ + throw new IllegalAccessError("CSVUtil class"); + } + public static Dataset parseValues(String filename, Query query) { List<String[]> rows = getRows(filename); Dataset result = new Dataset(); - String code = GenerateDSCode(query); + String code = generateDSCode(query); Date date = new Date(); List<String> header = new LinkedList<>(); List<String> grouping = new LinkedList<>(); @@ -140,7 +149,7 @@ public class CSVUtil { data.put(c, ll); } } catch (IOException e) { - e.printStackTrace(); + LOGGER.trace(e); } result.setCode(code); result.setDate(date); @@ -155,7 +164,7 @@ public class CSVUtil { private static List<String[]> getRows(String filename) { List<String[]> rows = new LinkedList<>(); try { - InputStream is = Dataset.class.getClassLoader().getResourceAsStream(filename); + InputStream is = CSVUtil.class.getClassLoader().getResourceAsStream(filename); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String[] firstRow = br.readLine().split(SEPARATOR, -1); // 1st row -> headers @@ -167,7 +176,8 @@ public class CSVUtil { isr.close(); is.close(); } catch (IOException e) { - e.printStackTrace(); + LOGGER.trace(e); + LOGGER.warn("A problem occured while trying to read a CSV file !"); } return rows; @@ -181,7 +191,7 @@ public class CSVUtil { return -1; } - private static String GenerateDSCode(Query query) { + private static String generateDSCode(Query query) { String prefix = "DS"; String queryStr = Integer.toString(query.hashCode()); String memId; diff --git a/src/main/java/org/hbp/mip/utils/HTTPUtil.java b/src/main/java/org/hbp/mip/utils/HTTPUtil.java index 92beffaf45e7f48e8c71d51e36414fb78ce827ae..0a524bb99d7fa8403af05fb94fdfec0c1e9d9a25 100644 --- a/src/main/java/org/hbp/mip/utils/HTTPUtil.java +++ b/src/main/java/org/hbp/mip/utils/HTTPUtil.java @@ -2,6 +2,7 @@ package org.hbp.mip.utils; import java.io.BufferedReader; import java.io.DataOutputStream; +import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; @@ -11,20 +12,26 @@ import java.net.URL; */ public class HTTPUtil { - public static int sendGet(String url, StringBuilder resp) throws Exception { + 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"); } - public static int sendPost(String url, String query, StringBuilder resp) throws Exception { + public static int sendPost(String url, String query, StringBuilder resp) throws IOException { return sendHTTP(url, query, resp, "POST"); } - public static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb) throws Exception { + public static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb) throws IOException { URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - if(!httpVerb.equals("GET")) { + if(!"GET".equals(httpVerb)) { con.setRequestMethod(httpVerb); if(query != null && query.length() > 0) { diff --git a/src/main/java/org/hbp/mip/utils/HibernateUtil.java b/src/main/java/org/hbp/mip/utils/HibernateUtil.java index 3048e20b8f338a7ce22d047f9701ac89176d98b8..87cde9618993e4070518b70d2bf6e4d058d54760 100644 --- a/src/main/java/org/hbp/mip/utils/HibernateUtil.java +++ b/src/main/java/org/hbp/mip/utils/HibernateUtil.java @@ -4,15 +4,25 @@ package org.hbp.mip.utils; +import org.apache.log4j.Logger; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateUtil { + + private static final Logger LOGGER = Logger.getLogger(CSVUtil.class); + private static ServiceRegistry serviceRegistry; + private static SessionFactory sessionFactory = buildSessionFactory(); + private HibernateUtil() { + /* Hide implicit public constructor */ + throw new IllegalAccessError("HibernateUtil class"); + } + private static SessionFactory buildSessionFactory() { try { Configuration configuration = new Configuration(); @@ -21,8 +31,8 @@ public class HibernateUtil { configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); return sessionFactory; - } catch (Throwable ex) { - System.err.println("Initial SessionFactory creation failed." + ex); + } catch (RuntimeException ex) { + LOGGER.error("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } diff --git a/src/main/java/org/hbp/mip/utils/JSONUtil.java b/src/main/java/org/hbp/mip/utils/JSONUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..938cfbb70a26974495782707d151089fad9b4d01 --- /dev/null +++ b/src/main/java/org/hbp/mip/utils/JSONUtil.java @@ -0,0 +1,30 @@ +package org.hbp.mip.utils; + +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import org.apache.log4j.Logger; + +/** + * Created by mirco on 01.07.16. + */ +public class JSONUtil { + + private static final Logger LOGGER = Logger.getLogger(JSONUtil.class); + + private JSONUtil() { + /* Hide implicit public constructor */ + throw new IllegalAccessError("JSONUtil class"); + } + + public static boolean isJSONValid(String test) { + try { + new JsonParser().parse(test); + } catch (JsonParseException jpe) + { + LOGGER.trace(jpe); // This is the normal behavior when the input string is not JSON-ified + return false; + } + return true; + } + +}