From cf48ecb9f2f0c05dbff754a2205999927e7ea9ce Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Mon, 19 Oct 2020 02:21:46 -0700
Subject: [PATCH 01/52] Experiments/Models Refactoring

1) Removed Models entity.
2) CRUD for experiments.
3) Database cleanup.
4) Useless entities removed.
5) Implemented service layer.
6) DAOs - DTOs cleanup.
---
 build.sh                                      |   2 +-
 pom.xml                                       |   7 -
 .../eu/hbp/mip/controllers/AlgorithmsApi.java |   2 +-
 .../eu/hbp/mip/controllers/ArticlesApi.java   | 193 -----
 .../eu/hbp/mip/controllers/ExperimentApi.java | 818 +-----------------
 .../java/eu/hbp/mip/controllers/FilesAPI.java |  47 -
 .../eu/hbp/mip/controllers/MiningApi.java     | 110 ---
 .../eu/hbp/mip/controllers/ModelsApi.java     | 259 ------
 .../hbp/mip/controllers/PathologiesApi.java   |   2 +-
 .../java/eu/hbp/mip/controllers/StatsApi.java |  50 --
 src/main/java/eu/hbp/mip/model/Article.java   |  13 -
 src/main/java/eu/hbp/mip/model/Config.java    | 112 ---
 .../eu/hbp/mip/model/DAOs/ExperimentDAO.java  | 203 +++++
 .../mip/model/{ => DTOs}/AlgorithmDTO.java    |   2 +-
 .../eu/hbp/mip/model/DTOs/ExperimentDTO.java  | 126 +++
 .../mip/model/{ => DTOs}/PathologyDTO.java    |   2 +-
 src/main/java/eu/hbp/mip/model/Dataset.java   | 106 ---
 .../eu/hbp/mip/model/DatasetDescription.java  |  46 -
 .../java/eu/hbp/mip/model/Experiment.java     | 232 -----
 .../hbp/mip/model/ExperimentExecutionDTO.java | 106 ---
 src/main/java/eu/hbp/mip/model/Group.java     |  37 -
 src/main/java/eu/hbp/mip/model/Mining.java    |  64 --
 .../java/eu/hbp/mip/model/MiningQuery.java    |  96 --
 src/main/java/eu/hbp/mip/model/Model.java     | 163 ----
 src/main/java/eu/hbp/mip/model/Query.java     | 164 ----
 src/main/java/eu/hbp/mip/model/Tag.java       |  39 -
 src/main/java/eu/hbp/mip/model/User.java      | 228 +----
 src/main/java/eu/hbp/mip/model/UserInfo.java  |   1 -
 src/main/java/eu/hbp/mip/model/Value.java     |  43 -
 src/main/java/eu/hbp/mip/model/Variable.java  |  59 --
 .../eu/hbp/mip/model/galaxy/WorkflowDTO.java  |   2 +-
 .../mip/repositories/ConfigRepository.java    |  11 -
 .../mip/repositories/DatasetRepository.java   |  11 -
 .../repositories/ExperimentRepository.java    |   8 +-
 .../hbp/mip/repositories/ModelRepository.java |  17 -
 .../hbp/mip/repositories/QueryRepository.java |  11 -
 .../hbp/mip/repositories/TagRepository.java   |  11 -
 .../hbp/mip/repositories/ValueRepository.java |  11 -
 .../mip/repositories/VariableRepository.java  |  10 -
 .../hbp/mip/services/ExperimentService.java   | 776 +++++++++++++++++
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |   2 +-
 .../java/eu/hbp/mip/utils/JsonConverters.java |  27 +
 .../V7_0__NewExperimentStructure.sql          |  45 +
 src/main/resources/logback.xml                |   3 +-
 44 files changed, 1218 insertions(+), 3059 deletions(-)
 delete mode 100644 src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
 delete mode 100644 src/main/java/eu/hbp/mip/controllers/FilesAPI.java
 delete mode 100644 src/main/java/eu/hbp/mip/controllers/MiningApi.java
 delete mode 100644 src/main/java/eu/hbp/mip/controllers/ModelsApi.java
 delete mode 100644 src/main/java/eu/hbp/mip/controllers/StatsApi.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Config.java
 create mode 100644 src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
 rename src/main/java/eu/hbp/mip/model/{ => DTOs}/AlgorithmDTO.java (95%)
 create mode 100644 src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
 rename src/main/java/eu/hbp/mip/model/{ => DTOs}/PathologyDTO.java (93%)
 delete mode 100644 src/main/java/eu/hbp/mip/model/Dataset.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/DatasetDescription.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Experiment.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Group.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Mining.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/MiningQuery.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Model.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Query.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Tag.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Value.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/Variable.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/ConfigRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/DatasetRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/ModelRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/QueryRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/TagRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/ValueRepository.java
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/VariableRepository.java
 create mode 100644 src/main/java/eu/hbp/mip/services/ExperimentService.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/JsonConverters.java
 create mode 100644 src/main/resources/db/migration/V7_0__NewExperimentStructure.sql

diff --git a/build.sh b/build.sh
index ef4f10565..6a18d98ec 100755
--- a/build.sh
+++ b/build.sh
@@ -26,7 +26,7 @@ else
   DOCKER="sudo docker"
 fi
 
-IMAGE="hbpmip/portal-backend"
+IMAGE="kfilippopolitis/portal-backend"
 VCS_REF=$(git describe --tags --dirty)
 VERSION=$(git describe --tags --dirty)
 
diff --git a/pom.xml b/pom.xml
index 20a6f0661..87ef337aa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -211,13 +211,6 @@
             <artifactId>jaxb-runtime</artifactId>
             <version>2.4.0-b180830.0438</version>
         </dependency>
-        
-        <dependency>
-            <groupId>com.auth0</groupId>
-            <artifactId>java-jwt</artifactId>
-            <version>3.8.3</version>
-        </dependency>
-
         <!-- https://mvnrepository.com/artifact/com.github.jmchilton.blend4j/blend4j -->
         <dependency>
             <groupId>com.github.jmchilton.blend4j</groupId>
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index 8310973a3..fcde558b8 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -8,7 +8,7 @@ import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
-import eu.hbp.mip.model.AlgorithmDTO;
+import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.model.galaxy.WorkflowDTO;
 import eu.hbp.mip.utils.CustomResourceLoader;
diff --git a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java b/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
deleted file mode 100644
index d4eb46e9f..000000000
--- a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.controllers;
-
-
-import com.github.slugify.Slugify;
-import eu.hbp.mip.model.Article;
-import eu.hbp.mip.model.User;
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.repositories.ArticleRepository;
-import eu.hbp.mip.utils.Logging;
-import io.swagger.annotations.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.io.IOException;
-import java.util.Date;
-import java.util.Iterator;
-
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-@RestController
-@RequestMapping(value = "/articles", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/articles", description = "the articles API")
-public class ArticlesApi {
-
-    @Autowired
-    private UserInfo userInfo;
-
-    @Autowired
-    private ArticleRepository articleRepository;
-
-    @ApiOperation(value = "Get articles", response = Article.class, responseContainer = "List")
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<Iterable> getArticles(
-            @ApiParam(value = "Only ask own articles") @RequestParam(value = "own", required = false) Boolean own,
-            @ApiParam(value = "Only ask results matching status", allowableValues = "draft, published") @RequestParam(value = "status", required = false) String status
-    ) {
-        User user = userInfo.getUser();
-        Iterable<Article> articles;
-        Logging.LogUserAction(user.getUsername(), "(GET) /articles", "Loading articles...");
-
-        if (own != null && own) {
-            articles = articleRepository.findByCreatedBy(user);
-        } else {
-            articles = articleRepository.findByStatusOrCreatedBy("published", user);
-        }
-        int articlesSize = 0;
-        if (status != null) {
-            for (Iterator<Article> i = articles.iterator(); i.hasNext(); ) {
-                Article a = i.next();
-                if (!status.equals(a.getStatus())) {
-                    i.remove();
-                }
-                articlesSize++;
-            }
-        }
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /articles", "Successfully Loaded " + articlesSize + " articles");
-
-        return ResponseEntity.ok(articles);
-    }
-
-
-    @ApiOperation(value = "Create an article")
-    @ApiResponses(value = {@ApiResponse(code = 201, message = "Article created")})
-    @RequestMapping(method = RequestMethod.POST)
-    public ResponseEntity<Void> addAnArticle(
-            @RequestBody @ApiParam(value = "Article to create", required = true) @Valid Article article
-    ) {
-
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(POST) /articles", "Creating article...");
-
-        article.setCreatedAt(new Date());
-        if ("published".equals(article.getStatus())) {
-            article.setPublishedAt(new Date());
-        }
-        article.setCreatedBy(user);
-
-        long count = 1;
-        for (int i = 1; count > 0; i++) {
-            count = articleRepository.countByTitle(article.getTitle());
-
-            if (count > 0) {
-                String title = article.getTitle();
-                if (i > 1) {
-                    title = title.substring(0, title.length() - 4);
-                }
-                article.setTitle(title + " (" + i + ")");
-            }
-        }
-
-        String slug;
-        try {
-            slug = new Slugify().slugify(article.getTitle());
-        } catch (IOException e) {
-            slug = "";
-            //LOGGER.trace("Cannot slugify title", e);
-        }
-
-        boolean alreadyExists = true;
-        for (int i = 1; alreadyExists; i++) {
-            alreadyExists = articleRepository.exists(slug);
-            if (alreadyExists) {
-                if (i > 1) {
-                    slug = slug.substring(0, slug.length() - 2);
-                }
-                slug += "-" + i;
-            }
-            article.setSlug(slug);
-        }
-        articleRepository.save(article);
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /articles", "Successfully created article with id : " + article.getSlug());
-        return new ResponseEntity<>(HttpStatus.CREATED);
-    }
-
-
-    @ApiOperation(value = "Get an article", response = Article.class)
-    @RequestMapping(value = "/{slug}", method = RequestMethod.GET)
-    public ResponseEntity<Article> getAnArticle(
-            @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug
-    ) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /articles/{slug}", "Loading article with id : " + slug);
-
-        User user = userInfo.getUser();
-        Article article;
-        article = articleRepository.findOne(slug);
-
-        if (article == null) {
-            //LOGGER.warn("Cannot find article : " + slug);
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /articles/{slug}", "Article not found");
-            return ResponseEntity.badRequest().body(null);
-        }
-
-        if (!"published".equals(article.getStatus()) && !article.getCreatedBy().getUsername().equals(user.getUsername())) {
-            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
-        }
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /articles/{slug}", "Successfully Loaded article with id : " + slug);
-
-        return ResponseEntity.ok(article);
-    }
-
-
-    @ApiOperation(value = "Update an article")
-    @ApiResponses(value = {@ApiResponse(code = 204, message = "Article updated")})
-    @RequestMapping(value = "/{slug}", method = RequestMethod.PUT)
-    public ResponseEntity<Void> updateAnArticle(
-            @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug,
-            @RequestBody @ApiParam(value = "Article to update", required = true) @Valid Article article
-    ) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(PUT) /articles/{slug}", "Updating article with id : " + slug);
-
-        User user = userInfo.getUser();
-
-        String author = articleRepository.findOne(slug).getCreatedBy().getUsername();
-
-        if (!user.getUsername().equals(author)) {
-            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
-        }
-
-        String oldTitle = articleRepository.findOne(slug).getTitle();
-
-        String newTitle = article.getTitle();
-
-        if (!newTitle.equals(oldTitle)) {
-            long count = 1;
-            for (int i = 1; count > 0 && !newTitle.equals(oldTitle); i++) {
-                newTitle = article.getTitle();
-                count = articleRepository.countByTitle(newTitle);
-                if (count > 0 && !newTitle.equals(oldTitle)) {
-                    if (i > 1) {
-                        newTitle = newTitle.substring(0, newTitle.length() - 4);
-                    }
-                    article.setTitle(newTitle + " (" + i + ")");
-                }
-            }
-        }
-
-        articleRepository.save(article);
-
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(PUT) /articles/{slug}", "Successfully pdated article with id : " + slug);
-
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index f05151474..d28d8aac3 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -1,43 +1,20 @@
 package eu.hbp.mip.controllers;
 
-import com.github.jmchilton.blend4j.galaxy.GalaxyInstance;
-import com.github.jmchilton.blend4j.galaxy.GalaxyInstanceFactory;
-import com.github.jmchilton.blend4j.galaxy.WorkflowsClient;
-import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
-import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
-import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
-import com.google.common.collect.Lists;
-import com.google.gson.*;
-import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
-import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
-import eu.hbp.mip.model.*;
-import eu.hbp.mip.model.ExperimentExecutionDTO.AlgorithmExecutionDTO.AlgorithmExecutionParamDTO;
-import eu.hbp.mip.model.galaxy.ErrorResponse;
-import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
-import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
-import eu.hbp.mip.repositories.ExperimentRepository;
-import eu.hbp.mip.repositories.ModelRepository;
-import eu.hbp.mip.utils.ClaimUtils;
-import eu.hbp.mip.utils.HTTPUtil;
-import eu.hbp.mip.utils.Logging;
+import com.google.gson.Gson;
+import eu.hbp.mip.model.DTOs.ExperimentDTO;
+import eu.hbp.mip.model.UserInfo;
+import eu.hbp.mip.services.ExperimentService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
 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.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
-import retrofit2.Call;
-import retrofit2.Response;
 
-import java.io.IOException;
-import java.util.*;
+import java.util.List;
 
-import static java.lang.Thread.sleep;
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 /*
@@ -50,784 +27,41 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/experiments")
 public class ExperimentApi {
 
-    private static final Gson gson = new Gson();
-
     @Autowired
     private UserInfo userInfo;
 
-    private static final Gson gsonOnlyExposed = new GsonBuilder().serializeNulls()
-            .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").excludeFieldsWithoutExposeAnnotation().create();
-
-    @Value("#{'${services.exareme.queryExaremeUrl}'}")
-    private String queryExaremeUrl;
-
-    @Value("#{'${services.workflows.workflowUrl}'}")
-    private String workflowUrl;
-
-    @Value("#{'${services.workflows.jwtSecret}'}")
-    private String jwtSecret;
-
-    @Value("#{'${services.galaxy.galaxyUrl}'}")
-    private String galaxyUrl;
-
-    @Value("#{'${services.galaxy.galaxyApiKey}'}")
-    private String galaxyApiKey;
-
-    // Enable HBP collab authentication (1) or disable it (0). Default is 1
-    @Value("#{'${hbp.authentication.enabled:1}'}")
-    private boolean authenticationIsEnabled;
-
     @Autowired
-    private ModelRepository modelRepository;
+    private ExperimentService experimentService;
 
-    @Autowired
-    private ExperimentRepository experimentRepository;
+    @ApiOperation(value = "Get experiments", response = ExperimentDTO.class, responseContainer = "List")
+    @RequestMapping(method = RequestMethod.GET)
+    public ResponseEntity<String> getExperiments() {
+        return experimentService.getExperiments("(GET) /experiments");
+    }
 
-    @ApiOperation(value = "get an experiment", response = Experiment.class)
+    @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
     public ResponseEntity<String> getExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-
-        Experiment experiment;
-        UUID experimentUuid;
-        User user = userInfo.getUser();
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}", "Loading Experiment with uuid : " + uuid);
-
-        try {
-            experimentUuid = UUID.fromString(uuid);
-        } catch (IllegalArgumentException iae) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}", "Invalid Experiment UUID.");
-            return ResponseEntity.badRequest().body("Invalid Experiment UUID");
-        }
-
-        experiment = experimentRepository.findOne(experimentUuid);
-
-        if (experiment == null) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}", "Experiment Not found.");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
-
-        if (!experiment.isShared() && !experiment.getCreatedBy().getUsername().equals(user.getUsername())) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}", "Accessing Experiment is unauthorized.");
-            return new ResponseEntity<>("You don't have access to the experiment.", HttpStatus.UNAUTHORIZED);
-        }
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}", "Experiment was Loaded with uuid : " + uuid + ".");
-
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
-    }
-
-
-    @ApiOperation(value = "Create an experiment", response = Experiment.class)
-    @RequestMapping(value = "/runAlgorithm", method = RequestMethod.POST)
-    public ResponseEntity<String> runExperiment(Authentication authentication, @RequestBody ExperimentExecutionDTO experimentExecutionDTO) {
-        User user = userInfo.getUser();
-        // Get the type and name of algorithm
-        String algorithmType = experimentExecutionDTO.getAlgorithms().get(0).getType();
-        String algorithmName = experimentExecutionDTO.getAlgorithms().get(0).getName();
-
-        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        for (ExperimentExecutionDTO.AlgorithmExecutionDTO.AlgorithmExecutionParamDTO params : experimentExecutionDTO.getAlgorithms().get(0).getParameters()) {
-            parametersLogMessage
-                    .append("  ")
-                    .append(params.getLabel())
-                    .append(" -> ")
-                    .append(params.getValue())
-                    .append("\n");
-        }
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Executing " + algorithmName + parametersLogMessage);
-
-        if (authenticationIsEnabled) {
-            // Getting the dataset from the experiment parameters
-            String experimentDatasets = null;
-            for (ExperimentExecutionDTO.AlgorithmExecutionDTO.AlgorithmExecutionParamDTO parameter : experimentExecutionDTO.getAlgorithms().get(0).getParameters()) {
-                if (parameter.getLabel().equals("dataset")) {
-                    experimentDatasets = parameter.getValue();
-                    break;
-                }
-            }
-
-            if (experimentDatasets == null || experimentDatasets.equals("")) {
-                Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm",
-                        "A dataset should be specified to run an algorithm.");
-                return ResponseEntity.badRequest().body("Please provide at least one dataset to run the algorithm.");
-            }
-
-            // --- Validating proper access rights on the datasets  ---
-            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
-                return ResponseEntity.badRequest().body("You are not authorized to use these datasets.");
-            }
-        }
-
-        // Run with the appropriate engine
-        if (algorithmType.equals("workflow")) {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Algorithm runs on Galaxy.");
-            return runGalaxyWorkflow(experimentExecutionDTO);
-        } else {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Algorithm runs on Exareme.");
-            return runExaremeAlgorithm(experimentExecutionDTO);
-        }
+        return experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
     }
 
-    @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) {
-
-        Experiment experiment;
-        UUID experimentUuid;
-        User user = userInfo.getUser();
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}/markAsViewed", "Marking as viewed the experiment with uuid : " + uuid + ".");
-
-        try {
-            experimentUuid = UUID.fromString(uuid);
-        } catch (IllegalArgumentException iae) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}/markAsViewed", "Invalid Experiment UUID" + uuid + ".");
-            return ResponseEntity.badRequest().body("Invalid Experiment UUID");
-        }
-
-        experiment = experimentRepository.findOne(experimentUuid);
-        if (!experiment.getCreatedBy().getUsername().equals(user.getUsername())) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}/markAsViewed", "You're not the owner of this experiment");
-            return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
-        }
-        experiment.setResultsViewed(true);
-        experimentRepository.save(experiment);
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{uuid}/markAsViewed", "Experiment with uuid: " + uuid + " was marked as viewed.");
-
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
+    @ApiOperation(value = "Create an experiment", response = ExperimentDTO.class)
+    @RequestMapping(method = RequestMethod.POST)
+    public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+        return experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
     }
 
-    @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) {
-
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /experiments/{uuid}/markAsShared", "Marking as shared the experiment with uuid : " + uuid + ".");
-
-        return doMarkExperimentAsShared(uuid, true);
+    @ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
+    @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
+    public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO,@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
+        return experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
     }
 
-    @ApiOperation(value = "Mark an experiment as unshared", response = Experiment.class)
-    @RequestMapping(value = "/{uuid}/markAsUnshared", method = RequestMethod.GET)
-    public ResponseEntity<String> markExperimentAsUnshared(
+    @ApiOperation(value = "Delete an experiment", response = boolean.class)
+    @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
+    public ResponseEntity<String> deleteExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /experiments/{uuid}/markAs/Unshared", "Marking as unshared the experiment with uuid : " + uuid + ".");
-
-        return doMarkExperimentAsShared(uuid, false);
-    }
-
-    @ApiOperation(value = "list experiments", response = Experiment.class, responseContainer = "List")
-    @RequestMapping(method = RequestMethod.GET, params = {"maxResultCount"})
-    public ResponseEntity<String> listExperiments(
-            @ApiParam(value = "maxResultCount") @RequestParam int maxResultCount) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{maxResultCount}", "Listing experiments with a maximum amount of : " + maxResultCount + ".");
-
-        List<Experiment> expList = doListExperiments(false, null);
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{maxResultCount}", "Successfully listed experiments.");
-
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(expList), HttpStatus.OK);
-    }
-
-    @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) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{slug}/{maxResultCount}", "Listing experiments with a maximum amount of :" + maxResultCount + "with modelSlug : " + modelSlug + ".");
-
-        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);
-        }
-
-        List<Experiment> expList = doListExperiments(false, null);
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{slug}/{maxResultCount}", "Successfully listed my experiments.");
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(expList), HttpStatus.OK);
-    }
-
-    @ApiOperation(value = "list my experiments", response = Experiment.class, responseContainer = "List")
-    @RequestMapping(method = RequestMethod.GET, params = {"mine"})
-    public ResponseEntity<String> listMyExperiments(Authentication authentication, @ApiParam(value = "mine") @RequestParam("mine") boolean mine) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{mine}", "Listing my experiments.");
-        List<Experiment> expList = doListExperiments(true, null);
-        Logging.LogUserAction(user.getUsername(), "(GET) /experiments/{mine}", "Successfully listed my experiments.");
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(expList), HttpStatus.OK);
-    }
-
-    private List<Experiment> doListExperiments(boolean mine, String modelSlug) {
-        User user = userInfo.getUser();
-
-        Iterable<Experiment> myExperiments = experimentRepository.findByCreatedBy(user);
-        List<Experiment> expList = Lists.newLinkedList(myExperiments);
-        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(); ) {
-                Experiment e = it.next();
-                e.setResult(null);
-                e.setAlgorithms(null);
-                e.setValidations(null);
-                if (!e.getModel().getSlug().equals(modelSlug)) {
-                    it.remove();
-                }
-            }
-        }
-        return expList;
-    }
-
-    private ResponseEntity<String> doMarkExperimentAsShared(String uuid, boolean shared) {
-        Experiment experiment;
-        UUID experimentUuid;
-        User user = userInfo.getUser();
-
-        try {
-            experimentUuid = UUID.fromString(uuid);
-        } catch (IllegalArgumentException iae) {
-            //LOGGER.trace("Invalid UUID", iae);
-            //LOGGER.warn("An invalid Experiment UUID was received !");
-            Logging.LogUserAction(user.getUsername(), "List my experiments", "Listing my experiments.");
-            return ResponseEntity.badRequest().body("Invalid Experiment UUID");
-        }
-
-        experiment = experimentRepository.findOne(experimentUuid);
-
-        if (!experiment.getCreatedBy().getUsername().equals(user.getUsername()))
-            return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
-
-        experiment.setShared(shared);
-        experimentRepository.save(experiment);
-
-        Logging.LogUserAction(user.getUsername(), "Experiment updated (marked as shared)", "");
-
-        return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
-    }
-
-    /* -------------------------------  EXPERIMENT MODEL METHODS  ----------------------------------------------------*/
-
-    public Experiment createExperiment(ExperimentExecutionDTO experimentExecutionDTO) {
-        User user = userInfo.getUser();
-
-        Experiment experiment = new Experiment();
-        experiment.setUuid(UUID.randomUUID());
-        experiment.setCreatedBy(user);
-        experiment.setAlgorithms(gson.toJson(experimentExecutionDTO.getAlgorithms()));
-        Model model = modelRepository.findOne(experimentExecutionDTO.getModel());
-        experiment.setModel(model);
-        experiment.setName(experimentExecutionDTO.getName());
-        experimentRepository.save(experiment);
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " id : " + experiment.getUuid());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " algorithms : " + experiment.getAlgorithms());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " model : " + experiment.getModel().getSlug());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " name : " + experiment.getName());
-        return experiment;
-    }
-
-    private void saveExperiment(Experiment experiment) {
-        User user = userInfo.getUser();
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " id : " + experiment.getUuid());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " algorithms : " + experiment.getAlgorithms());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " model : " + experiment.getModel().getSlug());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " name : " + experiment.getName());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " historyId : " + experiment.getWorkflowHistoryId());
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", " status : " + experiment.getWorkflowStatus());
-
-        experimentRepository.save(experiment);
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Saved experiment");
-    }
-
-    private void finishExperiment(Experiment experiment) {
-        experiment.setFinished(new Date());
-        experimentRepository.save(experiment);
-    }
-
-    /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
-
-    /**
-     * The runExaremeExperiment will POST the algorithm to the exareme client
-     *
-     * @param experimentExecutionDTO is the request with the experiment information
-     * @return the response to be returned
-     */
-    public ResponseEntity<String> runExaremeAlgorithm(ExperimentExecutionDTO experimentExecutionDTO) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Running the algorithm...");
-
-        Experiment experiment = createExperiment(experimentExecutionDTO);
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Created experiment with uuid :" + experiment.getUuid());
-
-        // Run the 1st algorithm from the list
-        String algorithmName = experimentExecutionDTO.getAlgorithms().get(0).getName();
-
-        // Get the parameters
-        List<ExperimentExecutionDTO.AlgorithmExecutionDTO.AlgorithmExecutionParamDTO> algorithmParameters
-                = experimentExecutionDTO.getAlgorithms().get(0).getParameters();
-
-        String body = gson.toJson(algorithmParameters);
-        String url = queryExaremeUrl + "/" + algorithmName;
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "url: " + url + ", body: " + body);
-
-        ResponseEntity<String> response = new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm",
-                "Completed, returning: " + experiment.toString());
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm",
-                "Starting exareme execution thread");
-        new Thread(() -> {
-            // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
-            Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
-
-            try {
-                StringBuilder results = new StringBuilder();
-                int code = HTTPUtil.sendPost(url, body, results);
-
-                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Algorithm finished with code: " + code);
-
-                // Results are stored in the experiment object
-                experiment.setResult("[" + results.toString() + "]");
-                experiment.setHasError(code >= 400);
-                experiment.setHasServerError(code >= 500);
-            } catch (Exception e) {
-                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "There was an exception: " + e.getMessage());
-
-                experiment.setHasError(true);
-                experiment.setHasServerError(true);
-                experiment.setResult(e.getMessage());
-            }
-
-            finishExperiment(experiment);
-            Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Finished the experiment: " + experiment.toString());
-        }).start();
-
-        return response;
-    }
-
-    /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
-
-
-    /**
-     * The runWorkflow will POST the algorithm to the galaxy client
-     *
-     * @param experimentExecutionDTO is the request with the experiment information
-     * @return the response to be returned
-     */
-    public ResponseEntity<String> runGalaxyWorkflow(ExperimentExecutionDTO experimentExecutionDTO) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Running a workflow...");
-
-        Experiment experiment = createExperiment(experimentExecutionDTO);
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Created experiment with uuid :" + experiment.getUuid());
-
-
-        // Run the 1st algorithm from the list
-        String workflowId = experimentExecutionDTO.getAlgorithms().get(0).getName();
-
-        // Get the parameters
-        List<AlgorithmExecutionParamDTO> algorithmParameters
-                = experimentExecutionDTO.getAlgorithms().get(0).getParameters();
-
-        // Convert the parameters to workflow parameters
-        HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>();
-        if (algorithmParameters != null) {
-            for (AlgorithmExecutionParamDTO param : algorithmParameters) {
-                algorithmParamsIncludingEmpty.put(param.getName(), param.getValue());
-            }
-        }
-
-        // Get all the algorithm parameters because the frontend provides only the non-null
-        final GalaxyInstance instance = GalaxyInstanceFactory.get(galaxyUrl, galaxyApiKey);
-        final WorkflowsClient workflowsClient = instance.getWorkflowsClient();
-        Workflow workflow = null;
-        for (Workflow curWorkflow : workflowsClient.getWorkflows()) {
-            if (curWorkflow.getId().equals(workflowId)) {
-                workflow = curWorkflow;
-                break;
-            }
-        }
-        if (workflow == null) {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm",
-                    "Could not find algorithm code: " + workflowId);
-            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
-                    .body(new ErrorResponse("Could not find galaxy algorithm.").toString());
-        }
-        final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId());
-        for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) {
-            if (!(algorithmParamsIncludingEmpty.containsKey(workflowParameter.getValue().getUuid()))) {
-                algorithmParamsIncludingEmpty.put(workflowParameter.getValue().getUuid(), "");
-            }
-        }
-
-        // Create the body of the request
-        HashMap<String, HashMap<String, String>> requestBody = new HashMap<>();
-        requestBody.put("inputs", algorithmParamsIncludingEmpty);
-        JsonObject requestBodyJson = new JsonParser().parse(gson.toJson(requestBody)).getAsJsonObject();
-
-        // Create the request client
-        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Running Galaxy workflow with id: " + workflow.getId());
-
-        // Call Galaxy to run the workflow
-        Call<PostWorkflowToGalaxyDtoResponse> call = service.postWorkflowToGalaxy(workflow.getId(), galaxyApiKey, requestBodyJson);
-        try {
-            Response<PostWorkflowToGalaxyDtoResponse> response = call.execute();
-
-            if (response.code() == 200) {       // Call succeeded
-                String responseBody = gson.toJson(response.body());
-                Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Response: " + responseBody);
-
-                String historyId = (String) new JSONObject(responseBody).get("history_id");
-                experiment.setWorkflowHistoryId(historyId);
-                experiment.setWorkflowStatus("running");
-                experiment.setHasError(false);
-                experiment.setHasServerError(response.code() >= 500);
-
-            } else {     // Something unexpected happened
-                String msgErr = gson.toJson(response.errorBody());
-                Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Error Response: " + msgErr);
-
-                // Values are read from streams.
-                JSONObject jObjectError = new JSONObject(msgErr);
-                String errMsg = jObjectError.get("err_msg").toString();
-
-                experiment.setResult("[" + new ErrorResponse(errMsg).toString() + "]");
-                experiment.setHasError(response.code() >= 400);
-                experiment.setHasServerError(response.code() >= 500);
-            }
-
-        } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "An exception occurred: " + e.getMessage());
-            experiment.setHasError(true);
-            experiment.setHasServerError(true);
-            experiment.setResult(e.getMessage());
-        }
-        saveExperiment(experiment);
-
-        // Start the process of fetching the status
-        updateWorkflowExperiment(experiment);
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Run workflow completed!");
-
-        return new ResponseEntity(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
-    }
-
-
-    /**
-     * This method creates a thread that will fetch the workflow result when it is ready
-     *
-     * @param experiment will be used to fetch it's workflow status, it should have the workflowHistoryId initialized
-     *                   and the result should not already be fetched
-     * @return nothing, just updates the experiment
-     */
-    public void updateWorkflowExperiment(Experiment experiment) {
-        User user = userInfo.getUser();
-
-        if (experiment == null) {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "The experiment does not exist.");
-            return;
-        }
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm",
-                " Experiment id : " + experiment.getUuid());
-        if (experiment.getWorkflowHistoryId() == null) {
-            Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "History Id does not exist.");
-            return;
-        }
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /experiments/runAlgorithm", "Starting Thread...");
-        new Thread(() -> {
-            while (true) {
-                // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogExperimentAction!
-                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Thread is running...");
-
-                try {
-                    sleep(2000);
-                } catch (InterruptedException e) {
-                    Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Sleep was disrupted: " + e.getMessage());
-                }
-
-                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Fetching status for experiment Id: " + experiment.getUuid());
-
-                String state = getWorkflowStatus(experiment);
-                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "State is: " + state);
-
-                switch (state) {
-                    case "running":
-                        // Do nothing, when the experiment is created the status is set to running
-                        Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Workflow is still running.");
-                        break;
-
-                    case "completed":
-                        // Get only the job result that is visible
-                        List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experiment);
-                        Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Results are: " + workflowJobsResults.toString());
-
-                        boolean resultFound = false;
-                        for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
-                            if (jobResult.getVisible()) {
-                                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Visible result are: " + jobResult.getId());
-
-                                String result = getWorkflowResultBody(experiment, jobResult.getId());
-
-                                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Result: " + result);
-                                if (result == null) {
-                                    experiment.setHasError(true);
-                                    experiment.setHasServerError(true);
-                                }
-                                experiment.setResult("[" + result + "]");
-                                experiment.setWorkflowStatus("completed");
-                                resultFound = true;
-                            }
-                        }
-
-                        if (!resultFound) {      // If there is no visible result
-                            Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "No visible result");
-                            experiment.setResult("[" + new ErrorResponse("The workflow has no visible result.").toString() + "]");
-                            experiment.setHasError(true);
-                            experiment.setHasServerError(true);
-                        }
-
-                        finishExperiment(experiment);
-                        break;
-
-                    case "error":
-                        // Get the job result that failed
-                        workflowJobsResults = getWorkflowResults(experiment);
-                        Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Error results are: " + workflowJobsResults.toString());
-
-                        boolean failedJobFound = false;
-                        for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
-                            if (jobResult.getState().equals("error")) {
-                                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Failed job is: " + jobResult.getId());
-
-                                String result = getWorkflowJobError(jobResult.getId(), experiment);
-
-                                Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Job result: " + result);
-                                if (result == null) {
-                                    experiment.setHasError(true);
-                                    experiment.setHasServerError(true);
-                                }
-                                experiment.setResult("[" + result + "]");
-                                experiment.setWorkflowStatus("error");
-                                failedJobFound = true;
-                            }
-                        }
-
-                        if (!failedJobFound) {      // If there is no visible failed job
-                            Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "No failed result");
-                            experiment.setResult("[" + new ErrorResponse("The workflow has no failed result.").toString() + "]");
-                            experiment.setHasError(true);
-                            experiment.setHasServerError(true);
-                        }
-                        finishExperiment(experiment);
-                        break;
-
-                    default:        // InternalError or unexpected result
-                        experiment.setResult("[" + new ErrorResponse("An unexpected error occurred.").toString() + "]");
-                        experiment.setHasError(true);
-                        experiment.setHasServerError(true);
-                        finishExperiment(experiment);
-                        break;
-                }
-
-                // If result exists return
-                if (experiment.getResult() != null) {
-                    Logging.LogExperimentAction(experiment.getName(), experiment.getUuid(), "Result exists: " + experiment.getResult());
-                    return;
-                }
-            }
-        }).start();
-    }
-
-
-    /**
-     * @param experiment The experiment of the workflow
-     * @return "running"           ->      When the workflow is still running
-     * "internalError"     ->      When an exception or a bad request occurred
-     * "error"             ->      When the workflow produced an error
-     * "completed"         ->      When the workflow completed successfully
-     */
-    public String getWorkflowStatus(Experiment experiment) {
-        String historyId = experiment.getWorkflowHistoryId();
-        String experimentName = experiment.getName();
-        UUID experimentId = experiment.getUuid();
-
-        // ATTENTION: This function is used from a Thread. Only LogExperimentAction should be used, not LogUserAction!
-        Logging.LogExperimentAction(experimentName, experimentId, " History Id : " + historyId);
-
-        // Create the request client
-        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Call<Object> call = service.getWorkflowStatusFromGalaxy(historyId, galaxyApiKey);
-
-        String result = null;
-        try {
-            Response<Object> response = call.execute();
-            if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
-                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
-                return "internalError";
-            }
-            result = new Gson().toJson(response.body());
-            Logging.LogExperimentAction(experimentName, experimentId, " Result: " + result);
-
-        } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
-            return "internalError";
-        }
-
-        String state = null;
-        try {
-            JSONObject resultJson = new JSONObject(result);
-            state = resultJson.getString("state");
-        } catch (JSONException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
-            return "internalError";
-        }
-
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
-        switch (state) {
-            case "ok":
-                return "completed";
-            case "error":
-                return "error";
-            case "running":
-            case "new":
-            case "waiting":
-            case "queued":
-                return "running";
-            default:
-                return "internalError";
-        }
-    }
-
-    /**
-     * @param experiment The experiment of the workflow
-     * @return a List<GalaxyWorkflowResult>   or null when an error occurred
-     */
-    public List<GalaxyWorkflowResult> getWorkflowResults(Experiment experiment) {
-
-        String historyId = experiment.getWorkflowHistoryId();
-        String experimentName = experiment.getName();
-        UUID experimentId = experiment.getUuid();
-        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
-
-        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
-
-        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList = null;
-        try {
-            Response<List<GalaxyWorkflowResult>> response = call.execute();
-            if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
-                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
-                return null;
-            }
-            getGalaxyWorkflowResultList = response.body();
-            Logging.LogExperimentAction(experimentName, experimentId, " Result: " + response.body());
-
-        } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
-            return null;
-        }
-
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
-        return getGalaxyWorkflowResultList;
-
+        return experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
     }
-
-    /**
-     * @param experiment The experiment of the workflow
-     * @param contentId  the id of the job result that we want
-     * @return the result of the specific workflow job, null if there was an error
-     */
-    public String getWorkflowResultBody(Experiment experiment, String contentId) {
-
-        String historyId = experiment.getWorkflowHistoryId();
-        String experimentName = experiment.getName();
-        UUID experimentId = experiment.getUuid();
-
-        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
-
-        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Call<Object> call =
-                service.getWorkflowResultsBodyFromGalaxy(historyId, contentId, galaxyApiKey);
-
-        String resultJson = null;
-        try {
-            Response<Object> response = call.execute();
-            if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
-                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
-                return null;
-            }
-            resultJson = new Gson().toJson(response.body());
-            Logging.LogExperimentAction(experimentName, experimentId, " Result: " + resultJson);
-
-        } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId,
-                    " An exception happened: " + e.getMessage());
-            return null;
-        }
-
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
-        return resultJson;
-    }
-
-
-    /**
-     * @param jobId the id of the workflow job that failed
-     * @return the error that was produced or null if an error occurred
-     */
-    public String getWorkflowJobError(String jobId, Experiment experiment) {
-        String experimentName = experiment.getName();
-        UUID experimentId = experiment.getUuid();
-
-        Logging.LogExperimentAction(experimentName, experimentId, " jobId : " + jobId);
-        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
-
-        String fullError = null;
-        String returnError = null;
-        try {
-            Response<Object> response = callError.execute();
-            if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, "Response code: "
-                        + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
-                return null;
-            }
-
-            // Parsing the stderr of the job that failed
-            String jsonString = new Gson().toJson(response.body());
-            JsonElement jsonElement = new JsonParser().parse(jsonString);
-            JsonObject rootObject = jsonElement.getAsJsonObject();
-            fullError = rootObject.get("stderr").getAsString();
-            Logging.LogExperimentAction(experimentName, experimentId, "Error: " + fullError);
-
-            String[] arrOfStr = fullError.split("ValueError", 0);
-            String specError = arrOfStr[arrOfStr.length - 1];
-            returnError = specError.substring(1);
-            Logging.LogExperimentAction(experimentName, experimentId, "Parsed Error: " + returnError);
-
-        } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, "Exception: " + e.getMessage());
-            return null;
-        }
-
-        Logging.LogExperimentAction(experimentName, experimentId, "Completed successfully!");
-
-        return returnError;
-    }
-
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java b/src/main/java/eu/hbp/mip/controllers/FilesAPI.java
deleted file mode 100644
index 69e7f3ba9..000000000
--- a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package eu.hbp.mip.controllers;
-
-import eu.hbp.mip.model.User;
-import eu.hbp.mip.model.UserInfo;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-import eu.hbp.mip.utils.Logging;
-
-/**
- * Created by mirco on 08.05.17.
- */
-
-@RestController
-@RequestMapping(value = "/protected")
-@Api(value = "/protected", description = "the protected files API")
-public class FilesAPI {
-
-
-    @Autowired
-    private UserInfo userInfo;
-
-    @ApiOperation(value = "Get protected files")
-    @RequestMapping(value = "/{filename:.+}", method = RequestMethod.GET)
-    public ResponseEntity<Void> getProtectedFile(
-            @ApiParam(value = "filename", required = true) @PathVariable("filename") String filename
-    ) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(GET) /protected/{filename:.+}", "Loading protected file with filename : " + filename);
-
-        String filepath = "/protected/" + filename;
-        Logging.LogUserAction(user.getUsername(), "(GET) /protected/{filename:.+}" + filepath, "Downloaded protected file");
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("X-Accel-Redirect", filepath);
-
-        return new ResponseEntity<>(headers, HttpStatus.OK);
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/controllers/MiningApi.java b/src/main/java/eu/hbp/mip/controllers/MiningApi.java
deleted file mode 100644
index 6a198cc0d..000000000
--- a/src/main/java/eu/hbp/mip/controllers/MiningApi.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package eu.hbp.mip.controllers;
-
-import eu.hbp.mip.utils.HTTPUtil;
-
-import com.google.gson.Gson;
-
-import eu.hbp.mip.model.UserInfo;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-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.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
-import eu.hbp.mip.utils.Logging;
-
-
-import java.util.*;
-import java.io.IOException;
-
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-/**
- * Created by mirco on 06.01.17.
- */
-@RestController
-@RequestMapping(value = "/mining", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/mining", description = "the mining API")
-public class MiningApi {
-
-    private static final Gson gson = new Gson();
-
-    @Autowired
-    private UserInfo userInfo;
-
-    @Value("#{'${services.exareme.queryExaremeUrl:http://localhost:9090/mining/query}'}")
-    public String queryExaremeUrl;
-
-    @ApiOperation(value = "Create a histogram on Exareme", response = String.class)
-    @RequestMapping(value = "/histograms", method = RequestMethod.POST)
-    public ResponseEntity runExaremeHistograms(@RequestBody List<HashMap<String, String>> queryList) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /mining/histogram", "Executing histogram...");
-
-        String query = gson.toJson(queryList);
-        String url = queryExaremeUrl + "/" + "MULTIPLE_HISTOGRAMS";
-
-        try {
-            StringBuilder results = new StringBuilder();
-            int code = HTTPUtil.sendPost(url, query, results);
-
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /mining/histogram", "Executed histogram with result :" + results.toString());
-            return ResponseEntity.ok(gson.toJson(results.toString()));
-        } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /mining/histogram", "Histogram algorithm was not found");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @ApiOperation(value = "Create a descriptive statistic on Exareme", response = String.class)
-    @RequestMapping(value = "/descriptive_stats", method = RequestMethod.POST)
-    public ResponseEntity runExaremeDescriptiveStats(@RequestBody List<HashMap<String, String>> queryList) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats", "Executing Exareme descriptive stats...");
-
-        String query = gson.toJson(queryList);
-        String url = queryExaremeUrl + "/" + "DESCRIPTIVE_STATS";
-
-        try {
-            StringBuilder results = new StringBuilder();
-            int code = HTTPUtil.sendPost(url, query, results);
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats", "Executed descriptive stats with result : " + results.toString());
-            return ResponseEntity.ok(gson.toJson(results.toString()));
-        } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats", "Descriptive stats algorithm was not found");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @ApiOperation(value = "Create a descriptive statistic on Exareme", response = String.class)
-    @RequestMapping(value = "/descriptive_stats_v2", method = RequestMethod.POST)
-    public ResponseEntity runExaremeDescriptiveStatsV2(@RequestBody List<HashMap<String, String>> queryList) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats_v2", "Executing an Exareme descriptive stats v2");
-
-        String query = gson.toJson(queryList);
-        String url = queryExaremeUrl + "/" + "DESCRIPTIVE_STATS_v2";
-
-        try {
-            StringBuilder results = new StringBuilder();
-            int code = HTTPUtil.sendPost(url, query, results);
-
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats_v2", "Successfully executed descriptive stats v2 with results : " + results.toString());
-            return ResponseEntity.ok(gson.toJson(results.toString()));
-        } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/descriptive_stats_v2", "Descriptive stats v2 algorithm was not found");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @ApiOperation(value = "Check if a formula is valid", response = String.class)
-    @RequestMapping(value = "/checkFormula", method = RequestMethod.POST)
-    public ResponseEntity checkFormulaValidity(String formula) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /experiments/checkFormula", "Executing  checkFormula ...");
-
-        return ResponseEntity.ok("");
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java b/src/main/java/eu/hbp/mip/controllers/ModelsApi.java
deleted file mode 100644
index 6f013ee33..000000000
--- a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.controllers;
-
-import com.github.slugify.Slugify;
-import eu.hbp.mip.model.Model;
-import eu.hbp.mip.model.User;
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.model.Variable;
-import eu.hbp.mip.repositories.*;
-import io.swagger.annotations.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import eu.hbp.mip.utils.Logging;
-
-import java.io.IOException;
-import java.util.*;
-
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-@RestController
-@RequestMapping(value = "/models", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/models", description = "the models API")
-public class ModelsApi {
-
-
-    @Autowired
-    private UserInfo userInfo;
-
-    @Autowired
-    private DatasetRepository datasetRepository;
-
-    @Autowired
-    private ModelRepository modelRepository;
-
-    @Autowired
-    private QueryRepository queryRepository;
-
-    @Autowired
-    private ConfigRepository configRepository;
-
-    @Autowired
-    private VariableRepository variableRepository;
-
-    @ApiOperation(value = "get models", response = Model.class, responseContainer = "List")
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<List> getModels(
-            @ApiParam(value = "Only ask own models") @RequestParam(value = "own", required = false) Boolean own,
-            @ApiParam(value = "Only ask published models") @RequestParam(value = "valid", required = false) Boolean valid
-    ) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /models", "Loading models ...");
-
-        User user = userInfo.getUser();
-
-        Iterable<Model> models;
-        if (own != null && own) {
-            models = modelRepository.findByCreatedByOrderByCreatedAt(user);
-        } else {
-            models = modelRepository.findByValidOrCreatedByOrderByCreatedAt(true, user);
-        }
-
-        if (valid != null && models != null) {
-            for (Iterator<Model> i = models.iterator(); i.hasNext(); ) {
-                Model m = i.next();
-                if (valid != m.getValid()) {
-                    i.remove();
-                }
-            }
-        }
-
-        List<Object> modelsList = new LinkedList<>();
-        models = models != null ? models : new LinkedList<>();
-        for (Model m : models) {
-            m.setDataset(datasetRepository.findOne(m.getDataset().getCode()));
-            modelsList.add(m);
-        }
-
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /models", "Successfully loaded " + modelsList.size() + " models.");
-
-        return ResponseEntity.ok(modelsList);
-    }
-
-
-    @ApiOperation(value = "Create a model", response = Model.class)
-    @ApiResponses(value = {@ApiResponse(code = 201, message = "Model created")})
-    @RequestMapping(method = RequestMethod.POST)
-    public ResponseEntity<Model> addAModel(
-            @RequestBody @ApiParam(value = "Model to create", required = true) Model model
-    ) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(POST) /models", "Creating a model");
-
-        model.setTitle(model.getConfig().getTitle().get("text"));
-        model.setCreatedBy(user);
-        model.setCreatedAt(new Date());
-        if (model.getValid() == null) {
-            model.setValid(false);
-        }
-
-        ensureTitleUniqueness(model);
-        ensureSlugUniqueness(model);
-
-        Map<String, String> map = new HashMap<>(model.getConfig().getTitle());
-        map.put("text", model.getTitle());
-        model.getConfig().setTitle(map);
-
-        saveVariables(model.getQuery().getVariables());
-        saveVariables(model.getQuery().getCovariables());
-        saveVariables(model.getQuery().getGrouping());
-        saveVariables(model.getQuery().getTrainingDatasets());
-
-        configRepository.save(model.getConfig());
-        queryRepository.save(model.getQuery());
-        if (model.getDataset() != null) {
-            datasetRepository.save(model.getDataset());
-        }
-        modelRepository.save(model);
-
-        Logging.LogUserAction(user.getUsername(), "(POST) /models", "Created model with id : " + model.getSlug() + ", model.config and model.query");
-
-        return ResponseEntity.status(HttpStatus.CREATED).body(model);
-    }
-
-    private void saveVariables(@RequestBody @ApiParam(value = "Model to create", required = true) List<Variable> variables) {
-        for (Variable var : variables) {
-            variableRepository.save(var);
-        }
-    }
-
-    private void ensureSlugUniqueness(@RequestBody @ApiParam(value = "Model to create", required = true) Model model) {
-        String slug = createSlug(model.getTitle());
-        boolean slugExists = true;
-        for (int i = 1; slugExists; i++) {
-            slugExists = modelRepository.exists(slug);
-            if (slugExists) {
-                if (i > 1) {
-                    slug = slug.substring(0, slug.length() - 2);
-                }
-                slug += "-" + i;
-            }
-            model.setSlug(slug);
-        }
-    }
-
-    private String createSlug(@RequestBody @ApiParam(value = "Model to create", required = true) String title) {
-        String slug;
-        try {
-            slug = new Slugify().slugify(title);
-        } catch (IOException e) {
-            slug = "";  // Should never happen
-            //LOGGER.trace("Cannot slugify title", e);
-        }
-        return slug;
-    }
-
-    private void ensureTitleUniqueness(@RequestBody @ApiParam(value = "Model to create", required = true) Model model) {
-        boolean titleExists = true;
-        for (int i = 1; titleExists; i++) {
-            String title = model.getTitle();
-            titleExists = modelRepository.countByTitle(title) > 0;
-            if (titleExists) {
-                if (i > 1) {
-                    title = title.substring(0, title.length() - 4);
-                }
-                model.setTitle(title + " (" + i + ")");
-            }
-        }
-    }
-
-    @ApiOperation(value = "Get a model", response = Model.class)
-    @RequestMapping(value = "/{slug}", method = RequestMethod.GET)
-    public ResponseEntity<Model> getAModel(
-            @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug
-    ) {
-
-        User user = userInfo.getUser();
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /models/{slug}", "Loading model with id : " + slug);
-
-        Model model = modelRepository.findOne(slug);
-        if (model == null) {
-            //LOGGER.warn("Cannot find model : " + slug);
-            Logging.LogUserAction(user.getUsername(), "(GET) /models/{slug}", "Model was not found");
-            return ResponseEntity.badRequest().body(null);
-        }
-
-        if (!model.getValid() && !model.getCreatedBy().getUsername().equals(user.getUsername())) {
-            Logging.LogUserAction(user.getUsername(), "(GET) /models/{slug}", "You are not authorized to retrieve models. ");
-            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
-        }
-
-        List<String> yAxisVars = configRepository.findOne(model.getConfig().getId()).getyAxisVariables();
-        Collection<String> yAxisVarsColl = new LinkedHashSet<>(yAxisVars);
-        model.getConfig().setyAxisVariables(new LinkedList<>(yAxisVarsColl));
-
-        Logging.LogUserAction(user.getUsername(), "(GET) /models/{slug}", "Loaded model with id : " + slug);
-        return ResponseEntity.ok(model);
-    }
-
-
-    @ApiOperation(value = "Update a model", response = Void.class)
-    @ApiResponses(value = {@ApiResponse(code = 204, message = "Model updated")})
-    @RequestMapping(value = "/{slug}", method = RequestMethod.PUT)
-    public ResponseEntity<Void> updateAModel(
-            @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug,
-            @RequestBody @ApiParam(value = "Model to update", required = true) Model model
-    ) {
-        User user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), "(PUT) /models/{slug}", "Updating model with id : " + slug);
-        Model oldModel = modelRepository.findOne(slug);
-
-        if (!user.getUsername().equals(oldModel.getCreatedBy().getUsername())) {
-            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
-        }
-
-        model.setTitle(model.getConfig().getTitle().get("text"));
-
-        String oldTitle = oldModel.getTitle();
-        String newTitle = model.getTitle();
-
-        // If title has been updated, ensure it is unique
-        if (!newTitle.equals(oldTitle)) {
-            boolean newTitleExists = true;
-            for (int i = 1; newTitleExists && !newTitle.equals(oldTitle); i++) {
-                newTitle = model.getTitle();
-                newTitleExists = modelRepository.countByTitle(newTitle) > 0;
-                if (newTitleExists && !newTitle.equals(oldTitle)) {
-                    if (i > 1) {
-                        newTitle = newTitle.substring(0, newTitle.length() - 4);
-                    }
-                    model.setTitle(newTitle + " (" + i + ")");
-                }
-            }
-        }
-
-        Map<String, String> map = new HashMap<>(model.getConfig().getTitle());
-        map.put("text", model.getTitle());
-        model.getConfig().setTitle(map);
-
-        saveVariables(model.getQuery().getVariables());
-        saveVariables(model.getQuery().getCovariables());
-        saveVariables(model.getQuery().getGrouping());
-        saveVariables(model.getQuery().getTrainingDatasets());
-
-        configRepository.save(model.getConfig());
-        queryRepository.save(model.getQuery());
-        datasetRepository.save(model.getDataset());
-        modelRepository.save(model);
-
-        Logging.LogUserAction(user.getUsername(), "(PUT) /models/{slug}", "Updated model and saved/updated model.config and model.query");
-
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 779169814..66a97896b 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -6,7 +6,7 @@ package eu.hbp.mip.controllers;
 
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
-import eu.hbp.mip.model.PathologyDTO;
+import eu.hbp.mip.model.DTOs.PathologyDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
diff --git a/src/main/java/eu/hbp/mip/controllers/StatsApi.java b/src/main/java/eu/hbp/mip/controllers/StatsApi.java
deleted file mode 100644
index 8bd109e53..000000000
--- a/src/main/java/eu/hbp/mip/controllers/StatsApi.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Created by mirco on 18.01.16.
- */
-
-package eu.hbp.mip.controllers;
-
-import eu.hbp.mip.model.GeneralStats;
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.repositories.ArticleRepository;
-import eu.hbp.mip.repositories.UserRepository;
-import eu.hbp.mip.utils.Logging;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-@RestController
-@RequestMapping(value = "/stats", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/stats", description = "the stats API")
-public class StatsApi {
-    @Autowired
-    private UserRepository userRepository;
-
-    @Autowired
-    private UserInfo userInfo;
-
-    @Autowired
-    private ArticleRepository articleRepository;
-
-
-    @ApiOperation(value = "Get general statistics", response = GeneralStats.class)
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<GeneralStats> getGeneralStatistics() {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /stats", "Loading general statistics");
-
-        GeneralStats stats = new GeneralStats();
-
-        stats.setUsers(userRepository.count());
-        stats.setArticles(articleRepository.count());
-
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /stats", "Loaded " + userRepository.count() + " user statistics and " + articleRepository.count() + " artcle statistics.");
-        return ResponseEntity.ok(stats);
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/Article.java b/src/main/java/eu/hbp/mip/model/Article.java
index 95c7cbbae..b79f2a33a 100644
--- a/src/main/java/eu/hbp/mip/model/Article.java
+++ b/src/main/java/eu/hbp/mip/model/Article.java
@@ -52,10 +52,6 @@ public class Article {
     @JoinColumn(name = "updatedby_username")
     private User updatedBy = null;
 
-    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
-    private List<Tag> tags = new LinkedList<>();
-
-
     public Article() {
         /*
          *  Empty constructor is needed by Hibernate
@@ -154,13 +150,4 @@ public class Article {
         this.updatedBy = updatedBy;
     }
 
-
-    public List<Tag> getTags() {
-        return tags;
-    }
-
-    public void setTags(List<Tag> tags) {
-        this.tags = tags;
-    }
-
 }
diff --git a/src/main/java/eu/hbp/mip/model/Config.java b/src/main/java/eu/hbp/mip/model/Config.java
deleted file mode 100644
index 2362194b2..000000000
--- a/src/main/java/eu/hbp/mip/model/Config.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Created by mirco on 25.02.16.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.*;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-@Entity
-@Table(name = "`config`")
-@ApiModel
-@JsonIgnoreProperties(value = {"id"})
-public class Config {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.SEQUENCE)
-    private Long id = null;
-
-    private String type = null;
-
-    private Integer height = null;
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(name = "config_yAxisVariables", joinColumns = @JoinColumn(name = "config_id"))
-    private List<String> yAxisVariables = new LinkedList<>();
-
-    private String xAxisVariable = null;
-
-    private Boolean hasXAxis = null;
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(name = "config_title", joinColumns = @JoinColumn(name = "config_id"))
-    private Map<String, String> title = new HashMap<>();
-
-
-    public Config() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-
-    public Integer getHeight() {
-        return height;
-    }
-
-    public void setHeight(Integer height) {
-        this.height = height;
-    }
-
-
-    public List<String> getyAxisVariables() {
-        return yAxisVariables;
-    }
-
-    public void setyAxisVariables(List<String> yAxisVariables) {
-        this.yAxisVariables = yAxisVariables;
-    }
-
-
-    public String getxAxisVariable() {
-        return xAxisVariable;
-    }
-
-    public void setxAxisVariable(String xAxisVariable) {
-        this.xAxisVariable = xAxisVariable;
-    }
-
-
-    public Boolean getHasXAxis() {
-        return hasXAxis;
-    }
-
-    public void setHasXAxis(Boolean hasXAxis) {
-        this.hasXAxis = hasXAxis;
-    }
-
-
-    public Map<String, String> getTitle() {
-        return title;
-    }
-
-    public void setTitle(Map<String, String> title) {
-        this.title = title;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
new file mode 100644
index 000000000..682f121ce
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
@@ -0,0 +1,203 @@
+package eu.hbp.mip.model.DAOs;
+
+import com.google.gson.Gson;
+import com.google.gson.annotations.Expose;
+import eu.hbp.mip.model.DTOs.AlgorithmDTO;
+import eu.hbp.mip.model.DTOs.ExperimentDTO;
+import eu.hbp.mip.model.User;
+import eu.hbp.mip.utils.JsonConverters;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * Created by habfast on 21/04/16.
+ */
+@Entity
+@Table(name = "`experiment`")
+public class ExperimentDAO {
+
+    private static final Gson gson = new Gson();
+
+    @Id
+    @Column(columnDefinition = "uuid", updatable = false)
+    @org.hibernate.annotations.Type(type = "pg-uuid")
+    @Expose
+    private UUID uuid;
+
+    @Column(columnDefinition = "TEXT")
+    @Expose
+    private String name;
+
+    @Expose
+    @ManyToOne
+    @JoinColumn(name = "created_by_username")
+    private User createdBy;
+
+    @Column(name="workflow_history_id", columnDefinition = "TEXT")
+    @Expose
+    private String workflowHistoryId;
+
+    @Column(columnDefinition = "TEXT")
+    @Expose
+    private Status status;
+
+    @Column(columnDefinition = "TEXT")
+    @Expose
+    private String result;
+
+    @Expose
+    private Date finished;
+
+    @Expose
+    private String algorithm;
+
+    @Expose
+    private Date created = new Date();
+
+    @Expose
+    private boolean shared = false;
+
+    // whether or not the experiment's result have been viewed by its owner
+    @Expose
+    private boolean viewed = false;
+
+    public enum Status {
+        error,
+        pending,
+        success
+    }
+
+    public enum MimeTypes {
+        ERROR("text/plain+error"),
+        WARNING("text/plain+warning"),
+        USER_WARNING("text/plain+user_error"),
+        HIGHCHARTS("application/vnd.highcharts+json"),
+        JSON("application/json"),
+        JSONBTREE("application/binary-tree+json"),
+        PFA("application/pfa+json"),
+        JSONDATA("application/vnd.dataresource+json"),
+        HTML("text/html"),
+        TEXT("text/plain");
+
+        private String types;
+
+        //Constructor to initialize the instance variable
+        MimeTypes(String types) {
+            this.types = types;
+        }
+
+        public String getTypes() {
+            return this.types;
+        }
+    }
+
+    public ExperimentDAO() {
+        /*
+         *  Empty constructor is needed by Hibernate
+         */
+    }
+
+    public ExperimentDTO convertToDTO()
+    {
+        ExperimentDTO experimentDTO = new ExperimentDTO();
+        experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithm, AlgorithmDTO.class));
+        experimentDTO.setCreated(this.created);
+        experimentDTO.setCreatedBy(this.createdBy.getUsername());
+        experimentDTO.setName(this.name);
+        experimentDTO.setResult(JsonConverters.convertJsonStringToObject(this.result, ExperimentDTO.ResultDTO.class));
+        experimentDTO.setShared(this.shared);
+        experimentDTO.setUuid(this.uuid.toString());
+        experimentDTO.setViewed(this.viewed);
+        return experimentDTO;
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public String getWorkflowHistoryId() {
+        return workflowHistoryId;
+    }
+
+    public void setWorkflowHistoryId(String workflowHistoryId) {
+        this.workflowHistoryId = workflowHistoryId;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public Date getFinished() {
+        return finished;
+    }
+
+    public void setFinished(Date finished) {
+        this.finished = finished;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public User getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(User createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public boolean isViewed() {
+        return viewed;
+    }
+
+    public void setViewed(boolean viewed) {
+        this.viewed = viewed;
+    }
+
+    public boolean isShared() {
+        return shared;
+    }
+
+    public void setShared(boolean shared) {
+        this.shared = shared;
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/model/AlgorithmDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java
similarity index 95%
rename from src/main/java/eu/hbp/mip/model/AlgorithmDTO.java
rename to src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java
index ed0ef2a15..0a49c5ad6 100644
--- a/src/main/java/eu/hbp/mip/model/AlgorithmDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.model;
+package eu.hbp.mip.model.DTOs;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
new file mode 100644
index 000000000..b4214dd0a
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
@@ -0,0 +1,126 @@
+package eu.hbp.mip.model.DTOs;
+
+import eu.hbp.mip.model.DAOs.ExperimentDAO;
+
+import java.util.Date;
+import java.util.List;
+
+public class ExperimentDTO {
+
+    private String uuid;
+    private String name;
+    private String createdBy;
+    private Date created;
+    private Boolean shared;
+    private Boolean viewed;
+    private ExperimentDTO.ResultDTO result;
+    private ExperimentDAO.Status status;
+
+    private AlgorithmDTO algorithm;
+
+    public AlgorithmDTO getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(AlgorithmDTO algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public Boolean getShared() {
+        return shared;
+    }
+
+    public void setShared(Boolean shared) {
+        this.shared = shared;
+    }
+
+    public Boolean getViewed() {
+        return viewed;
+    }
+
+    public void setViewed(Boolean viewed) {
+        this.viewed = viewed;
+    }
+
+    public ExperimentDTO.ResultDTO getResult() {
+        return result;
+    }
+
+    public void setResult(ExperimentDTO.ResultDTO result) {
+        this.result = result;
+    }
+
+    public ExperimentDAO.Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(ExperimentDAO.Status status) {
+        this.status = status;
+    }
+
+    public static class OutputDTO {
+
+        private String data;
+        private ExperimentDAO.MimeTypes mimeTypes;
+
+        public String getData() {
+            return this.data;
+        }
+
+        public void setData(String data) {
+            this.data = data;
+        }
+
+        public ExperimentDAO.MimeTypes getMimeTypes() {
+            return mimeTypes;
+        }
+
+        public void setMimeTypes(ExperimentDAO.MimeTypes mimeTypes) {
+            this.mimeTypes = mimeTypes;
+        }
+    }
+
+    public static class ResultDTO {
+        private List<OutputDTO> result;
+
+        public List<OutputDTO> getResult() {
+            return this.result;
+        }
+
+        public void setResult(List<OutputDTO> result) {
+            this.result = result;
+        }
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/model/PathologyDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java
similarity index 93%
rename from src/main/java/eu/hbp/mip/model/PathologyDTO.java
rename to src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java
index c58238b62..6a4580e81 100644
--- a/src/main/java/eu/hbp/mip/model/PathologyDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.model;
+package eu.hbp.mip.model.DTOs;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/Dataset.java b/src/main/java/eu/hbp/mip/model/Dataset.java
deleted file mode 100644
index d920571d9..000000000
--- a/src/main/java/eu/hbp/mip/model/Dataset.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.*;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-// TODO: deprecate
-
-@Entity
-@Table(name = "`dataset`")
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Dataset {
-
-    @Id
-    private String code = null;
-
-    private Date date = null;
-
-    // Aka covariables
-    @ElementCollection
-    @CollectionTable(name = "dataset_header", joinColumns = @JoinColumn(name = "dataset_code"))
-    private List<String> header = new LinkedList<>();
-
-    @ElementCollection
-    @CollectionTable(name = "dataset_grouping", joinColumns = @JoinColumn(name = "dataset_code"))
-    private List<String> grouping = new LinkedList<>();
-
-    @ElementCollection
-    @CollectionTable(name = "dataset_variable", joinColumns = @JoinColumn(name = "dataset_code"))
-    private List<String> variable = new LinkedList<>();
-
-    // TODO:
-    @Transient
-    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
-    private Object data = null;
-
-
-    public Dataset() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-
-    public Date getDate() {
-        return date;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-
-
-    public List<String> getHeader() {
-        return header;
-    }
-
-    public void setHeader(List<String> header) {
-        this.header = header;
-    }
-
-
-    public List<String> getGrouping() {
-        return grouping;
-    }
-
-    public void setGrouping(List<String> grouping) {
-        this.grouping = grouping;
-    }
-
-
-    public List<String> getVariable() {
-        return variable;
-    }
-
-    public void setVariable(List<String> variable) {
-        this.variable = variable;
-    }
-
-    public Object getData() {
-        return data;
-    }
-
-    public void setData(Object data) {
-        this.data = data;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/DatasetDescription.java b/src/main/java/eu/hbp/mip/model/DatasetDescription.java
deleted file mode 100644
index c77c50aea..000000000
--- a/src/main/java/eu/hbp/mip/model/DatasetDescription.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import io.swagger.annotations.ApiModel;
-
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class DatasetDescription {
-
-    private String code;
-    private String label;
-    private String description;
-    private String anonymisationLevel;
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getAnonymisationLevel() {
-        return anonymisationLevel;
-    }
-
-    public void setAnonymisationLevel(String anonymisationLevel) {
-        this.anonymisationLevel = anonymisationLevel;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/Experiment.java b/src/main/java/eu/hbp/mip/model/Experiment.java
deleted file mode 100644
index c40d91d34..000000000
--- a/src/main/java/eu/hbp/mip/model/Experiment.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package eu.hbp.mip.model;
-
-import com.google.gson.*;
-import com.google.gson.annotations.Expose;
-import org.hibernate.annotations.Cascade;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.persistence.*;
-import java.util.*;
-
-/**
- * Created by habfast on 21/04/16.
- */
-@Entity
-@Table(name = "`experiment`")
-public class Experiment {
-
-    private static final Gson gson = new Gson();
-
-    @Id
-    @Column(columnDefinition = "uuid")
-    @org.hibernate.annotations.Type(type = "pg-uuid")
-    @Expose
-    private UUID uuid;
-
-    @Column(columnDefinition = "TEXT")
-    @Expose
-    private String name;
-
-    @Expose
-    @ManyToOne
-    @JoinColumn(name = "createdby_username")
-    private User createdBy;
-
-    @ManyToOne
-    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
-    @Expose
-    private Model model;
-
-    @Column(columnDefinition = "TEXT")
-    @Expose
-    private String algorithms;
-
-    @Column(columnDefinition = "TEXT")
-    private String validations;
-
-    @Column(columnDefinition = "TEXT")
-    @Expose
-    private String workflowHistoryId;
-
-    @Column(columnDefinition = "TEXT")
-    @Expose
-    private String workflowStatus;
-
-    @Column(columnDefinition = "TEXT")
-    @Expose
-    private String result;
-
-    @Expose
-    private Date created = new Date();
-
-    @Expose
-    private Date finished;
-
-    @Expose
-    private boolean hasError = false;
-
-    @Expose
-    private boolean hasServerError = false;
-
-    @Expose
-    private boolean shared = false;
-
-    // whether or not the experiment's result have been resultsViewed by its owner
-    @Expose
-    private boolean resultsViewed = false;
-
-    public Experiment() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public JsonObject jsonify() {
-        JsonObject exp = gson.toJsonTree(this).getAsJsonObject();
-        JsonParser parser = new JsonParser();
-
-        if (this.algorithms != null) {
-            exp.remove("algorithms");
-            JsonArray jsonAlgorithms = parser.parse(this.algorithms).getAsJsonArray();
-            exp.add("algorithms", jsonAlgorithms);
-        }
-
-        if (this.validations != null) {
-            exp.remove("validations");
-            JsonArray jsonValidations = parser.parse(this.validations).getAsJsonArray();
-            exp.add("validations", jsonValidations);
-        }
-
-        if (this.result != null && !this.hasServerError) {
-            exp.remove("result");
-
-            JsonElement jsonResult = parser.parse(this.result);
-            exp.add("result", jsonResult);
-
-        }
-
-        return exp;
-    }
-
-    public String getValidations() {
-        return validations;
-    }
-
-    public void setValidations(String validations) {
-        this.validations = validations;
-    }
-
-    public String getAlgorithms() {
-        return algorithms;
-    }
-
-    public void setAlgorithms(String algorithms) {
-        this.algorithms = algorithms;
-    }
-
-    public Model getModel() {
-        return model;
-    }
-
-    public void setModel(Model model) {
-        this.model = model;
-    }
-
-    public boolean isHasError() {
-        return hasError;
-    }
-
-    public void setHasError(boolean hasError) {
-        this.hasError = hasError;
-    }
-
-    public String getWorkflowHistoryId() {
-        return workflowHistoryId;
-    }
-
-    public void setWorkflowHistoryId(String workflowHistoryId) {
-        this.workflowHistoryId = workflowHistoryId;
-    }
-
-    public String getWorkflowStatus() {
-        return workflowStatus;
-    }
-
-    public void setWorkflowStatus(String workflowStatus) {
-        this.workflowStatus = workflowStatus;
-    }
-
-    public String getResult() {
-        return result;
-    }
-
-    public void setResult(String result) {
-        this.result = result;
-    }
-
-    public Date getFinished() {
-        return finished;
-    }
-
-    public void setFinished(Date finished) {
-        this.finished = finished;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public UUID getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(UUID uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public User getCreatedBy() {
-        return createdBy;
-    }
-
-    public void setCreatedBy(User createdBy) {
-        this.createdBy = createdBy;
-    }
-
-    public boolean isResultsViewed() {
-        return resultsViewed;
-    }
-
-    public void setResultsViewed(boolean resultsViewed) {
-        this.resultsViewed = resultsViewed;
-    }
-
-    public boolean isHasServerError() {
-        return hasServerError;
-    }
-
-    public void setHasServerError(boolean hasServerError) {
-        this.hasServerError = hasServerError;
-    }
-
-    public boolean isShared() {
-        return shared;
-    }
-
-    public void setShared(boolean shared) {
-        this.shared = shared;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java b/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java
deleted file mode 100644
index a68cd9121..000000000
--- a/src/main/java/eu/hbp/mip/model/ExperimentExecutionDTO.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package eu.hbp.mip.model;
-
-import java.util.List;
-
-public class ExperimentExecutionDTO {
-
-    private String name;
-    private String model;
-    private List<AlgorithmExecutionDTO> algorithms;
-
-    public String getModel() {
-        return model;
-    }
-
-    public void setModel(String model) {
-        this.model = model;
-    }
-
-    public List<AlgorithmExecutionDTO> getAlgorithms() {
-        return algorithms;
-    }
-
-    public void setAlgorithms(List<AlgorithmExecutionDTO> algorithms) {
-        this.algorithms = algorithms;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public static class AlgorithmExecutionDTO {
-
-        private String name;
-        private String label;
-        private String type;
-
-        private List<AlgorithmExecutionParamDTO> parameters;
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public void setType(String type) {
-            this.type = type;
-        }
-
-        public List<AlgorithmExecutionDTO.AlgorithmExecutionParamDTO> getParameters() {
-            return parameters;
-        }
-
-        public void setParameters(List<AlgorithmExecutionDTO.AlgorithmExecutionParamDTO> parameters) {
-            this.parameters = parameters;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        public void setLabel(String label) {
-            this.label = label;
-        }
-
-        public static class AlgorithmExecutionParamDTO {
-
-            private String name;
-            private String label;
-            private String value;
-
-            public String getName() {
-                return this.name;
-            }
-
-            public void setName(String name) {
-                this.name = name;
-            }
-
-            public String getValue() {
-                return value;
-            }
-
-            public void setValue(String value) {
-                this.value = value;
-            }
-
-            public String getLabel() {
-                return label;
-            }
-
-            public void setLabel(String label) {
-                this.label = label;
-            }
-        }
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/Group.java b/src/main/java/eu/hbp/mip/model/Group.java
deleted file mode 100644
index abb195a93..000000000
--- a/src/main/java/eu/hbp/mip/model/Group.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "`group`")
-@ApiModel
-@JsonIgnoreProperties(value = {"parent"})
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Group {
-
-    @Id
-    private String code = null;
-
-
-    public Group() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public String getCode() {
-        return code;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/Mining.java b/src/main/java/eu/hbp/mip/model/Mining.java
deleted file mode 100644
index 46cfd6c3e..000000000
--- a/src/main/java/eu/hbp/mip/model/Mining.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package eu.hbp.mip.model;
-
-import com.google.gson.*;
-
-import java.util.Date;
-
-public class Mining {
-
-    private static final Gson gson = new Gson();
-
-    private final String jobId;
-    private final String node;
-    private final String function;
-    private final String shape;
-    private final Date timestamp;
-    private final String data;
-
-    public Mining(String jobId, String node, String function, String shape, Date timestamp, String data) {
-        this.jobId = jobId;
-        this.node = node;
-        this.function = function;
-        this.shape = shape;
-        this.timestamp = timestamp;
-        this.data = data;
-    }
-
-    public String getJobId() {
-        return jobId;
-    }
-
-    public String getNode() {
-        return node;
-    }
-
-    public String getFunction() {
-        return function;
-    }
-
-    public String getShape() {
-        return shape;
-    }
-
-    public Date getTimestamp() {
-        return timestamp;
-    }
-
-    public String getData() {
-        return data;
-    }
-
-    public JsonObject jsonify() {
-        JsonObject exp = gson.toJsonTree(this).getAsJsonObject();
-        JsonParser parser = new JsonParser();
-
-        if (this.data != null) {
-            exp.remove("data");
-            JsonElement jsonResult = parser.parse(this.data);
-            exp.add("data", jsonResult);
-        }
-
-        return exp;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/MiningQuery.java b/src/main/java/eu/hbp/mip/model/MiningQuery.java
deleted file mode 100644
index 171c55032..000000000
--- a/src/main/java/eu/hbp/mip/model/MiningQuery.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package eu.hbp.mip.model;
-
-import com.google.gson.Gson;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Created by mirco on 06.01.17.
- */
-public class MiningQuery {
-
-    private List<Variable> variables;
-    private List<Variable> covariables;
-    private List<Variable> grouping;
-    private List<Variable> datasets;
-    private String filters;
-    private ExperimentExecutionDTO.AlgorithmExecutionDTO algorithm;
-
-    public MiningQuery() {
-        this.variables = new LinkedList<>();
-        this.covariables = new LinkedList<>();
-        this.grouping = new LinkedList<>();
-        this.datasets = new LinkedList<>();
-        this.filters = "";
-    }
-
-    public List<Variable> getVariables() {
-        return variables;
-    }
-
-    public void setVariables(List<Variable> variables) {
-        this.variables = variables;
-    }
-
-    public void addVariable(Variable variable) {
-        this.variables.add(variable);
-    }
-
-    public List<Variable> getCovariables() {
-        return covariables;
-    }
-
-    public void setCovariables(List<Variable> covariables) {
-        this.covariables = covariables;
-    }
-
-    public void addCovariable(Variable variable) {
-        this.covariables.add(variable);
-    }
-
-    public List<Variable> getGrouping() {
-        return grouping;
-    }
-
-    public void setGrouping(List<Variable> grouping) {
-        this.grouping = grouping;
-    }
-
-    public List<Variable> getDatasets() {
-        return datasets;
-    }
-
-    public void setDataset(List<Variable> datasets) {
-        this.datasets = datasets;
-    }
-
-    public void addDataset(Variable variable) {
-        this.datasets.add(variable);
-    }
-
-    public void addGrouping(Variable variable) {
-        this.grouping.add(variable);
-    }
-
-    public String getFilters() {
-        return filters;
-    }
-
-    public void setFilters(String filters) {
-        this.filters = filters;
-    }
-
-    public ExperimentExecutionDTO.AlgorithmExecutionDTO getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setAlgorithm(ExperimentExecutionDTO.AlgorithmExecutionDTO algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    @Override
-    public String toString() {
-        return new Gson().toJson(this);
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/Model.java b/src/main/java/eu/hbp/mip/model/Model.java
deleted file mode 100644
index b15908037..000000000
--- a/src/main/java/eu/hbp/mip/model/Model.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.google.gson.annotations.Expose;
-import io.swagger.annotations.ApiModel;
-import org.hibernate.annotations.Cascade;
-import org.hibernate.annotations.CascadeType;
-
-import javax.persistence.*;
-import java.util.Date;
-
-@Entity
-@Table(name = "`model`")
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Model {
-
-    @Id
-    @Expose
-    private String slug = null;
-
-    @Expose
-    private String title = null;
-
-    private String description = null;
-
-    private Boolean valid = null;
-
-    private Date createdAt = null;
-
-    private Date updatedAt = null;
-
-    @ManyToOne
-    @Cascade(CascadeType.SAVE_UPDATE)
-    private eu.hbp.mip.model.Query query = null;
-
-    @ManyToOne
-    @Cascade(CascadeType.SAVE_UPDATE)
-    private Dataset dataset = null;
-
-    @ManyToOne
-    @Cascade(CascadeType.SAVE_UPDATE)
-    private Config config = null;
-
-    @ManyToOne
-    @JoinColumn(name = "createdby_username")
-    private User createdBy = null;
-
-    @ManyToOne
-    @JoinColumn(name = "updatedby_username")
-    private User updatedBy = null;
-
-
-    public Model() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-
-    public String getSlug() {
-        return slug;
-    }
-
-    public void setSlug(String slug) {
-        this.slug = slug;
-    }
-
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-
-    public eu.hbp.mip.model.Query getQuery() {
-        return query;
-    }
-
-    public void setQuery(eu.hbp.mip.model.Query query) {
-        this.query = query;
-    }
-
-
-    public Dataset getDataset() {
-        return dataset;
-    }
-
-    public void setDataset(Dataset dataset) {
-        this.dataset = dataset;
-    }
-
-
-    public Boolean getValid() {
-        return valid;
-    }
-
-    public void setValid(Boolean valid) {
-        this.valid = valid;
-    }
-
-
-    public Config getConfig() {
-        return config;
-    }
-
-    public void setConfig(Config config) {
-        this.config = config;
-    }
-
-
-    public Date getCreatedAt() {
-        return createdAt;
-    }
-
-    public void setCreatedAt(Date createdAt) {
-        this.createdAt = createdAt;
-    }
-
-
-    public Date getUpdatedAt() {
-        return updatedAt;
-    }
-
-    public void setUpdatedAt(Date updatedAt) {
-        this.updatedAt = updatedAt;
-    }
-
-
-    public User getCreatedBy() {
-        return createdBy;
-    }
-
-    public void setCreatedBy(User createdBy) {
-        this.createdBy = createdBy;
-    }
-
-
-    public User getUpdatedBy() {
-        return updatedBy;
-    }
-
-    public void setUpdatedBy(User updatedBy) {
-        this.updatedBy = updatedBy;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/Query.java b/src/main/java/eu/hbp/mip/model/Query.java
deleted file mode 100644
index 8e4d78dcb..000000000
--- a/src/main/java/eu/hbp/mip/model/Query.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.*;
-import java.util.LinkedList;
-import java.util.List;
-
-@Entity
-@ApiModel
-@Table(name = "`query`")
-@JsonIgnoreProperties(value = {"id"})
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Query {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.SEQUENCE)
-    private Long id = null;
-
-    @ManyToMany
-    @JoinTable(name = "query_variable", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> variables = new LinkedList<>();
-
-    @ManyToMany
-    @JoinTable(name = "query_covariable", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> covariables = new LinkedList<>();
-
-    @ManyToMany
-    @JoinTable(name = "query_grouping", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> grouping = new LinkedList<>();
-
-    @ManyToMany
-    @JoinTable(name = "query_training_datasets", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> trainingDatasets = new LinkedList<>();
-
-    @ManyToMany
-    @JoinTable(name = "query_testing_datasets", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> testingDatasets = new LinkedList<>();
-
-    @ManyToMany
-    @JoinTable(name = "query_validation_datasets", joinColumns = {
-            @JoinColumn(name = "id", nullable = false, updatable = false)},
-            inverseJoinColumns = {@JoinColumn(name = "code",
-                    nullable = false, updatable = false)})
-    private List<Variable> validationDatasets = new LinkedList<>();
-
-    @Column(columnDefinition = "text")
-    private String filters = "";
-
-    @Column(columnDefinition = "text")
-    private String pathology = "";
-
-
-    public Query() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-
-    @JsonProperty("variables")
-    public List<Variable> getVariables() {
-        return variables;
-    }
-
-    public void setVariables(List<Variable> variables) {
-        this.variables = variables;
-    }
-
-
-    @JsonProperty("coVariables")
-    public List<Variable> getCovariables() {
-        return covariables;
-    }
-
-    public void setCovariables(List<Variable> covariables) {
-        this.covariables = covariables;
-    }
-
-
-    @JsonProperty("groupings")
-    public List<Variable> getGrouping() {
-        return grouping;
-    }
-
-    public void setGrouping(List<Variable> grouping) {
-        this.grouping = grouping;
-    }
-
-    @JsonProperty("trainingDatasets")
-    public List<Variable> getTrainingDatasets() {
-        return trainingDatasets;
-    }
-
-    public void setTrainingDatasets(List<Variable> trainingDatasets) {
-        this.trainingDatasets = trainingDatasets;
-    }
-
-    @JsonProperty("testingDatasets")
-    public List<Variable> getTestingDatasets() {
-        return testingDatasets;
-    }
-
-    public void setTestingDatasets(List<Variable> testingDatasets) {
-        this.testingDatasets = testingDatasets;
-    }
-
-    @JsonProperty("validationDatasets")
-    public List<Variable> getValidationDatasets() {
-        return validationDatasets;
-    }
-
-    public void setValidationDatasets(List<Variable> validationDatasets) {
-        this.validationDatasets = validationDatasets;
-    }
-
-    public String getFilters() {
-        return filters;
-    }
-
-    public void setFilters(String filters) {
-        this.filters = filters;
-    }
-
-    public String getPathology() {
-        return pathology;
-    }
-
-    public void setPathology(String pathology) {
-        this.pathology = pathology;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/Tag.java b/src/main/java/eu/hbp/mip/model/Tag.java
deleted file mode 100644
index 693c98656..000000000
--- a/src/main/java/eu/hbp/mip/model/Tag.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "`tag`")
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Tag {
-
-    @Id
-    private String name = null;
-
-
-    public Tag() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/User.java b/src/main/java/eu/hbp/mip/model/User.java
index 64fee4b67..f1ee34059 100644
--- a/src/main/java/eu/hbp/mip/model/User.java
+++ b/src/main/java/eu/hbp/mip/model/User.java
@@ -9,11 +9,11 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.annotations.Expose;
 import io.swagger.annotations.ApiModel;
 
-import javax.persistence.*;
-import java.util.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 
 @Entity
 @Table(name = "`user`")
@@ -29,58 +29,9 @@ public class User {
     @Expose
     private String fullname = null;
 
-    @Expose
-    private String firstname = null;
-
-    @Expose
-    private String lastname = null;
-
-    @Expose
-    private String picture = null;
-
-    @Expose
-    private String web = null;
-
-    @Expose
-    private String phone = null;
-
-    @Expose
-    private String birthday = null;
-
-    @Expose
-    private String gender = null;
-
-    @Expose
-    private String city = null;
-
-    @Expose
-    private String country = null;
-
-    @Expose
-    private String password = null;
-
     @Expose
     private String email = null;
 
-    @Expose
-    private String apikey = null;
-
-    @Expose
-    private String team = null;
-
-    @Expose
-    private Boolean isActive = null;
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(name = "user_languages", joinColumns = @JoinColumn(name = "user_username"))
-    @Expose
-    private List<String> languages = new LinkedList<>();
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_username"))
-    @Expose
-    private List<String> roles = new LinkedList<>();
-
     private Boolean agreeNDA = null;
 
 
@@ -113,49 +64,12 @@ public class User {
             this.fullname = m.group(1);
         }
 
-        p = Pattern.compile("given_name=([\\w ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.firstname = m.group(1);
-        }
-
-        p = Pattern.compile("family_name=([\\w ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.lastname = m.group(1);
-        }
-
         p = Pattern.compile("email=([\\w.]+@[\\w.]+)");
         m = p.matcher(userInfo);
         if (m.find()) {
             this.email = m.group(1);
         }
 
-        p = Pattern.compile("title=([\\w ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            if ("Mr".equals(m.group(1))) {
-                this.gender = "Male";
-            } else {
-                this.gender = "Female";
-            }
-        }
-
-        p = Pattern.compile("contractor=([\\w ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.team = m.group(1);
-        }
-
-        p = Pattern.compile("picture=([-a-zA-Z0-9+&@#/%=~_|.: ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.picture = m.group(1);
-        }
-
-        if (this.picture == null || this.picture.isEmpty()) {
-            this.picture = "images/users/default_user.png";
-        }
 
     }
 
@@ -178,96 +92,6 @@ public class User {
     }
 
 
-    public String getFirstname() {
-        return firstname;
-    }
-
-    public void setFirstname(String firstname) {
-        this.firstname = firstname;
-    }
-
-
-    public String getLastname() {
-        return lastname;
-    }
-
-    public void setLastname(String lastname) {
-        this.lastname = lastname;
-    }
-
-
-    public String getPicture() {
-        return picture;
-    }
-
-    public void setPicture(String picture) {
-        this.picture = picture;
-    }
-
-
-    public String getWeb() {
-        return web;
-    }
-
-    public void setWeb(String web) {
-        this.web = web;
-    }
-
-
-    public String getPhone() {
-        return phone;
-    }
-
-    public void setPhone(String phone) {
-        this.phone = phone;
-    }
-
-
-    public String getBirthday() {
-        return birthday;
-    }
-
-    public void setBirthday(String birthday) {
-        this.birthday = birthday;
-    }
-
-
-    public String getGender() {
-        return gender;
-    }
-
-    public void setGender(String gender) {
-        this.gender = gender;
-    }
-
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-
-    public String getCountry() {
-        return country;
-    }
-
-    public void setCountry(String country) {
-        this.country = country;
-    }
-
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-
     public String getEmail() {
         return email;
     }
@@ -276,52 +100,6 @@ public class User {
         this.email = email;
     }
 
-
-    public String getApikey() {
-        return apikey;
-    }
-
-    public void setApikey(String apikey) {
-        this.apikey = apikey;
-    }
-
-
-    public String getTeam() {
-        return team;
-    }
-
-    public void setTeam(String team) {
-        this.team = team;
-    }
-
-
-    public Boolean getIsActive() {
-        return isActive;
-    }
-
-    public void setIsActive(Boolean isActive) {
-        this.isActive = isActive;
-    }
-
-
-    public List<String> getLanguages() {
-        return languages;
-    }
-
-    public void setLanguages(List<String> languages) {
-        this.languages = languages;
-    }
-
-
-    public List<String> getRoles() {
-        return roles;
-    }
-
-    public void setRoles(List<String> roles) {
-        this.roles = roles;
-    }
-
-
     public Boolean getAgreeNDA() {
         return agreeNDA;
     }
diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java
index 71eee3573..7bd9a97f3 100644
--- a/src/main/java/eu/hbp/mip/model/UserInfo.java
+++ b/src/main/java/eu/hbp/mip/model/UserInfo.java
@@ -53,7 +53,6 @@ public class UserInfo {
                 user.setUsername("anonymous");
                 user.setFullname("anonymous");
                 user.setEmail("anonymous@anonymous.com");
-                user.setPicture("images/users/default_user.png");
             } else {
                 user = new User(getUserInfos());
             }
diff --git a/src/main/java/eu/hbp/mip/model/Value.java b/src/main/java/eu/hbp/mip/model/Value.java
deleted file mode 100644
index 784452e59..000000000
--- a/src/main/java/eu/hbp/mip/model/Value.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import io.swagger.annotations.ApiModel;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "`value`")
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Value {
-
-    @Id
-    private String code = null;
-
-    private String label = null;
-
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/Variable.java b/src/main/java/eu/hbp/mip/model/Variable.java
deleted file mode 100644
index 596be8d77..000000000
--- a/src/main/java/eu/hbp/mip/model/Variable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.google.gson.annotations.Expose;
-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`")
-@ApiModel
-@JsonIgnoreProperties(value = {"queries"})
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Variable {
-
-    @Id
-    @Expose
-    private String code = null;
-
-    /**
-     * Empty constructor is needed by Hibernate
-     */
-    public Variable() {
-    }
-
-    public Variable(String code) {
-        this.code = code;
-    }
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        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();
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java b/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java
index fa0cb4b33..4b01b3819 100644
--- a/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java
+++ b/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java
@@ -2,7 +2,7 @@ package eu.hbp.mip.model.galaxy;
 
 import com.google.gson.Gson;
 import com.google.gson.annotations.SerializedName;
-import eu.hbp.mip.model.AlgorithmDTO;
+import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 
 import java.util.*;
 
diff --git a/src/main/java/eu/hbp/mip/repositories/ConfigRepository.java b/src/main/java/eu/hbp/mip/repositories/ConfigRepository.java
deleted file mode 100644
index deb286150..000000000
--- a/src/main/java/eu/hbp/mip/repositories/ConfigRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Config;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface ConfigRepository extends CrudRepository<Config, Long> {
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/DatasetRepository.java b/src/main/java/eu/hbp/mip/repositories/DatasetRepository.java
deleted file mode 100644
index 7c6da1e97..000000000
--- a/src/main/java/eu/hbp/mip/repositories/DatasetRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Dataset;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface DatasetRepository extends CrudRepository<Dataset, String> {
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index 2f6ae857d..eb1d25415 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.repositories;
 
-import eu.hbp.mip.model.Experiment;
+import eu.hbp.mip.model.DAOs.ExperimentDAO;
 import eu.hbp.mip.model.User;
 import org.springframework.data.repository.CrudRepository;
 
@@ -10,8 +10,8 @@ import java.util.UUID;
  * Created by mirco on 11.07.16.
  */
 
-public interface ExperimentRepository extends CrudRepository<Experiment, UUID> {
-    Iterable<Experiment> findByCreatedBy(User user);
+public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID> {
+    Iterable<ExperimentDAO> findByCreatedBy(User user);
 
-    Iterable<Experiment> findByShared(Boolean shared);
+    Iterable<ExperimentDAO> findByShared(Boolean shared);
 }
diff --git a/src/main/java/eu/hbp/mip/repositories/ModelRepository.java b/src/main/java/eu/hbp/mip/repositories/ModelRepository.java
deleted file mode 100644
index c25b1e5bb..000000000
--- a/src/main/java/eu/hbp/mip/repositories/ModelRepository.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Model;
-import eu.hbp.mip.model.User;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface ModelRepository extends CrudRepository<Model, String> {
-    Long countByTitle(String Title);
-
-    Iterable<Model> findByCreatedByOrderByCreatedAt(User user);
-
-    Iterable<Model> findByValidOrCreatedByOrderByCreatedAt(Boolean valid, User user);
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/QueryRepository.java b/src/main/java/eu/hbp/mip/repositories/QueryRepository.java
deleted file mode 100644
index f0b95d39c..000000000
--- a/src/main/java/eu/hbp/mip/repositories/QueryRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Query;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface QueryRepository extends CrudRepository<Query, Long> {
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/TagRepository.java b/src/main/java/eu/hbp/mip/repositories/TagRepository.java
deleted file mode 100644
index 4edb4090e..000000000
--- a/src/main/java/eu/hbp/mip/repositories/TagRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Tag;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface TagRepository extends CrudRepository<Tag, String> {
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/ValueRepository.java b/src/main/java/eu/hbp/mip/repositories/ValueRepository.java
deleted file mode 100644
index b41574d60..000000000
--- a/src/main/java/eu/hbp/mip/repositories/ValueRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Value;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface ValueRepository extends CrudRepository<Value, String> {
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/VariableRepository.java b/src/main/java/eu/hbp/mip/repositories/VariableRepository.java
deleted file mode 100644
index 3ded94943..000000000
--- a/src/main/java/eu/hbp/mip/repositories/VariableRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.Variable;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 13.09.16.
- */
-public interface VariableRepository extends CrudRepository<Variable, String> {
-}
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
new file mode 100644
index 000000000..bd0bed359
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -0,0 +1,776 @@
+package eu.hbp.mip.services;
+
+import com.github.jmchilton.blend4j.galaxy.GalaxyInstance;
+import com.github.jmchilton.blend4j.galaxy.GalaxyInstanceFactory;
+import com.github.jmchilton.blend4j.galaxy.WorkflowsClient;
+import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
+import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
+import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
+import com.google.common.collect.Lists;
+import com.google.gson.*;
+import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
+import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
+import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.model.DTOs.AlgorithmDTO;
+import eu.hbp.mip.model.DTOs.ExperimentDTO;
+import eu.hbp.mip.model.User;
+import eu.hbp.mip.model.UserInfo;
+import eu.hbp.mip.model.galaxy.ErrorResponse;
+import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
+import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
+import eu.hbp.mip.repositories.ExperimentRepository;
+import eu.hbp.mip.utils.ClaimUtils;
+import eu.hbp.mip.utils.HTTPUtil;
+import eu.hbp.mip.utils.JsonConverters;
+import eu.hbp.mip.utils.Logging;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+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.security.core.Authentication;
+import org.springframework.stereotype.Service;
+import retrofit2.Call;
+import retrofit2.Response;
+
+import java.io.IOException;
+import java.util.*;
+
+import static java.lang.Thread.sleep;
+
+@Service
+public class ExperimentService {
+
+    @Autowired
+    private UserInfo userInfo;
+
+    private static final Gson gsonOnlyExposed = new GsonBuilder().serializeNulls()
+            .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").excludeFieldsWithoutExposeAnnotation().create();
+
+    @Value("#{'${services.exareme.queryExaremeUrl}'}")
+    private String queryExaremeUrl;
+
+    @Value("#{'${services.workflows.workflowUrl}'}")
+    private String workflowUrl;
+
+    @Value("#{'${services.workflows.jwtSecret}'}")
+    private String jwtSecret;
+
+    @Value("#{'${services.galaxy.galaxyUrl}'}")
+    private String galaxyUrl;
+
+    @Value("#{'${services.galaxy.galaxyApiKey}'}")
+    private String galaxyApiKey;
+
+    // Enable HBP collab authentication (1) or disable it (0). Default is 1
+    @Value("#{'${hbp.authentication.enabled:1}'}")
+    private boolean authenticationIsEnabled;
+
+    @Autowired
+    private ExperimentRepository experimentRepository;
+
+    private static final Gson gson = new Gson();
+
+    public ResponseEntity<String> getExperiment(String uuid, String endpoint) {
+
+        ExperimentDAO experimentDAO;
+        User user = userInfo.getUser();
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
+
+        experimentDAO = loadExperiment(uuid);
+
+        if (experimentDAO == null) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "Experiment Not found.");
+            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
+        }
+
+        if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
+            return new ResponseEntity<>("You don't have access to the experiment.", HttpStatus.UNAUTHORIZED);
+        }
+        ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Experiment was Loaded with uuid : " + uuid + ".");
+
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+    public ResponseEntity<String> createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
+        User user = userInfo.getUser();
+
+        //Checking if check (POST) /experiments has proper input.
+        if (checkPostExperimentProperInput(experimentDTO)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Invalid input.");
+            return ResponseEntity.badRequest().body("Please provide proper input.");
+        }
+        // Get the type and name of algorithm
+        String algorithmType = experimentDTO.getAlgorithm().getType();
+        String algorithmName = experimentDTO.getAlgorithm().getName();
+
+        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
+        for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithm().getParameters()) {
+            parametersLogMessage
+                    .append("  ")
+                    .append(params.getLabel())
+                    .append(" -> ")
+                    .append(params.getValue())
+                    .append("\n");
+        }
+        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+
+        if (authenticationIsEnabled) {
+            // Getting the dataset from the experiment parameters
+            String experimentDatasets = null;
+            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithm().getParameters()) {
+                if (parameter.getLabel().equals("dataset")) {
+                    experimentDatasets = parameter.getValue();
+                    break;
+                }
+            }
+
+            if (experimentDatasets == null || experimentDatasets.equals("")) {
+                Logging.LogUserAction(user.getUsername(), endpoint,
+                        "A dataset should be specified to run an algorithm.");
+                return ResponseEntity.badRequest().body("Please provide at least one dataset to run the algorithm.");
+            }
+
+            // --- Validating proper access rights on the datasets  ---
+            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
+                return ResponseEntity.badRequest().body("You are not authorized to use these datasets.");
+            }
+        }
+
+        // Run with the appropriate engine
+        if (algorithmType.equals("workflow")) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "Algorithm runs on Galaxy.");
+            return runGalaxyWorkflow(experimentDTO, endpoint);
+        } else {
+            Logging.LogUserAction(user.getUsername(), endpoint, "Algorithm runs on Exareme.");
+            return runExaremeAlgorithm(experimentDTO, endpoint);
+        }
+    }
+
+    public ResponseEntity<String> getExperiments( String endpoint) {
+        User user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
+
+        Iterable<ExperimentDAO> myExperiments = experimentRepository.findByCreatedBy(user);
+        List<ExperimentDAO> expList = Lists.newLinkedList(myExperiments);
+        Iterable<ExperimentDAO> sharedExperiments = experimentRepository.findByShared(true);
+        List<ExperimentDAO> sharedExpList = Lists.newLinkedList(sharedExperiments);
+        expList.addAll(sharedExpList);
+        Logging.LogUserAction(user.getUsername(), endpoint, "Successfully listed my experiments.");
+        List<ExperimentDTO> experimentDTOs = new LinkedList<>();
+
+        for (ExperimentDAO experimentDAO: expList){
+            ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
+            experimentDTOs.add(experimentDTO);
+        }
+        return new ResponseEntity<>(new Gson().toJson(experimentDTOs ), HttpStatus.OK);
+    }
+
+    public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
+    {
+        ExperimentDAO experimentDAO;
+        User user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + experimentDTO.getUuid() + ".");
+        //Checking if check (PUT) /experiments has proper input.
+        if (checkPutExperimentProperInput(experimentDTO)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Invalid input.");
+            return ResponseEntity.badRequest().body("Please provide proper input.");
+        }
+
+        if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0)
+                && experimentDTO.getShared() == null
+                && experimentDTO.getViewed() == null
+                && experimentDTO.getAlgorithm() == null)
+        {
+            return ResponseEntity.badRequest().body("Input is required.");
+        }
+
+        experimentDAO = loadExperiment(uuid);
+
+        if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
+            return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
+
+        if(experimentDTO.getName() != null && experimentDTO.getName().length() != 0)
+        {
+            experimentDAO.setName(experimentDTO.getName());
+        }
+
+        if(experimentDTO.getShared() != null)
+        {
+            experimentDAO.setShared(experimentDTO.getShared());
+        }
+
+        if(experimentDTO.getViewed() != null)
+        {
+            experimentDAO.setViewed(experimentDTO.getViewed());
+        }
+
+        experimentRepository.save(experimentDAO);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + experimentDTO.getUuid() + ".");
+
+        experimentDTO = experimentDAO.convertToDTO();
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+    public ResponseEntity<String> deleteExperiment(String uuid, String endpoint)
+    {
+        ExperimentDAO experimentDAO;
+        User user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
+
+        experimentDAO = loadExperiment(uuid);
+
+        if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
+            return new ResponseEntity<>(endpoint, HttpStatus.UNAUTHORIZED);
+
+        experimentRepository.delete(experimentDAO);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
+        return new ResponseEntity<>(HttpStatus.OK);
+    }
+
+    //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
+    private boolean checkPostExperimentProperInput(ExperimentDTO experimentDTO)
+    {
+        return  experimentDTO.getShared() != null
+                || experimentDTO.getViewed() != null
+                || experimentDTO.getCreated() != null
+                || experimentDTO.getCreatedBy() != null
+                || experimentDTO.getResult() != null
+                || experimentDTO.getStatus() != null
+                || experimentDTO.getUuid() != null;
+    }
+
+    private boolean checkPutExperimentProperInput(ExperimentDTO experimentDTO)
+    {
+        return experimentDTO.getUuid() != null
+                || experimentDTO.getCreated() != null
+                || experimentDTO.getResult() != null
+                || experimentDTO.getStatus() != null;
+    }
+
+    private ExperimentDAO loadExperiment(String uuid){
+
+        UUID experimentUuid ;
+
+        try {
+            experimentUuid = UUID.fromString(uuid);
+        } catch (IllegalArgumentException iae) {
+            return null;
+        }
+
+        return experimentRepository.findOne(experimentUuid);
+    }
+
+    private ExperimentDAO createExperiment(ExperimentDTO experimentDTO, String endpoint) {
+        User user = userInfo.getUser();
+
+        ExperimentDAO experimentDAO = new ExperimentDAO();
+        experimentDAO.setUuid(UUID.randomUUID());
+        experimentDAO.setCreatedBy(user);
+        experimentDAO.setAlgorithm(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm()));
+        experimentDAO.setName(experimentDTO.getName());
+        experimentRepository.save(experimentDAO);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
+        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm());
+        Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
+        return experimentDAO;
+    }
+
+    private void saveExperiment(ExperimentDAO experimentDAO, String endpoint) {
+        User user = userInfo.getUser();
+
+        Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
+        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm());
+        Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
+        Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId());
+        Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus());
+
+        experimentRepository.save(experimentDAO);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Saved experiment");
+    }
+
+    private void finishExperiment(ExperimentDAO experimentDAO) {
+        experimentDAO.setFinished(new Date());
+        experimentRepository.save(experimentDAO);
+    }
+
+    /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
+
+    /**
+     * The runExaremeExperiment will POST the algorithm to the exareme client
+     *
+     * @param experimentDTO is the request with the experiment information
+     * @return the response to be returned
+     */
+    public ResponseEntity<String> runExaremeAlgorithm(ExperimentDTO experimentDTO, String endpoint) {
+        User user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
+
+        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
+
+        // Run the 1st algorithm from the list
+        String algorithmName = experimentDTO.getAlgorithm().getName();
+
+        // Get the parameters
+        List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
+                = experimentDTO.getAlgorithm().getParameters();
+
+        String body = gson.toJson(algorithmParameters);
+        String url = queryExaremeUrl + "/" + algorithmName;
+        Logging.LogUserAction(user.getUsername(), endpoint, "url: " + url + ", body: " + body);
+
+        Logging.LogUserAction(user.getUsername(), endpoint,
+                "Completed, returning: " + experimentDTO.toString());
+
+        Logging.LogUserAction(user.getUsername(), endpoint,
+                "Starting exareme execution thread");
+        new Thread(() -> {
+            // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
+            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
+
+            try {
+                StringBuilder results = new StringBuilder();
+                int code = HTTPUtil.sendPost(url, body, results);
+
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Algorithm finished with code: " + code);
+
+                // Results are stored in the experiment object
+                ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
+
+                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(resultDTO));
+//                experimentDAO.setHasError(code >= 400);
+//                experimentDAO.setHasServerError(code >= 500);
+            } catch (Exception e) {
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
+
+                experimentDAO.setStatus(ExperimentDAO.Status.error);
+                experimentDAO.setResult(e.getMessage());
+            }
+
+            finishExperiment(experimentDAO);
+            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
+        }).start();
+        experimentDTO = experimentDAO.convertToDTO();
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+    /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
+
+
+    /**
+     * The runWorkflow will POST the algorithm to the galaxy client
+     *
+     * @param experimentDTO is the request with the experiment information
+     * @return the response to be returned
+     */
+    public ResponseEntity<String> runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
+        User user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
+
+        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
+
+
+        // Run the 1st algorithm from the list
+        String workflowId = experimentDTO.getAlgorithm().getName();
+
+        // Get the parameters
+        List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
+                = experimentDTO.getAlgorithm().getParameters();
+
+        // Convert the parameters to workflow parameters
+        HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>();
+        if (algorithmParameters != null) {
+            for (AlgorithmDTO.AlgorithmParamDTO param : algorithmParameters) {
+                algorithmParamsIncludingEmpty.put(param.getName(), param.getValue());
+            }
+        }
+
+        // Get all the algorithm parameters because the frontend provides only the non-null
+        final GalaxyInstance instance = GalaxyInstanceFactory.get(galaxyUrl, galaxyApiKey);
+        final WorkflowsClient workflowsClient = instance.getWorkflowsClient();
+        Workflow workflow = null;
+        for (Workflow curWorkflow : workflowsClient.getWorkflows()) {
+            if (curWorkflow.getId().equals(workflowId)) {
+                workflow = curWorkflow;
+                break;
+            }
+        }
+        if (workflow == null) {
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Could not find algorithm code: " + workflowId);
+            return ResponseEntity.badRequest()
+                    .body(new ErrorResponse("Could not find galaxy algorithm.").toString());
+        }
+        final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId());
+        for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) {
+            if (!(algorithmParamsIncludingEmpty.containsKey(workflowParameter.getValue().getUuid()))) {
+                algorithmParamsIncludingEmpty.put(workflowParameter.getValue().getUuid(), "");
+            }
+        }
+
+        // Create the body of the request
+        HashMap<String, HashMap<String, String>> requestBody = new HashMap<>();
+        requestBody.put("inputs", algorithmParamsIncludingEmpty);
+        JsonObject requestBodyJson = new JsonParser().parse(gson.toJson(requestBody)).getAsJsonObject();
+
+        // Create the request client
+        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
+        Logging.LogUserAction(user.getUsername(), endpoint, "Running Galaxy workflow with id: " + workflow.getId());
+
+        // Call Galaxy to run the workflow
+        Call<PostWorkflowToGalaxyDtoResponse> call = service.postWorkflowToGalaxy(workflow.getId(), galaxyApiKey, requestBodyJson);
+        try {
+            Response<PostWorkflowToGalaxyDtoResponse> response = call.execute();
+
+            if (response.code() == 200) {       // Call succeeded
+                String responseBody = gson.toJson(response.body());
+                Logging.LogUserAction(user.getUsername(), endpoint, "Response: " + responseBody);
+
+                String historyId = (String) new JSONObject(responseBody).get("history_id");
+                experimentDAO.setWorkflowHistoryId(historyId);
+                experimentDAO.setStatus(ExperimentDAO.Status.pending);
+//                experimentDAO.setHasServerError(response.code() >= 500);
+
+            } else {     // Something unexpected happened
+                String msgErr = gson.toJson(response.errorBody());
+                Logging.LogUserAction(user.getUsername(), endpoint, "Error Response: " + msgErr);
+
+                // Values are read from streams.
+                JSONObject jObjectError = new JSONObject(msgErr);
+                String errMsg = jObjectError.get("err_msg").toString();
+
+                experimentDAO.setResult(errMsg);
+//                experimentDAO.setHasError(response.code() >= 400);
+//                experimentDAO.setHasServerError(response.code() >= 500);
+            }
+
+        } catch (Exception e) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "An exception occurred: " + e.getMessage());
+            experimentDAO.setStatus(ExperimentDAO.Status.error);
+            experimentDAO.setResult(e.getMessage());
+        }
+        saveExperiment(experimentDAO, endpoint);
+
+        // Start the process of fetching the status
+        updateWorkflowExperiment(experimentDAO, endpoint);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
+
+        experimentDTO = experimentDAO.convertToDTO();
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+
+    /**
+     * This method creates a thread that will fetch the workflow result when it is ready
+     *
+     * @param experimentDAO will be used to fetch it's workflow status, it should have the workflowHistoryId initialized
+     *                   and the result should not already be fetched
+     * @return nothing, just updates the experiment
+     */
+    public void updateWorkflowExperiment(ExperimentDAO experimentDAO, String endpoint) {
+        User user = userInfo.getUser();
+
+        if (experimentDAO == null) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "The experiment does not exist.");
+            return;
+        }
+
+        Logging.LogUserAction(user.getUsername(), endpoint,
+                " Experiment id : " + experimentDAO.getUuid());
+        if (experimentDAO.getWorkflowHistoryId() == null) {
+            Logging.LogUserAction(user.getUsername(), endpoint, "History Id does not exist.");
+            return;
+        }
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Starting Thread...");
+        new Thread(() -> {
+            while (true) {
+                // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogExperimentAction!
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running...");
+
+                try {
+                    sleep(2000);
+                } catch (InterruptedException e) {
+                    Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage());
+                }
+
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid());
+
+                String state = getWorkflowStatus(experimentDAO);
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
+
+                switch (state) {
+                    case "running":
+                        // Do nothing, when the experiment is created the status is set to running
+                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
+                        break;
+
+                    case "completed":
+                        // Get only the job result that is visible
+                        List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experimentDAO);
+                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
+
+                        boolean resultFound = false;
+                        for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
+                            if (jobResult.getVisible()) {
+                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId());
+
+                                String result = getWorkflowResultBody(experimentDAO, jobResult.getId());
+
+                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result);
+                                if (result == null) {
+                                    experimentDAO.setStatus(ExperimentDAO.Status.error);
+                                }
+                                experimentDAO.setResult("[" + result + "]");
+                                experimentDAO.setStatus(ExperimentDAO.Status.success);
+                                resultFound = true;
+                            }
+                        }
+
+                        if (!resultFound) {      // If there is no visible result
+                            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
+                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no visible result.").toString() + "]");
+                            experimentDAO.setStatus(ExperimentDAO.Status.error);
+                        }
+
+                        finishExperiment(experimentDAO);
+                        break;
+
+                    case "error":
+                        // Get the job result that failed
+                        workflowJobsResults = getWorkflowResults(experimentDAO);
+                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString());
+
+                        boolean failedJobFound = false;
+                        for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
+                            if (jobResult.getState().equals("error")) {
+                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId());
+
+                                String result = getWorkflowJobError(jobResult.getId(), experimentDAO);
+
+                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result);
+                                if (result == null) {
+                                    experimentDAO.setStatus(ExperimentDAO.Status.error);
+                                }
+                                experimentDAO.setResult("[" + result + "]");
+                                experimentDAO.setStatus(ExperimentDAO.Status.error);
+                                failedJobFound = true;
+                            }
+                        }
+
+                        if (!failedJobFound) {      // If there is no visible failed job
+                            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
+                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no failed result.").toString() + "]");
+                            experimentDAO.setStatus(ExperimentDAO.Status.error);
+                        }
+                        finishExperiment(experimentDAO);
+                        break;
+
+                    default:        // InternalError or unexpected result
+                        experimentDAO.setResult("[" + new ErrorResponse("An unexpected error occurred.").toString() + "]");
+                        experimentDAO.setStatus(ExperimentDAO.Status.error);
+                        finishExperiment(experimentDAO);
+                        break;
+                }
+
+                // If result exists return
+                if (experimentDAO.getResult() != null) {
+                    Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
+                    return;
+                }
+            }
+        }).start();
+    }
+
+
+    /**
+     * @param experimentDAO The experiment of the workflow
+     * @return "running"           ->      When the workflow is still running
+     * "internalError"     ->      When an exception or a bad request occurred
+     * "error"             ->      When the workflow produced an error
+     * "completed"         ->      When the workflow completed successfully
+     */
+    public String getWorkflowStatus(ExperimentDAO experimentDAO) {
+        String historyId = experimentDAO.getWorkflowHistoryId();
+        String experimentName = experimentDAO.getName();
+        UUID experimentId = experimentDAO.getUuid();
+
+        // ATTENTION: This function is used from a Thread. Only LogExperimentAction should be used, not LogUserAction!
+        Logging.LogExperimentAction(experimentName, experimentId, " History Id : " + historyId);
+
+        // Create the request client
+        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
+        Call<Object> call = service.getWorkflowStatusFromGalaxy(historyId, galaxyApiKey);
+
+        String result = null;
+        try {
+            Response<Object> response = call.execute();
+            if (response.code() >= 400) {
+                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
+                return "internalError";
+            }
+            result = new Gson().toJson(response.body());
+            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + result);
+
+        } catch (IOException e) {
+            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            return "internalError";
+        }
+
+        String state = null;
+        try {
+            JSONObject resultJson = new JSONObject(result);
+            state = resultJson.getString("state");
+        } catch (JSONException e) {
+            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            return "internalError";
+        }
+
+        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        switch (state) {
+            case "ok":
+                return "completed";
+            case "error":
+                return "error";
+            case "running":
+            case "new":
+            case "waiting":
+            case "queued":
+                return "running";
+            default:
+                return "internalError";
+        }
+    }
+
+    /**
+     * @param experimentDAO The experiment of the workflow
+     * @return a List<GalaxyWorkflowResult>   or null when an error occurred
+     */
+    public List<GalaxyWorkflowResult> getWorkflowResults(ExperimentDAO experimentDAO) {
+
+        String historyId = experimentDAO.getWorkflowHistoryId();
+        String experimentName = experimentDAO.getName();
+        UUID experimentId = experimentDAO.getUuid();
+        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+
+        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
+        Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
+
+        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList = null;
+        try {
+            Response<List<GalaxyWorkflowResult>> response = call.execute();
+            if (response.code() >= 400) {
+                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
+                return null;
+            }
+            getGalaxyWorkflowResultList = response.body();
+            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + response.body());
+
+        } catch (IOException e) {
+            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            return null;
+        }
+
+        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        return getGalaxyWorkflowResultList;
+
+    }
+
+    /**
+     * @param experimentDAO The experiment of the workflow
+     * @param contentId  the id of the job result that we want
+     * @return the result of the specific workflow job, null if there was an error
+     */
+    public String getWorkflowResultBody(ExperimentDAO experimentDAO, String contentId) {
+
+        String historyId = experimentDAO.getWorkflowHistoryId();
+        String experimentName = experimentDAO.getName();
+        UUID experimentId = experimentDAO.getUuid();
+
+        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+
+        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
+        Call<Object> call =
+                service.getWorkflowResultsBodyFromGalaxy(historyId, contentId, galaxyApiKey);
+
+        String resultJson = null;
+        try {
+            Response<Object> response = call.execute();
+            if (response.code() >= 400) {
+                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                        + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
+                return null;
+            }
+            resultJson = new Gson().toJson(response.body());
+            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
+
+        } catch (IOException e) {
+            Logging.LogExperimentAction(experimentName, experimentId,
+                    " An exception happened: " + e.getMessage());
+            return null;
+        }
+
+        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        return resultJson;
+    }
+
+
+    /**
+     * @param jobId the id of the workflow job that failed
+     * @return the error that was produced or null if an error occurred
+     */
+    public String getWorkflowJobError(String jobId, ExperimentDAO experimentDAO) {
+        String experimentName = experimentDAO.getName();
+        UUID experimentId = experimentDAO.getUuid();
+
+        Logging.LogExperimentAction(experimentName, experimentId, " jobId : " + jobId);
+        RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
+        Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
+
+        String fullError = null;
+        String returnError = null;
+        try {
+            Response<Object> response = callError.execute();
+            if (response.code() >= 400) {
+                Logging.LogExperimentAction(experimentName, experimentId, "Response code: "
+                        + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
+                return null;
+            }
+
+            // Parsing the stderr of the job that failed
+            String jsonString = new Gson().toJson(response.body());
+            JsonElement jsonElement = new JsonParser().parse(jsonString);
+            JsonObject rootObject = jsonElement.getAsJsonObject();
+            fullError = rootObject.get("stderr").getAsString();
+            Logging.LogExperimentAction(experimentName, experimentId, "Error: " + fullError);
+
+            String[] arrOfStr = fullError.split("ValueError", 0);
+            String specError = arrOfStr[arrOfStr.length - 1];
+            returnError = specError.substring(1);
+            Logging.LogExperimentAction(experimentName, experimentId, "Parsed Error: " + returnError);
+
+        } catch (IOException e) {
+            Logging.LogExperimentAction(experimentName, experimentId, "Exception: " + e.getMessage());
+            return null;
+        }
+
+        Logging.LogExperimentAction(experimentName, experimentId, "Completed successfully!");
+
+        return returnError;
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index e71d3f190..5872819bc 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -1,7 +1,7 @@
 package eu.hbp.mip.utils;
 
 import com.google.gson.Gson;
-import eu.hbp.mip.model.PathologyDTO;
+import eu.hbp.mip.model.DTOs.PathologyDTO;
 import org.springframework.security.core.GrantedAuthority;
 
 import java.util.ArrayList;
diff --git a/src/main/java/eu/hbp/mip/utils/JsonConverters.java b/src/main/java/eu/hbp/mip/utils/JsonConverters.java
new file mode 100644
index 000000000..52305124a
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/JsonConverters.java
@@ -0,0 +1,27 @@
+package eu.hbp.mip.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+
+import java.lang.reflect.Type;
+
+public class JsonConverters {
+    Gson gson = new Gson();
+
+    public static String convertObjectToJsonString(Object object)  {
+        ObjectMapper mapper = new ObjectMapper();
+        //Converting the Object to JSONString
+        try {
+            return mapper.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            return e.getMessage();
+        }
+    }
+
+    public static  <T> T convertJsonStringToObject(String jsonString, Type typeOfT)  {
+        if(jsonString == null || jsonString.isEmpty())
+            return null;
+        return new Gson().fromJson(jsonString, typeOfT);
+    }
+}
diff --git a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
new file mode 100644
index 000000000..b69ae2b70
--- /dev/null
+++ b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
@@ -0,0 +1,45 @@
+ALTER TABLE experiment
+DROP COLUMN haserror,
+DROP COLUMN hasservererror,
+DROP COLUMN validations,
+DROP COLUMN model_slug;
+
+ALTER TABLE experiment
+RENAME algorithms TO algorithm;
+ALTER TABLE experiment
+RENAME createdby_username TO created_by_username;
+ALTER TABLE experiment
+RENAME workflowhistoryid TO workflow_history_id;
+ALTER TABLE experiment
+RENAME resultsviewed TO viewed;
+ALTER TABLE experiment
+RENAME workflowstatus TO status;
+
+ALTER TABLE "user"
+DROP COLUMN birthday,
+DROP COLUMN city,
+DROP COLUMN country,
+DROP COLUMN firstname,
+DROP COLUMN gender,
+DROP COLUMN isactive,
+DROP COLUMN lastname,
+DROP COLUMN password,
+DROP COLUMN phone,
+DROP COLUMN picture,
+DROP COLUMN team,
+DROP COLUMN web;
+
+DROP TABLE "config_title", "config_yaxisvariables";
+DROP TABLE "dataset_variable", "dataset_grouping", "dataset_data", "dataset_header";
+DROP TABLE "query_variable", "query_grouping", "query_filter", "query_covariable";
+DROP TABLE "article_tag", "tag";
+DROP TABLE "variable_value";
+DROP TABLE "query_training_datasets", "query_validation_datasets", "query_testing_datasets";
+DROP TABLE "variable", "value";
+DROP TABLE "group_group", "group";
+DROP TABLE "model";
+DROP TABLE "query";
+DROP TABLE "dataset";
+DROP TABLE "config";
+DROP TABLE "vote", "app";
+DROP TABLE "user_roles", "user_languages";
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 0726d82f4..eb9ace1a6 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -10,8 +10,7 @@
 	<logger name="eu.hbp.mip">
 		<appender-ref ref="FILE1" />
 	</logger>
-    <include resource="org/springframework/boot/logging/logback/base.xml"/>
-    <logger name="org.springframework.web" level="ERROR">
+    <logger name="org.springframework.web" level="INFO">
 		<appender-ref ref="FILE1" />
 	</logger>
     <logger name="eu.hbp.mip.utils" level="INFO" additivity="false">
-- 
GitLab


From 3d25810a35ca939182d4b1d1842942f0ca250ffb Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Fri, 6 Nov 2020 01:36:08 -0800
Subject: [PATCH 02/52] Merge with elastic logs.

---
 docker/config/application.tmpl |  2 +-
 src/main/resources/logback.xml | 19 -------------------
 2 files changed, 1 insertion(+), 20 deletions(-)
 delete mode 100644 src/main/resources/logback.xml

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 6174fb409..ae9d0f8fd 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -53,7 +53,7 @@ logging:
     root: {{ default .Env.LOG_LEVEL "INFO" }}
     org:
       springframework:
-        security: DEBUG
+        security: INFO
         web: {{ default .Env.LOGGING_LEVEL_WEB "WARN" }}
         web.servlet.handler.BeanNameUrlHandlerMapping: WARN
       hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "WARN" }}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
deleted file mode 100644
index eb9ace1a6..000000000
--- a/src/main/resources/logback.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<configuration>
-    <appender name="FILE1" class="ch.qos.logback.core.FileAppender">
-        <file>logs/portal-backend.txt</file>
-        <append>true</append>
-        <encoder>
-            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n</pattern>
-        </encoder>
-    </appender>
-
-	<logger name="eu.hbp.mip">
-		<appender-ref ref="FILE1" />
-	</logger>
-    <logger name="org.springframework.web" level="INFO">
-		<appender-ref ref="FILE1" />
-	</logger>
-    <logger name="eu.hbp.mip.utils" level="INFO" additivity="false">
-        <appender-ref ref="FILE1" />
-    </logger>
-</configuration>
\ No newline at end of file
-- 
GitLab


From c899bb9586c7707c7308f87a29425935d10477fa Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 20 Oct 2020 14:15:31 +0300
Subject: [PATCH 03/52] Limit logs from spring framework.

---
 docker/config/application.tmpl | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index ae9d0f8fd..dce1ac742 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -53,10 +53,10 @@ logging:
     root: {{ default .Env.LOG_LEVEL "INFO" }}
     org:
       springframework:
-        security: INFO
-        web: {{ default .Env.LOGGING_LEVEL_WEB "WARN" }}
-        web.servlet.handler.BeanNameUrlHandlerMapping: WARN
-      hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "WARN" }}
+        security: ERROR
+        web: {{ default .Env.LOGGING_LEVEL_WEB "ERROR" }}
+        web.servlet.handler.BeanNameUrlHandlerMapping: ERROR
+      hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "ERROR" }}
     eu:
       hbp: {{ default .Env.LOGGING_LEVEL_MIP "INFO" }}
 
-- 
GitLab


From cedf93f60856d57a05a3e6c86cca3fd38f3921d8 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 23 Oct 2020 12:41:03 +0300
Subject: [PATCH 04/52] Removed curl installation because build was failing.

---
 Dockerfile | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index a4fa1142f..458fbc8a3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,8 +14,7 @@ RUN cp /usr/share/maven/ref/settings-docker.xml /root/.m2/settings.xml \
 
 FROM hbpmip/java-base:11.0.1-1
 
-RUN apt-get update && apt-get install -y --no-install-recommends curl \
-    && rm -rf /var/lib/apt/lists/* /tmp/*
+RUN rm -rf /var/lib/apt/lists/* /tmp/*
 
 COPY docker/config/application.tmpl /opt/portal/config/application.tmpl
 COPY docker/README.md docker/run.sh /opt/portal/
-- 
GitLab


From 82acc556a0c063dda910c2f95ef3500ae9d199ca Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 23 Oct 2020 13:08:02 +0300
Subject: [PATCH 05/52] Reduced logs and removed spacing.

---
 docker/config/application.tmpl                   |  2 +-
 .../mip/configuration/SecurityConfiguration.java |  2 --
 src/main/java/eu/hbp/mip/utils/Logging.java      | 16 ----------------
 3 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index dce1ac742..8d76148db 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -50,7 +50,7 @@ frontend:
   
 logging:
   level:
-    root: {{ default .Env.LOG_LEVEL "INFO" }}
+    root: {{ default .Env.LOG_LEVEL "ERROR" }}
     org:
       springframework:
         security: ERROR
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 7836edf94..4ea52570f 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -274,7 +274,6 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
     public void logout() {
         // POSTするリクエストパラメーターを作成
-        Logging.LogAction("refresh token ", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
         RestTemplate restTemplate = new RestTemplate();
         MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
         formParams.add("client_id", hbp().getClientId());
@@ -284,7 +283,6 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
         // リクエストを作成
-        Logging.LogAction("logoutUri is ", logoutUri);
         RequestEntity<MultiValueMap<String, String>> requestEntity =
                 new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
                         URI.create(logoutUri));
diff --git a/src/main/java/eu/hbp/mip/utils/Logging.java b/src/main/java/eu/hbp/mip/utils/Logging.java
index f3ed45e83..9b75de636 100644
--- a/src/main/java/eu/hbp/mip/utils/Logging.java
+++ b/src/main/java/eu/hbp/mip/utils/Logging.java
@@ -11,9 +11,7 @@ public class Logging {
 
     public static void LogUserAction(String userName, String endpoint, String actionInfo) {
         LOGGER.info(" User -> " + userName + " ,"
-                + calculateAdditionalSpacing(userName.length(), 8)
                 + "Endpoint -> " + endpoint + " ,"
-                + calculateAdditionalSpacing(endpoint.length(), 32)
                 + "Info ->  " + actionInfo);
     }
 
@@ -21,20 +19,6 @@ public class Logging {
     public static void LogExperimentAction(String experimentName, UUID experimentId, String actionInfo) {
         LOGGER.info(" Experiment -> " + experimentName
                 + "(" + experimentId + ") ,"
-                + calculateAdditionalSpacing(experimentName.length() + experimentId.toString().length() + 2, 20)
                 + "Info -> " + actionInfo);
     }
-
-    // Used when a user is not authorised yet
-    public static void LogAction(String actionName, String actionIdInfo) {
-        LOGGER.info(" Action -> " + actionName + " ,"
-                + calculateAdditionalSpacing(actionName.length() + 2, 20)
-                + "Info -> " + actionIdInfo);
-    }
-
-    // Calculates the spacing that is needed to create consistent logs.
-    private static String calculateAdditionalSpacing(Integer currentLen, Integer maxLen) {
-        int additionalSpacing = (maxLen > currentLen ? maxLen - currentLen + 2 : 2);
-        return String.format("%" + additionalSpacing + "s", "");
-    }
 }
-- 
GitLab


From 168ff3318edc9aece5305b39f9ea47b4f708402a Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 23 Oct 2020 14:15:59 +0300
Subject: [PATCH 06/52] Log level default values and env variables changed.

---
 docker/README.md               |  4 ++--
 docker/config/application.tmpl | 10 ++--------
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/docker/README.md b/docker/README.md
index faedc351e..3f3437aec 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -46,8 +46,8 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 
 ### LOGGING
 
-* LOGGING_LEVEL_WEB: log level for the web layer of the application. Default to "WARN".
-* LOGGING_LEVEL_HIBERNATE: log level for the Hibernate layer of the application. Default to "WARN".
+* LOG_LEVEL: log level for the developer added logs. Default is "ERROR".
+* LOG_LEVEL_FRAMEWORK: log level for all the framework logs. Default is "ERROR".
 
 
 ### ENDPOINTS
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 8d76148db..13fc65779 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -50,15 +50,9 @@ frontend:
   
 logging:
   level:
-    root: {{ default .Env.LOG_LEVEL "ERROR" }}
-    org:
-      springframework:
-        security: ERROR
-        web: {{ default .Env.LOGGING_LEVEL_WEB "ERROR" }}
-        web.servlet.handler.BeanNameUrlHandlerMapping: ERROR
-      hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "ERROR" }}
+    root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
     eu:
-      hbp: {{ default .Env.LOGGING_LEVEL_MIP "INFO" }}
+      hbp: {{ default .Env.LOG_LEVEL "INFO" }}
 
 # EMBEDDED SERVER CONFIGURATION
 server:
-- 
GitLab


From f362422371acb8a524f6acca14e9521bb5871c47 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Mon, 2 Nov 2020 04:40:37 -0800
Subject: [PATCH 07/52] Updated dependecies

---
 pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 87ef337aa..2caa3f349 100644
--- a/pom.xml
+++ b/pom.xml
@@ -209,7 +209,7 @@
         <dependency>
             <groupId>org.glassfish.jaxb</groupId>
             <artifactId>jaxb-runtime</artifactId>
-            <version>2.4.0-b180830.0438</version>
+            <version>3.0.0-M4</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/com.github.jmchilton.blend4j/blend4j -->
         <dependency>
@@ -221,27 +221,27 @@
         <dependency>
             <groupId>com.squareup.retrofit2</groupId>
             <artifactId>retrofit</artifactId>
-            <version>2.5.0</version>
+            <version>2.9.0</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
         <dependency>
             <groupId>com.squareup.retrofit2</groupId>
             <artifactId>converter-gson</artifactId>
-            <version>2.4.0</version>
+            <version>2.9.0</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor -->
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>
             <artifactId>logging-interceptor</artifactId>
-            <version>3.12.1</version>
+            <version>4.10.0-RC1</version>
         </dependency>
 
         <dependency>
             <groupId>com.auth0</groupId>
             <artifactId>java-jwt</artifactId>
-            <version>3.8.3</version>
+            <version>3.11.0</version>
         </dependency>
     </dependencies>
 
-- 
GitLab


From e8cb6d0d48e53dcf5f264534be4918c9f22fe317 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 5 Nov 2020 06:48:20 -0800
Subject: [PATCH 08/52] Updating pom.xml and implementing optional filtering in
 GET /experiments.

---
 docker/config/application.tmpl                |  4 +-
 pom.xml                                       | 65 ++++++++-------
 .../PersistenceConfiguration.java             | 22 ++---
 .../configuration/PortalErrorAttributes.java  | 43 ----------
 .../configuration/SecurityConfiguration.java  |  2 +-
 .../mip/configuration/WebConfiguration.java   | 10 +--
 .../eu/hbp/mip/controllers/ExperimentApi.java | 13 +--
 .../eu/hbp/mip/controllers/SecurityApi.java   |  4 +-
 .../java/eu/hbp/mip/controllers/UsersApi.java |  8 +-
 .../{Article.java => DAOs/ArticleDAO.java}    | 20 ++---
 .../eu/hbp/mip/model/DAOs/ExperimentDAO.java  | 42 +++++++---
 .../model/{User.java => DAOs/UserDAO.java}    |  8 +-
 .../eu/hbp/mip/model/DTOs/ExperimentDTO.java  | 19 ++++-
 src/main/java/eu/hbp/mip/model/UserInfo.java  | 11 +--
 .../mip/repositories/ArticleRepository.java   | 10 +--
 .../repositories/ExperimentRepository.java    |  9 +-
 .../hbp/mip/repositories/UserRepository.java  |  5 +-
 .../hbp/mip/services/ExperimentService.java   | 74 ++++++++---------
 .../services/ExperimentSpecifications.java    | 82 +++++++++++++++++++
 .../V7_0__NewExperimentStructure.sql          |  5 +-
 20 files changed, 266 insertions(+), 190 deletions(-)
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java
 rename src/main/java/eu/hbp/mip/model/{Article.java => DAOs/ArticleDAO.java} (87%)
 rename src/main/java/eu/hbp/mip/model/{User.java => DAOs/UserDAO.java} (94%)
 create mode 100644 src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 13fc65779..4e723b8a3 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -2,7 +2,7 @@
 
 # See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
 spring:
-  portalDatasource:
+  portal-datasource:
     url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://172.22.0.1:5432/portal" }}
     schema: {{ default .Env.PORTAL_DB_SCHEMA "public" }}
     username: {{ default .Env.PORTAL_DB_USER "postgres" }}
@@ -16,6 +16,8 @@ spring:
   jpa:
     hibernate:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
+      ddl-auto: validate
+
   # SPRING RESOURCES HANDLING
   resources:
     chain:
diff --git a/pom.xml b/pom.xml
index 2caa3f349..02129ae2b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,9 +14,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>1.3.8.RELEASE</version>
-        <relativePath/>
-
+        <version>2.3.5.RELEASE</version>
     </parent>
 
     <properties>
@@ -25,16 +23,18 @@
         <sonar.projectName>MIP portal-backend</sonar.projectName>
         <sonar.sources>src/main/java/</sonar.sources>
         <java.version>1.8</java.version>
+        <springfox-swagger.version>2.5.0</springfox-swagger.version>
+        <spring-context.version>5.2.10.RELEASE</spring-context.version>
+        <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
         <asciidoctor.maven.plugin.version>1.5.5</asciidoctor.maven.plugin.version>
         <asciidoctorj.pdf.version>1.5.0-alpha.15</asciidoctorj.pdf.version>
         <asciidoctorj.version>1.5.5</asciidoctorj.version>
-        <spring-data-commons.version>1.12.3.RELEASE</spring-data-commons.version>
         <angularjs.version>1.5.7</angularjs.version>
         <jquery.version>3.0.0</jquery.version>
         <bootstrap.version>3.3.7</bootstrap.version>
+        <webjars-locator.version>0.36</webjars-locator.version>
         <h2.version>1.4.192</h2.version>
         <postgresql.version>42.2.1</postgresql.version>
-        <springfox-swagger.version>2.5.0</springfox-swagger.version>
         <gson.version>2.7</gson.version>
         <slugify.version>2.1.5</slugify.version>
         <maven-resources-plugin.version>3.0.1</maven-resources-plugin.version>
@@ -42,15 +42,12 @@
         <swagger2markup-maven-plugin.version>1.0.0</swagger2markup-maven-plugin.version>
         <maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
         <hibernate4-maven-plugin.version>1.1.1</hibernate4-maven-plugin.version>
+        <commons-dbcp.version>2.7.0</commons-dbcp.version>
         <flyway-core.version>4.2.0</flyway-core.version>
         <hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version>
-        <hibernate.version>4.3.11.Final</hibernate.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>
+        <hibernate.version>5.4.10.Final</hibernate.version>
         <aspectjweaver.version>1.8.9</aspectjweaver.version>
         <javax-inject.version>1</javax-inject.version>
-        <akka.version>2.5.22</akka.version>
-        <spring-context.version>4.3.4.RELEASE</spring-context.version>
         <protobuf-java.version>3.1.0</protobuf-java.version>
     </properties>
 
@@ -66,32 +63,39 @@
     </repositories>
 
     <dependencies>
-
+        <dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <version>6.4</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security.oauth.boot</groupId>
+            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
+            <version>2.0.1.RELEASE</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
-            <version>${spring-boot-starter-actuator.version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-commons</artifactId>
-            <version>${spring-data-commons.version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-resource-server</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security.oauth</groupId>
-            <artifactId>spring-security-oauth2</artifactId>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
@@ -115,6 +119,7 @@
         <dependency>
             <groupId>org.webjars</groupId>
             <artifactId>webjars-locator</artifactId>
+            <version>${webjars-locator.version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -148,13 +153,8 @@
         </dependency>
         <dependency>
             <groupId>io.springfox</groupId>
-            <artifactId>springfox-swagger2</artifactId>
-            <version>${springfox-swagger.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>io.springfox</groupId>
-            <artifactId>springfox-swagger-ui</artifactId>
-            <version>${springfox-swagger.version}</version>
+            <artifactId>springfox-boot-starter</artifactId>
+            <version>${springfox-boot-starter.version}</version>
         </dependency>
         <dependency>
             <groupId>com.google.code.gson</groupId>
@@ -169,11 +169,11 @@
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-jpa</artifactId>
-            <version>${spring-data-jpa.version}</version>
         </dependency>
         <dependency>
-            <groupId>commons-dbcp</groupId>
-            <artifactId>commons-dbcp</artifactId>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-dbcp2</artifactId>
+            <version>${commons-dbcp.version}</version>
         </dependency>
         <dependency>
             <groupId>org.flywaydb</groupId>
@@ -192,9 +192,9 @@
             <version>${javax-inject.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring.version}</version>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context</artifactId>
+        <version>${spring-context.version}</version>
         </dependency>
         <dependency>
             <groupId>com.google.protobuf</groupId>
@@ -243,6 +243,11 @@
             <artifactId>java-jwt</artifactId>
             <version>3.11.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security.oauth</groupId>
+            <artifactId>spring-security-oauth2</artifactId>
+            <version>2.5.0.RELEASE</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
index c8024e1bf..bca25598a 100644
--- a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
@@ -1,10 +1,12 @@
 package eu.hbp.mip.configuration;
 
 import org.flywaydb.core.Flyway;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
 import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.orm.jpa.EntityScan;
-import org.springframework.context.annotation.*;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Primary;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 import org.springframework.orm.jpa.JpaVendorAdapter;
 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -18,12 +20,11 @@ import javax.sql.DataSource;
 
 @Configuration
 @EnableJpaRepositories("eu.hbp.mip.repositories")
-@EntityScan(basePackages = "eu.hbp.mip.model")
 public class PersistenceConfiguration {
 
     @Primary
-    @Bean(name = "portalDatasource")
-    @ConfigurationProperties(prefix = "spring.portalDatasource")
+    @Bean(name = "portal-datasource")
+    @ConfigurationProperties(prefix = "spring.portal-datasource")
     public DataSource portalDataSource() {
         return DataSourceBuilder.create().build();
     }
@@ -32,11 +33,12 @@ public class PersistenceConfiguration {
     @Bean(name = "entityManagerFactory")
     @DependsOn("flyway")
     public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
-        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
-        em.setDataSource(portalDataSource());
+        LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
+        emfb.setDataSource(portalDataSource());
         JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
-        em.setJpaVendorAdapter(vendorAdapter);
-        return em;
+        emfb.setJpaVendorAdapter(vendorAdapter);
+        emfb.setPackagesToScan("eu.hbp.mip.model.DAOs");
+        return emfb;
     }
 
     @Bean(name = "flyway", initMethod = "migrate")
diff --git a/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java b/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java
deleted file mode 100644
index 352b1d156..000000000
--- a/src/main/java/eu/hbp/mip/configuration/PortalErrorAttributes.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package eu.hbp.mip.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.RequestAttributes;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class PortalErrorAttributes extends DefaultErrorAttributes {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(PortalErrorAttributes.class);
-
-    @Override
-    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
-        Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
-
-        Throwable throwable = getError(requestAttributes);
-        StringBuilder sb = new StringBuilder("[");
-        for (String attr : requestAttributes.getAttributeNames(RequestAttributes.SCOPE_REQUEST)) {
-            Object v = requestAttributes.getAttribute(attr, RequestAttributes.SCOPE_REQUEST);
-            sb.append(attr).append(" = ").append(v).append('\n');
-        }
-        sb.append("]");
-        LOGGER.error("Reporting server error on request with attributes " + sb.toString(), throwable);
-
-        if (throwable != null) {
-
-            Throwable cause = throwable.getCause();
-            if (cause != null) {
-                Map<String, Object> causeErrorAttributes = new HashMap<>();
-                causeErrorAttributes.put("exception", cause.getClass().getName());
-                causeErrorAttributes.put("message", cause.getMessage());
-                errorAttributes.put("cause", causeErrorAttributes);
-            }
-        }
-
-        return errorAttributes;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 4ea52570f..afd3e56ed 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
-import org.springframework.boot.context.embedded.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
index a5b514dfb..17e38a5ee 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
@@ -2,7 +2,6 @@ package eu.hbp.mip.configuration;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.DependsOn;
 import org.springframework.data.web.config.EnableSpringDataWebSupport;
 import springfox.documentation.builders.ApiInfoBuilder;
 import springfox.documentation.builders.RequestHandlerSelectors;
@@ -10,7 +9,6 @@ import springfox.documentation.service.ApiInfo;
 import springfox.documentation.service.Contact;
 import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger.web.UiConfiguration;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 /**
@@ -22,10 +20,10 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 @EnableSpringDataWebSupport
 public class WebConfiguration {
 
-    @Bean
-    public UiConfiguration swaggerUiConfig() {
-        return UiConfiguration.DEFAULT;
-    }
+//    @Bean
+//    public String[] swaggerUiConfig() {
+//        return UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS;
+//    }
 
     @Bean
     public Docket swaggerDocumentation() {
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index d28d8aac3..c3b93cbe1 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -1,6 +1,5 @@
 package eu.hbp.mip.controllers;
 
-import com.google.gson.Gson;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.services.ExperimentService;
@@ -8,13 +7,10 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 /*
@@ -35,8 +31,13 @@ public class ExperimentApi {
 
     @ApiOperation(value = "Get experiments", response = ExperimentDTO.class, responseContainer = "List")
     @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<String> getExperiments() {
-        return experimentService.getExperiments("(GET) /experiments");
+    public ResponseEntity<String> getExperiments(
+            @RequestParam(name = "name", required = false) String name,
+            @RequestParam(name = "algorithm", required = false) String algorithm,
+            @RequestParam(name = "shared", required = false) Boolean shared,
+            @RequestParam(name = "viewed", required = false) Boolean viewed
+    ) {
+        return experimentService.getExperiments(name, algorithm, shared, viewed, "(GET) /experiments");
     }
 
     @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index 4e412aea0..ff8d70a80 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import eu.hbp.mip.configuration.SecurityConfiguration;
-import eu.hbp.mip.model.User;
+import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.repositories.UserRepository;
 import eu.hbp.mip.utils.Logging;
@@ -70,7 +70,7 @@ public class SecurityApi {
     @RequestMapping(path = "/user", method = RequestMethod.POST)
     public ResponseEntity<Void> postUser(
             @ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA") Boolean agreeNDA) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
         if (user != null) {
             user.setAgreeNDA(agreeNDA);
             userRepository.save(user);
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index b791a7858..886ad1ac9 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -4,7 +4,7 @@
 
 package eu.hbp.mip.controllers;
 
-import eu.hbp.mip.model.User;
+import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.repositories.UserRepository;
 import eu.hbp.mip.utils.Logging;
@@ -31,13 +31,13 @@ public class UsersApi {
     @Autowired
     private UserInfo userInfo;
 
-    @ApiOperation(value = "Get a user", response = User.class)
+    @ApiOperation(value = "Get a user", response = UserDAO.class)
     @RequestMapping(value = "/{username}", method = RequestMethod.GET)
-    public ResponseEntity<User> getAUser(
+    public ResponseEntity<UserDAO> getAUser(
             @ApiParam(value = "username", required = true) @PathVariable("username") String username
     ) {
         Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /users/{username}", "Loaded a user with username : " + userInfo.getUser().getUsername());
 
-        return ResponseEntity.ok(userRepository.findOne(username));
+        return ResponseEntity.ok(userRepository.findByUsername(username));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/model/Article.java b/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
similarity index 87%
rename from src/main/java/eu/hbp/mip/model/Article.java
rename to src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
index b79f2a33a..541c50765 100644
--- a/src/main/java/eu/hbp/mip/model/Article.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
@@ -2,7 +2,7 @@
  * Created by mirco on 04.12.15.
  */
 
-package eu.hbp.mip.model;
+package eu.hbp.mip.model.DAOs;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -13,15 +13,13 @@ import javax.persistence.*;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
 
 @Entity
 @Table(name = "`article`")
 @ApiModel
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Validated
-public class Article {
+public class ArticleDAO {
 
     @Id
     private String slug = null;
@@ -46,13 +44,13 @@ public class Article {
 
     @ManyToOne
     @JoinColumn(name = "createdby_username")
-    private User createdBy = null;
+    private UserDAO createdBy = null;
 
     @ManyToOne
     @JoinColumn(name = "updatedby_username")
-    private User updatedBy = null;
+    private UserDAO updatedBy = null;
 
-    public Article() {
+    public ArticleDAO() {
         /*
          *  Empty constructor is needed by Hibernate
          */
@@ -133,20 +131,20 @@ public class Article {
     }
 
 
-    public User getCreatedBy() {
+    public UserDAO getCreatedBy() {
         return createdBy;
     }
 
-    public void setCreatedBy(User createdBy) {
+    public void setCreatedBy(UserDAO createdBy) {
         this.createdBy = createdBy;
     }
 
 
-    public User getUpdatedBy() {
+    public UserDAO getUpdatedBy() {
         return updatedBy;
     }
 
-    public void setUpdatedBy(User updatedBy) {
+    public void setUpdatedBy(UserDAO updatedBy) {
         this.updatedBy = updatedBy;
     }
 
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
index 682f121ce..30d6c87da 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
@@ -1,11 +1,12 @@
 package eu.hbp.mip.model.DAOs;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.User;
 import eu.hbp.mip.utils.JsonConverters;
+import io.swagger.annotations.ApiModel;
 
 import javax.persistence.*;
 import java.util.Date;
@@ -16,51 +17,62 @@ import java.util.UUID;
  */
 @Entity
 @Table(name = "`experiment`")
+@ApiModel
+@JsonInclude(JsonInclude.Include.NON_NULL)
 public class ExperimentDAO {
 
     private static final Gson gson = new Gson();
 
+    @Expose
     @Id
     @Column(columnDefinition = "uuid", updatable = false)
     @org.hibernate.annotations.Type(type = "pg-uuid")
-    @Expose
     private UUID uuid;
 
-    @Column(columnDefinition = "TEXT")
     @Expose
+    @Column(columnDefinition = "TEXT")
     private String name;
 
     @Expose
     @ManyToOne
-    @JoinColumn(name = "created_by_username")
-    private User createdBy;
+    @JoinColumn(name = "created_by_username",columnDefinition = "CHARACTER VARYING")
+    private UserDAO createdBy;
 
-    @Column(name="workflow_history_id", columnDefinition = "TEXT")
     @Expose
+    @Column(name="workflow_history_id", columnDefinition = "TEXT")
     private String workflowHistoryId;
 
-    @Column(columnDefinition = "TEXT")
     @Expose
+    @Column(columnDefinition = "TEXT")
     private Status status;
 
-    @Column(columnDefinition = "TEXT")
     @Expose
+    @Column(columnDefinition = "TEXT")
     private String result;
 
     @Expose
+    @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
     private Date finished;
 
     @Expose
+    @Column(columnDefinition = "TEXT")
+    private String algorithmDetails;
+
+    @Expose
+    @Column(columnDefinition = "TEXT")
     private String algorithm;
 
     @Expose
+    @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
     private Date created = new Date();
 
     @Expose
+    @Column(columnDefinition = "BOOLEAN")
     private boolean shared = false;
 
     // whether or not the experiment's result have been viewed by its owner
     @Expose
+    @Column(columnDefinition = "BOOLEAN")
     private boolean viewed = false;
 
     public enum Status {
@@ -102,7 +114,7 @@ public class ExperimentDAO {
     public ExperimentDTO convertToDTO()
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
-        experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithm, AlgorithmDTO.class));
+        experimentDTO.setAlgorithmDetails(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
         experimentDTO.setCreated(this.created);
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
@@ -113,6 +125,14 @@ public class ExperimentDAO {
         return experimentDTO;
     }
 
+    public String getAlgorithmDetails() {
+        return algorithmDetails;
+    }
+
+    public void setAlgorithmDetails(String algorithmDetails) {
+        this.algorithmDetails = algorithmDetails;
+    }
+
     public String getAlgorithm() {
         return algorithm;
     }
@@ -177,11 +197,11 @@ public class ExperimentDAO {
         this.name = name;
     }
 
-    public User getCreatedBy() {
+    public UserDAO getCreatedBy() {
         return createdBy;
     }
 
-    public void setCreatedBy(User createdBy) {
+    public void setCreatedBy(UserDAO createdBy) {
         this.createdBy = createdBy;
     }
 
diff --git a/src/main/java/eu/hbp/mip/model/User.java b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
similarity index 94%
rename from src/main/java/eu/hbp/mip/model/User.java
rename to src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
index f1ee34059..1e35ac831 100644
--- a/src/main/java/eu/hbp/mip/model/User.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
@@ -2,7 +2,7 @@
  * Created by mirco on 04.12.15.
  */
 
-package eu.hbp.mip.model;
+package eu.hbp.mip.model.DAOs;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
@@ -20,7 +20,7 @@ import java.util.regex.Pattern;
 @ApiModel
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonIgnoreProperties(value = {"appsVotes"})
-public class User {
+public class UserDAO {
 
     @Id
     @Expose
@@ -35,7 +35,7 @@ public class User {
     private Boolean agreeNDA = null;
 
 
-    public User() {
+    public UserDAO() {
         /*
          *  Empty constructor is needed by Hibernate
          */
@@ -47,7 +47,7 @@ public class User {
      *
      * @param userInfo info from OpenID UserInfo endpoint
      */
-    public User(String userInfo) {
+    public UserDAO(String userInfo) {
 
         Pattern p;
         Matcher m;
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
index b4214dd0a..e4b9d34a5 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
@@ -16,16 +16,29 @@ public class ExperimentDTO {
     private ExperimentDTO.ResultDTO result;
     private ExperimentDAO.Status status;
 
-    private AlgorithmDTO algorithm;
+    private String algorithm;
+    private AlgorithmDTO algorithmDetails;
 
-    public AlgorithmDTO getAlgorithm() {
+    public ExperimentDTO() {
+    }
+
+    public String getAlgorithm() {
         return algorithm;
     }
 
-    public void setAlgorithm(AlgorithmDTO algorithm) {
+    public void setAlgorithm(String algorithm) {
         this.algorithm = algorithm;
     }
 
+    public AlgorithmDTO getAlgorithmDetails() {
+        return algorithmDetails;
+    }
+
+    public void setAlgorithmDetails(AlgorithmDTO algorithmDetails) {
+        this.algorithmDetails = algorithmDetails;
+        this.algorithm = algorithmDetails.getName();
+    }
+
     public String getUuid() {
         return uuid;
     }
diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java
index 7bd9a97f3..cb61cfcea 100644
--- a/src/main/java/eu/hbp/mip/model/UserInfo.java
+++ b/src/main/java/eu/hbp/mip/model/UserInfo.java
@@ -1,5 +1,6 @@
 package eu.hbp.mip.model;
 
+import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.repositories.UserRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -26,7 +27,7 @@ public class UserInfo {
     @Value("#{'${hbp.authentication.enabled:1}'}")
     private boolean authentication;
 
-    private User user;
+    private UserDAO user;
 
     /**
      * Set to true if using no-auth mode and user has clicked on the login button
@@ -45,18 +46,18 @@ public class UserInfo {
      *
      * @return the user for the current session
      */
-    public User getUser() {
+    public UserDAO getUser() {
         if (user == null) {
 
             if (!authentication) {
-                user = new User();
+                user = new UserDAO();
                 user.setUsername("anonymous");
                 user.setFullname("anonymous");
                 user.setEmail("anonymous@anonymous.com");
             } else {
-                user = new User(getUserInfos());
+                user = new UserDAO(getUserInfos());
             }
-            User foundUser = userRepository.findOne(user.getUsername());
+            UserDAO foundUser = userRepository.findByUsername(user.getUsername());
             if (foundUser != null) {
                 user.setAgreeNDA(foundUser.getAgreeNDA());
             }
diff --git a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java b/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java
index 1a93186ff..5f6589ab5 100644
--- a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java
@@ -1,17 +1,17 @@
 package eu.hbp.mip.repositories;
 
-import eu.hbp.mip.model.Article;
-import eu.hbp.mip.model.User;
+import eu.hbp.mip.model.DAOs.ArticleDAO;
+import eu.hbp.mip.model.DAOs.UserDAO;
 import org.springframework.data.repository.CrudRepository;
 
 /**
  * Created by mirco on 11.07.16.
  */
 
-public interface ArticleRepository extends CrudRepository<Article, String> {
+public interface ArticleRepository extends CrudRepository<ArticleDAO, String> {
     Long countByTitle(String title);
 
-    Iterable<Article> findByCreatedBy(User user);
+    Iterable<ArticleDAO> findByCreatedBy(UserDAO user);
 
-    Iterable<Article> findByStatusOrCreatedBy(String status, User user);
+    Iterable<ArticleDAO> findByStatusOrCreatedBy(String status, UserDAO user);
 }
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index eb1d25415..a9fb10f27 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -1,7 +1,7 @@
 package eu.hbp.mip.repositories;
 
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
-import eu.hbp.mip.model.User;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 
 import java.util.UUID;
@@ -10,8 +10,7 @@ import java.util.UUID;
  * Created by mirco on 11.07.16.
  */
 
-public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID> {
-    Iterable<ExperimentDAO> findByCreatedBy(User user);
-
-    Iterable<ExperimentDAO> findByShared(Boolean shared);
+public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID>, JpaSpecificationExecutor<ExperimentDAO>
+{
+    ExperimentDAO findByUuid(UUID experimentUuid);
 }
diff --git a/src/main/java/eu/hbp/mip/repositories/UserRepository.java b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
index 3a0db7ee3..4a3a7c698 100644
--- a/src/main/java/eu/hbp/mip/repositories/UserRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
@@ -1,12 +1,13 @@
 package eu.hbp.mip.repositories;
 
-import eu.hbp.mip.model.User;
+import eu.hbp.mip.model.DAOs.UserDAO;
 import org.springframework.data.repository.CrudRepository;
 
 /**
  * Created by mirco on 11.07.16.
  */
 
-public interface UserRepository extends CrudRepository<User, String> {
+public interface UserRepository extends CrudRepository<UserDAO, String> {
 
+    UserDAO findByUsername(String username);
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index bd0bed359..d8545b9be 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -6,14 +6,13 @@ import com.github.jmchilton.blend4j.galaxy.WorkflowsClient;
 import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
-import com.google.common.collect.Lists;
 import com.google.gson.*;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.User;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.model.galaxy.ErrorResponse;
 import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
@@ -27,6 +26,7 @@ import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.jpa.domain.Specification;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
@@ -51,12 +51,6 @@ public class ExperimentService {
     @Value("#{'${services.exareme.queryExaremeUrl}'}")
     private String queryExaremeUrl;
 
-    @Value("#{'${services.workflows.workflowUrl}'}")
-    private String workflowUrl;
-
-    @Value("#{'${services.workflows.jwtSecret}'}")
-    private String jwtSecret;
-
     @Value("#{'${services.galaxy.galaxyUrl}'}")
     private String galaxyUrl;
 
@@ -75,7 +69,7 @@ public class ExperimentService {
     public ResponseEntity<String> getExperiment(String uuid, String endpoint) {
 
         ExperimentDAO experimentDAO;
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
@@ -97,7 +91,7 @@ public class ExperimentService {
     }
 
     public ResponseEntity<String> createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
 
         //Checking if check (POST) /experiments has proper input.
         if (checkPostExperimentProperInput(experimentDTO)){
@@ -106,11 +100,11 @@ public class ExperimentService {
             return ResponseEntity.badRequest().body("Please provide proper input.");
         }
         // Get the type and name of algorithm
-        String algorithmType = experimentDTO.getAlgorithm().getType();
-        String algorithmName = experimentDTO.getAlgorithm().getName();
+        String algorithmType = experimentDTO.getAlgorithmDetails().getType();
+        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
         StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithm().getParameters()) {
+        for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithmDetails().getParameters()) {
             parametersLogMessage
                     .append("  ")
                     .append(params.getLabel())
@@ -123,7 +117,7 @@ public class ExperimentService {
         if (authenticationIsEnabled) {
             // Getting the dataset from the experiment parameters
             String experimentDatasets = null;
-            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithm().getParameters()) {
+            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
                 if (parameter.getLabel().equals("dataset")) {
                     experimentDatasets = parameter.getValue();
                     break;
@@ -152,19 +146,18 @@ public class ExperimentService {
         }
     }
 
-    public ResponseEntity<String> getExperiments( String endpoint) {
-        User user = userInfo.getUser();
+    public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, String endpoint) {
+        UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
+        Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
+                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
+                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
+                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed));
 
-        Iterable<ExperimentDAO> myExperiments = experimentRepository.findByCreatedBy(user);
-        List<ExperimentDAO> expList = Lists.newLinkedList(myExperiments);
-        Iterable<ExperimentDAO> sharedExperiments = experimentRepository.findByShared(true);
-        List<ExperimentDAO> sharedExpList = Lists.newLinkedList(sharedExperiments);
-        expList.addAll(sharedExpList);
-        Logging.LogUserAction(user.getUsername(), endpoint, "Successfully listed my experiments.");
-        List<ExperimentDTO> experimentDTOs = new LinkedList<>();
+        List<ExperimentDAO> experimentDAOs = experimentRepository.findAll(spec);
 
-        for (ExperimentDAO experimentDAO: expList){
+        List<ExperimentDTO> experimentDTOs= new ArrayList<>();
+        for (ExperimentDAO experimentDAO: experimentDAOs){
             ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
             experimentDTOs.add(experimentDTO);
         }
@@ -174,7 +167,7 @@ public class ExperimentService {
     public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
     {
         ExperimentDAO experimentDAO;
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + experimentDTO.getUuid() + ".");
         //Checking if check (PUT) /experiments has proper input.
         if (checkPutExperimentProperInput(experimentDTO)){
@@ -186,7 +179,7 @@ public class ExperimentService {
         if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0)
                 && experimentDTO.getShared() == null
                 && experimentDTO.getViewed() == null
-                && experimentDTO.getAlgorithm() == null)
+                && experimentDTO.getAlgorithmDetails() == null)
         {
             return ResponseEntity.badRequest().body("Input is required.");
         }
@@ -222,7 +215,7 @@ public class ExperimentService {
     public ResponseEntity<String> deleteExperiment(String uuid, String endpoint)
     {
         ExperimentDAO experimentDAO;
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
         experimentDAO = loadExperiment(uuid);
@@ -266,30 +259,31 @@ public class ExperimentService {
             return null;
         }
 
-        return experimentRepository.findOne(experimentUuid);
+        return experimentRepository.findByUuid(experimentUuid);
     }
 
     private ExperimentDAO createExperiment(ExperimentDTO experimentDTO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
         experimentDAO.setUuid(UUID.randomUUID());
         experimentDAO.setCreatedBy(user);
-        experimentDAO.setAlgorithm(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm()));
+        experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()));
+        experimentDAO.setAlgorithm(experimentDTO.getAlgorithm());
         experimentDAO.setName(experimentDTO.getName());
         experimentRepository.save(experimentDAO);
 
         Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
-        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm());
+        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
         Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
         return experimentDAO;
     }
 
     private void saveExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
-        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithm());
+        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
         Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
         Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId());
         Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus());
@@ -313,18 +307,18 @@ public class ExperimentService {
      * @return the response to be returned
      */
     public ResponseEntity<String> runExaremeAlgorithm(ExperimentDTO experimentDTO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
 
         ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
         // Run the 1st algorithm from the list
-        String algorithmName = experimentDTO.getAlgorithm().getName();
+        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
-                = experimentDTO.getAlgorithm().getParameters();
+                = experimentDTO.getAlgorithmDetails().getParameters();
 
         String body = gson.toJson(algorithmParameters);
         String url = queryExaremeUrl + "/" + algorithmName;
@@ -375,7 +369,7 @@ public class ExperimentService {
      * @return the response to be returned
      */
     public ResponseEntity<String> runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
 
         ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
@@ -383,11 +377,11 @@ public class ExperimentService {
 
 
         // Run the 1st algorithm from the list
-        String workflowId = experimentDTO.getAlgorithm().getName();
+        String workflowId = experimentDTO.getAlgorithmDetails().getName();
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
-                = experimentDTO.getAlgorithm().getParameters();
+                = experimentDTO.getAlgorithmDetails().getParameters();
 
         // Convert the parameters to workflow parameters
         HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>();
@@ -481,7 +475,7 @@ public class ExperimentService {
      * @return nothing, just updates the experiment
      */
     public void updateWorkflowExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        User user = userInfo.getUser();
+        UserDAO user = userInfo.getUser();
 
         if (experimentDAO == null) {
             Logging.LogUserAction(user.getUsername(), endpoint, "The experiment does not exist.");
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
new file mode 100644
index 000000000..6596a319a
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -0,0 +1,82 @@
+package eu.hbp.mip.services;
+
+import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import org.springframework.data.jpa.domain.Specification;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+public class ExperimentSpecifications {
+    public static class ExperimentWithName implements Specification<ExperimentDAO> {
+
+        private String name;
+        private String regExp;
+
+        public  ExperimentWithName(String name){
+            this.name = name;
+            this.regExp = "%"+name+"%";
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb)
+        {
+            if (name == null) {
+                return cb.isTrue(cb.literal(true));
+            }
+
+            return cb.like( root.get( "name" ), regExp );
+        }
+    }
+    public static class ExperimentWithAlgorithm implements Specification<ExperimentDAO> {
+
+        private String algorithm;
+
+        public  ExperimentWithAlgorithm(String algorithm){
+            this.algorithm = algorithm;
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb)
+        {
+            if (algorithm == null) {
+                return cb.isTrue(cb.literal(true));
+            }
+
+            return cb.equal(root.get("algorithm"), this.algorithm);
+        }
+    }
+
+    public static class ExperimentWithViewed implements Specification<ExperimentDAO> {
+
+        private Boolean viewed;
+
+        public  ExperimentWithViewed(Boolean viewed){
+            this.viewed = viewed;
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+            if (viewed == null) {
+                return cb.isTrue(cb.literal(true)); // always true = no filtering
+            }
+            return cb.equal(root.get("viewed"), this.viewed);
+        }
+    }
+
+    public static class ExperimentWithShared implements org.springframework.data.jpa.domain.Specification<ExperimentDAO> {
+
+        private Boolean shared;
+
+        public  ExperimentWithShared(Boolean shared){
+            this.shared = shared;
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+            if (shared == null) {
+                return cb.isTrue(cb.literal(true));
+            }
+            return cb.equal(root.get("shared"), this.shared);
+        }
+
+    }
+}
+
diff --git a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
index b69ae2b70..73a15addd 100644
--- a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
@@ -5,7 +5,7 @@ DROP COLUMN validations,
 DROP COLUMN model_slug;
 
 ALTER TABLE experiment
-RENAME algorithms TO algorithm;
+RENAME algorithms TO algorithmDetails;
 ALTER TABLE experiment
 RENAME createdby_username TO created_by_username;
 ALTER TABLE experiment
@@ -15,6 +15,9 @@ RENAME resultsviewed TO viewed;
 ALTER TABLE experiment
 RENAME workflowstatus TO status;
 
+ALTER TABLE experiment
+ADD COLUMN algorithm text;
+
 ALTER TABLE "user"
 DROP COLUMN birthday,
 DROP COLUMN city,
-- 
GitLab


From e2ad3a7a25f5af81649cfb5a506233e5899cf639 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Fri, 6 Nov 2020 01:29:22 -0800
Subject: [PATCH 09/52] Improved exception handling.

---
 .../eu/hbp/mip/controllers/AlgorithmsApi.java |  3 +-
 .../eu/hbp/mip/controllers/ExperimentApi.java |  6 +-
 .../hbp/mip/controllers/PathologiesApi.java   |  3 +-
 .../repositories/ExperimentRepository.java    |  3 +-
 .../hbp/mip/services/ExperimentService.java   | 83 +++++++++++--------
 .../mip/utils/ControllerExceptionHandler.java | 35 ++++++++
 .../java/eu/hbp/mip/utils/ErrorMessage.java   | 34 ++++++++
 .../java/eu/hbp/mip/utils/ErrorMessages.java  |  7 --
 .../mip/utils/ResourceNotFoundException.java  | 10 +++
 9 files changed, 136 insertions(+), 48 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/ErrorMessage.java
 delete mode 100644 src/main/java/eu/hbp/mip/utils/ErrorMessages.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java

diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index fcde558b8..d5dca19ae 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -31,7 +31,6 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
-import static eu.hbp.mip.utils.ErrorMessages.disabledAlgorithmsCouldNotBeLoaded;
 import static eu.hbp.mip.utils.InputStreamConverter.convertInputStreamToString;
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
@@ -83,7 +82,7 @@ public class AlgorithmsApi {
             disabledAlgorithms = getDisabledAlgorithms();
         } catch (IOException e) {
             Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
-                    disabledAlgorithmsCouldNotBeLoaded);
+                    "The disabled algorithms could not be loaded.");
         }
 
         // Remove any disabled algorithm
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index c3b93cbe1..7cb949a4b 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -35,9 +35,11 @@ public class ExperimentApi {
             @RequestParam(name = "name", required = false) String name,
             @RequestParam(name = "algorithm", required = false) String algorithm,
             @RequestParam(name = "shared", required = false) Boolean shared,
-            @RequestParam(name = "viewed", required = false) Boolean viewed
+            @RequestParam(name = "viewed", required = false) Boolean viewed,
+            @RequestParam(defaultValue = "0") int page,
+            @RequestParam(defaultValue = "3") int size
     ) {
-        return experimentService.getExperiments(name, algorithm, shared, viewed, "(GET) /experiments");
+        return experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
     }
 
     @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 66a97896b..9560cc6dd 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.RestController;
 import java.io.IOException;
 import java.util.List;
 
-import static eu.hbp.mip.utils.ErrorMessages.pathologiesCouldNotBeLoaded;
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 @RestController
@@ -57,7 +56,7 @@ public class PathologiesApi {
             }.getType());
         } catch (IOException e) {
             Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
-            return ResponseEntity.badRequest().body(pathologiesCouldNotBeLoaded);
+            return ResponseEntity.badRequest().body("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index a9fb10f27..5f2c8dc76 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -4,6 +4,7 @@ import eu.hbp.mip.model.DAOs.ExperimentDAO;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 
+import java.util.Optional;
 import java.util.UUID;
 
 /**
@@ -12,5 +13,5 @@ import java.util.UUID;
 
 public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID>, JpaSpecificationExecutor<ExperimentDAO>
 {
-    ExperimentDAO findByUuid(UUID experimentUuid);
+    Optional<ExperimentDAO> findByUuid(UUID experimentUuid);
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index d8545b9be..a02af3ab6 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -18,14 +18,14 @@ import eu.hbp.mip.model.galaxy.ErrorResponse;
 import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
 import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
-import eu.hbp.mip.utils.ClaimUtils;
-import eu.hbp.mip.utils.HTTPUtil;
-import eu.hbp.mip.utils.JsonConverters;
-import eu.hbp.mip.utils.Logging;
+import eu.hbp.mip.utils.*;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -45,9 +45,6 @@ public class ExperimentService {
     @Autowired
     private UserInfo userInfo;
 
-    private static final Gson gsonOnlyExposed = new GsonBuilder().serializeNulls()
-            .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").excludeFieldsWithoutExposeAnnotation().create();
-
     @Value("#{'${services.exareme.queryExaremeUrl}'}")
     private String queryExaremeUrl;
 
@@ -66,6 +63,36 @@ public class ExperimentService {
 
     private static final Gson gson = new Gson();
 
+    public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
+        UserDAO user = userInfo.getUser();
+        Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
+        if(size > 10 )
+            return ResponseEntity.badRequest().body("Invalid size input, max size is 10.");
+
+        Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
+                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
+                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
+                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed));
+
+        Pageable paging = PageRequest.of(page, size);
+        Page<ExperimentDAO> pageExperiments = experimentRepository.findAll(spec, paging);
+        List<ExperimentDAO> experimentDAOs = pageExperiments.getContent();
+
+        if (experimentDAOs.isEmpty())
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+
+        List<ExperimentDTO> experimentDTOs = new ArrayList<>();
+        experimentDAOs.forEach(experimentDAO -> experimentDTOs.add(experimentDAO.convertToDTO()));
+
+        Map<String, Object> response = new HashMap<>();
+        response.put("experiments", experimentDTOs);
+        response.put("currentPage", pageExperiments.getNumber());
+        response.put("totalExperiments", pageExperiments.getTotalElements());
+        response.put("totalPages", pageExperiments.getTotalPages());
+
+        return new ResponseEntity(response, HttpStatus.OK);
+    }
+
     public ResponseEntity<String> getExperiment(String uuid, String endpoint) {
 
         ExperimentDAO experimentDAO;
@@ -73,7 +100,7 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
-        experimentDAO = loadExperiment(uuid);
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ResourceNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (experimentDAO == null) {
             Logging.LogUserAction(user.getUsername(), endpoint, "Experiment Not found.");
@@ -142,26 +169,8 @@ public class ExperimentService {
             return runGalaxyWorkflow(experimentDTO, endpoint);
         } else {
             Logging.LogUserAction(user.getUsername(), endpoint, "Algorithm runs on Exareme.");
-            return runExaremeAlgorithm(experimentDTO, endpoint);
-        }
-    }
-
-    public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, String endpoint) {
-        UserDAO user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
-        Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
-                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
-                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
-                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed));
-
-        List<ExperimentDAO> experimentDAOs = experimentRepository.findAll(spec);
-
-        List<ExperimentDTO> experimentDTOs= new ArrayList<>();
-        for (ExperimentDAO experimentDAO: experimentDAOs){
-            ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
-            experimentDTOs.add(experimentDTO);
+            return createExaremeExperiment(experimentDTO, endpoint);
         }
-        return new ResponseEntity<>(new Gson().toJson(experimentDTOs ), HttpStatus.OK);
     }
 
     public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
@@ -184,7 +193,7 @@ public class ExperimentService {
             return ResponseEntity.badRequest().body("Input is required.");
         }
 
-        experimentDAO = loadExperiment(uuid);
+        experimentDAO = loadExperiment(uuid).get();
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
@@ -218,7 +227,7 @@ public class ExperimentService {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid);
+        experimentDAO = loadExperiment(uuid).get();
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             return new ResponseEntity<>(endpoint, HttpStatus.UNAUTHORIZED);
@@ -226,7 +235,7 @@ public class ExperimentService {
         experimentRepository.delete(experimentDAO);
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
-        return new ResponseEntity<>(HttpStatus.OK);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
@@ -249,7 +258,8 @@ public class ExperimentService {
                 || experimentDTO.getStatus() != null;
     }
 
-    private ExperimentDAO loadExperiment(String uuid){
+    private Optional<ExperimentDAO> loadExperiment(String uuid){
+
 
         UUID experimentUuid ;
 
@@ -306,7 +316,7 @@ public class ExperimentService {
      * @param experimentDTO is the request with the experiment information
      * @return the response to be returned
      */
-    public ResponseEntity<String> runExaremeAlgorithm(ExperimentDTO experimentDTO, String endpoint) {
+    public ResponseEntity<String> createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
 
@@ -330,10 +340,13 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint,
                 "Starting exareme execution thread");
         new Thread(() -> {
+
             // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
             try {
+
+                // --> New function runExaremeAlgorithm
                 StringBuilder results = new StringBuilder();
                 int code = HTTPUtil.sendPost(url, body, results);
 
@@ -342,6 +355,8 @@ public class ExperimentService {
                 // Results are stored in the experiment object
                 ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
 
+                // <-- New function runExaremeAlgorithm
+
                 experimentDAO.setResult(JsonConverters.convertObjectToJsonString(resultDTO));
 //                experimentDAO.setHasError(code >= 400);
 //                experimentDAO.setHasServerError(code >= 500);
@@ -356,7 +371,7 @@ public class ExperimentService {
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
         }).start();
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
     }
 
     /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
@@ -463,7 +478,7 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
 
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
     }
 
 
diff --git a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
new file mode 100644
index 000000000..4e6f8da32
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
@@ -0,0 +1,35 @@
+package eu.hbp.mip.utils;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+
+import java.util.Date;
+
+@ControllerAdvice
+public class ControllerExceptionHandler {
+
+    @ExceptionHandler(ResourceNotFoundException.class)
+    public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                2,
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);
+    }
+
+    @ExceptionHandler(Exception.class)
+    public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.INTERNAL_SERVER_ERROR.value(),
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/utils/ErrorMessage.java b/src/main/java/eu/hbp/mip/utils/ErrorMessage.java
new file mode 100644
index 000000000..ef15c71ae
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/ErrorMessage.java
@@ -0,0 +1,34 @@
+package eu.hbp.mip.utils;
+
+
+import java.util.Date;
+
+public class ErrorMessage {
+    private int statusCode;
+    private Date timestamp;
+    private String message;
+    private String description;
+
+    public ErrorMessage(int statusCode, Date timestamp, String message, String description) {
+        this.statusCode = statusCode;
+        this.timestamp = timestamp;
+        this.message = message;
+        this.description = description;
+    }
+
+    public int getStatusCode() {
+        return statusCode;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/utils/ErrorMessages.java b/src/main/java/eu/hbp/mip/utils/ErrorMessages.java
deleted file mode 100644
index 9f672f81b..000000000
--- a/src/main/java/eu/hbp/mip/utils/ErrorMessages.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.hbp.mip.utils;
-
-public class ErrorMessages {
-
-    public static String pathologiesCouldNotBeLoaded = "The pathologies could not be loaded.";
-    public static String disabledAlgorithmsCouldNotBeLoaded = "The disabled algorithms could not be loaded.";
-}
diff --git a/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java b/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
new file mode 100644
index 000000000..38f067c42
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
@@ -0,0 +1,10 @@
+package eu.hbp.mip.utils;
+
+public class ResourceNotFoundException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public ResourceNotFoundException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
-- 
GitLab


From 78583a675de474db03ff8eda5e013f8045f83fed Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 6 Nov 2020 12:53:30 +0200
Subject: [PATCH 10/52] Cleaning up security configuration code.

---
 Dockerfile                                    |   7 +-
 docker/README.md                              |   4 +-
 docker/config/application.tmpl                |  16 +--
 .../configuration/SecurityConfiguration.java  | 134 ++++++------------
 .../eu/hbp/mip/controllers/SecurityApi.java   |   5 +-
 5 files changed, 53 insertions(+), 113 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 458fbc8a3..866c01bf4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -43,17 +43,16 @@ WORKDIR /home/portal
 ENTRYPOINT ["/run.sh"]
 
 # 8080: Web service API, health checks on http://host:8080$CONTEXT_PATH/health
-# 4089: Akka cluster
-EXPOSE 4089 8080
+EXPOSE 8080
 
 HEALTHCHECK --start-period=60s CMD curl -v --silent http://localhost:8080$CONTEXT_PATH/health 2>&1 | grep UP
 
 LABEL org.label-schema.build-date=$BUILD_DATE \
       org.label-schema.name="hbpmip/portal-backend" \
-      org.label-schema.description="Java backend for the MIP portal" \
+      org.label-schema.description="Spring backend for the MIP portal" \
       org.label-schema.url="https://mip.humanbrainproject.eu" \
       org.label-schema.vcs-type="git" \
-      org.label-schema.vcs-url="https://github.com/LREN-CHUV/portal-backend" \
+      org.label-schema.vcs-url="https://github.com/HBPMedical/portal-backend" \
       org.label-schema.vcs-ref=$VCS_REF \
       org.label-schema.version="$VERSION" \
       org.label-schema.vendor="LREN CHUV" \
diff --git a/docker/README.md b/docker/README.md
index 3f3437aec..cc8c59fe1 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -72,4 +72,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 
 * RELEASE_STAGE: Release stage used when reporting errors to Bugsnag. Values are dev, staging, production
 * DATA_CENTER_LOCATION: Location of the datacenter, used when reporting errors to Bugsnag
-* CONTAINER_ORCHESTRATION: Container orchestration system used to execute the Docker containers. Values are mesos, docker-compose, kubernetes
+
+
+# TODO Refactor variables
\ No newline at end of file
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 4e723b8a3..190f04f90 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -30,26 +30,14 @@ hbp:
   client:
     clientId: {{ default .Env.CLIENT_ID "996f97c5-a3ca-460e-b18b-00df3e2be89a" }}
     clientSecret: {{ .Env.CLIENT_SECRET }}
-    accessTokenUri: {{ default .Env.TOKEN_URI "https://services.humanbrainproject.eu/oidc/token" }}
-    userAuthorizationUri: {{ default .Env.AUTH_URI "https://services.humanbrainproject.eu/oidc/authorize" }}
     logoutUri: {{ .Env.LOGOUT_URI }}
-    tokenName: access_token
-    authenticationScheme: query
-    clientAuthenticationScheme: form
-    useCurrentUri: false
-    preEstablishedRedirectUri: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
-  resource:
-    userInfoUri: {{ default .Env.USER_INFO_URI "https://services.humanbrainproject.eu/oidc/userinfo" }}
-    revokeTokenUri: {{ default .Env.REVOKE_TOKEN_URI "https://services.humanbrainproject.eu/oidc/slo" }}
-  sso:
-    login-path:
 
 # WEB FRONTEND
 frontend:
   loginUrl: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
+  redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/" }}
   redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL (default .Env.LOGIN_URI "http://frontend/services/login/hbp") }}
-  redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/home" }}
-  
+
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index afd3e56ed..ff28602a1 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -1,7 +1,8 @@
 package eu.hbp.mip.configuration;
 
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.utils.*;
+import eu.hbp.mip.utils.CORSFilter;
+import eu.hbp.mip.utils.CustomAccessDeniedHandler;
+import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -9,14 +10,16 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.*;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.RequestEntity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.oauth2.client.OAuth2ClientContext;
@@ -57,8 +60,9 @@ import java.util.List;
 import java.util.Map;
 
 
-// See https://spring.io/guides/tutorials/spring-boot-oauth2/ for reference about configuring OAuth2 login
+// Reference for OAuth2 login: https://spring.io/guides/tutorials/spring-boot-oauth2/
 // also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
+// Security with Keycloak: https://www.thomasvitale.com/keycloak-authentication-flow-sso-client/
 
 @Configuration
 @EnableOAuth2Client
@@ -72,38 +76,40 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     /**
      * Enable HBP collab authentication (1) or disable it (0). Default is 1
      */
-    @Value("#{'${hbp.authentication.enabled:1}'}")
-    private boolean authentication;
+    @Value("#{'${hbp.authentication.enabled}'}")
+    private boolean authenticationEnabled;
 
     /**
      * Absolute URL to redirect to when login is required
      */
-    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
+    @Value("#{'${frontend.loginUrl}'}")
     private String loginUrl;
 
     /**
      * Absolute URL to redirect to when logout is required
      */
     @Value("#{'${hbp.client.logoutUri}'}")
-    private String logoutUri;
+    private String logoutUrl;
 
     /**
      * Absolute URL to redirect to after successful login
      */
-    @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
+    @Value("#{'${frontend.redirectAfterLoginUrl}'}")
     private String frontendRedirectAfterLogin;
 
     /**
-     * Absolute URL to redirect to after logout has occurred
+     * Absolute URL to redirect to after successful logout
      */
-    @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
+    @Value("#{'${frontend.redirectAfterLogoutUrl}'}")
     private String redirectAfterLogoutUrl;
 
-    /**
-     * URL to revoke auth token
-     */
-    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
-    private String revokeTokenURI;
+    public boolean getAuthenticationEnabled() {
+        return authenticationEnabled;
+    }
+
+    public String getFrontendRedirectAfterLogin() {
+        return frontendRedirectAfterLogin;
+    }
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
@@ -111,15 +117,15 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         // @formatter:off
         http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
 
-        if (authentication) {
+        if (authenticationEnabled) {
             http.antMatcher("/**")
                     .authorizeRequests()
                     .antMatchers(
-                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
-                    )
-                    .permitAll()
+                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**",
+                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
+                            "/swagger-ui.html", "/swagger-resources/**"
+                    ).permitAll()
                     .antMatchers("/galaxy*", "/galaxy/*").hasRole("Data Manager")
-                    //.anyRequest().authenticated()
                     .anyRequest().hasRole("Researcher")
                     .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
                     .accessDeniedHandler(new CustomAccessDeniedHandler())
@@ -131,7 +137,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         } else {
             http.antMatcher("/**")
                     .authorizeRequests()
-                    .antMatchers("/**").permitAll().and().csrf().disable();
+                    .antMatchers("/**").permitAll()
+                    .and().csrf().disable();
         }
     }
 
@@ -165,13 +172,6 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         return new ResourceServerProperties();
     }
 
-    public boolean isAuthentication() {
-        return authentication;
-    }
-
-    public String getFrontendRedirectAfterLogin() {
-        return frontendRedirectAfterLogin;
-    }
 
     private Filter csrfHeaderFilter() {
         return new OncePerRequestFilter() {
@@ -199,43 +199,6 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         return repository;
     }
 
-    private class CustomLogoutHandler implements LogoutHandler {
-        @Override
-        public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
-
-            // Hackish way of accessing to this information...
-            final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
-            if (userInfo != null) {
-                userInfo.setFakeAuth(false);
-            }
-
-            if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null) {
-                return;
-            }
-
-            String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
-
-            StringBuilder query = new StringBuilder();
-            query.append("{");
-            query.append("\"token\":");
-            query.append("\"").append(idToken).append("\"");
-            query.append("}");
-
-            try {
-                int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
-                if (responseCode != 200) {
-                    LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
-                } else {
-                    LOGGER.info("Should be logged out");
-                }
-            } catch (IOException e) {
-                LOGGER.warn("Cannot notify logout to OIDC server !");
-                LOGGER.trace("Cannot notify logout", e);
-            }
-
-        }
-    }
-
     @Bean
     public AuthoritiesExtractor keycloakAuthoritiesExtractor() {
         return new KeycloakAuthoritiesExtractor();
@@ -273,33 +236,31 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
 
     public void logout() {
-        // POSTするリクエストパラメーターを作成
+        // TODO Try removing
+
         RestTemplate restTemplate = new RestTemplate();
         MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
         formParams.add("client_id", hbp().getClientId());
         formParams.add("client_secret", hbp().getClientSecret());
         formParams.add("refresh_token", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
-        // リクエストヘッダーを作成
+
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
-        // リクエストを作成
         RequestEntity<MultiValueMap<String, String>> requestEntity =
                 new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
-                        URI.create(logoutUri));
-        // POSTリクエスト送信(ログアウト実行)
-
-        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
+                        URI.create(logoutUrl));
+        restTemplate.exchange(requestEntity, String.class);
     }
 
     @Value("#{'${services.keycloak.keycloakUrl}'}")
     private String keycloakUrl;
 
-    // static {
-    // disableCertificateValidation();
-    // }
-
     public void disableCertificateValidation() {
+
+        //TODO Refactor logging
+
         LOGGER.info("disabling certificate validation host : " + keycloakUrl);
+
         // Create a trust manager that does not validate certificate chains
         TrustManager[] trustAllCerts = new TrustManager[]{
                 new X509TrustManager() {
@@ -316,18 +277,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
 
         // Ignore differences between given hostname and certificate hostname
-        HostnameVerifier hv = new HostnameVerifier() {
-            public boolean verify(String hostname, SSLSession session) {
-
-                // System.out.println("Warning: URL Host: " + hostname + " vs. "
-                // + session.getPeerHost());
-                if (hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl)) {
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        };
+        HostnameVerifier hv =
+                (hostname, session) -> hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl);
 
         // Install the all-trusting trust manager
         try {
@@ -336,6 +287,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
             HttpsURLConnection.setDefaultHostnameVerifier(hv);
         } catch (Exception e) {
+            // TODO add log message
         }
 
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index ff8d70a80..e179b3172 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -55,7 +55,7 @@ public class SecurityApi {
             //LOGGER.trace("Cannot read user json", e);
         }
 
-        if (!securityConfiguration.isAuthentication()) {
+        if (!securityConfiguration.getAuthenticationEnabled()) {
             if (userInfo.isFakeAuth()) {
                 response.setStatus(401);
             }
@@ -85,7 +85,7 @@ public class SecurityApi {
     @ConditionalOnExpression("${hbp.authentication.enabled:0}")
     public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
         userInfo.setFakeAuth(true);
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unathorized login.");
+        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
 
         httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
     }
@@ -104,7 +104,6 @@ public class SecurityApi {
      *
      * @return Return a @{@link ResponseEntity} with the token.
      */
-
     @RequestMapping(path = "/galaxy", method = RequestMethod.GET, produces = "application/json")
     @PreAuthorize("hasRole('Data Manager')")
     @ResponseStatus(value = HttpStatus.OK)
-- 
GitLab


From 83b90cd6bdf9bfbffba8e1bb678128404da01291 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 10 Nov 2020 16:33:18 +0200
Subject: [PATCH 11/52] pom.xml cleanup.

---
 pom.xml | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/pom.xml b/pom.xml
index 02129ae2b..817f39ab6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,39 +63,44 @@
     </repositories>
 
     <dependencies>
-        <dependency>
-            <groupId>net.logstash.logback</groupId>
-            <artifactId>logstash-logback-encoder</artifactId>
-            <version>6.4</version>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security.oauth.boot</groupId>
-            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
-            <version>2.0.1.RELEASE</version>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security.oauth.boot</groupId>
+            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
+            <version>2.0.1.RELEASE</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-oauth2-resource-server</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
+            <groupId>org.springframework.security.oauth</groupId>
+            <artifactId>spring-security-oauth2</artifactId>
+            <version>2.5.0.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <version>6.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
@@ -243,11 +248,6 @@
             <artifactId>java-jwt</artifactId>
             <version>3.11.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.security.oauth</groupId>
-            <artifactId>spring-security-oauth2</artifactId>
-            <version>2.5.0.RELEASE</version>
-        </dependency>
     </dependencies>
 
     <build>
-- 
GitLab


From fb4611e74a0ddff34fc674d62e1983a9e6951d83 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Tue, 10 Nov 2020 08:54:12 -0800
Subject: [PATCH 12/52] Implemented exteption/error handling and added java
 docs on service layer.

---
 .../eu/hbp/mip/controllers/ExperimentApi.java |  32 +-
 .../hbp/mip/controllers/PathologiesApi.java   |   3 +-
 .../eu/hbp/mip/model/DAOs/ExperimentDAO.java  |   2 +-
 .../eu/hbp/mip/model/DTOs/ExperimentDTO.java  |   7 +-
 .../hbp/mip/services/ExperimentService.java   | 385 +++++++++++++-----
 .../services/ExperimentSpecifications.java    |   7 +-
 .../mip/utils/ControllerExceptionHandler.java |  62 ++-
 .../utils/Exceptions/BadRequestException.java |   8 +
 .../ExperimentNotFoundException.java          |   8 +
 .../utils/Exceptions/InternalServerError.java |   8 +
 .../hbp/mip/utils/Exceptions/NoContent.java   |   8 +
 .../Exceptions/UnauthorizedException.java     |   8 +
 .../mip/utils/ResourceNotFoundException.java  |  10 -
 ...ure.sql => V7_0__NewDatabaseStructure.sql} |   0
 14 files changed, 423 insertions(+), 125 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
 delete mode 100644 src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
 rename src/main/resources/db/migration/{V7_0__NewExperimentStructure.sql => V7_0__NewDatabaseStructure.sql} (100%)

diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index 7cb949a4b..322f33f4f 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -3,14 +3,18 @@ package eu.hbp.mip.controllers;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.services.ExperimentService;
+import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Map;
+
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 /*
@@ -39,32 +43,50 @@ public class ExperimentApi {
             @RequestParam(defaultValue = "0") int page,
             @RequestParam(defaultValue = "3") int size
     ) {
-        return experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
+        Map experiments = experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
+        return new ResponseEntity(experiments, HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
     public ResponseEntity<String> getExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
+       ExperimentDTO experimentDTO = experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Create an experiment", response = ExperimentDTO.class)
     @RequestMapping(method = RequestMethod.POST)
     public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        return experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
+        experimentDTO =  experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
     }
 
+
+    @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
+    @RequestMapping(value = "/{transient}",method = RequestMethod.POST)
+    public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+            experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
+
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+
     @ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
     public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO,@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
+        experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Delete an experiment", response = boolean.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
     public ResponseEntity<String> deleteExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
+        experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
+        return new ResponseEntity<>(HttpStatus.OK);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 9560cc6dd..4ec7c8e36 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -10,6 +10,7 @@ import eu.hbp.mip.model.DTOs.PathologyDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
+import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import eu.hbp.mip.utils.InputStreamConverter;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
@@ -56,7 +57,7 @@ public class PathologiesApi {
             }.getType());
         } catch (IOException e) {
             Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
-            return ResponseEntity.badRequest().body("The pathologies could not be loaded.");
+            throw new BadRequestException("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
index 30d6c87da..2ee8e0ba4 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
@@ -120,7 +120,7 @@ public class ExperimentDAO {
         experimentDTO.setName(this.name);
         experimentDTO.setResult(JsonConverters.convertJsonStringToObject(this.result, ExperimentDTO.ResultDTO.class));
         experimentDTO.setShared(this.shared);
-        experimentDTO.setUuid(this.uuid.toString());
+        experimentDTO.setUuid(this.uuid);
         experimentDTO.setViewed(this.viewed);
         return experimentDTO;
     }
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
index e4b9d34a5..64ade455b 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
@@ -4,10 +4,11 @@ import eu.hbp.mip.model.DAOs.ExperimentDAO;
 
 import java.util.Date;
 import java.util.List;
+import java.util.UUID;
 
 public class ExperimentDTO {
 
-    private String uuid;
+    private UUID uuid;
     private String name;
     private String createdBy;
     private Date created;
@@ -39,11 +40,11 @@ public class ExperimentDTO {
         this.algorithm = algorithmDetails.getName();
     }
 
-    public String getUuid() {
+    public UUID getUuid() {
         return uuid;
     }
 
-    public void setUuid(String uuid) {
+    public void setUuid(UUID uuid) {
         this.uuid = uuid;
     }
 
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index a02af3ab6..2590e1edd 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -6,7 +6,10 @@ import com.github.jmchilton.blend4j.galaxy.WorkflowsClient;
 import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
-import com.google.gson.*;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
@@ -14,11 +17,14 @@ import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.model.galaxy.ErrorResponse;
 import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
 import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
-import eu.hbp.mip.utils.*;
+import eu.hbp.mip.utils.ClaimUtils;
+import eu.hbp.mip.utils.Exceptions.*;
+import eu.hbp.mip.utils.HTTPUtil;
+import eu.hbp.mip.utils.JsonConverters;
+import eu.hbp.mip.utils.Logging;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,8 +33,6 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Service;
 import retrofit2.Call;
@@ -63,11 +67,24 @@ public class ExperimentService {
 
     private static final Gson gson = new Gson();
 
-    public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
+    /**
+     * The getExperiments will retrieve the experiments from database according to the filters.
+     *
+     * @param name is optional, in case it is required to filter the experiments by name
+     * @param algorithm is optional, in case it is required to filter the experiments by algorithm name
+     * @param shared is optional, in case it is required to filter the experiments by shared
+     * @param viewed is optional, in case it is required to filter the experiments by viewed
+     * @param page is the page that is required to be retrieve
+     * @param size is the size of each page
+     * @param endpoint is the endpoint that called the function
+     * @return a list of mapped experiments
+     */
+    public Map getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
         if(size > 10 )
-            return ResponseEntity.badRequest().body("Invalid size input, max size is 10.");
+            throw new BadRequestException("Invalid size input, max size is 10.");
+
 
         Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
                 .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
@@ -79,7 +96,7 @@ public class ExperimentService {
         List<ExperimentDAO> experimentDAOs = pageExperiments.getContent();
 
         if (experimentDAOs.isEmpty())
-            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+            throw new NoContent("No experiment found with the filters provided.");
 
         List<ExperimentDTO> experimentDTOs = new ArrayList<>();
         experimentDAOs.forEach(experimentDAO -> experimentDTOs.add(experimentDAO.convertToDTO()));
@@ -90,55 +107,64 @@ public class ExperimentService {
         response.put("totalExperiments", pageExperiments.getTotalElements());
         response.put("totalPages", pageExperiments.getTotalPages());
 
-        return new ResponseEntity(response, HttpStatus.OK);
+        return response;
     }
 
-    public ResponseEntity<String> getExperiment(String uuid, String endpoint) {
+    /**
+     * The getExperiment will retrieve the experiment from database according to the input uuid
+     *
+     * @param uuid is the id of the experiment to be retrieved
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information that was retrieved from the database
+     */
+    public ExperimentDTO getExperiment(String uuid, String endpoint) {
 
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
-        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ResourceNotFoundException("Not found Experimnet with id = " + uuid));
-
-        if (experimentDAO == null) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Experiment Not found.");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())) {
             Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
-            return new ResponseEntity<>("You don't have access to the experiment.", HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
         }
         ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
         Logging.LogUserAction(user.getUsername(), endpoint, "Experiment was Loaded with uuid : " + uuid + ".");
 
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return experimentDTO;
     }
 
-    public ResponseEntity<String> createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
+    /**
+     * The createExperiment will create and save an experiment in the database.
+     *
+     * @param authentication is the role of the user
+     * @param experimentDTO is the experiment information
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information which was created
+     */
+    public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
 
         //Checking if check (POST) /experiments has proper input.
         if (checkPostExperimentProperInput(experimentDTO)){
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Invalid input.");
-            return ResponseEntity.badRequest().body("Please provide proper input.");
+            throw new BadRequestException("Please provide proper input.");
         }
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithmDetails().getType();
         String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
         StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithmDetails().getParameters()) {
-            parametersLogMessage
-                    .append("  ")
-                    .append(params.getLabel())
-                    .append(" -> ")
-                    .append(params.getValue())
-                    .append("\n");
-        }
+        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+            params -> parametersLogMessage
+                .append("  ")
+                .append(params.getLabel())
+                .append(" -> ")
+                .append(params.getValue())
+                .append("\n") );
         Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
 
         if (authenticationIsEnabled) {
@@ -154,12 +180,12 @@ public class ExperimentService {
             if (experimentDatasets == null || experimentDatasets.equals("")) {
                 Logging.LogUserAction(user.getUsername(), endpoint,
                         "A dataset should be specified to run an algorithm.");
-                return ResponseEntity.badRequest().body("Please provide at least one dataset to run the algorithm.");
+                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
             }
 
             // --- Validating proper access rights on the datasets  ---
             if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
-                return ResponseEntity.badRequest().body("You are not authorized to use these datasets.");
+                throw new BadRequestException("You are not authorized to use these datasets.");
             }
         }
 
@@ -173,7 +199,93 @@ public class ExperimentService {
         }
     }
 
-    public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
+    /**
+     * The createTransientExperiment will run synchronous a transient experiment into exareme and provide results
+     *
+     * @param authentication is the role of the user
+     * @param experimentDTO is the experiment information
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information which was created
+     */
+    public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint){
+        UserDAO user = userInfo.getUser();
+
+        //Checking if check (POST) /experiments has proper input.
+        if (checkPostExperimentProperInput(experimentDTO)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Invalid input.");
+            throw new BadRequestException("Please provide proper input.");
+        }
+
+        // Get the parameters
+        List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
+                = experimentDTO.getAlgorithmDetails().getParameters();
+
+        // Get the type and name of algorithm
+        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
+
+        if (!loadProperAlgorithms().contains(algorithmName)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Not proper algorithm.");
+            throw new BadRequestException("Please provide proper algorithm.");
+        }
+
+        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
+        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+            params -> parametersLogMessage
+                .append("  ")
+                .append(params.getLabel())
+                .append(" -> ")
+                .append(params.getValue())
+                .append("\n") );
+        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+
+        if (authenticationIsEnabled) {
+            // Getting the dataset from the experiment parameters
+            String experimentDatasets = null;
+            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
+                if (parameter.getLabel().equals("dataset")) {
+                    experimentDatasets = parameter.getValue();
+                    break;
+                }
+            }
+
+            if (experimentDatasets == null || experimentDatasets.equals("")) {
+                Logging.LogUserAction(user.getUsername(), endpoint,
+                        "A dataset should be specified to run an algorithm.");
+                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
+            }
+
+            // --- Validating proper access rights on the datasets  ---
+            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
+                throw new BadRequestException("You are not authorized to use these datasets.");
+            }
+        }
+
+        String body = gson.toJson(algorithmParameters);
+        String url = queryExaremeUrl + "/" + algorithmName;
+        Logging.LogUserAction(user.getUsername(), endpoint, "url: " + url + ", body: " + body);
+
+        Logging.LogUserAction(user.getUsername(), endpoint,
+                "Completed, returning: " + experimentDTO.toString());
+
+        // Results are stored in the experiment object
+        ExaremeResult exaremeResult = runExaremeExperiment(url, body, experimentDTO);
+        experimentDTO.setResult(exaremeResult.result);
+        experimentDTO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
+
+        return experimentDTO;
+    }
+
+    /**
+     * The updateExperiment will update the experiment's properties
+     *
+     * @param uuid is the id of the experiment to be updated
+     * @param experimentDTO is the experiment information to be updated
+     * @param endpoint is the endpoint that called the function
+     * @return the updated experiment information
+     */
+    public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
     {
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
@@ -182,7 +294,7 @@ public class ExperimentService {
         if (checkPutExperimentProperInput(experimentDTO)){
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Invalid input.");
-            return ResponseEntity.badRequest().body("Please provide proper input.");
+            throw new BadRequestException("Please provide proper input.");
         }
 
         if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0)
@@ -190,13 +302,13 @@ public class ExperimentService {
                 && experimentDTO.getViewed() == null
                 && experimentDTO.getAlgorithmDetails() == null)
         {
-            return ResponseEntity.badRequest().body("Input is required.");
+            throw new BadRequestException("Input is required.");
         }
 
-        experimentDAO = loadExperiment(uuid).get();
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
-            return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
 
         if(experimentDTO.getName() != null && experimentDTO.getName().length() != 0)
         {
@@ -213,29 +325,39 @@ public class ExperimentService {
             experimentDAO.setViewed(experimentDTO.getViewed());
         }
 
-        experimentRepository.save(experimentDAO);
-
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
         Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + experimentDTO.getUuid() + ".");
 
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return experimentDTO;
     }
 
-    public ResponseEntity<String> deleteExperiment(String uuid, String endpoint)
+    /**
+     * The deleteExperiment will delete an experiment from the database
+     *
+     * @param uuid is the id of the experiment to be deleted
+     * @param endpoint is the endpoint that called the function
+     */
+    public void deleteExperiment(String uuid, String endpoint)
     {
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid).get();
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
-            return new ResponseEntity<>(endpoint, HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
 
         experimentRepository.delete(experimentDAO);
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
@@ -250,6 +372,14 @@ public class ExperimentService {
                 || experimentDTO.getUuid() != null;
     }
 
+    private List<String> loadProperAlgorithms()
+    {
+        List<String> properAlgorithms = new ArrayList<>();
+        properAlgorithms.add("histograms");
+        properAlgorithms.add("descriptive_stats");
+        return properAlgorithms;
+    }
+
     private boolean checkPutExperimentProperInput(ExperimentDTO experimentDTO)
     {
         return experimentDTO.getUuid() != null
@@ -258,21 +388,29 @@ public class ExperimentService {
                 || experimentDTO.getStatus() != null;
     }
 
+    /**
+     * The loadExperiment access the database and load the information of a specific experiment
+     *
+     * @param uuid is the id of the experiment to be retrieved
+     * @return the experiment information that was retrieved from database
+     */
     private Optional<ExperimentDAO> loadExperiment(String uuid){
 
 
         UUID experimentUuid ;
 
-        try {
-            experimentUuid = UUID.fromString(uuid);
-        } catch (IllegalArgumentException iae) {
-            return null;
-        }
+        experimentUuid = Optional.of(UUID.fromString(uuid)).orElseThrow(() -> new IllegalArgumentException("Invalid input uuid:"+ uuid));
 
         return experimentRepository.findByUuid(experimentUuid);
     }
 
-    private ExperimentDAO createExperiment(ExperimentDTO experimentDTO, String endpoint) {
+    /**
+     * The createExperimentInTheDatabase will insert a new experiment in the database according to the given experiment information
+     *
+     * @param experimentDTO is the experiment information to inserted in the database
+     * @return the experiment information that was inserted into the database
+     */
+    private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
@@ -281,7 +419,14 @@ public class ExperimentService {
         experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()));
         experimentDAO.setAlgorithm(experimentDTO.getAlgorithm());
         experimentDAO.setName(experimentDTO.getName());
-        experimentRepository.save(experimentDAO);
+        experimentDAO.setStatus(ExperimentDAO.Status.pending);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
 
         Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
         Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
@@ -298,29 +443,43 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId());
         Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus());
 
-        experimentRepository.save(experimentDAO);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Saved experiment");
     }
 
-    private void finishExperiment(ExperimentDAO experimentDAO) {
+    private void finishExperiment(ExperimentDAO experimentDAO, String endpoint) {
         experimentDAO.setFinished(new Date());
-        experimentRepository.save(experimentDAO);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
     }
 
     /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
 
     /**
-     * The runExaremeExperiment will POST the algorithm to the exareme client
+     * The createExaremeExperiment will POST the algorithm to the exareme client
      *
      * @param experimentDTO is the request with the experiment information
-     * @return the response to be returned
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information that was retrieved from exareme
      */
-    public ResponseEntity<String> createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
+
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
 
-        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
         // Run the 1st algorithm from the list
@@ -339,41 +498,57 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint,
                 "Starting exareme execution thread");
+        ExperimentDTO finalExperimentDTO = experimentDTO;
         new Thread(() -> {
 
             // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
             try {
-
-                // --> New function runExaremeAlgorithm
-                StringBuilder results = new StringBuilder();
-                int code = HTTPUtil.sendPost(url, body, results);
-
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Algorithm finished with code: " + code);
-
                 // Results are stored in the experiment object
-                ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
+                ExaremeResult exaremeResult = runExaremeExperiment(url, body, finalExperimentDTO);
 
-                // <-- New function runExaremeAlgorithm
-
-                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(resultDTO));
-//                experimentDAO.setHasError(code >= 400);
-//                experimentDAO.setHasServerError(code >= 500);
+                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(exaremeResult.result));
+                experimentDAO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
             } catch (Exception e) {
                 Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
 
                 experimentDAO.setStatus(ExperimentDAO.Status.error);
-                experimentDAO.setResult(e.getMessage());
             }
 
-            finishExperiment(experimentDAO);
+            finishExperiment(experimentDAO, endpoint);
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
         }).start();
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
+        return experimentDTO;
     }
 
+    /**
+     * The runExaremeExperiment will run to exareme the experiment
+     *
+     * @param url is the url that contain the results of the experiment
+     * @param body is the parameters of the algorithm
+     * @param experimentDTO is the experiment information to be executed in the exareme
+     * @return the result of exareme as well as the http status that was retrieved
+     */
+    public ExaremeResult runExaremeExperiment(String url,String body, ExperimentDTO experimentDTO) {
+
+        StringBuilder results = new StringBuilder();
+        int code;
+        try {
+            code = HTTPUtil.sendPost(url, body, results);
+        }
+        catch (Exception e){
+            throw new InternalServerError("Error occured : "+ e.getMessage());
+        }
+        Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
+
+        // Results are stored in the experiment object
+        ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
+        return new ExaremeResult(code, resultDTO);
+    }
+
+
     /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
 
 
@@ -383,11 +558,11 @@ public class ExperimentService {
      * @param experimentDTO is the request with the experiment information
      * @return the response to be returned
      */
-    public ResponseEntity<String> runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
 
-        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
 
@@ -419,8 +594,7 @@ public class ExperimentService {
         if (workflow == null) {
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Could not find algorithm code: " + workflowId);
-            return ResponseEntity.badRequest()
-                    .body(new ErrorResponse("Could not find galaxy algorithm.").toString());
+            throw new BadRequestException("Could not find galaxy algorithm.");
         }
         final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId());
         for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) {
@@ -449,8 +623,7 @@ public class ExperimentService {
 
                 String historyId = (String) new JSONObject(responseBody).get("history_id");
                 experimentDAO.setWorkflowHistoryId(historyId);
-                experimentDAO.setStatus(ExperimentDAO.Status.pending);
-//                experimentDAO.setHasServerError(response.code() >= 500);
+                experimentDAO.setStatus(ExperimentDAO.Status.success);
 
             } else {     // Something unexpected happened
                 String msgErr = gson.toJson(response.errorBody());
@@ -460,15 +633,12 @@ public class ExperimentService {
                 JSONObject jObjectError = new JSONObject(msgErr);
                 String errMsg = jObjectError.get("err_msg").toString();
 
-                experimentDAO.setResult(errMsg);
-//                experimentDAO.setHasError(response.code() >= 400);
-//                experimentDAO.setHasServerError(response.code() >= 500);
+                experimentDTO.setStatus((response.code()>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
             }
 
         } catch (Exception e) {
             Logging.LogUserAction(user.getUsername(), endpoint, "An exception occurred: " + e.getMessage());
             experimentDAO.setStatus(ExperimentDAO.Status.error);
-            experimentDAO.setResult(e.getMessage());
         }
         saveExperiment(experimentDAO, endpoint);
 
@@ -478,7 +648,7 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
 
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
+        return experimentDTO;
     }
 
 
@@ -543,19 +713,20 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
-                                experimentDAO.setResult("[" + result + "]");
-                                experimentDAO.setStatus(ExperimentDAO.Status.success);
-                                resultFound = true;
+                                else {
+                                    experimentDAO.setResult("[" + result + "]");
+                                    experimentDAO.setStatus(ExperimentDAO.Status.success);
+                                    resultFound = true;
+                                }
                             }
                         }
 
                         if (!resultFound) {      // If there is no visible result
                             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
-                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no visible result.").toString() + "]");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
 
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
 
                     case "error":
@@ -574,7 +745,6 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
-                                experimentDAO.setResult("[" + result + "]");
                                 experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 failedJobFound = true;
                             }
@@ -582,16 +752,15 @@ public class ExperimentService {
 
                         if (!failedJobFound) {      // If there is no visible failed job
                             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
-                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no failed result.").toString() + "]");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
 
                     default:        // InternalError or unexpected result
-                        experimentDAO.setResult("[" + new ErrorResponse("An unexpected error occurred.").toString() + "]");
+                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
                         experimentDAO.setStatus(ExperimentDAO.Status.error);
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
                 }
 
@@ -624,7 +793,7 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> call = service.getWorkflowStatusFromGalaxy(historyId, galaxyApiKey);
 
-        String result = null;
+        String result;
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
@@ -640,7 +809,7 @@ public class ExperimentService {
             return "internalError";
         }
 
-        String state = null;
+        String state;
         try {
             JSONObject resultJson = new JSONObject(result);
             state = resultJson.getString("state");
@@ -679,7 +848,7 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
 
-        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList = null;
+        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList;
         try {
             Response<List<GalaxyWorkflowResult>> response = call.execute();
             if (response.code() >= 400) {
@@ -717,7 +886,7 @@ public class ExperimentService {
         Call<Object> call =
                 service.getWorkflowResultsBodyFromGalaxy(historyId, contentId, galaxyApiKey);
 
-        String resultJson = null;
+        String resultJson ;
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
@@ -751,8 +920,8 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
 
-        String fullError = null;
-        String returnError = null;
+        String fullError;
+        String returnError;
         try {
             Response<Object> response = callError.execute();
             if (response.code() >= 400) {
@@ -782,4 +951,22 @@ public class ExperimentService {
 
         return returnError;
     }
+
+    final class ExaremeResult {
+        private final int code;
+        private final ExperimentDTO.ResultDTO result;
+
+        public ExaremeResult(int code, ExperimentDTO.ResultDTO result) {
+            this.code = code;
+            this.result = result;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public ExperimentDTO.ResultDTO getResult() {
+            return result;
+        }
+    }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index 6596a319a..076249e0b 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -16,7 +16,7 @@ public class ExperimentSpecifications {
 
         public  ExperimentWithName(String name){
             this.name = name;
-            this.regExp = "%"+name+"%";
+            this.regExp = name;
         }
 
         public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb)
@@ -24,8 +24,11 @@ public class ExperimentSpecifications {
             if (name == null) {
                 return cb.isTrue(cb.literal(true));
             }
+            else {
+                regExp = (name.contains("%")?name:name+"%");
+            }
 
-            return cb.like( root.get( "name" ), regExp );
+            return cb.like( root.get( "name" ), this.regExp );
         }
     }
     public static class ExperimentWithAlgorithm implements Specification<ExperimentDAO> {
diff --git a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
index 4e6f8da32..7f644fb7f 100644
--- a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
+++ b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
@@ -1,26 +1,80 @@
 package eu.hbp.mip.utils;
 
+import eu.hbp.mip.utils.Exceptions.*;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
 
 import java.util.Date;
 
 @ControllerAdvice
-public class ControllerExceptionHandler {
+public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
+
+    @ExceptionHandler(ExperimentNotFoundException.class)
+    public ResponseEntity<Object> handleExperimentNotFoundException(ExperimentNotFoundException ex, WebRequest request) {
 
-    @ExceptionHandler(ResourceNotFoundException.class)
-    public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
         ErrorMessage message = new ErrorMessage(
-                2,
+                HttpStatus.NOT_FOUND.value(),
                 new Date(),
                 ex.getMessage(),
                 request.getDescription(false));
 
         return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);
     }
+    
+    @ExceptionHandler(BadRequestException.class)
+    public ResponseEntity<Object> handleBadRequestException(BadRequestException ex, WebRequest request) {
+
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.BAD_REQUEST.value(),
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(UnauthorizedException.class)
+    public ResponseEntity<Object> handleUnauthorizedException(UnauthorizedException ex, WebRequest request) {
+
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.UNAUTHORIZED.value(),
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.UNAUTHORIZED);
+    }
+
+    @ExceptionHandler(IllegalArgumentException.class)
+    public Object handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
+        return null;
+    }
+
+    @ExceptionHandler(InternalServerError.class)
+    public ResponseEntity<ErrorMessage> handleInternalServerError(InternalServerError er, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.INTERNAL_SERVER_ERROR.value(),
+                new Date(),
+                er.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+
+    @ExceptionHandler(NoContent.class)
+    public ResponseEntity<ErrorMessage> handleNoContent(NoContent nc, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.NO_CONTENT.value(),
+                new Date(),
+                nc.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.NO_CONTENT);
+    }
 
     @ExceptionHandler(Exception.class)
     public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
new file mode 100644
index 000000000..6684cae28
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class BadRequestException extends RuntimeException {
+
+    public BadRequestException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
new file mode 100644
index 000000000..b8e05d7e6
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class ExperimentNotFoundException extends RuntimeException {
+
+    public ExperimentNotFoundException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java b/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
new file mode 100644
index 000000000..19bc88eed
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class InternalServerError extends RuntimeException {
+
+    public InternalServerError(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java b/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
new file mode 100644
index 000000000..9bb67d811
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class NoContent extends RuntimeException {
+
+    public NoContent(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
new file mode 100644
index 000000000..379911dae
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class UnauthorizedException extends RuntimeException {
+
+    public UnauthorizedException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java b/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
deleted file mode 100644
index 38f067c42..000000000
--- a/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package eu.hbp.mip.utils;
-
-public class ResourceNotFoundException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    public ResourceNotFoundException(String msg) {
-        super(msg);
-    }
-}
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
similarity index 100%
rename from src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
rename to src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
-- 
GitLab


From 12f91d4474bf14de071f517d6c4ba6779a56468f Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 10 Nov 2020 20:44:45 +0200
Subject: [PATCH 13/52] Added spring debug level.

---
 docker/config/application.tmpl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 190f04f90..324b73432 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -41,6 +41,7 @@ frontend:
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
+    org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
     eu:
       hbp: {{ default .Env.LOG_LEVEL "INFO" }}
 
-- 
GitLab


From 61d3ef9094ebcebca75cccf8de789c9b563e6331 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Wed, 11 Nov 2020 05:19:52 -0800
Subject: [PATCH 14/52] Fixing 404 message on login as well as on swagger.

---
 docker/config/application.tmpl                               | 3 ++-
 pom.xml                                                      | 4 ++++
 src/main/java/eu/hbp/mip/configuration/WebConfiguration.java | 2 --
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 190f04f90..9496499da 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -46,7 +46,8 @@ logging:
 
 # EMBEDDED SERVER CONFIGURATION
 server:
-  contextPath: {{ default .Env.CONTEXT_PATH "/services" }}
+  servlet:
+    contextPath: {{ default .Env.CONTEXT_PATH "/services" }}
   port: 8080
   use-forward-headers: true
   session:
diff --git a/pom.xml b/pom.xml
index 817f39ab6..e08146ef2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
+        <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-rest</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
index 17e38a5ee..72bcad789 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
@@ -2,7 +2,6 @@ package eu.hbp.mip.configuration;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.data.web.config.EnableSpringDataWebSupport;
 import springfox.documentation.builders.ApiInfoBuilder;
 import springfox.documentation.builders.RequestHandlerSelectors;
 import springfox.documentation.service.ApiInfo;
@@ -17,7 +16,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 @Configuration
 @EnableSwagger2
-@EnableSpringDataWebSupport
 public class WebConfiguration {
 
 //    @Bean
-- 
GitLab


From 2c515aaf748c79de34276975dc799d27a4ce15ee Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 6 Nov 2020 12:53:30 +0200
Subject: [PATCH 15/52] Configuring keycloak security.

---
 Dockerfile                                    |   7 +-
 docker/README.md                              |   4 +-
 docker/config/application.tmpl                |  46 +--
 pom.xml                                       |  51 ++-
 .../configuration/SecurityConfiguration.java  | 365 ++++++++----------
 .../eu/hbp/mip/controllers/SecurityApi.java   |   7 +-
 .../java/eu/hbp/mip/model/DAOs/UserDAO.java   |  48 ++-
 src/main/java/eu/hbp/mip/model/UserInfo.java  |  20 +-
 8 files changed, 242 insertions(+), 306 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 458fbc8a3..866c01bf4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -43,17 +43,16 @@ WORKDIR /home/portal
 ENTRYPOINT ["/run.sh"]
 
 # 8080: Web service API, health checks on http://host:8080$CONTEXT_PATH/health
-# 4089: Akka cluster
-EXPOSE 4089 8080
+EXPOSE 8080
 
 HEALTHCHECK --start-period=60s CMD curl -v --silent http://localhost:8080$CONTEXT_PATH/health 2>&1 | grep UP
 
 LABEL org.label-schema.build-date=$BUILD_DATE \
       org.label-schema.name="hbpmip/portal-backend" \
-      org.label-schema.description="Java backend for the MIP portal" \
+      org.label-schema.description="Spring backend for the MIP portal" \
       org.label-schema.url="https://mip.humanbrainproject.eu" \
       org.label-schema.vcs-type="git" \
-      org.label-schema.vcs-url="https://github.com/LREN-CHUV/portal-backend" \
+      org.label-schema.vcs-url="https://github.com/HBPMedical/portal-backend" \
       org.label-schema.vcs-ref=$VCS_REF \
       org.label-schema.version="$VERSION" \
       org.label-schema.vendor="LREN CHUV" \
diff --git a/docker/README.md b/docker/README.md
index 3f3437aec..cc8c59fe1 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -72,4 +72,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 
 * RELEASE_STAGE: Release stage used when reporting errors to Bugsnag. Values are dev, staging, production
 * DATA_CENTER_LOCATION: Location of the datacenter, used when reporting errors to Bugsnag
-* CONTAINER_ORCHESTRATION: Container orchestration system used to execute the Docker containers. Values are mesos, docker-compose, kubernetes
+
+
+# TODO Refactor variables
\ No newline at end of file
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 4e723b8a3..84ef19c5e 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -18,38 +18,12 @@ spring:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
 
-  # SPRING RESOURCES HANDLING
-  resources:
-    chain:
-      enabled: true # TODO: why is that enabled? Do we serve any resources from the backend?
-
-# HBP OAUTH2 LOGIN
-hbp:
-  authentication:
-    enabled: {{ default .Env.AUTHENTICATION "1" }}
-  client:
-    clientId: {{ default .Env.CLIENT_ID "996f97c5-a3ca-460e-b18b-00df3e2be89a" }}
-    clientSecret: {{ .Env.CLIENT_SECRET }}
-    accessTokenUri: {{ default .Env.TOKEN_URI "https://services.humanbrainproject.eu/oidc/token" }}
-    userAuthorizationUri: {{ default .Env.AUTH_URI "https://services.humanbrainproject.eu/oidc/authorize" }}
-    logoutUri: {{ .Env.LOGOUT_URI }}
-    tokenName: access_token
-    authenticationScheme: query
-    clientAuthenticationScheme: form
-    useCurrentUri: false
-    preEstablishedRedirectUri: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
-  resource:
-    userInfoUri: {{ default .Env.USER_INFO_URI "https://services.humanbrainproject.eu/oidc/userinfo" }}
-    revokeTokenUri: {{ default .Env.REVOKE_TOKEN_URI "https://services.humanbrainproject.eu/oidc/slo" }}
-  sso:
-    login-path:
-
 # WEB FRONTEND
 frontend:
   loginUrl: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
+  redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/" }}
   redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL (default .Env.LOGIN_URI "http://frontend/services/login/hbp") }}
-  redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/home" }}
-  
+
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
@@ -72,6 +46,7 @@ endpoints:
     endpoint: /health
     sensitive: false
 
+# External Services
 services:
   exareme:
     queryExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query
@@ -84,5 +59,16 @@ services:
     galaxyUsername:  {{ default .Env.GALAXY_USERNAME "admin" }}
     galaxyPassword:  {{ default .Env.GALAXY_PASSWORD "password" }}
 
-  keycloak:
-    keycloakUrl: {{ .Env.KEYCLOAK_URL }}
+# HBP Authentication
+hbp:
+  authentication:
+    enabled: {{ default .Env.AUTHENTICATION "1" }}
+
+# Keycloak
+keycloak:
+    auth-server-url: {{ .Env.KEYCLOAK_URL }}
+    realm: {{ .Env.KEYCLOAK_REALM }}
+    resource: {{ .Env.CLIENT_ID }}
+    credentials:
+        secret: {{ .Env.CLIENT_SECRET }}
+   # logoutUrl: {{ .Env.LOGOUT_URL }}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 02129ae2b..a856ee073 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,11 +18,9 @@
     </parent>
 
     <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <sonar.host.url>https://hbps1.chuv.ch/sonarqube/</sonar.host.url>
-        <sonar.projectName>MIP portal-backend</sonar.projectName>
-        <sonar.sources>src/main/java/</sonar.sources>
         <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <keycloak-spring-boot-starter.version>11.0.2</keycloak-spring-boot-starter.version>
         <springfox-swagger.version>2.5.0</springfox-swagger.version>
         <spring-context.version>5.2.10.RELEASE</spring-context.version>
         <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
@@ -63,40 +61,46 @@
     </repositories>
 
     <dependencies>
-        <dependency>
-            <groupId>net.logstash.logback</groupId>
-            <artifactId>logstash-logback-encoder</artifactId>
-            <version>6.4</version>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security.oauth.boot</groupId>
-            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
-            <version>2.0.1.RELEASE</version>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
+            <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-oauth2-resource-server</artifactId>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-spring-boot-starter</artifactId>
+            <version>${keycloak-spring-boot-starter.version}</version>
         </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.security</groupId>-->
+<!--            <artifactId>spring-security-oauth2-resource-server</artifactId>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.security.oauth.boot</groupId>-->
+<!--            <artifactId>spring-security-oauth2-autoconfigure</artifactId>-->
+<!--            <version>2.0.1.RELEASE</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.security.oauth</groupId>-->
+<!--            <artifactId>spring-security-oauth2</artifactId>-->
+<!--            <version>2.5.0.RELEASE</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-orm</artifactId>
@@ -243,11 +247,6 @@
             <artifactId>java-jwt</artifactId>
             <version>3.11.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.security.oauth</groupId>
-            <artifactId>spring-security-oauth2</artifactId>
-            <version>2.5.0.RELEASE</version>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index afd3e56ed..68a1ca4a1 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -1,42 +1,30 @@
 package eu.hbp.mip.configuration;
 
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.utils.*;
+import eu.hbp.mip.utils.CORSFilter;
+import eu.hbp.mip.utils.CustomAccessDeniedHandler;
+import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint;
+import org.keycloak.adapters.KeycloakConfigResolver;
+import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
+import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
+import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
+import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
-import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
-import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.*;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.oauth2.client.OAuth2ClientContext;
-import org.springframework.security.oauth2.client.OAuth2RestTemplate;
-import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
-import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
-import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
-import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
+import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
+import org.springframework.security.core.session.SessionRegistryImpl;
 import org.springframework.security.web.access.channel.ChannelProcessingFilter;
-import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
-import org.springframework.security.web.authentication.logout.LogoutHandler;
-import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
+import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
+import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
 import org.springframework.security.web.csrf.CsrfFilter;
 import org.springframework.security.web.csrf.CsrfToken;
 import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
 
@@ -48,130 +36,133 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.net.URI;
 import java.security.SecureRandom;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
 
 
-// See https://spring.io/guides/tutorials/spring-boot-oauth2/ for reference about configuring OAuth2 login
+// Reference for OAuth2 login: https://spring.io/guides/tutorials/spring-boot-oauth2/
 // also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
+// Security with Keycloak: https://www.thomasvitale.com/keycloak-authentication-flow-sso-client/
 
-@Configuration
-@EnableOAuth2Client
-public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+@KeycloakConfiguration
+public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
 
-    @Autowired
-    private OAuth2ClientContext oauth2ClientContext;
-
     /**
      * Enable HBP collab authentication (1) or disable it (0). Default is 1
      */
-    @Value("#{'${hbp.authentication.enabled:1}'}")
-    private boolean authentication;
+    @Value("#{'${hbp.authentication.enabled}'}")
+    private boolean authenticationEnabled;
 
     /**
      * Absolute URL to redirect to when login is required
      */
-    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
+    @Value("#{'${frontend.loginUrl}'}")
     private String loginUrl;
 
-    /**
-     * Absolute URL to redirect to when logout is required
-     */
-    @Value("#{'${hbp.client.logoutUri}'}")
-    private String logoutUri;
-
     /**
      * Absolute URL to redirect to after successful login
      */
-    @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
+    @Value("#{'${frontend.redirectAfterLoginUrl}'}")
     private String frontendRedirectAfterLogin;
 
     /**
-     * Absolute URL to redirect to after logout has occurred
+     * Absolute URL to redirect to after successful logout
      */
-    @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
+    @Value("#{'${frontend.redirectAfterLogoutUrl}'}")
     private String redirectAfterLogoutUrl;
 
-    /**
-     * URL to revoke auth token
-     */
-    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
-    private String revokeTokenURI;
+    public boolean getAuthenticationEnabled() {
+        return authenticationEnabled;
+    }
+
+    public String getFrontendRedirectAfterLogin() {
+        return frontendRedirectAfterLogin;
+    }
+
+    @Bean
+    public KeycloakConfigResolver KeycloakConfigResolver() {
+        return new KeycloakSpringBootConfigResolver();
+    }
+
+    @Override
+    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
+        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
+    }
+
+
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) {
+        SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
+        grantedAuthorityMapper.setPrefix("ROLE_");
+        grantedAuthorityMapper.setConvertToUpperCase(true);
+
+        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
+        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
+        auth.authenticationProvider(keycloakAuthenticationProvider);
+    }
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
-        disableCertificateValidation();
+        disableCertificateValidation();  //  TODO needed?
         // @formatter:off
         http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
 
-        if (authentication) {
-            http.antMatcher("/**")
-                    .authorizeRequests()
+        if (authenticationEnabled) {
+            http.authorizeRequests()
                     .antMatchers(
-                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
-                    )
-                    .permitAll()
+                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**",
+                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
+                            "/swagger-ui.html", "/swagger-resources/**"
+                    ).permitAll()
                     .antMatchers("/galaxy*", "/galaxy/*").hasRole("Data Manager")
-                    //.anyRequest().authenticated()
                     .anyRequest().hasRole("Researcher")
                     .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
                     .accessDeniedHandler(new CustomAccessDeniedHandler())
-                    .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
+                    // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
                     .and().logout().permitAll()
                     .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
                     .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
-                    .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
+            ; // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
         } else {
             http.antMatcher("/**")
                     .authorizeRequests()
-                    .antMatchers("/**").permitAll().and().csrf().disable();
+                    .antMatchers("/**").permitAll()
+                    .and().csrf().disable();
         }
     }
 
-    private Filter ssoFilter() {
-        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
-        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
-        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
-        hbpFilter.setRestTemplate(hbpTemplate);
-        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
-        return hbpFilter;
-    }
-
-    @Bean
-    public FilterRegistrationBean oauth2ClientFilterRegistration(
-            OAuth2ClientContextFilter filter) {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setFilter(filter);
-        registration.setOrder(-100);
-        return registration;
-    }
-
-    @Bean(name = "hbp")
-    @ConfigurationProperties("hbp.client")
-    public BaseOAuth2ProtectedResourceDetails hbp() {
-        return new AuthorizationCodeResourceDetails();
-    }
+//    private Filter ssoFilter() {
+//        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
+//        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
+//        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
+//        hbpFilter.setRestTemplate(hbpTemplate);
+//        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
+//        return hbpFilter;
+//    }
+
+//    @Bean
+//    public FilterRegistrationBean oauth2ClientFilterRegistration(
+//            OAuth2ClientContextFilter filter) {
+//        FilterRegistrationBean registration = new FilterRegistrationBean();
+//        registration.setFilter(filter);
+//        registration.setOrder(-100);
+//        return registration;
+//    }
+
+//    @Bean(name = "hbp")
+//    @ConfigurationProperties("hbp.client")
+//    public BaseOAuth2ProtectedResourceDetails hbp() {
+//        return new AuthorizationCodeResourceDetails();
+//    }
+//
+//    @Bean(name = "hbpResource")
+//    @ConfigurationProperties("hbp.resource")
+//    public ResourceServerProperties hbpResource() {
+//        return new ResourceServerProperties();
+//    }
 
-    @Bean(name = "hbpResource")
-    @ConfigurationProperties("hbp.resource")
-    public ResourceServerProperties hbpResource() {
-        return new ResourceServerProperties();
-    }
-
-    public boolean isAuthentication() {
-        return authentication;
-    }
-
-    public String getFrontendRedirectAfterLogin() {
-        return frontendRedirectAfterLogin;
-    }
 
     private Filter csrfHeaderFilter() {
         return new OncePerRequestFilter() {
@@ -199,107 +190,70 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         return repository;
     }
 
-    private class CustomLogoutHandler implements LogoutHandler {
-        @Override
-        public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
 
-            // Hackish way of accessing to this information...
-            final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
-            if (userInfo != null) {
-                userInfo.setFakeAuth(false);
-            }
-
-            if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null) {
-                return;
-            }
-
-            String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
-
-            StringBuilder query = new StringBuilder();
-            query.append("{");
-            query.append("\"token\":");
-            query.append("\"").append(idToken).append("\"");
-            query.append("}");
-
-            try {
-                int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
-                if (responseCode != 200) {
-                    LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
-                } else {
-                    LOGGER.info("Should be logged out");
-                }
-            } catch (IOException e) {
-                LOGGER.warn("Cannot notify logout to OIDC server !");
-                LOGGER.trace("Cannot notify logout", e);
-            }
-
-        }
-    }
-
-    @Bean
-    public AuthoritiesExtractor keycloakAuthoritiesExtractor() {
-        return new KeycloakAuthoritiesExtractor();
-    }
-
-
-    public class KeycloakAuthoritiesExtractor
-            implements AuthoritiesExtractor {
-
-        @Override
-        public List<GrantedAuthority> extractAuthorities
-                (Map<String, Object> map) {
-            return AuthorityUtils
-                    .commaSeparatedStringToAuthorityList(asAuthorities(map));
-        }
-
-        private String asAuthorities(Map<String, Object> map) {
-            List<String> authorities = new ArrayList<>();
-//            authorities.add("BAELDUNG_USER");
-            List<LinkedHashMap<String, String>> authz;
-            authz = (List<LinkedHashMap<String, String>>) map.get("authorities");
-            for (LinkedHashMap<String, String> entry : authz) {
-                authorities.add(entry.get("authority"));
-            }
-            return String.join(",", authorities);
-        }
-    }
-
-
-    private LogoutHandler authLogoutHandler() {
-        return (request, response, authentication) -> {
-            logout();
-        };
-    }
-
-
-    public void logout() {
-        // POSTするリクエストパラメーターを作成
-        RestTemplate restTemplate = new RestTemplate();
-        MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
-        formParams.add("client_id", hbp().getClientId());
-        formParams.add("client_secret", hbp().getClientSecret());
-        formParams.add("refresh_token", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
-        // リクエストヘッダーを作成
-        HttpHeaders httpHeaders = new HttpHeaders();
-        httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
-        // リクエストを作成
-        RequestEntity<MultiValueMap<String, String>> requestEntity =
-                new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
-                        URI.create(logoutUri));
-        // POSTリクエスト送信(ログアウト実行)
-
-        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
-    }
-
-    @Value("#{'${services.keycloak.keycloakUrl}'}")
+//    @Bean
+//    public AuthoritiesExtractor keycloakAuthoritiesExtractor() {
+//        return new KeycloakAuthoritiesExtractor();
+//    }
+//
+//
+//    public class KeycloakAuthoritiesExtractor
+//            implements AuthoritiesExtractor {
+//
+//        @Override
+//        public List<GrantedAuthority> extractAuthorities
+//                (Map<String, Object> map) {
+//            return AuthorityUtils
+//                    .commaSeparatedStringToAuthorityList(asAuthorities(map));
+//        }
+//
+//        private String asAuthorities(Map<String, Object> map) {
+//            List<String> authorities = new ArrayList<>();
+////            authorities.add("BAELDUNG_USER");
+//            List<LinkedHashMap<String, String>> authz;
+//            authz = (List<LinkedHashMap<String, String>>) map.get("authorities");
+//            for (LinkedHashMap<String, String> entry : authz) {
+//                authorities.add(entry.get("authority"));
+//            }
+//            return String.join(",", authorities);
+//        }
+//    }
+
+
+//    private LogoutHandler authLogoutHandler() {
+//        return (request, response, authentication) -> {
+//            logout();
+//        };
+//    }
+
+
+//    public void logout() {
+//        // TODO Try removing
+//
+//        RestTemplate restTemplate = new RestTemplate();
+//        MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
+//        formParams.add("client_id", hbp().getClientId());
+//        formParams.add("client_secret", hbp().getClientSecret());
+//        formParams.add("refresh_token", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
+//
+//        HttpHeaders httpHeaders = new HttpHeaders();
+//        httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+//        RequestEntity<MultiValueMap<String, String>> requestEntity =
+//                new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
+//                        URI.create(logoutUrl));
+//        restTemplate.exchange(requestEntity, String.class);
+//    }
+
+// TODO needed?
+    @Value("#{'${keycloak.auth-server-url}'}")
     private String keycloakUrl;
 
-    // static {
-    // disableCertificateValidation();
-    // }
-
     public void disableCertificateValidation() {
+
+        //TODO Refactor logging
+
         LOGGER.info("disabling certificate validation host : " + keycloakUrl);
+
         // Create a trust manager that does not validate certificate chains
         TrustManager[] trustAllCerts = new TrustManager[]{
                 new X509TrustManager() {
@@ -316,18 +270,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
 
         // Ignore differences between given hostname and certificate hostname
-        HostnameVerifier hv = new HostnameVerifier() {
-            public boolean verify(String hostname, SSLSession session) {
-
-                // System.out.println("Warning: URL Host: " + hostname + " vs. "
-                // + session.getPeerHost());
-                if (hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl)) {
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        };
+        HostnameVerifier hv =
+                (hostname, session) -> hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl);
 
         // Install the all-trusting trust manager
         try {
@@ -336,6 +280,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
             HttpsURLConnection.setDefaultHostnameVerifier(hv);
         } catch (Exception e) {
+            // TODO add log message
         }
 
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index ff8d70a80..716f0da00 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -55,8 +55,8 @@ public class SecurityApi {
             //LOGGER.trace("Cannot read user json", e);
         }
 
-        if (!securityConfiguration.isAuthentication()) {
-            if (userInfo.isFakeAuth()) {
+        if (!securityConfiguration.getAuthenticationEnabled()) {
+            if (userInfo.getFakeAuth()) {
                 response.setStatus(401);
             }
             String principalJson = "{\"principal\": \"anonymous\", \"name\": \"anonymous\", \"userAuthentication\": {"
@@ -85,7 +85,7 @@ public class SecurityApi {
     @ConditionalOnExpression("${hbp.authentication.enabled:0}")
     public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
         userInfo.setFakeAuth(true);
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unathorized login.");
+        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
 
         httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
     }
@@ -104,7 +104,6 @@ public class SecurityApi {
      *
      * @return Return a @{@link ResponseEntity} with the token.
      */
-
     @RequestMapping(path = "/galaxy", method = RequestMethod.GET, produces = "application/json")
     @PreAuthorize("hasRole('Data Manager')")
     @ResponseStatus(value = HttpStatus.OK)
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
index 1e35ac831..ccf2a7fd7 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
@@ -19,7 +19,6 @@ import java.util.regex.Pattern;
 @Table(name = "`user`")
 @ApiModel
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = {"appsVotes"})
 public class UserDAO {
 
     @Id
@@ -49,26 +48,33 @@ public class UserDAO {
      */
     public UserDAO(String userInfo) {
 
-        Pattern p;
-        Matcher m;
-
-        p = Pattern.compile("preferred_username=([\\w- ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.username = m.group(1);
-        }
-
-        p = Pattern.compile("name=([\\w ]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.fullname = m.group(1);
-        }
-
-        p = Pattern.compile("email=([\\w.]+@[\\w.]+)");
-        m = p.matcher(userInfo);
-        if (m.find()) {
-            this.email = m.group(1);
-        }
+
+        // TODO fix
+        this.username = "test";
+        this.fullname = "test";
+        this.email = "test";
+
+        //
+//        Pattern p;
+//        Matcher m;
+//
+//        p = Pattern.compile("preferred_username=([\\w- ]+)");
+//        m = p.matcher(userInfo);
+//        if (m.find()) {
+//            this.username = m.group(1);
+//        }
+//
+//        p = Pattern.compile("name=([\\w ]+)");
+//        m = p.matcher(userInfo);
+//        if (m.find()) {
+//            this.fullname = m.group(1);
+//        }
+//
+//        p = Pattern.compile("email=([\\w.]+@[\\w.]+)");
+//        m = p.matcher(userInfo);
+//        if (m.find()) {
+//            this.email = m.group(1);
+//        }
 
 
     }
diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java
index cb61cfcea..4f58aaa41 100644
--- a/src/main/java/eu/hbp/mip/model/UserInfo.java
+++ b/src/main/java/eu/hbp/mip/model/UserInfo.java
@@ -6,9 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
 import org.springframework.stereotype.Component;
 
 import javax.inject.Named;
@@ -24,7 +21,7 @@ public class UserInfo {
     /**
      * Enable HBP collab authentication (1) or disable it (0). Default is 1
      */
-    @Value("#{'${hbp.authentication.enabled:1}'}")
+    @Value("#{'${hbp.authentication.enabled}'}")
     private boolean authentication;
 
     private UserDAO user;
@@ -55,7 +52,7 @@ public class UserInfo {
                 user.setFullname("anonymous");
                 user.setEmail("anonymous@anonymous.com");
             } else {
-                user = new UserDAO(getUserInfos());
+                user = new UserDAO(getUserInformation());
             }
             UserDAO foundUser = userRepository.findByUsername(user.getUsername());
             if (foundUser != null) {
@@ -67,7 +64,7 @@ public class UserInfo {
         return user;
     }
 
-    public boolean isFakeAuth() {
+    public boolean getFakeAuth() {
         return fakeAuth;
     }
 
@@ -75,10 +72,13 @@ public class UserInfo {
         this.fakeAuth = fakeAuth;
     }
 
-    private String getUserInfos() {
-        OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
-        Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
-        return userAuthentication.getDetails().toString();
+    private String getUserInformation() {
+        // TODO
+        return "";
+        // get details from keycloak configuration
+//        OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
+//        Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
+//        return userAuthentication.getDetails().toString();
     }
 
 }
-- 
GitLab


From 4afa62b65f816d6a92bbc30ad570363fe6f43430 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Mon, 9 Nov 2020 11:07:49 +0200
Subject: [PATCH 16/52] Fixed log level env variables for portal-backend.

---
 docker/config/application.tmpl                               | 1 +
 .../java/eu/hbp/mip/configuration/SecurityConfiguration.java | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 84ef19c5e..b78a41f59 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -71,4 +71,5 @@ keycloak:
     resource: {{ .Env.CLIENT_ID }}
     credentials:
         secret: {{ .Env.CLIENT_SECRET }}
+    principal-attribute: "preferred_username"
    # logoutUrl: {{ .Env.LOGOUT_URL }}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 68a1ca4a1..323d974a2 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -122,8 +122,9 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
                     .accessDeniedHandler(new CustomAccessDeniedHandler())
                     // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
                     .and().logout().permitAll()
-                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
+                    .and().csrf().disable() // TODO Remove
+            //.and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+                    //.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
             ; // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
         } else {
             http.antMatcher("/**")
-- 
GitLab


From 5e34a2363bdc24016d308c96359a5855f0bc4097 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Mon, 9 Nov 2020 11:21:19 +0200
Subject: [PATCH 17/52] Configuring keycloak security.

---
 build.sh                                      |   2 +-
 docker/config/application.tmpl                |  37 ++--
 pom.xml                                       |  16 +-
 .../configuration/SecurityConfiguration.java  | 166 +++++++++++-------
 .../SecurityUtils}/CORSFilter.java            |  12 +-
 .../CustomAccessDeniedHandler.java            |   5 +-
 ...ustomLoginUrlAuthenticationEntryPoint.java |   5 +-
 .../hbp/mip/controllers/PathologiesApi.java   |   2 +-
 .../eu/hbp/mip/controllers/SecurityApi.java   |  16 +-
 .../java/eu/hbp/mip/model/DAOs/UserDAO.java   |   5 -
 src/main/java/eu/hbp/mip/model/UserInfo.java  |   3 +-
 .../hbp/mip/services/ExperimentService.java   |   2 +-
 src/main/resources/application.conf           |  20 ---
 src/main/resources/kamon.conf                 |  75 --------
 14 files changed, 153 insertions(+), 213 deletions(-)
 rename src/main/java/eu/hbp/mip/{utils => configuration/SecurityUtils}/CORSFilter.java (79%)
 rename src/main/java/eu/hbp/mip/{utils => configuration/SecurityUtils}/CustomAccessDeniedHandler.java (92%)
 rename src/main/java/eu/hbp/mip/{utils => configuration/SecurityUtils}/CustomLoginUrlAuthenticationEntryPoint.java (87%)
 delete mode 100644 src/main/resources/application.conf
 delete mode 100644 src/main/resources/kamon.conf

diff --git a/build.sh b/build.sh
index 6a18d98ec..458b5c085 100755
--- a/build.sh
+++ b/build.sh
@@ -26,7 +26,7 @@ else
   DOCKER="sudo docker"
 fi
 
-IMAGE="kfilippopolitis/portal-backend"
+IMAGE="thanasulas/portal-backend"
 VCS_REF=$(git describe --tags --dirty)
 VERSION=$(git describe --tags --dirty)
 
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index b78a41f59..3b9311454 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -3,7 +3,7 @@
 # See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
 spring:
   portal-datasource:
-    url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://172.22.0.1:5432/portal" }}
+    url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://88.197.53.106:5432/portal" }}
     schema: {{ default .Env.PORTAL_DB_SCHEMA "public" }}
     username: {{ default .Env.PORTAL_DB_USER "postgres" }}
     password: {{ .Env.PORTAL_DB_PASSWORD }}
@@ -22,17 +22,19 @@ spring:
 frontend:
   loginUrl: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
   redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/" }}
-  redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL (default .Env.LOGIN_URI "http://frontend/services/login/hbp") }}
+  redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL "http://frontend/services/login/hbp" }}
 
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
+    org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
     eu:
       hbp: {{ default .Env.LOG_LEVEL "INFO" }}
 
 # EMBEDDED SERVER CONFIGURATION
 server:
-  contextPath: {{ default .Env.CONTEXT_PATH "/services" }}
+  servlet:
+    contextPath: {{ default .Env.CONTEXT_PATH "/services" }}
   port: 8080
   use-forward-headers: true
   session:
@@ -59,17 +61,24 @@ services:
     galaxyUsername:  {{ default .Env.GALAXY_USERNAME "admin" }}
     galaxyPassword:  {{ default .Env.GALAXY_PASSWORD "password" }}
 
-# HBP Authentication
-hbp:
-  authentication:
-    enabled: {{ default .Env.AUTHENTICATION "1" }}
+# Authentication
+authentication:
+  enabled: {{ default .Env.AUTHENTICATION "1" }}
 
 # Keycloak
 keycloak:
-    auth-server-url: {{ .Env.KEYCLOAK_URL }}
-    realm: {{ .Env.KEYCLOAK_REALM }}
-    resource: {{ .Env.CLIENT_ID }}
-    credentials:
-        secret: {{ .Env.CLIENT_SECRET }}
-    principal-attribute: "preferred_username"
-   # logoutUrl: {{ .Env.LOGOUT_URL }}
\ No newline at end of file
+  enabled: true
+  auth-server-url: {{ .Env.KEYCLOAK_AUTH_URL }}
+  realm: {{ .Env.KEYCLOAK_REALM }}
+  resource: {{ .Env.CLIENT_ID }}
+  enable-basic-auth: true
+  credentials:
+    secret: {{ .Env.CLIENT_SECRET }}
+  principal-attribute: "preferred_username"
+#  cors: true
+#  cors-max-age: 3600
+#  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
+#  cors-allowed-headers: "*"
+#  cors-exposed-headers: "*"
+
+  # logoutUrl: {{ .Env.LOGOUT_URL }}
diff --git a/pom.xml b/pom.xml
index a856ee073..e5d87b28f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
     <properties>
         <java.version>1.8</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <keycloak-spring-boot-starter.version>11.0.2</keycloak-spring-boot-starter.version>
+        <keycloak-spring.version>11.0.2</keycloak-spring.version>
         <springfox-swagger.version>2.5.0</springfox-swagger.version>
         <spring-context.version>5.2.10.RELEASE</spring-context.version>
         <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
@@ -44,6 +44,7 @@
         <flyway-core.version>4.2.0</flyway-core.version>
         <hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version>
         <hibernate.version>5.4.10.Final</hibernate.version>
+        <hibernate-validator.version>6.1.0.Final</hibernate-validator.version>
         <aspectjweaver.version>1.8.9</aspectjweaver.version>
         <javax-inject.version>1</javax-inject.version>
         <protobuf-java.version>3.1.0</protobuf-java.version>
@@ -84,9 +85,13 @@
         <dependency>
             <groupId>org.keycloak</groupId>
             <artifactId>keycloak-spring-boot-starter</artifactId>
-            <version>${keycloak-spring-boot-starter.version}</version>
+            <version>${keycloak-spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-spring-security-adapter</artifactId>
+            <version>${keycloak-spring.version}</version>
         </dependency>
-
 <!--        <dependency>-->
 <!--            <groupId>org.springframework.security</groupId>-->
 <!--            <artifactId>spring-security-oauth2-resource-server</artifactId>-->
@@ -140,6 +145,11 @@
             <artifactId>hibernate-core</artifactId>
             <version>${hibernate.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>${hibernate-validator.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-entitymanager</artifactId>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 323d974a2..d2a0dd739 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -1,35 +1,40 @@
 package eu.hbp.mip.configuration;
 
-import eu.hbp.mip.utils.CORSFilter;
-import eu.hbp.mip.utils.CustomAccessDeniedHandler;
-import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint;
+import eu.hbp.mip.configuration.SecurityUtils.CORSFilter;
+import eu.hbp.mip.configuration.SecurityUtils.CustomAccessDeniedHandler;
+import eu.hbp.mip.configuration.SecurityUtils.CustomLoginUrlAuthenticationEntryPoint;
 import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
 import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
 import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
+import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler;
 import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
+import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;
+import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
 import org.springframework.security.core.session.SessionRegistryImpl;
 import org.springframework.security.web.access.channel.ChannelProcessingFilter;
-import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
 import org.springframework.security.web.csrf.CsrfFilter;
 import org.springframework.security.web.csrf.CsrfToken;
 import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
 
 import javax.net.ssl.*;
-import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
 import javax.servlet.http.Cookie;
@@ -52,7 +57,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     /**
      * Enable HBP collab authentication (1) or disable it (0). Default is 1
      */
-    @Value("#{'${hbp.authentication.enabled}'}")
+    @Value("#{'${authentication.enabled}'}")
     private boolean authenticationEnabled;
 
     /**
@@ -91,11 +96,10 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
     }
 
-
     @Autowired
     public void configureGlobal(AuthenticationManagerBuilder auth) {
         SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
-        grantedAuthorityMapper.setPrefix("ROLE_");
+        //grantedAuthorityMapper.setPrefix("ROLE_");
         grantedAuthorityMapper.setConvertToUpperCase(true);
 
         KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
@@ -103,29 +107,41 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         auth.authenticationProvider(keycloakAuthenticationProvider);
     }
 
+    @Override
+    protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception {
+        return super.keycloakLogoutHandler();
+    }
+
     @Override
     protected void configure(HttpSecurity http) throws Exception {
-        disableCertificateValidation();  //  TODO needed?
-        // @formatter:off
+        super.configure(http);
+        //disableCertificateValidation();  //  TODO needed?
+
+        // TODO Check if needed.
+        // Check if it works when removing keycloak cors from app properties.
         http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
 
         if (authenticationEnabled) {
-            http.authorizeRequests()
-                    .antMatchers(
-                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**",
-                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
-                            "/swagger-ui.html", "/swagger-resources/**"
-                    ).permitAll()
-                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("Data Manager")
-                    .anyRequest().hasRole("Researcher")
-                    .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
-                    .accessDeniedHandler(new CustomAccessDeniedHandler())
-                    // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
-                    .and().logout().permitAll()
-                    .and().csrf().disable() // TODO Remove
-            //.and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-                    //.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
-            ; // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
+            http.antMatcher("/**")
+                    .authorizeRequests()
+                    .antMatchers("/**").permitAll()
+//                    .antMatchers(
+//                            "/login**", "/health/**", "/info/**", "/metrics/**",
+//                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
+//                            "/swagger-ui.html", "/swagger-resources/**"
+//                    ).permitAll()
+//                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
+//                    .anyRequest().hasRole("RESEARCHER")
+                   // .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
+                   // .accessDeniedHandler(new CustomAccessDeniedHandler())
+                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf();
+//                    .and().logout().logoutSuccessUrl("/logout");
+//
+//
+//                    // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
+//                    .and().logout().permitAll()
+                    // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
         } else {
             http.antMatcher("/**")
                     .authorizeRequests()
@@ -134,6 +150,22 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         }
     }
 
+
+//    @Bean
+//    public FilterRegistrationBean corsFilter() {
+//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+//        CorsConfiguration config = new CorsConfiguration();
+//        config.setAllowCredentials(true);
+//        config.addAllowedOrigin("*");
+//        config.addAllowedHeader("*");
+//        config.addAllowedMethod("*");
+//        source.registerCorsConfiguration("/**", config);
+//
+//        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
+//        bean.setOrder(-100);
+//        return bean;
+//    }
+
 //    private Filter ssoFilter() {
 //        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
 //        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
@@ -165,7 +197,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
 //    }
 
 
-    private Filter csrfHeaderFilter() {
+    private OncePerRequestFilter csrfHeaderFilter() {
         return new OncePerRequestFilter() {
             @Override
             protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
@@ -245,45 +277,45 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
 //        restTemplate.exchange(requestEntity, String.class);
 //    }
 
-// TODO needed?
-    @Value("#{'${keycloak.auth-server-url}'}")
-    private String keycloakUrl;
-
-    public void disableCertificateValidation() {
-
-        //TODO Refactor logging
-
-        LOGGER.info("disabling certificate validation host : " + keycloakUrl);
-
-        // Create a trust manager that does not validate certificate chains
-        TrustManager[] trustAllCerts = new TrustManager[]{
-                new X509TrustManager() {
-                    public X509Certificate[] getAcceptedIssuers() {
-                        return new X509Certificate[0];
-                    }
-
-                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
-                    }
-
-                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
-                    }
-                }};
-
-
-        // Ignore differences between given hostname and certificate hostname
-        HostnameVerifier hv =
-                (hostname, session) -> hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl);
-
-        // Install the all-trusting trust manager
-        try {
-            SSLContext sc = SSLContext.getInstance("SSL");
-            sc.init(null, trustAllCerts, new SecureRandom());
-            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-            HttpsURLConnection.setDefaultHostnameVerifier(hv);
-        } catch (Exception e) {
-            // TODO add log message
-        }
-
-    }
+    // TODO needed?
+//    @Value("#{'${keycloak.auth-server-url}'}")
+//    private String keycloakUrl;
+//
+//    public void disableCertificateValidation() {
+//
+//        //TODO Refactor logging
+//
+//        LOGGER.info("disabling certificate validation host : " + keycloakUrl);
+//
+//        // Create a trust manager that does not validate certificate chains
+//        TrustManager[] trustAllCerts = new TrustManager[]{
+//                new X509TrustManager() {
+//                    public X509Certificate[] getAcceptedIssuers() {
+//                        return new X509Certificate[0];
+//                    }
+//
+//                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
+//                    }
+//
+//                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
+//                    }
+//                }};
+//
+//
+//        // Ignore differences between given hostname and certificate hostname
+//        HostnameVerifier hv =
+//                (hostname, session) -> hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl);
+//
+//        // Install the all-trusting trust manager
+//        try {
+//            SSLContext sc = SSLContext.getInstance("SSL");
+//            sc.init(null, trustAllCerts, new SecureRandom());
+//            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+//            HttpsURLConnection.setDefaultHostnameVerifier(hv);
+//        } catch (Exception e) {
+//            // TODO add log message
+//        }
+//
+//    }
 
 }
diff --git a/src/main/java/eu/hbp/mip/utils/CORSFilter.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
similarity index 79%
rename from src/main/java/eu/hbp/mip/utils/CORSFilter.java
rename to src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
index 7ed1ecf38..2a259ea22 100644
--- a/src/main/java/eu/hbp/mip/utils/CORSFilter.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.utils;
+package eu.hbp.mip.configuration.SecurityUtils;
 
 import javax.servlet.*;
 import javax.servlet.http.HttpServletResponse;
@@ -19,14 +19,4 @@ public class CORSFilter implements Filter {
         response.setHeader("Access-Control-Request-Headers", "*");
         chain.doFilter(req, res);
     }
-
-    @Override
-    public void init(FilterConfig filterConfig) {
-        /* Nothing to do */
-    }
-
-    @Override
-    public void destroy() {
-        /* Nothing to do */
-    }
 }
diff --git a/src/main/java/eu/hbp/mip/utils/CustomAccessDeniedHandler.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
similarity index 92%
rename from src/main/java/eu/hbp/mip/utils/CustomAccessDeniedHandler.java
rename to src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
index 783e4a3ff..552abd29f 100644
--- a/src/main/java/eu/hbp/mip/utils/CustomAccessDeniedHandler.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
@@ -1,11 +1,10 @@
-package eu.hbp.mip.utils;
+package eu.hbp.mip.configuration.SecurityUtils;
 
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.web.access.AccessDeniedHandler;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -14,7 +13,7 @@ import java.sql.Timestamp;
 public class CustomAccessDeniedHandler implements AccessDeniedHandler {
     @Override
     public void handle(HttpServletRequest request, HttpServletResponse response,
-                       AccessDeniedException accessDeniedException) throws IOException, ServletException {
+                       AccessDeniedException accessDeniedException) throws IOException {
         response.setContentType("application/json;charset=UTF-8");
         response.setStatus(403);
         try {
diff --git a/src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java
similarity index 87%
rename from src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java
rename to src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java
index 45870c777..068ca591b 100644
--- a/src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java
@@ -1,9 +1,8 @@
-package eu.hbp.mip.utils;
+package eu.hbp.mip.configuration.SecurityUtils;
 
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -15,7 +14,7 @@ public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticati
     }
 
     @Override
-    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
+    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
         response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
     }
 }
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 9560cc6dd..4b37d2c5d 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -38,7 +38,7 @@ public class PathologiesApi {
     private UserInfo userInfo;
 
     // Enable HBP collab authentication (1) or disable it (0). Default is 1
-    @Value("#{'${hbp.authentication.enabled:1}'}")
+    @Value("#{'${authentication.enabled}'}")
     private boolean authenticationIsEnabled;
 
     @Autowired
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index 716f0da00..9d2b66492 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -81,14 +81,14 @@ public class SecurityApi {
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
-    @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
-    @ConditionalOnExpression("${hbp.authentication.enabled:0}")
-    public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
-        userInfo.setFakeAuth(true);
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
-
-        httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
-    }
+//    @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
+//    @ConditionalOnExpression("${authentication.enabled:0}")
+//    public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
+//        userInfo.setFakeAuth(true);
+//        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
+//
+//        httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
+//    }
 
     @Value("#{'${services.galaxy.galaxyUsername:admin}'}")
     private String galaxyUsername;
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
index ccf2a7fd7..0d0ba246d 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
@@ -4,7 +4,6 @@
 
 package eu.hbp.mip.model.DAOs;
 
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.annotations.Expose;
 import io.swagger.annotations.ApiModel;
@@ -12,8 +11,6 @@ import io.swagger.annotations.ApiModel;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 @Entity
 @Table(name = "`user`")
@@ -88,7 +85,6 @@ public class UserDAO {
         this.fullname = fullname;
     }
 
-
     public String getUsername() {
         return username;
     }
@@ -97,7 +93,6 @@ public class UserDAO {
         this.username = username;
     }
 
-
     public String getEmail() {
         return email;
     }
diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java
index 4f58aaa41..617b25a5f 100644
--- a/src/main/java/eu/hbp/mip/model/UserInfo.java
+++ b/src/main/java/eu/hbp/mip/model/UserInfo.java
@@ -21,7 +21,7 @@ public class UserInfo {
     /**
      * Enable HBP collab authentication (1) or disable it (0). Default is 1
      */
-    @Value("#{'${hbp.authentication.enabled}'}")
+    @Value("#{'${authentication.enabled}'}")
     private boolean authentication;
 
     private UserDAO user;
@@ -54,6 +54,7 @@ public class UserInfo {
             } else {
                 user = new UserDAO(getUserInformation());
             }
+
             UserDAO foundUser = userRepository.findByUsername(user.getUsername());
             if (foundUser != null) {
                 user.setAgreeNDA(foundUser.getAgreeNDA());
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index a02af3ab6..fe1b4023c 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -55,7 +55,7 @@ public class ExperimentService {
     private String galaxyApiKey;
 
     // Enable HBP collab authentication (1) or disable it (0). Default is 1
-    @Value("#{'${hbp.authentication.enabled:1}'}")
+    @Value("#{'${authentication.enabled:1}'}")
     private boolean authenticationIsEnabled;
 
     @Autowired
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
deleted file mode 100644
index e2abfd5ae..000000000
--- a/src/main/resources/application.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-app {
-  # Name of the application
-  name = "Portal backend"
-  # Type of the application
-  type = "Spring"
-  clusterSystemName = ${clustering.cluster.name}
-}
-
-clustering {
-  ip = "127.0.0.1"
-  ip = ${?CLUSTER_IP}
-  port = 4489
-  port = ${?CLUSTER_PORT}
-}
-
-akka {
-  cluster {
-    roles = ["portal"]
-  }
-}
diff --git a/src/main/resources/kamon.conf b/src/main/resources/kamon.conf
deleted file mode 100644
index face394cb..000000000
--- a/src/main/resources/kamon.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-kamon {
-  enabled = no
-  enabled = ${?KAMON_ENABLED}
-
-  environment {
-    service = "portal-backend"
-    service = ${?KAMON_SERVICE_NAME}
-  }
-
-  zipkin = {
-    enabled = no
-    enabled = ${?ZIPKIN_ENABLED}
-    host = "zipkin"
-    host = ${?ZIPKIN_IP}
-    port = 9411
-    port = ${?ZIPKIN_PORT}
-  }
-
-  prometheus = {
-    enabled = no
-    enabled = ${?PROMETHEUS_ENABLED}
-    host = "prometheus"
-    host = ${?PROMETHEUS_IP}
-    port = 9090
-    port = ${?PROMETHEUS_PORT}
-  }
-
-  util.filters {
-    "akka.tracked-actor" {
-      includes = ["**"]
-    }
-
-    "akka.tracked-dispatcher" {
-      includes = ["**"]
-    }
-
-    "akka.traced-actor" {
-      includes = ["**"]
-      excludes = [
-        ${clustering.cluster.name}"/system/IO**",
-        ${clustering.cluster.name}"/user/Stream**",
-        ${clustering.cluster.name}"/system/transports**",
-        ${clustering.cluster.name}"/system/cluster**",
-        ${clustering.cluster.name}"/system/remote**",
-        ${clustering.cluster.name}"/system/endpointmanager/**",
-        ${clustering.cluster.name}"/system/sharding/UserActor/**"]
-    }
-
-  }
-
-  akka-http {
-    add-http-status-code-as-metric-tag = true
-  }
-
-  akka {
-    ask-pattern-timeout-warning = lightweight
-  }
-
-  trace {
-    join-remote-parents-with-same-span-id = yes
-    sampler = "always"
-  }
-
-  system-metrics {
-    host {
-      enabled = no
-      enabled = ${?SIGAR_SYSTEM_METRICS}
-    }
-    jvm {
-      enabled = no
-      enabled = ${?JVM_SYSTEM_METRICS}
-    }
-  }
-
-}
-- 
GitLab


From 7a382421a40d1085c5ddad91615c323b7c81c6f2 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Tue, 10 Nov 2020 08:54:12 -0800
Subject: [PATCH 18/52] Implemented exteption/error handling and added java
 docs on service layer.

---
 .../eu/hbp/mip/controllers/ExperimentApi.java |  32 +-
 .../hbp/mip/controllers/PathologiesApi.java   |   3 +-
 .../eu/hbp/mip/model/DAOs/ExperimentDAO.java  |   2 +-
 .../eu/hbp/mip/model/DTOs/ExperimentDTO.java  |   7 +-
 .../hbp/mip/services/ExperimentService.java   | 385 +++++++++++++-----
 .../services/ExperimentSpecifications.java    |   7 +-
 .../mip/utils/ControllerExceptionHandler.java |  62 ++-
 .../utils/Exceptions/BadRequestException.java |   8 +
 .../ExperimentNotFoundException.java          |   8 +
 .../utils/Exceptions/InternalServerError.java |   8 +
 .../hbp/mip/utils/Exceptions/NoContent.java   |   8 +
 .../Exceptions/UnauthorizedException.java     |   8 +
 .../mip/utils/ResourceNotFoundException.java  |  10 -
 ...ure.sql => V7_0__NewDatabaseStructure.sql} |   0
 14 files changed, 423 insertions(+), 125 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
 create mode 100644 src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
 delete mode 100644 src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
 rename src/main/resources/db/migration/{V7_0__NewExperimentStructure.sql => V7_0__NewDatabaseStructure.sql} (100%)

diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index 7cb949a4b..322f33f4f 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -3,14 +3,18 @@ package eu.hbp.mip.controllers;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.services.ExperimentService;
+import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Map;
+
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 /*
@@ -39,32 +43,50 @@ public class ExperimentApi {
             @RequestParam(defaultValue = "0") int page,
             @RequestParam(defaultValue = "3") int size
     ) {
-        return experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
+        Map experiments = experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
+        return new ResponseEntity(experiments, HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
     public ResponseEntity<String> getExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
+       ExperimentDTO experimentDTO = experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Create an experiment", response = ExperimentDTO.class)
     @RequestMapping(method = RequestMethod.POST)
     public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        return experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
+        experimentDTO =  experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
     }
 
+
+    @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
+    @RequestMapping(value = "/{transient}",method = RequestMethod.POST)
+    public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+            experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
+
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
+
+
     @ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
     public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO,@ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
+        experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
+
     @ApiOperation(value = "Delete an experiment", response = boolean.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
     public ResponseEntity<String> deleteExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        return experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
+        experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
+        return new ResponseEntity<>(HttpStatus.OK);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 4b37d2c5d..6c89e1b94 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -10,6 +10,7 @@ import eu.hbp.mip.model.DTOs.PathologyDTO;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
+import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import eu.hbp.mip.utils.InputStreamConverter;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
@@ -56,7 +57,7 @@ public class PathologiesApi {
             }.getType());
         } catch (IOException e) {
             Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
-            return ResponseEntity.badRequest().body("The pathologies could not be loaded.");
+            throw new BadRequestException("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
index 30d6c87da..2ee8e0ba4 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
@@ -120,7 +120,7 @@ public class ExperimentDAO {
         experimentDTO.setName(this.name);
         experimentDTO.setResult(JsonConverters.convertJsonStringToObject(this.result, ExperimentDTO.ResultDTO.class));
         experimentDTO.setShared(this.shared);
-        experimentDTO.setUuid(this.uuid.toString());
+        experimentDTO.setUuid(this.uuid);
         experimentDTO.setViewed(this.viewed);
         return experimentDTO;
     }
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
index e4b9d34a5..64ade455b 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
@@ -4,10 +4,11 @@ import eu.hbp.mip.model.DAOs.ExperimentDAO;
 
 import java.util.Date;
 import java.util.List;
+import java.util.UUID;
 
 public class ExperimentDTO {
 
-    private String uuid;
+    private UUID uuid;
     private String name;
     private String createdBy;
     private Date created;
@@ -39,11 +40,11 @@ public class ExperimentDTO {
         this.algorithm = algorithmDetails.getName();
     }
 
-    public String getUuid() {
+    public UUID getUuid() {
         return uuid;
     }
 
-    public void setUuid(String uuid) {
+    public void setUuid(UUID uuid) {
         this.uuid = uuid;
     }
 
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index fe1b4023c..d11971ddd 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -6,7 +6,10 @@ import com.github.jmchilton.blend4j.galaxy.WorkflowsClient;
 import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
 import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
-import com.google.gson.*;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
@@ -14,11 +17,14 @@ import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.model.galaxy.ErrorResponse;
 import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
 import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
-import eu.hbp.mip.utils.*;
+import eu.hbp.mip.utils.ClaimUtils;
+import eu.hbp.mip.utils.Exceptions.*;
+import eu.hbp.mip.utils.HTTPUtil;
+import eu.hbp.mip.utils.JsonConverters;
+import eu.hbp.mip.utils.Logging;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,8 +33,6 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Service;
 import retrofit2.Call;
@@ -63,11 +67,24 @@ public class ExperimentService {
 
     private static final Gson gson = new Gson();
 
-    public ResponseEntity<String> getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
+    /**
+     * The getExperiments will retrieve the experiments from database according to the filters.
+     *
+     * @param name is optional, in case it is required to filter the experiments by name
+     * @param algorithm is optional, in case it is required to filter the experiments by algorithm name
+     * @param shared is optional, in case it is required to filter the experiments by shared
+     * @param viewed is optional, in case it is required to filter the experiments by viewed
+     * @param page is the page that is required to be retrieve
+     * @param size is the size of each page
+     * @param endpoint is the endpoint that called the function
+     * @return a list of mapped experiments
+     */
+    public Map getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
         if(size > 10 )
-            return ResponseEntity.badRequest().body("Invalid size input, max size is 10.");
+            throw new BadRequestException("Invalid size input, max size is 10.");
+
 
         Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
                 .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
@@ -79,7 +96,7 @@ public class ExperimentService {
         List<ExperimentDAO> experimentDAOs = pageExperiments.getContent();
 
         if (experimentDAOs.isEmpty())
-            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+            throw new NoContent("No experiment found with the filters provided.");
 
         List<ExperimentDTO> experimentDTOs = new ArrayList<>();
         experimentDAOs.forEach(experimentDAO -> experimentDTOs.add(experimentDAO.convertToDTO()));
@@ -90,55 +107,64 @@ public class ExperimentService {
         response.put("totalExperiments", pageExperiments.getTotalElements());
         response.put("totalPages", pageExperiments.getTotalPages());
 
-        return new ResponseEntity(response, HttpStatus.OK);
+        return response;
     }
 
-    public ResponseEntity<String> getExperiment(String uuid, String endpoint) {
+    /**
+     * The getExperiment will retrieve the experiment from database according to the input uuid
+     *
+     * @param uuid is the id of the experiment to be retrieved
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information that was retrieved from the database
+     */
+    public ExperimentDTO getExperiment(String uuid, String endpoint) {
 
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
-        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ResourceNotFoundException("Not found Experimnet with id = " + uuid));
-
-        if (experimentDAO == null) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Experiment Not found.");
-            return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
-        }
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())) {
             Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
-            return new ResponseEntity<>("You don't have access to the experiment.", HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
         }
         ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
         Logging.LogUserAction(user.getUsername(), endpoint, "Experiment was Loaded with uuid : " + uuid + ".");
 
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return experimentDTO;
     }
 
-    public ResponseEntity<String> createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
+    /**
+     * The createExperiment will create and save an experiment in the database.
+     *
+     * @param authentication is the role of the user
+     * @param experimentDTO is the experiment information
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information which was created
+     */
+    public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
 
         //Checking if check (POST) /experiments has proper input.
         if (checkPostExperimentProperInput(experimentDTO)){
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Invalid input.");
-            return ResponseEntity.badRequest().body("Please provide proper input.");
+            throw new BadRequestException("Please provide proper input.");
         }
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithmDetails().getType();
         String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
         StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        for (AlgorithmDTO.AlgorithmParamDTO params : experimentDTO.getAlgorithmDetails().getParameters()) {
-            parametersLogMessage
-                    .append("  ")
-                    .append(params.getLabel())
-                    .append(" -> ")
-                    .append(params.getValue())
-                    .append("\n");
-        }
+        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+            params -> parametersLogMessage
+                .append("  ")
+                .append(params.getLabel())
+                .append(" -> ")
+                .append(params.getValue())
+                .append("\n") );
         Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
 
         if (authenticationIsEnabled) {
@@ -154,12 +180,12 @@ public class ExperimentService {
             if (experimentDatasets == null || experimentDatasets.equals("")) {
                 Logging.LogUserAction(user.getUsername(), endpoint,
                         "A dataset should be specified to run an algorithm.");
-                return ResponseEntity.badRequest().body("Please provide at least one dataset to run the algorithm.");
+                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
             }
 
             // --- Validating proper access rights on the datasets  ---
             if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
-                return ResponseEntity.badRequest().body("You are not authorized to use these datasets.");
+                throw new BadRequestException("You are not authorized to use these datasets.");
             }
         }
 
@@ -173,7 +199,93 @@ public class ExperimentService {
         }
     }
 
-    public ResponseEntity<String> updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
+    /**
+     * The createTransientExperiment will run synchronous a transient experiment into exareme and provide results
+     *
+     * @param authentication is the role of the user
+     * @param experimentDTO is the experiment information
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information which was created
+     */
+    public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint){
+        UserDAO user = userInfo.getUser();
+
+        //Checking if check (POST) /experiments has proper input.
+        if (checkPostExperimentProperInput(experimentDTO)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Invalid input.");
+            throw new BadRequestException("Please provide proper input.");
+        }
+
+        // Get the parameters
+        List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
+                = experimentDTO.getAlgorithmDetails().getParameters();
+
+        // Get the type and name of algorithm
+        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
+
+        if (!loadProperAlgorithms().contains(algorithmName)){
+            Logging.LogUserAction(user.getUsername(), endpoint,
+                    "Not proper algorithm.");
+            throw new BadRequestException("Please provide proper algorithm.");
+        }
+
+        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
+        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+            params -> parametersLogMessage
+                .append("  ")
+                .append(params.getLabel())
+                .append(" -> ")
+                .append(params.getValue())
+                .append("\n") );
+        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+
+        if (authenticationIsEnabled) {
+            // Getting the dataset from the experiment parameters
+            String experimentDatasets = null;
+            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
+                if (parameter.getLabel().equals("dataset")) {
+                    experimentDatasets = parameter.getValue();
+                    break;
+                }
+            }
+
+            if (experimentDatasets == null || experimentDatasets.equals("")) {
+                Logging.LogUserAction(user.getUsername(), endpoint,
+                        "A dataset should be specified to run an algorithm.");
+                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
+            }
+
+            // --- Validating proper access rights on the datasets  ---
+            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
+                throw new BadRequestException("You are not authorized to use these datasets.");
+            }
+        }
+
+        String body = gson.toJson(algorithmParameters);
+        String url = queryExaremeUrl + "/" + algorithmName;
+        Logging.LogUserAction(user.getUsername(), endpoint, "url: " + url + ", body: " + body);
+
+        Logging.LogUserAction(user.getUsername(), endpoint,
+                "Completed, returning: " + experimentDTO.toString());
+
+        // Results are stored in the experiment object
+        ExaremeResult exaremeResult = runExaremeExperiment(url, body, experimentDTO);
+        experimentDTO.setResult(exaremeResult.result);
+        experimentDTO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
+
+        return experimentDTO;
+    }
+
+    /**
+     * The updateExperiment will update the experiment's properties
+     *
+     * @param uuid is the id of the experiment to be updated
+     * @param experimentDTO is the experiment information to be updated
+     * @param endpoint is the endpoint that called the function
+     * @return the updated experiment information
+     */
+    public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
     {
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
@@ -182,7 +294,7 @@ public class ExperimentService {
         if (checkPutExperimentProperInput(experimentDTO)){
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Invalid input.");
-            return ResponseEntity.badRequest().body("Please provide proper input.");
+            throw new BadRequestException("Please provide proper input.");
         }
 
         if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0)
@@ -190,13 +302,13 @@ public class ExperimentService {
                 && experimentDTO.getViewed() == null
                 && experimentDTO.getAlgorithmDetails() == null)
         {
-            return ResponseEntity.badRequest().body("Input is required.");
+            throw new BadRequestException("Input is required.");
         }
 
-        experimentDAO = loadExperiment(uuid).get();
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
-            return new ResponseEntity<>("You're not the owner of this experiment", HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
 
         if(experimentDTO.getName() != null && experimentDTO.getName().length() != 0)
         {
@@ -213,29 +325,39 @@ public class ExperimentService {
             experimentDAO.setViewed(experimentDTO.getViewed());
         }
 
-        experimentRepository.save(experimentDAO);
-
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
         Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + experimentDTO.getUuid() + ".");
 
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+        return experimentDTO;
     }
 
-    public ResponseEntity<String> deleteExperiment(String uuid, String endpoint)
+    /**
+     * The deleteExperiment will delete an experiment from the database
+     *
+     * @param uuid is the id of the experiment to be deleted
+     * @param endpoint is the endpoint that called the function
+     */
+    public void deleteExperiment(String uuid, String endpoint)
     {
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid).get();
+        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
-            return new ResponseEntity<>(endpoint, HttpStatus.UNAUTHORIZED);
+            throw new UnauthorizedException("You don't have access to the experiment.");
 
         experimentRepository.delete(experimentDAO);
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
@@ -250,6 +372,14 @@ public class ExperimentService {
                 || experimentDTO.getUuid() != null;
     }
 
+    private List<String> loadProperAlgorithms()
+    {
+        List<String> properAlgorithms = new ArrayList<>();
+        properAlgorithms.add("histograms");
+        properAlgorithms.add("descriptive_stats");
+        return properAlgorithms;
+    }
+
     private boolean checkPutExperimentProperInput(ExperimentDTO experimentDTO)
     {
         return experimentDTO.getUuid() != null
@@ -258,21 +388,29 @@ public class ExperimentService {
                 || experimentDTO.getStatus() != null;
     }
 
+    /**
+     * The loadExperiment access the database and load the information of a specific experiment
+     *
+     * @param uuid is the id of the experiment to be retrieved
+     * @return the experiment information that was retrieved from database
+     */
     private Optional<ExperimentDAO> loadExperiment(String uuid){
 
 
         UUID experimentUuid ;
 
-        try {
-            experimentUuid = UUID.fromString(uuid);
-        } catch (IllegalArgumentException iae) {
-            return null;
-        }
+        experimentUuid = Optional.of(UUID.fromString(uuid)).orElseThrow(() -> new IllegalArgumentException("Invalid input uuid:"+ uuid));
 
         return experimentRepository.findByUuid(experimentUuid);
     }
 
-    private ExperimentDAO createExperiment(ExperimentDTO experimentDTO, String endpoint) {
+    /**
+     * The createExperimentInTheDatabase will insert a new experiment in the database according to the given experiment information
+     *
+     * @param experimentDTO is the experiment information to inserted in the database
+     * @return the experiment information that was inserted into the database
+     */
+    private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
@@ -281,7 +419,14 @@ public class ExperimentService {
         experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()));
         experimentDAO.setAlgorithm(experimentDTO.getAlgorithm());
         experimentDAO.setName(experimentDTO.getName());
-        experimentRepository.save(experimentDAO);
+        experimentDAO.setStatus(ExperimentDAO.Status.pending);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
 
         Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
         Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
@@ -298,29 +443,43 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId());
         Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus());
 
-        experimentRepository.save(experimentDAO);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Saved experiment");
     }
 
-    private void finishExperiment(ExperimentDAO experimentDAO) {
+    private void finishExperiment(ExperimentDAO experimentDAO, String endpoint) {
         experimentDAO.setFinished(new Date());
-        experimentRepository.save(experimentDAO);
+        try {
+            experimentRepository.save(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
     }
 
     /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
 
     /**
-     * The runExaremeExperiment will POST the algorithm to the exareme client
+     * The createExaremeExperiment will POST the algorithm to the exareme client
      *
      * @param experimentDTO is the request with the experiment information
-     * @return the response to be returned
+     * @param endpoint is the endpoint that called the function
+     * @return the experiment information that was retrieved from exareme
      */
-    public ResponseEntity<String> createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
+
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
 
-        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
         // Run the 1st algorithm from the list
@@ -339,41 +498,57 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint,
                 "Starting exareme execution thread");
+        ExperimentDTO finalExperimentDTO = experimentDTO;
         new Thread(() -> {
 
             // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
             try {
-
-                // --> New function runExaremeAlgorithm
-                StringBuilder results = new StringBuilder();
-                int code = HTTPUtil.sendPost(url, body, results);
-
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Algorithm finished with code: " + code);
-
                 // Results are stored in the experiment object
-                ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
+                ExaremeResult exaremeResult = runExaremeExperiment(url, body, finalExperimentDTO);
 
-                // <-- New function runExaremeAlgorithm
-
-                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(resultDTO));
-//                experimentDAO.setHasError(code >= 400);
-//                experimentDAO.setHasServerError(code >= 500);
+                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(exaremeResult.result));
+                experimentDAO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
             } catch (Exception e) {
                 Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
 
                 experimentDAO.setStatus(ExperimentDAO.Status.error);
-                experimentDAO.setResult(e.getMessage());
             }
 
-            finishExperiment(experimentDAO);
+            finishExperiment(experimentDAO, endpoint);
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
         }).start();
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
+        return experimentDTO;
     }
 
+    /**
+     * The runExaremeExperiment will run to exareme the experiment
+     *
+     * @param url is the url that contain the results of the experiment
+     * @param body is the parameters of the algorithm
+     * @param experimentDTO is the experiment information to be executed in the exareme
+     * @return the result of exareme as well as the http status that was retrieved
+     */
+    public ExaremeResult runExaremeExperiment(String url,String body, ExperimentDTO experimentDTO) {
+
+        StringBuilder results = new StringBuilder();
+        int code;
+        try {
+            code = HTTPUtil.sendPost(url, body, results);
+        }
+        catch (Exception e){
+            throw new InternalServerError("Error occured : "+ e.getMessage());
+        }
+        Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
+
+        // Results are stored in the experiment object
+        ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
+        return new ExaremeResult(code, resultDTO);
+    }
+
+
     /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
 
 
@@ -383,11 +558,11 @@ public class ExperimentService {
      * @param experimentDTO is the request with the experiment information
      * @return the response to be returned
      */
-    public ResponseEntity<String> runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
 
-        ExperimentDAO experimentDAO = createExperiment(experimentDTO, endpoint);
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
 
@@ -419,8 +594,7 @@ public class ExperimentService {
         if (workflow == null) {
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Could not find algorithm code: " + workflowId);
-            return ResponseEntity.badRequest()
-                    .body(new ErrorResponse("Could not find galaxy algorithm.").toString());
+            throw new BadRequestException("Could not find galaxy algorithm.");
         }
         final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId());
         for (Map.Entry<String, WorkflowInputDefinition> workflowParameter : workflowDetails.getInputs().entrySet()) {
@@ -449,8 +623,7 @@ public class ExperimentService {
 
                 String historyId = (String) new JSONObject(responseBody).get("history_id");
                 experimentDAO.setWorkflowHistoryId(historyId);
-                experimentDAO.setStatus(ExperimentDAO.Status.pending);
-//                experimentDAO.setHasServerError(response.code() >= 500);
+                experimentDAO.setStatus(ExperimentDAO.Status.success);
 
             } else {     // Something unexpected happened
                 String msgErr = gson.toJson(response.errorBody());
@@ -460,15 +633,12 @@ public class ExperimentService {
                 JSONObject jObjectError = new JSONObject(msgErr);
                 String errMsg = jObjectError.get("err_msg").toString();
 
-                experimentDAO.setResult(errMsg);
-//                experimentDAO.setHasError(response.code() >= 400);
-//                experimentDAO.setHasServerError(response.code() >= 500);
+                experimentDTO.setStatus((response.code()>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
             }
 
         } catch (Exception e) {
             Logging.LogUserAction(user.getUsername(), endpoint, "An exception occurred: " + e.getMessage());
             experimentDAO.setStatus(ExperimentDAO.Status.error);
-            experimentDAO.setResult(e.getMessage());
         }
         saveExperiment(experimentDAO, endpoint);
 
@@ -478,7 +648,7 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
 
         experimentDTO = experimentDAO.convertToDTO();
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
+        return experimentDTO;
     }
 
 
@@ -543,19 +713,20 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
-                                experimentDAO.setResult("[" + result + "]");
-                                experimentDAO.setStatus(ExperimentDAO.Status.success);
-                                resultFound = true;
+                                else {
+                                    experimentDAO.setResult("[" + result + "]");
+                                    experimentDAO.setStatus(ExperimentDAO.Status.success);
+                                    resultFound = true;
+                                }
                             }
                         }
 
                         if (!resultFound) {      // If there is no visible result
                             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
-                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no visible result.").toString() + "]");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
 
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
 
                     case "error":
@@ -574,7 +745,6 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
-                                experimentDAO.setResult("[" + result + "]");
                                 experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 failedJobFound = true;
                             }
@@ -582,16 +752,15 @@ public class ExperimentService {
 
                         if (!failedJobFound) {      // If there is no visible failed job
                             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
-                            experimentDAO.setResult("[" + new ErrorResponse("The workflow has no failed result.").toString() + "]");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
 
                     default:        // InternalError or unexpected result
-                        experimentDAO.setResult("[" + new ErrorResponse("An unexpected error occurred.").toString() + "]");
+                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
                         experimentDAO.setStatus(ExperimentDAO.Status.error);
-                        finishExperiment(experimentDAO);
+                        finishExperiment(experimentDAO, endpoint);
                         break;
                 }
 
@@ -624,7 +793,7 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> call = service.getWorkflowStatusFromGalaxy(historyId, galaxyApiKey);
 
-        String result = null;
+        String result;
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
@@ -640,7 +809,7 @@ public class ExperimentService {
             return "internalError";
         }
 
-        String state = null;
+        String state;
         try {
             JSONObject resultJson = new JSONObject(result);
             state = resultJson.getString("state");
@@ -679,7 +848,7 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
 
-        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList = null;
+        List<GalaxyWorkflowResult> getGalaxyWorkflowResultList;
         try {
             Response<List<GalaxyWorkflowResult>> response = call.execute();
             if (response.code() >= 400) {
@@ -717,7 +886,7 @@ public class ExperimentService {
         Call<Object> call =
                 service.getWorkflowResultsBodyFromGalaxy(historyId, contentId, galaxyApiKey);
 
-        String resultJson = null;
+        String resultJson ;
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
@@ -751,8 +920,8 @@ public class ExperimentService {
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
 
-        String fullError = null;
-        String returnError = null;
+        String fullError;
+        String returnError;
         try {
             Response<Object> response = callError.execute();
             if (response.code() >= 400) {
@@ -782,4 +951,22 @@ public class ExperimentService {
 
         return returnError;
     }
+
+    final class ExaremeResult {
+        private final int code;
+        private final ExperimentDTO.ResultDTO result;
+
+        public ExaremeResult(int code, ExperimentDTO.ResultDTO result) {
+            this.code = code;
+            this.result = result;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public ExperimentDTO.ResultDTO getResult() {
+            return result;
+        }
+    }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index 6596a319a..076249e0b 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -16,7 +16,7 @@ public class ExperimentSpecifications {
 
         public  ExperimentWithName(String name){
             this.name = name;
-            this.regExp = "%"+name+"%";
+            this.regExp = name;
         }
 
         public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb)
@@ -24,8 +24,11 @@ public class ExperimentSpecifications {
             if (name == null) {
                 return cb.isTrue(cb.literal(true));
             }
+            else {
+                regExp = (name.contains("%")?name:name+"%");
+            }
 
-            return cb.like( root.get( "name" ), regExp );
+            return cb.like( root.get( "name" ), this.regExp );
         }
     }
     public static class ExperimentWithAlgorithm implements Specification<ExperimentDAO> {
diff --git a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
index 4e6f8da32..7f644fb7f 100644
--- a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
+++ b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
@@ -1,26 +1,80 @@
 package eu.hbp.mip.utils;
 
+import eu.hbp.mip.utils.Exceptions.*;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
 
 import java.util.Date;
 
 @ControllerAdvice
-public class ControllerExceptionHandler {
+public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
+
+    @ExceptionHandler(ExperimentNotFoundException.class)
+    public ResponseEntity<Object> handleExperimentNotFoundException(ExperimentNotFoundException ex, WebRequest request) {
 
-    @ExceptionHandler(ResourceNotFoundException.class)
-    public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
         ErrorMessage message = new ErrorMessage(
-                2,
+                HttpStatus.NOT_FOUND.value(),
                 new Date(),
                 ex.getMessage(),
                 request.getDescription(false));
 
         return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);
     }
+    
+    @ExceptionHandler(BadRequestException.class)
+    public ResponseEntity<Object> handleBadRequestException(BadRequestException ex, WebRequest request) {
+
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.BAD_REQUEST.value(),
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(UnauthorizedException.class)
+    public ResponseEntity<Object> handleUnauthorizedException(UnauthorizedException ex, WebRequest request) {
+
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.UNAUTHORIZED.value(),
+                new Date(),
+                ex.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.UNAUTHORIZED);
+    }
+
+    @ExceptionHandler(IllegalArgumentException.class)
+    public Object handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
+        return null;
+    }
+
+    @ExceptionHandler(InternalServerError.class)
+    public ResponseEntity<ErrorMessage> handleInternalServerError(InternalServerError er, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.INTERNAL_SERVER_ERROR.value(),
+                new Date(),
+                er.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+
+    @ExceptionHandler(NoContent.class)
+    public ResponseEntity<ErrorMessage> handleNoContent(NoContent nc, WebRequest request) {
+        ErrorMessage message = new ErrorMessage(
+                HttpStatus.NO_CONTENT.value(),
+                new Date(),
+                nc.getMessage(),
+                request.getDescription(false));
+
+        return new ResponseEntity<>(message, HttpStatus.NO_CONTENT);
+    }
 
     @ExceptionHandler(Exception.class)
     public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
new file mode 100644
index 000000000..6684cae28
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/BadRequestException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class BadRequestException extends RuntimeException {
+
+    public BadRequestException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
new file mode 100644
index 000000000..b8e05d7e6
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class ExperimentNotFoundException extends RuntimeException {
+
+    public ExperimentNotFoundException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java b/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
new file mode 100644
index 000000000..19bc88eed
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/InternalServerError.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class InternalServerError extends RuntimeException {
+
+    public InternalServerError(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java b/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
new file mode 100644
index 000000000..9bb67d811
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/NoContent.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class NoContent extends RuntimeException {
+
+    public NoContent(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java b/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
new file mode 100644
index 000000000..379911dae
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/Exceptions/UnauthorizedException.java
@@ -0,0 +1,8 @@
+package eu.hbp.mip.utils.Exceptions;
+
+public class UnauthorizedException extends RuntimeException {
+
+    public UnauthorizedException(String msg) {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java b/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
deleted file mode 100644
index 38f067c42..000000000
--- a/src/main/java/eu/hbp/mip/utils/ResourceNotFoundException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package eu.hbp.mip.utils;
-
-public class ResourceNotFoundException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    public ResourceNotFoundException(String msg) {
-        super(msg);
-    }
-}
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V7_0__NewExperimentStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
similarity index 100%
rename from src/main/resources/db/migration/V7_0__NewExperimentStructure.sql
rename to src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
-- 
GitLab


From 0d48ca86b1c3ef494dc8a1ca14f7e216252bdc43 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Wed, 11 Nov 2020 05:19:52 -0800
Subject: [PATCH 19/52] Fixing 404 message on login as well as on swagger.

---
 pom.xml                                                      | 4 ++++
 src/main/java/eu/hbp/mip/configuration/WebConfiguration.java | 2 --
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index e5d87b28f..e50a9bf47 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
+        <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-rest</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
index 17e38a5ee..72bcad789 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
@@ -2,7 +2,6 @@ package eu.hbp.mip.configuration;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.data.web.config.EnableSpringDataWebSupport;
 import springfox.documentation.builders.ApiInfoBuilder;
 import springfox.documentation.builders.RequestHandlerSelectors;
 import springfox.documentation.service.ApiInfo;
@@ -17,7 +16,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 @Configuration
 @EnableSwagger2
-@EnableSpringDataWebSupport
 public class WebConfiguration {
 
 //    @Bean
-- 
GitLab


From 4a162ad3d37bf94c69993dac520ec671b135930f Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 11 Nov 2020 11:51:08 -0800
Subject: [PATCH 20/52] Security API refactoring. 1) User API moved from
 Security API> 2) UserInfo is not activeUserService. 3) User Details read from
 Keycloak Authentication Token. 4) Added application.yml to develop the
 portal-backend without dockerizing.

---
 docker/README.md                              |  2 +-
 pom.xml                                       |  1 +
 .../configuration/SecurityConfiguration.java  |  8 +-
 .../eu/hbp/mip/controllers/AlgorithmsApi.java | 36 ++++----
 .../eu/hbp/mip/controllers/ExperimentApi.java |  4 +-
 .../hbp/mip/controllers/PathologiesApi.java   | 14 +--
 .../eu/hbp/mip/controllers/SecurityApi.java   | 75 +++-------------
 .../java/eu/hbp/mip/controllers/UsersApi.java | 63 +++++++++++---
 .../java/eu/hbp/mip/model/DAOs/UserDAO.java   | 57 +++----------
 .../java/eu/hbp/mip/model/GeneralStats.java   | 41 ---------
 src/main/java/eu/hbp/mip/model/UserInfo.java  | 85 -------------------
 .../hbp/mip/services/ActiveUserService.java   | 73 ++++++++++++++++
 .../hbp/mip/services/ExperimentService.java   | 27 +++---
 src/main/resources/application.yml            | 84 ++++++++++++++++++
 src/main/resources/test.test                  | 64 ++++++++++++++
 15 files changed, 341 insertions(+), 293 deletions(-)
 delete mode 100644 src/main/java/eu/hbp/mip/model/GeneralStats.java
 delete mode 100644 src/main/java/eu/hbp/mip/model/UserInfo.java
 create mode 100644 src/main/java/eu/hbp/mip/services/ActiveUserService.java
 create mode 100644 src/main/resources/application.yml
 create mode 100644 src/main/resources/test.test

diff --git a/docker/README.md b/docker/README.md
index cc8c59fe1..da8299413 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -33,7 +33,7 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 * CLIENT_SECRET: required when authentication is turned on, client secret for the [OpenID server of HBP](https://services.humanbrainproject.eu/oidc/).
 * TOKEN_URI: default to "https://services.humanbrainproject.eu/oidc/token".
 * AUTH_URI: default to "https://services.humanbrainproject.eu/oidc/authorize".
-* USER_INFO_URI: default to "https://services.humanbrainproject.eu/oidc/userinfo".
+* USER_INFO_URI: default to "https://services.humanbrainproject.eu/oidc/userInfo".
 * REVOKE_TOKEN_URI "https://services.humanbrainproject.eu/oidc/slo".
 
 
diff --git a/pom.xml b/pom.xml
index e50a9bf47..5292dffd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -274,6 +274,7 @@
                     <include>**/*.csv</include>
                     <include>**/*.sql</include>
                     <include>**/*.conf</include>
+                    <include>**/*.yml</include>    <!--  Only for development -->
                 </includes>
                 <filtering>true</filtering>
             </resource>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index d2a0dd739..22f904af5 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -99,7 +99,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     @Autowired
     public void configureGlobal(AuthenticationManagerBuilder auth) {
         SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
-        //grantedAuthorityMapper.setPrefix("ROLE_");
         grantedAuthorityMapper.setConvertToUpperCase(true);
 
         KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
@@ -125,6 +124,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
             http.antMatcher("/**")
                     .authorizeRequests()
                     .antMatchers("/**").permitAll()
+                    .and().csrf().disable();
 //                    .antMatchers(
 //                            "/login**", "/health/**", "/info/**", "/metrics/**",
 //                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
@@ -134,8 +134,8 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
 //                    .anyRequest().hasRole("RESEARCHER")
                    // .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
                    // .accessDeniedHandler(new CustomAccessDeniedHandler())
-                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf();
+//                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+//                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf();
 //                    .and().logout().logoutSuccessUrl("/logout");
 //
 //
@@ -171,7 +171,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
 //        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
 //        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
 //        hbpFilter.setRestTemplate(hbpTemplate);
-//        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
+//        hbpFilter.setTokenServices(new activeUserServiceTokenServices(hbpResource().getactiveUserServiceUri(), hbp().getClientId()));
 //        return hbpFilter;
 //    }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index d5dca19ae..51fc1b485 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -9,7 +9,7 @@ import com.google.gson.reflect.TypeToken;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
-import eu.hbp.mip.model.UserInfo;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.model.galaxy.WorkflowDTO;
 import eu.hbp.mip.utils.CustomResourceLoader;
 import eu.hbp.mip.utils.HTTPUtil;
@@ -42,7 +42,7 @@ public class AlgorithmsApi {
     private static final Gson gson = new Gson();
 
     @Autowired
-    private UserInfo userInfo;
+    private ActiveUserService activeUserService;
 
     @Value("#{'${services.exareme.algorithmsUrl}'}")
     private String exaremeAlgorithmsUrl;
@@ -56,24 +56,24 @@ public class AlgorithmsApi {
     @ApiOperation(value = "List all algorithms", response = String.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Executing...");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Executing...");
 
         LinkedList<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms();
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
         LinkedList<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows();
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
 
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         if (exaremeAlgorithms != null) {
             algorithms.addAll(exaremeAlgorithms);
         } else {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                     "Getting exareme algorithms failed and returned null");
         }
         if (galaxyAlgorithms != null) {
             algorithms.addAll(galaxyAlgorithms);
         } else {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                     "Getting galaxy workflows failed and returned null");
         }
 
@@ -81,7 +81,7 @@ public class AlgorithmsApi {
         try {
             disabledAlgorithms = getDisabledAlgorithms();
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                     "The disabled algorithms could not be loaded.");
         }
 
@@ -92,7 +92,7 @@ public class AlgorithmsApi {
                 allowedAlgorithms.add(algorithm);
             }
         }
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                 "Successfully listed " + allowedAlgorithms.size() + " algorithms");
         return ResponseEntity.ok(allowedAlgorithms);
     }
@@ -115,11 +115,11 @@ public class AlgorithmsApi {
                     }.getType()
             );
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
             return null;
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                 "Completed, returned " + algorithms.size() + " algorithms.");
         return algorithms;
     }
@@ -139,7 +139,7 @@ public class AlgorithmsApi {
 
             workflowList = new ArrayList<>(workflowsClient.getWorkflows());
         } catch (Exception e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Error when calling list galaxy workflows: " + e.getMessage());
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Error when calling list galaxy workflows: " + e.getMessage());
 
             return null;
         }
@@ -159,28 +159,28 @@ public class AlgorithmsApi {
 
                 } else {     // Something unexpected happened
                     String msgErr = gson.toJson(response.errorBody());
-                    Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Error Response: " + msgErr);
+                    Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Error Response: " + msgErr);
                     return null;
                 }
             } catch (Exception e) {
-                Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
+                Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
                 return null;
             }
         }
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Workflows fetched: " + workflows.size());
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Workflows fetched: " + workflows.size());
 
         // Convert the workflows to algorithms
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         for (WorkflowDTO workflow : workflows) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Converting workflow: " + workflow);
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Converting workflow: " + workflow);
 
             algorithms.add(workflow.convertToAlgorithmDTO());
 
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms",
                     "Converted algorithm: " + algorithms.get(algorithms.size() - 1));
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Completed!");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms", "Completed!");
         return algorithms;
     }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index 322f33f4f..d5fc161b1 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -1,7 +1,7 @@
 package eu.hbp.mip.controllers;
 
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.UserInfo;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.ExperimentService;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.Api;
@@ -28,7 +28,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 public class ExperimentApi {
 
     @Autowired
-    private UserInfo userInfo;
+    private ActiveUserService activeUserService;
 
     @Autowired
     private ExperimentService experimentService;
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 6c89e1b94..055b04b23 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -7,7 +7,7 @@ package eu.hbp.mip.controllers;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import eu.hbp.mip.model.DTOs.PathologyDTO;
-import eu.hbp.mip.model.UserInfo;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
 import eu.hbp.mip.utils.Exceptions.BadRequestException;
@@ -36,7 +36,7 @@ public class PathologiesApi {
     private static final Gson gson = new Gson();
 
     @Autowired
-    private UserInfo userInfo;
+    private ActiveUserService activeUserService;
 
     // Enable HBP collab authentication (1) or disable it (0). Default is 1
     @Value("#{'${authentication.enabled}'}")
@@ -47,7 +47,7 @@ public class PathologiesApi {
 
     @RequestMapping(name = "/pathologies", method = RequestMethod.GET)
     public ResponseEntity<String> getPathologies(Authentication authentication) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Loading pathologies ...");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Loading pathologies ...");
 
         // Load pathologies from file
         Resource resource = resourceLoader.getResource("file:/opt/portal/api/pathologies.json");
@@ -56,18 +56,18 @@ public class PathologiesApi {
             allPathologies = gson.fromJson(InputStreamConverter.convertInputStreamToString(resource.getInputStream()), new TypeToken<List<PathologyDTO>>() {
             }.getType());
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
             throw new BadRequestException("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
         if (!authenticationIsEnabled) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Successfully loaded " + allPathologies.size() + " pathologies");
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Successfully loaded " + allPathologies.size() + " pathologies");
             return ResponseEntity.ok().body(gson.toJson(allPathologies));
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Successfully loaded all authorized pathologies");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Successfully loaded all authorized pathologies");
         return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies(
-                userInfo.getUser().getUsername(), authentication.getAuthorities(), allPathologies));
+                activeUserService.getActiveUser().getUsername(), authentication.getAuthorities(), allPathologies));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index 9d2b66492..696fac039 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -1,29 +1,23 @@
 package eu.hbp.mip.controllers;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import eu.hbp.mip.configuration.SecurityConfiguration;
-import eu.hbp.mip.model.DAOs.UserDAO;
-import eu.hbp.mip.model.UserInfo;
-import eu.hbp.mip.repositories.UserRepository;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logging;
-import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.security.Principal;
 import java.util.Base64;
 
 @RestController
@@ -32,64 +26,21 @@ public class SecurityApi {
     private static final Gson gson = new Gson();
 
     @Autowired
-    private UserInfo userInfo;
-
-    @Autowired
-    private UserRepository userRepository;
+    private ActiveUserService activeUserService;
 
     @Autowired
     private SecurityConfiguration securityConfiguration;
 
-    @RequestMapping(path = "/user", method = RequestMethod.GET)
-    public Object user(Principal principal, HttpServletResponse response) {
-        ObjectMapper mapper = new ObjectMapper();
-
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user", "Loading user : " + userInfo.getUser().getUsername());
-        try {
-            String userJSON = mapper.writeValueAsString(userInfo.getUser());
-            Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8"));
-            cookie.setSecure(true);
-            cookie.setPath("/");
-            response.addCookie(cookie);
-        } catch (JsonProcessingException | UnsupportedEncodingException e) {
-            //LOGGER.trace("Cannot read user json", e);
-        }
-
-        if (!securityConfiguration.getAuthenticationEnabled()) {
-            if (userInfo.getFakeAuth()) {
-                response.setStatus(401);
-            }
-            String principalJson = "{\"principal\": \"anonymous\", \"name\": \"anonymous\", \"userAuthentication\": {"
-                    + "\"details\": {\"preferred_username\": \"anonymous\"}}}";
-            return new Gson().fromJson(principalJson, Object.class);
-        }
 
-        return principal;
-    }
-
-    @RequestMapping(path = "/user", method = RequestMethod.POST)
-    public ResponseEntity<Void> postUser(
-            @ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA") Boolean agreeNDA) {
-        UserDAO user = userInfo.getUser();
-        if (user != null) {
-            user.setAgreeNDA(agreeNDA);
-            userRepository.save(user);
-        }
+    // TODO How to redirect? keycloak off?
+    @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
+    @ConditionalOnExpression("${authentication.enabled:0}")
+    public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(POST) /user", "User has agreed on the NDA");
-
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
     }
 
-//    @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
-//    @ConditionalOnExpression("${authentication.enabled:0}")
-//    public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
-//        userInfo.setFakeAuth(true);
-//        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
-//
-//        httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
-//    }
-
     @Value("#{'${services.galaxy.galaxyUsername:admin}'}")
     private String galaxyUsername;
 
@@ -112,7 +63,7 @@ public class SecurityApi {
         JsonObject object = new JsonObject();
         object.addProperty("authorization", stringEncoded);
         object.addProperty("context", galaxyContext);
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /user/galaxy", "Successfully Loaded galaxy information.");
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/galaxy", "Successfully Loaded galaxy information.");
 
         return ResponseEntity.ok(gson.toJson(object));
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index 886ad1ac9..66f34b670 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -1,43 +1,80 @@
-/*
- * Created by mirco on 14.01.16.
- */
-
 package eu.hbp.mip.controllers;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import eu.hbp.mip.model.DAOs.UserDAO;
-import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.repositories.UserRepository;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 @RestController
 @RequestMapping(value = "/users", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/users", description = "the users API")
+@Api(value = "/users")
 public class UsersApi {
 
     @Autowired
-    private UserRepository userRepository;
+    private ActiveUserService activeUserService;
 
     @Autowired
-    private UserInfo userInfo;
+    private UserRepository userRepository;
 
     @ApiOperation(value = "Get a user", response = UserDAO.class)
     @RequestMapping(value = "/{username}", method = RequestMethod.GET)
     public ResponseEntity<UserDAO> getAUser(
             @ApiParam(value = "username", required = true) @PathVariable("username") String username
     ) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /users/{username}", "Loaded a user with username : " + userInfo.getUser().getUsername());
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/{username}",
+                "Loaded a user with username : " + username);
 
+        // TODO Error handling?
         return ResponseEntity.ok(userRepository.findByUsername(username));
     }
+
+    @ApiOperation(value = "Get the active user", response = UserDAO.class)
+    @RequestMapping(value = "/activeUser", method = RequestMethod.GET)
+    public ResponseEntity<UserDAO> getTheActiveUser(HttpServletResponse response) {
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/activeUser",
+                "Loading the details of the activeUser");
+
+        UserDAO activeUser = activeUserService.getActiveUser();
+
+        // Add the active user to a cookie
+        try {
+            // TODO needed? Ask Manuel
+            ObjectMapper mapper = new ObjectMapper();
+            String userJSON = mapper.writeValueAsString(activeUser);
+            Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8"));
+            cookie.setSecure(true);
+            cookie.setPath("/");
+            response.addCookie(cookie);
+        } catch (JsonProcessingException | UnsupportedEncodingException e) {
+            Logging.LogUserAction(activeUser.getUsername(),
+                    "(GET) /users/activeUser", "Failed to add Cookie. Exception: " + e.getMessage());
+        }
+
+        return ResponseEntity.ok(activeUserService.getActiveUser());
+    }
+
+    // TODO Kostas, why not working?
+    @ApiOperation(value = "The active user agrees to the NDA", response = UserDAO.class)
+    @RequestMapping(value = "/activeUser/agreeNDA", method = RequestMethod.POST)
+    public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(@RequestBody(required = false) UserDAO userDAO) {
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/activeUser/agreeNDA",
+                "The user agreed to the NDA");
+
+        return ResponseEntity.ok(activeUserService.agreeToNDA());
+    }
 }
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
index 0d0ba246d..0e1e9a9ff 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
@@ -20,63 +20,28 @@ public class UserDAO {
 
     @Id
     @Expose
-    private String username = null;
+    private String username;
 
     @Expose
-    private String fullname = null;
+    private String fullname;
 
     @Expose
-    private String email = null;
-
-    private Boolean agreeNDA = null;
+    private String email;
 
+    @Expose
+    private Boolean agreeNDA;
 
     public UserDAO() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
+        // Empty constructor is needed by Hibernate
     }
 
-
-    /**
-     * Create a user using OpenID user profile
-     *
-     * @param userInfo info from OpenID UserInfo endpoint
-     */
-    public UserDAO(String userInfo) {
-
-
-        // TODO fix
-        this.username = "test";
-        this.fullname = "test";
-        this.email = "test";
-
-        //
-//        Pattern p;
-//        Matcher m;
-//
-//        p = Pattern.compile("preferred_username=([\\w- ]+)");
-//        m = p.matcher(userInfo);
-//        if (m.find()) {
-//            this.username = m.group(1);
-//        }
-//
-//        p = Pattern.compile("name=([\\w ]+)");
-//        m = p.matcher(userInfo);
-//        if (m.find()) {
-//            this.fullname = m.group(1);
-//        }
-//
-//        p = Pattern.compile("email=([\\w.]+@[\\w.]+)");
-//        m = p.matcher(userInfo);
-//        if (m.find()) {
-//            this.email = m.group(1);
-//        }
-
-
+    public UserDAO(String username, String fullname, String email) {
+        this.username = username;
+        this.fullname = fullname;
+        this.email = email;
+        this.agreeNDA = false;
     }
 
-
     public String getFullname() {
         return fullname;
     }
diff --git a/src/main/java/eu/hbp/mip/model/GeneralStats.java b/src/main/java/eu/hbp/mip/model/GeneralStats.java
deleted file mode 100644
index 4253ae7dd..000000000
--- a/src/main/java/eu/hbp/mip/model/GeneralStats.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Created by mirco on 03.02.16.
- */
-
-package eu.hbp.mip.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import io.swagger.annotations.ApiModel;
-
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class GeneralStats {
-
-    private Long users = null;
-    private Long articles = null;
-
-
-    public GeneralStats() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-    }
-
-
-    public Long getUsers() {
-        return users;
-    }
-
-    public void setUsers(Long users) {
-        this.users = users;
-    }
-
-
-    public Long getArticles() {
-        return articles;
-    }
-
-    public void setArticles(Long articles) {
-        this.articles = articles;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java
deleted file mode 100644
index 617b25a5f..000000000
--- a/src/main/java/eu/hbp/mip/model/UserInfo.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package eu.hbp.mip.model;
-
-import eu.hbp.mip.model.DAOs.UserDAO;
-import eu.hbp.mip.repositories.UserRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Scope;
-import org.springframework.context.annotation.ScopedProxyMode;
-import org.springframework.stereotype.Component;
-
-import javax.inject.Named;
-
-@Component
-@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
-@Named("userInfo")
-public class UserInfo {
-
-    @Autowired
-    private UserRepository userRepository;
-
-    /**
-     * Enable HBP collab authentication (1) or disable it (0). Default is 1
-     */
-    @Value("#{'${authentication.enabled}'}")
-    private boolean authentication;
-
-    private UserDAO user;
-
-    /**
-     * Set to true if using no-auth mode and user has clicked on the login button
-     */
-    private boolean fakeAuth = false;
-
-    /**
-     * returns the user for the current session.
-     * <p>
-     * the "synchronized" keyword is there to avoid a bug that the transaction is supposed to protect me from.
-     * To test if your solution to removing it works, do the following:
-     * - clean DB from scratch
-     * - restart DB and backend (no session or anything like that)
-     * - log in using the front end
-     * - check you have no 500 error in the network logs.
-     *
-     * @return the user for the current session
-     */
-    public UserDAO getUser() {
-        if (user == null) {
-
-            if (!authentication) {
-                user = new UserDAO();
-                user.setUsername("anonymous");
-                user.setFullname("anonymous");
-                user.setEmail("anonymous@anonymous.com");
-            } else {
-                user = new UserDAO(getUserInformation());
-            }
-
-            UserDAO foundUser = userRepository.findByUsername(user.getUsername());
-            if (foundUser != null) {
-                user.setAgreeNDA(foundUser.getAgreeNDA());
-            }
-            userRepository.save(user);
-        }
-
-        return user;
-    }
-
-    public boolean getFakeAuth() {
-        return fakeAuth;
-    }
-
-    public void setFakeAuth(boolean fakeAuth) {
-        this.fakeAuth = fakeAuth;
-    }
-
-    private String getUserInformation() {
-        // TODO
-        return "";
-        // get details from keycloak configuration
-//        OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
-//        Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
-//        return userAuthentication.getDetails().toString();
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
new file mode 100644
index 000000000..d925ce3f5
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -0,0 +1,73 @@
+package eu.hbp.mip.services;
+
+import eu.hbp.mip.model.DAOs.UserDAO;
+import eu.hbp.mip.repositories.UserRepository;
+import org.keycloak.KeycloakPrincipal;
+import org.keycloak.representations.IDToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Named;
+
+@Component
+@Named("ActiveUserService")
+@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
+public class ActiveUserService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Value("#{'${authentication.enabled}'}")
+    private boolean authentication;
+
+    private UserDAO user;
+
+    /**
+     * Fetches the details of the active user.
+     * If the user doesn't exist, it's created on the fly from the auth token.
+     *
+     * @return the userDAO
+     */
+    public UserDAO getActiveUser() {
+
+        // User already loaded
+        if (user != null)
+            return user;
+
+        // If Authentication is OFF, create anonymous user with accepted NDA
+        if (!authentication) {
+            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com");
+            user.setAgreeNDA(true);
+            userRepository.save(user);
+            return user;
+        }
+
+        // If authentication is ON
+        KeycloakPrincipal keycloakPrincipal =
+                (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        IDToken idToken = keycloakPrincipal.getKeycloakSecurityContext().getIdToken();
+        UserDAO userInDatabase = userRepository.findByUsername(idToken.getPreferredUsername());
+        if (userInDatabase != null) {
+            user = userInDatabase;
+        } else {
+            UserDAO newUser = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail());
+            userRepository.save(newUser);
+            user = newUser;
+        }
+        return user;
+    }
+
+    public UserDAO agreeToNDA() {
+        // Fetch the active user
+        getActiveUser();
+
+        user.setAgreeNDA(true);
+        userRepository.save(user);
+
+        return user;
+    }
+}
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index d11971ddd..7ffffc7eb 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -16,7 +16,6 @@ import eu.hbp.mip.model.DAOs.ExperimentDAO;
 import eu.hbp.mip.model.DAOs.UserDAO;
 import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
 import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
@@ -47,7 +46,7 @@ import static java.lang.Thread.sleep;
 public class ExperimentService {
 
     @Autowired
-    private UserInfo userInfo;
+    private ActiveUserService activeUserService;
 
     @Value("#{'${services.exareme.queryExaremeUrl}'}")
     private String queryExaremeUrl;
@@ -80,7 +79,7 @@ public class ExperimentService {
      * @return a list of mapped experiments
      */
     public Map getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
         if(size > 10 )
             throw new BadRequestException("Invalid size input, max size is 10.");
@@ -120,7 +119,7 @@ public class ExperimentService {
     public ExperimentDTO getExperiment(String uuid, String endpoint) {
 
         ExperimentDAO experimentDAO;
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
@@ -145,7 +144,7 @@ public class ExperimentService {
      * @return the experiment information which was created
      */
     public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
         if (checkPostExperimentProperInput(experimentDTO)){
@@ -208,7 +207,7 @@ public class ExperimentService {
      * @return the experiment information which was created
      */
     public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint){
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
         if (checkPostExperimentProperInput(experimentDTO)){
@@ -288,7 +287,7 @@ public class ExperimentService {
     public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint)
     {
         ExperimentDAO experimentDAO;
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + experimentDTO.getUuid() + ".");
         //Checking if check (PUT) /experiments has proper input.
         if (checkPutExperimentProperInput(experimentDTO)){
@@ -347,7 +346,7 @@ public class ExperimentService {
     public void deleteExperiment(String uuid, String endpoint)
     {
         ExperimentDAO experimentDAO;
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
         experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
@@ -411,7 +410,7 @@ public class ExperimentService {
      * @return the experiment information that was inserted into the database
      */
     private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
         experimentDAO.setUuid(UUID.randomUUID());
@@ -435,7 +434,7 @@ public class ExperimentService {
     }
 
     private void saveExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
         Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
@@ -460,7 +459,7 @@ public class ExperimentService {
             experimentRepository.save(experimentDAO);
         }
         catch (Exception e){
-            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
     }
@@ -476,7 +475,7 @@ public class ExperimentService {
      */
     public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
 
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
 
         ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
@@ -559,7 +558,7 @@ public class ExperimentService {
      * @return the response to be returned
      */
     public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
 
         ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
@@ -660,7 +659,7 @@ public class ExperimentService {
      * @return nothing, just updates the experiment
      */
     public void updateWorkflowExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        UserDAO user = userInfo.getUser();
+        UserDAO user = activeUserService.getActiveUser();
 
         if (experimentDAO == null) {
             Logging.LogUserAction(user.getUsername(), endpoint, "The experiment does not exist.");
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 000000000..65ab563a9
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,84 @@
+# Configuration template for the portal running inside a Docker container
+
+# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+spring:
+  portal-datasource:
+    url: "jdbc:postgresql://127.0.0.1:5433/portal"
+    schema: "public"
+    username: "portal"
+    password: "portalpwd"
+    driver-class-name: org.postgresql.Driver
+
+  data:
+    jpa:
+      repositories:
+        bootstrap-mode: default
+  jpa:
+    hibernate:
+      dialect: org.hibernate.dialect.PostgreSQL9Dialect
+      ddl-auto: validate
+
+# WEB FRONTEND
+frontend:
+  loginUrl: "http://127.0.0.1/services/login/hbp"
+  redirectAfterLoginUrl: "http://127.0.0.1/"
+  redirectAfterLogoutUrl: "http://127.0.0.1/services/login/hbp"
+
+logging:
+  level:
+    root: "DEBUG"
+    org: "DEBUG"
+    eu:
+      hbp: "DEBUG"
+
+# EMBEDDED SERVER CONFIGURATION
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+  session:
+    timeout: "2592000"
+
+# ENDPOINTS
+endpoints:
+  enabled: true
+  health:
+    enabled: true
+    endpoint: "/health"
+    sensitive: false
+
+# External Services
+services:
+  exareme:
+    queryExaremeUrl: "http://127.0.0.1:9090/mining/query"
+    algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json"
+
+  galaxy:
+    galaxyUrl: "http://127.0.0.1:8090"
+    galaxyContext:  "nativeGalaxy/workflows/list"
+    galaxyApiKey:   "d14a4cc5eebf805eb2ff261374ed08a2"
+    galaxyUsername:  "admin"
+    galaxyPassword:  "password"
+
+# Authentication
+authentication:
+  enabled: true
+
+# Keycloak
+keycloak:
+  enabled: true
+  auth-server-url: "http://127.0.0.1/auth"
+  realm: "MIP"
+  resource: "MIP"
+  enable-basic-auth: true
+  credentials:
+    secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
+  principal-attribute: "preferred_username"
+  #  cors: true
+  #  cors-max-age: 3600
+  #  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
+  #  cors-allowed-headers: "*"
+  #  cors-exposed-headers: "*"
+
+  # logoutUrl: {{ .Env.LOGOUT_URL }}
diff --git a/src/main/resources/test.test b/src/main/resources/test.test
new file mode 100644
index 000000000..84be80128
--- /dev/null
+++ b/src/main/resources/test.test
@@ -0,0 +1,64 @@
+# Configuration template for the portal running inside a Docker container
+
+# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+
+spring.portal-datasource.url="jdbc:postgresql://127.0.0.1:5433/portal"
+spring.portal-datasource.schema="public"
+spring.portal-datasource.username="portal"
+spring.portal-datasource.password="portalpwd"
+spring.portal-datasource.driver-class-name=org.postgresql.Driver
+
+spring.data.jpa.repositories.bootstrap-mode=default
+spring.jpa.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
+spring.jpa.hibernate.ddl-auto=validate
+
+# WEB FRONTEND
+frontend.loginUrl="http://127.0.0.1/services/login/hbp" }}
+frontend.redirectAfterLoginUrl="http://127.0.0.1/"
+frontend.redirectAfterLogoutUrl="http://127.0.0.1/services/login/hbp"
+
+logging.level.root="DEBUG"
+logging.level.org="DEBUG"
+logging.level.eu.hbp="DEBUG"
+
+# EMBEDDED SERVER CONFIGURATION
+server.servlet.contextPath="/services"
+server.port=8080
+server.forward-headers-strategy=native
+server.session.timeout="2592000"
+
+# ENDPOINTS
+endpoints.enabled=true
+endpoints.health.enabled: true
+endpoints.health.endpoint: "/health"
+endpoints.health.sensitive: false
+
+# External Services
+services.exareme.queryExaremeUrl="http://localhost:9090/mining/query"
+services.exareme.algorithmsUrl="http://localhost:9090/mining/algorithms.json"
+
+
+galaxy.galaxyUrl="http://localhost:8090/"
+galaxy.galaxyContext="nativeGalaxy/workflows/list"
+galaxy.galaxyApiKey="sfas"
+galaxy.galaxyUsername="admin"
+galaxy.galaxyPassword="password"
+
+# Authentication
+authentication.enabled="1"
+
+# Keycloak
+keycloak.enabled=true
+keycloak.auth-server-url="http://127.0.0.1/auth"
+keycloak.realm="MIP"
+keycloak.resource="MIP"
+keycloak.enable-basic-auth=true
+keycloak.credentials.secret="dae83a6b-c769-4186-8383-f0984c6edf05"
+keycloak.principal-attribute="preferred_username"
+#  cors: true
+#  cors-max-age: 3600
+#  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
+#  cors-allowed-headers: "*"
+#  cors-exposed-headers: "*"
+
+# logoutUrl: {{ .Env.LOGOUT_URL }}
-- 
GitLab


From 1705e121ced29773bcd66b89a05c9fb3e0589d53 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Thu, 12 Nov 2020 02:30:46 -0800
Subject: [PATCH 21/52] Added custom application.yml for non docker deployment.

---
 pom.xml                                       |  1 +
 .../PersistenceConfiguration.java             |  1 -
 src/main/resources/application.conf           | 20 -----
 src/main/resources/application.yml            | 75 +++++++++++++++++++
 src/main/resources/kamon.conf                 | 75 -------------------
 5 files changed, 76 insertions(+), 96 deletions(-)
 delete mode 100644 src/main/resources/application.conf
 create mode 100644 src/main/resources/application.yml
 delete mode 100644 src/main/resources/kamon.conf

diff --git a/pom.xml b/pom.xml
index e08146ef2..f9c84d85d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -265,6 +265,7 @@
                     <include>**/*.csv</include>
                     <include>**/*.sql</include>
                     <include>**/*.conf</include>
+                    <include>**/*.yml</include>    <!--  Only for development -->
                 </includes>
                 <filtering>true</filtering>
             </resource>
diff --git a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
index bca25598a..909d2c1c8 100644
--- a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
@@ -29,7 +29,6 @@ public class PersistenceConfiguration {
         return DataSourceBuilder.create().build();
     }
 
-
     @Bean(name = "entityManagerFactory")
     @DependsOn("flyway")
     public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
deleted file mode 100644
index e2abfd5ae..000000000
--- a/src/main/resources/application.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-app {
-  # Name of the application
-  name = "Portal backend"
-  # Type of the application
-  type = "Spring"
-  clusterSystemName = ${clustering.cluster.name}
-}
-
-clustering {
-  ip = "127.0.0.1"
-  ip = ${?CLUSTER_IP}
-  port = 4489
-  port = ${?CLUSTER_PORT}
-}
-
-akka {
-  cluster {
-    roles = ["portal"]
-  }
-}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 000000000..825692ef7
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,75 @@
+# Configuration template for the portal running inside a Docker container
+
+# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+spring:
+  portal-datasource:
+    url: "jdbc:postgresql://127.0.0.1:5433/portal"
+    schema: "public"
+    username: "portal"
+    password: "portalpwd"
+    driver-class-name: org.postgresql.Driver
+
+  data:
+    jpa:
+      repositories:
+        bootstrap-mode: default
+  jpa:
+    hibernate:
+      dialect: org.hibernate.dialect.PostgreSQL9Dialect
+      ddl-auto: validate
+
+# HBP OAUTH2 LOGIN
+hbp:
+  authentication:
+    enabled: true
+  client:
+    clientId: "MIP"
+    clientSecret: "dae83a6b-c769-4186-8383-f0984c6edf05"
+    logoutUri: http://127.0.0.1/auth/realms/MIP/protocol/openid-connect/logout
+
+
+# WEB FRONTEND
+frontend:
+  loginUrl: "http://127.0.0.1/services/login/hbp"
+  redirectAfterLoginUrl: "http://127.0.0.1/"
+  redirectAfterLogoutUrl: "http://127.0.0.1/services/login/hbp"
+
+logging:
+  level:
+    root: "DEBUG"
+    org: "DEBUG"
+    eu:
+      hbp: "DEBUG"
+
+# EMBEDDED SERVER CONFIGURATION
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+  session:
+    timeout: "2592000"
+
+# ENDPOINTS
+endpoints:
+  enabled: true
+  health:
+    enabled: true
+    endpoint: "/health"
+    sensitive: false
+
+# External Services
+services:
+  exareme:
+    queryExaremeUrl: "http://127.0.0.1:9090/mining/query"
+    algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json"
+
+  galaxy:
+    galaxyUrl: "http://127.0.0.1:8090"
+    galaxyContext:  "nativeGalaxy/workflows/list"
+    galaxyApiKey:   "d14a4cc5eebf805eb2ff261374ed08a2"
+    galaxyUsername:  "admin"
+    galaxyPassword:  "password"
+
+    keycloak:
+      keycloakUrl: 127.0.0.1
\ No newline at end of file
diff --git a/src/main/resources/kamon.conf b/src/main/resources/kamon.conf
deleted file mode 100644
index face394cb..000000000
--- a/src/main/resources/kamon.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-kamon {
-  enabled = no
-  enabled = ${?KAMON_ENABLED}
-
-  environment {
-    service = "portal-backend"
-    service = ${?KAMON_SERVICE_NAME}
-  }
-
-  zipkin = {
-    enabled = no
-    enabled = ${?ZIPKIN_ENABLED}
-    host = "zipkin"
-    host = ${?ZIPKIN_IP}
-    port = 9411
-    port = ${?ZIPKIN_PORT}
-  }
-
-  prometheus = {
-    enabled = no
-    enabled = ${?PROMETHEUS_ENABLED}
-    host = "prometheus"
-    host = ${?PROMETHEUS_IP}
-    port = 9090
-    port = ${?PROMETHEUS_PORT}
-  }
-
-  util.filters {
-    "akka.tracked-actor" {
-      includes = ["**"]
-    }
-
-    "akka.tracked-dispatcher" {
-      includes = ["**"]
-    }
-
-    "akka.traced-actor" {
-      includes = ["**"]
-      excludes = [
-        ${clustering.cluster.name}"/system/IO**",
-        ${clustering.cluster.name}"/user/Stream**",
-        ${clustering.cluster.name}"/system/transports**",
-        ${clustering.cluster.name}"/system/cluster**",
-        ${clustering.cluster.name}"/system/remote**",
-        ${clustering.cluster.name}"/system/endpointmanager/**",
-        ${clustering.cluster.name}"/system/sharding/UserActor/**"]
-    }
-
-  }
-
-  akka-http {
-    add-http-status-code-as-metric-tag = true
-  }
-
-  akka {
-    ask-pattern-timeout-warning = lightweight
-  }
-
-  trace {
-    join-remote-parents-with-same-span-id = yes
-    sampler = "always"
-  }
-
-  system-metrics {
-    host {
-      enabled = no
-      enabled = ${?SIGAR_SYSTEM_METRICS}
-    }
-    jvm {
-      enabled = no
-      enabled = ${?JVM_SYSTEM_METRICS}
-    }
-  }
-
-}
-- 
GitLab


From 94dffcf023d31b2a324e5725261e1f4032d39905 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 12 Nov 2020 06:09:05 -0800
Subject: [PATCH 22/52] Added global variables for pathologies url and
 disabledAlgorithms.

---
 docker/config/application.tmpl                |  6 ++++++
 pom.xml                                       |  8 ++++++++
 .../configuration/SecurityConfiguration.java  |  2 ++
 .../eu/hbp/mip/controllers/AlgorithmsApi.java |  7 ++++++-
 .../hbp/mip/controllers/PathologiesApi.java   | 19 +++++++++++++------
 src/main/resources/application.yml            | 12 +++++++++---
 6 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 6588e210a..f25878893 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -76,3 +76,9 @@ services:
 
   keycloak:
     keycloakUrl: {{ .Env.KEYCLOAK_URL }}
+
+pathologies:
+  pathologiesUrl: "file:/opt/portal/api/pathologies.json"
+
+algorithms:
+  disabledAlgorithmsUrl: "file:/opt/portal/api/disabledAlgorithms.json"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f9c84d85d..b64596e79 100644
--- a/pom.xml
+++ b/pom.xml
@@ -268,6 +268,14 @@
                     <include>**/*.yml</include>    <!--  Only for development -->
                 </includes>
                 <filtering>true</filtering>
+
+            </resource>
+            <resource>
+                <directory>config</directory>
+                <includes>
+                    <include>*.json</include>
+                </includes>
+                <filtering>true</filtering>
             </resource>
         </resources>
 
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index ff28602a1..81afa6418 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -6,6 +6,7 @@ import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
@@ -70,6 +71,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
 
+    @Qualifier("oauth2ClientContext")
     @Autowired
     private OAuth2ClientContext oauth2ClientContext;
 
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index d5dca19ae..07ab6ef29 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -17,6 +17,7 @@ import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
@@ -41,6 +42,7 @@ public class AlgorithmsApi {
 
     private static final Gson gson = new Gson();
 
+    @Qualifier("userInfo")
     @Autowired
     private UserInfo userInfo;
 
@@ -53,6 +55,9 @@ public class AlgorithmsApi {
     @Value("#{'${services.galaxy.galaxyApiKey}'}")
     private String galaxyApiKey;
 
+    @Value("#{'${services.algorithms.disabledAlgorithmsUrl}'}")
+    private String disabledAlgorithmsUrl;
+
     @ApiOperation(value = "List all algorithms", response = String.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() {
@@ -195,7 +200,7 @@ public class AlgorithmsApi {
      */
     List<String> getDisabledAlgorithms() throws IOException {
 
-        Resource resource = resourceLoader.getResource("file:/opt/portal/api/disabledAlgorithms.json");
+        Resource resource = resourceLoader.getResource(disabledAlgorithmsUrl);
 
         List<String> response = gson.fromJson(convertInputStreamToString(
                 resource.getInputStream()),
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 4ec7c8e36..a6979e70c 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -15,6 +15,7 @@ import eu.hbp.mip.utils.InputStreamConverter;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
@@ -35,6 +36,7 @@ public class PathologiesApi {
 
     private static final Gson gson = new Gson();
 
+    @Qualifier("userInfo")
     @Autowired
     private UserInfo userInfo;
 
@@ -42,32 +44,37 @@ public class PathologiesApi {
     @Value("#{'${hbp.authentication.enabled:1}'}")
     private boolean authenticationIsEnabled;
 
+    @Value("#{'${services.pathologies.pathologiesUrl}'}")
+    private String pathologiesUrl;
+
     @Autowired
     private CustomResourceLoader resourceLoader;
 
     @RequestMapping(name = "/pathologies", method = RequestMethod.GET)
     public ResponseEntity<String> getPathologies(Authentication authentication) {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Loading pathologies ...");
+        String endpoint = "(GET) /pathologies";
+        String username = userInfo.getUser().getUsername();
+        Logging.LogUserAction(username, endpoint, "Loading pathologies ...");
 
         // Load pathologies from file
-        Resource resource = resourceLoader.getResource("file:/opt/portal/api/pathologies.json");
+        Resource resource = resourceLoader.getResource(pathologiesUrl);
         List<PathologyDTO> allPathologies;
         try {
             allPathologies = gson.fromJson(InputStreamConverter.convertInputStreamToString(resource.getInputStream()), new TypeToken<List<PathologyDTO>>() {
             }.getType());
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies");
+            Logging.LogUserAction(username, endpoint, "Unable to load pathologies");
             throw new BadRequestException("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
         if (!authenticationIsEnabled) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Successfully loaded " + allPathologies.size() + " pathologies");
+            Logging.LogUserAction(username, endpoint, "Successfully loaded " + allPathologies.size() + " pathologies");
             return ResponseEntity.ok().body(gson.toJson(allPathologies));
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /pathologies", "Successfully loaded all authorized pathologies");
+        Logging.LogUserAction(username, endpoint, "Successfully loaded all authorized pathologies");
         return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies(
-                userInfo.getUser().getUsername(), authentication.getAuthorities(), allPathologies));
+                username, authentication.getAuthorities(), allPathologies));
     }
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 825692ef7..a4c205725 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -21,7 +21,7 @@ spring:
 # HBP OAUTH2 LOGIN
 hbp:
   authentication:
-    enabled: true
+    enabled: 0
   client:
     clientId: "MIP"
     clientSecret: "dae83a6b-c769-4186-8383-f0984c6edf05"
@@ -71,5 +71,11 @@ services:
     galaxyUsername:  "admin"
     galaxyPassword:  "password"
 
-    keycloak:
-      keycloakUrl: 127.0.0.1
\ No newline at end of file
+  keycloak:
+   keycloakUrl: "127.0.0.1"
+
+  pathologies:
+    pathologiesUrl: "classPath:/pathologies.json"
+
+  algorithms:
+    disabledAlgorithmsUrl: "classPath:/disableAlgorithms.json"
\ No newline at end of file
-- 
GitLab


From 8a65e51898479dd25a0cc538d4c464e1441c72e4 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 12 Nov 2020 07:47:14 -0800
Subject: [PATCH 23/52] Fixed dependencies that blocked the GET /algorithms.

---
 pom.xml                                       |  1 -
 .../eu/hbp/mip/controllers/AlgorithmsApi.java | 39 +++++++++++--------
 src/main/resources/application.yml            |  4 +-
 3 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/pom.xml b/pom.xml
index b64596e79..0c3f8a8c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -244,7 +244,6 @@
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>
             <artifactId>logging-interceptor</artifactId>
-            <version>4.10.0-RC1</version>
         </dependency>
 
         <dependency>
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index 07ab6ef29..8fc9fcbf9 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -61,24 +61,26 @@ public class AlgorithmsApi {
     @ApiOperation(value = "List all algorithms", response = String.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() {
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Executing...");
+        String username = userInfo.getUser().getUsername();
+        String endpoint = "(GET) /algorithms";
+        Logging.LogUserAction(username, endpoint, "Executing...");
 
         LinkedList<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms();
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
+        Logging.LogUserAction(username, endpoint, "Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
         LinkedList<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows();
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
+        Logging.LogUserAction(username, endpoint, "Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
 
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         if (exaremeAlgorithms != null) {
             algorithms.addAll(exaremeAlgorithms);
         } else {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(username, endpoint,
                     "Getting exareme algorithms failed and returned null");
         }
         if (galaxyAlgorithms != null) {
             algorithms.addAll(galaxyAlgorithms);
         } else {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(username, endpoint,
                     "Getting galaxy workflows failed and returned null");
         }
 
@@ -86,7 +88,7 @@ public class AlgorithmsApi {
         try {
             disabledAlgorithms = getDisabledAlgorithms();
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(username, endpoint,
                     "The disabled algorithms could not be loaded.");
         }
 
@@ -97,7 +99,7 @@ public class AlgorithmsApi {
                 allowedAlgorithms.add(algorithm);
             }
         }
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+        Logging.LogUserAction(username, endpoint,
                 "Successfully listed " + allowedAlgorithms.size() + " algorithms");
         return ResponseEntity.ok(allowedAlgorithms);
     }
@@ -108,6 +110,8 @@ public class AlgorithmsApi {
      * @return a list of AlgorithmDTOs or null if something fails
      */
     public LinkedList<AlgorithmDTO> getExaremeAlgorithms() {
+        String username = userInfo.getUser().getUsername();
+        String endpoint = "(GET) /algorithms";
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         // Get exareme algorithms
         try {
@@ -120,11 +124,11 @@ public class AlgorithmsApi {
                     }.getType()
             );
         } catch (IOException e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
+            Logging.LogUserAction(username, endpoint, "An exception occurred: " + e.getMessage());
             return null;
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+        Logging.LogUserAction(username, endpoint,
                 "Completed, returned " + algorithms.size() + " algorithms.");
         return algorithms;
     }
@@ -135,7 +139,8 @@ public class AlgorithmsApi {
      * @return a list of AlgorithmDTOs or null if something fails
      */
     public LinkedList<AlgorithmDTO> getGalaxyWorkflows() {
-
+        String username = userInfo.getUser().getUsername();
+        String endpoint = "(GET) /algorithms";
         List<Workflow> workflowList;
         try {
             // Get all the workflows with the galaxy client
@@ -144,7 +149,7 @@ public class AlgorithmsApi {
 
             workflowList = new ArrayList<>(workflowsClient.getWorkflows());
         } catch (Exception e) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Error when calling list galaxy workflows: " + e.getMessage());
+            Logging.LogUserAction(username, endpoint, "Error when calling list galaxy workflows: " + e.getMessage());
 
             return null;
         }
@@ -164,28 +169,28 @@ public class AlgorithmsApi {
 
                 } else {     // Something unexpected happened
                     String msgErr = gson.toJson(response.errorBody());
-                    Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Error Response: " + msgErr);
+                    Logging.LogUserAction(username, endpoint, "Error Response: " + msgErr);
                     return null;
                 }
             } catch (Exception e) {
-                Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "An exception occurred: " + e.getMessage());
+                Logging.LogUserAction(username, endpoint, "An exception occurred: " + e.getMessage());
                 return null;
             }
         }
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Workflows fetched: " + workflows.size());
+        Logging.LogUserAction(username, endpoint, "Workflows fetched: " + workflows.size());
 
         // Convert the workflows to algorithms
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         for (WorkflowDTO workflow : workflows) {
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Converting workflow: " + workflow);
+            Logging.LogUserAction(username, endpoint, "Converting workflow: " + workflow);
 
             algorithms.add(workflow.convertToAlgorithmDTO());
 
-            Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms",
+            Logging.LogUserAction(username, endpoint,
                     "Converted algorithm: " + algorithms.get(algorithms.size() - 1));
         }
 
-        Logging.LogUserAction(userInfo.getUser().getUsername(), "(GET) /algorithms", "Completed!");
+        Logging.LogUserAction(username, endpoint, "Completed!");
         return algorithms;
     }
 
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a4c205725..1728999c2 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -36,8 +36,8 @@ frontend:
 
 logging:
   level:
-    root: "DEBUG"
-    org: "DEBUG"
+    root: "ERROR"
+    org: "ERROR"
     eu:
       hbp: "DEBUG"
 
-- 
GitLab


From d1c2859496b44517c61768658496d10fdfade326 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Fri, 13 Nov 2020 03:57:25 -0800
Subject: [PATCH 24/52] Beautification of non_docker additions.

---
 docker/config/application.tmpl                         |  9 ++++-----
 pom.xml                                                |  3 ++-
 .../java/eu/hbp/mip/controllers/AlgorithmsApi.java     |  6 +++---
 .../java/eu/hbp/mip/controllers/PathologiesApi.java    | 10 +++-------
 src/main/java/eu/hbp/mip/controllers/SecurityApi.java  |  2 +-
 src/main/resources/application.yml                     |  9 ++++-----
 6 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index f25878893..5bdfa36a1 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -77,8 +77,7 @@ services:
   keycloak:
     keycloakUrl: {{ .Env.KEYCLOAK_URL }}
 
-pathologies:
-  pathologiesUrl: "file:/opt/portal/api/pathologies.json"
-
-algorithms:
-  disabledAlgorithmsUrl: "file:/opt/portal/api/disabledAlgorithms.json"
\ No newline at end of file
+# Files are imported when building the docker image
+files:
+  pathologies_json: "file:/opt/portal/api/pathologies.json"
+  disabledAlgorithms_json: "file:/opt/portal/api/disabledAlgorithms.json"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b64596e79..ba87e5423 100644
--- a/pom.xml
+++ b/pom.xml
@@ -268,8 +268,9 @@
                     <include>**/*.yml</include>    <!--  Only for development -->
                 </includes>
                 <filtering>true</filtering>
-
             </resource>
+
+            <!-- Used for development. Docker/config folder files added as resources -->
             <resource>
                 <directory>config</directory>
                 <includes>
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index 07ab6ef29..e2c3b6e0e 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -55,8 +55,8 @@ public class AlgorithmsApi {
     @Value("#{'${services.galaxy.galaxyApiKey}'}")
     private String galaxyApiKey;
 
-    @Value("#{'${services.algorithms.disabledAlgorithmsUrl}'}")
-    private String disabledAlgorithmsUrl;
+    @Value("#{'${files.disabledAlgorithms_json}'}")
+    private String disabledAlgorithmsFilePath;
 
     @ApiOperation(value = "List all algorithms", response = String.class)
     @RequestMapping(method = RequestMethod.GET)
@@ -200,7 +200,7 @@ public class AlgorithmsApi {
      */
     List<String> getDisabledAlgorithms() throws IOException {
 
-        Resource resource = resourceLoader.getResource(disabledAlgorithmsUrl);
+        Resource resource = resourceLoader.getResource(disabledAlgorithmsFilePath);
 
         List<String> response = gson.fromJson(convertInputStreamToString(
                 resource.getInputStream()),
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index a6979e70c..383515660 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -1,7 +1,3 @@
-/**
- * Created by mirco on 04.12.15.
- */
-
 package eu.hbp.mip.controllers;
 
 import com.google.gson.Gson;
@@ -44,8 +40,8 @@ public class PathologiesApi {
     @Value("#{'${hbp.authentication.enabled:1}'}")
     private boolean authenticationIsEnabled;
 
-    @Value("#{'${services.pathologies.pathologiesUrl}'}")
-    private String pathologiesUrl;
+    @Value("#{'${files.pathologies_json}'}")
+    private String pathologiesFilePath;
 
     @Autowired
     private CustomResourceLoader resourceLoader;
@@ -57,7 +53,7 @@ public class PathologiesApi {
         Logging.LogUserAction(username, endpoint, "Loading pathologies ...");
 
         // Load pathologies from file
-        Resource resource = resourceLoader.getResource(pathologiesUrl);
+        Resource resource = resourceLoader.getResource(pathologiesFilePath);
         List<PathologyDTO> allPathologies;
         try {
             allPathologies = gson.fromJson(InputStreamConverter.convertInputStreamToString(resource.getInputStream()), new TypeToken<List<PathologyDTO>>() {
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index e179b3172..77b22fae8 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -96,7 +96,7 @@ public class SecurityApi {
     @Value("#{'${services.galaxy.galaxyPassword:password}'}")
     private String galaxyPassword;
 
-    @Value("#{'${services.galaxy.galaxyContext:nativeGalaxy}'}")
+    @Value("#{'${services.galaxy.galaxpathoyContext:nativeGalaxy}'}")
     private String galaxyContext;
 
     /**
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a4c205725..5fda7331d 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -74,8 +74,7 @@ services:
   keycloak:
    keycloakUrl: "127.0.0.1"
 
-  pathologies:
-    pathologiesUrl: "classPath:/pathologies.json"
-
-  algorithms:
-    disabledAlgorithmsUrl: "classPath:/disableAlgorithms.json"
\ No newline at end of file
+# Files are loaded from the resources
+files:
+  pathologies_json: "classPath:/pathologies.json"
+  disabledAlgorithms_json: "classPath:/disabledAlgorithms.json"
\ No newline at end of file
-- 
GitLab


From dd3ac2f9a0585f923a398c70bcd56569a81c130c Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 17 Nov 2020 07:14:54 -0800
Subject: [PATCH 25/52] Removing users endpoint and security cleanup.

---
 pom.xml                                       | 14 ----
 .../configuration/SecurityConfiguration.java  | 12 +++-
 .../SecurityUtils/CORSFilter.java             |  1 +
 .../eu/hbp/mip/controllers/SecurityApi.java   |  2 +-
 .../java/eu/hbp/mip/controllers/UsersApi.java | 29 ++-------
 src/main/resources/application.yml            |  7 --
 src/main/resources/test.test                  | 64 -------------------
 7 files changed, 18 insertions(+), 111 deletions(-)
 delete mode 100644 src/main/resources/test.test

diff --git a/pom.xml b/pom.xml
index 1019b1ccf..2be66e4cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -96,20 +96,6 @@
             <artifactId>keycloak-spring-security-adapter</artifactId>
             <version>${keycloak-spring.version}</version>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.security</groupId>-->
-<!--            <artifactId>spring-security-oauth2-resource-server</artifactId>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.security.oauth.boot</groupId>-->
-<!--            <artifactId>spring-security-oauth2-autoconfigure</artifactId>-->
-<!--            <version>2.0.1.RELEASE</version>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.security.oauth</groupId>-->
-<!--            <artifactId>spring-security-oauth2</artifactId>-->
-<!--            <version>2.5.0.RELEASE</version>-->
-<!--        </dependency>-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-orm</artifactId>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 8617e2270..8ebf2c376 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -22,6 +22,9 @@ import org.springframework.security.web.authentication.session.SessionAuthentica
 import org.springframework.security.web.csrf.CsrfToken;
 import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
 
@@ -31,6 +34,8 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
 
 
 // Reference for OAuth2 login: https://spring.io/guides/tutorials/spring-boot-oauth2/
@@ -104,9 +109,9 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         super.configure(http);
         //disableCertificateValidation();  //  TODO needed?
 
-        // TODO Check if needed.
-        // Check if it works when removing keycloak cors from app properties.
-        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
+        // TODO Is that needed for development? On Galaxy?
+//        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
+//        http.cors();
 
         if (authenticationEnabled) {
             http.antMatcher("/**")
@@ -138,6 +143,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         }
     }
 
+
 //    @Bean
 //    public FilterRegistrationBean corsFilter() {
 //        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
index 2a259ea22..b7d3f7733 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
@@ -8,6 +8,7 @@ import java.io.IOException;
  * Created by mirco on 12.02.16.
  */
 public class CORSFilter implements Filter {
+    // TODO needed?
 
     @Override
     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index 7bc4fb7b7..9ee70b0be 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -31,7 +31,7 @@ public class SecurityApi {
     @Autowired
     private SecurityConfiguration securityConfiguration;
 
-    // TODO How to redirect? keycloak off?
+    // TODO Fix no authentication instance
     @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
     @ConditionalOnExpression("${authentication.enabled:0}")
     public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index 66f34b670..1c60aba1e 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -21,32 +21,17 @@ import java.net.URLEncoder;
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 @RestController
-@RequestMapping(value = "/users", produces = {APPLICATION_JSON_VALUE})
-@Api(value = "/users")
+@RequestMapping(value = "/activeUser", produces = {APPLICATION_JSON_VALUE})
+@Api(value = "/activeUser")
 public class UsersApi {
 
     @Autowired
     private ActiveUserService activeUserService;
 
-    @Autowired
-    private UserRepository userRepository;
-
-    @ApiOperation(value = "Get a user", response = UserDAO.class)
-    @RequestMapping(value = "/{username}", method = RequestMethod.GET)
-    public ResponseEntity<UserDAO> getAUser(
-            @ApiParam(value = "username", required = true) @PathVariable("username") String username
-    ) {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/{username}",
-                "Loaded a user with username : " + username);
-
-        // TODO Error handling?
-        return ResponseEntity.ok(userRepository.findByUsername(username));
-    }
-
     @ApiOperation(value = "Get the active user", response = UserDAO.class)
-    @RequestMapping(value = "/activeUser", method = RequestMethod.GET)
+    @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<UserDAO> getTheActiveUser(HttpServletResponse response) {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/activeUser",
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser",
                 "Loading the details of the activeUser");
 
         UserDAO activeUser = activeUserService.getActiveUser();
@@ -62,7 +47,7 @@ public class UsersApi {
             response.addCookie(cookie);
         } catch (JsonProcessingException | UnsupportedEncodingException e) {
             Logging.LogUserAction(activeUser.getUsername(),
-                    "(GET) /users/activeUser", "Failed to add Cookie. Exception: " + e.getMessage());
+                    "(GET) /activeUser", "Failed to add Cookie. Exception: " + e.getMessage());
         }
 
         return ResponseEntity.ok(activeUserService.getActiveUser());
@@ -70,9 +55,9 @@ public class UsersApi {
 
     // TODO Kostas, why not working?
     @ApiOperation(value = "The active user agrees to the NDA", response = UserDAO.class)
-    @RequestMapping(value = "/activeUser/agreeNDA", method = RequestMethod.POST)
+    @RequestMapping(value = "/agreeNDA", method = RequestMethod.POST)
     public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(@RequestBody(required = false) UserDAO userDAO) {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /users/activeUser/agreeNDA",
+        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser/agreeNDA",
                 "The user agreed to the NDA");
 
         return ResponseEntity.ok(activeUserService.agreeToNDA());
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index bd45b740e..7ff94d087 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -37,8 +37,6 @@ server:
     contextPath: "/services"
   port: 8080
   forward-headers-strategy: native
-  session:
-    timeout: "2592000"
 
 # ENDPOINTS
 endpoints:
@@ -75,11 +73,6 @@ keycloak:
   credentials:
     secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
   principal-attribute: "preferred_username"
-  #  cors: true
-  #  cors-max-age: 3600
-  #  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
-  #  cors-allowed-headers: "*"
-  #  cors-exposed-headers: "*"
 
   # logoutUrl: {{ .Env.LOGOUT_URL }}
 
diff --git a/src/main/resources/test.test b/src/main/resources/test.test
deleted file mode 100644
index 84be80128..000000000
--- a/src/main/resources/test.test
+++ /dev/null
@@ -1,64 +0,0 @@
-# Configuration template for the portal running inside a Docker container
-
-# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
-
-spring.portal-datasource.url="jdbc:postgresql://127.0.0.1:5433/portal"
-spring.portal-datasource.schema="public"
-spring.portal-datasource.username="portal"
-spring.portal-datasource.password="portalpwd"
-spring.portal-datasource.driver-class-name=org.postgresql.Driver
-
-spring.data.jpa.repositories.bootstrap-mode=default
-spring.jpa.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
-spring.jpa.hibernate.ddl-auto=validate
-
-# WEB FRONTEND
-frontend.loginUrl="http://127.0.0.1/services/login/hbp" }}
-frontend.redirectAfterLoginUrl="http://127.0.0.1/"
-frontend.redirectAfterLogoutUrl="http://127.0.0.1/services/login/hbp"
-
-logging.level.root="DEBUG"
-logging.level.org="DEBUG"
-logging.level.eu.hbp="DEBUG"
-
-# EMBEDDED SERVER CONFIGURATION
-server.servlet.contextPath="/services"
-server.port=8080
-server.forward-headers-strategy=native
-server.session.timeout="2592000"
-
-# ENDPOINTS
-endpoints.enabled=true
-endpoints.health.enabled: true
-endpoints.health.endpoint: "/health"
-endpoints.health.sensitive: false
-
-# External Services
-services.exareme.queryExaremeUrl="http://localhost:9090/mining/query"
-services.exareme.algorithmsUrl="http://localhost:9090/mining/algorithms.json"
-
-
-galaxy.galaxyUrl="http://localhost:8090/"
-galaxy.galaxyContext="nativeGalaxy/workflows/list"
-galaxy.galaxyApiKey="sfas"
-galaxy.galaxyUsername="admin"
-galaxy.galaxyPassword="password"
-
-# Authentication
-authentication.enabled="1"
-
-# Keycloak
-keycloak.enabled=true
-keycloak.auth-server-url="http://127.0.0.1/auth"
-keycloak.realm="MIP"
-keycloak.resource="MIP"
-keycloak.enable-basic-auth=true
-keycloak.credentials.secret="dae83a6b-c769-4186-8383-f0984c6edf05"
-keycloak.principal-attribute="preferred_username"
-#  cors: true
-#  cors-max-age: 3600
-#  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
-#  cors-allowed-headers: "*"
-#  cors-exposed-headers: "*"
-
-# logoutUrl: {{ .Env.LOGOUT_URL }}
-- 
GitLab


From 966db4c9e042214630eb3ce34fb51370f996c686 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 17 Nov 2020 09:36:27 -0800
Subject: [PATCH 26/52] Keycloak security authentication/authorization fixed.

---
 docker/config/application.tmpl                |  34 +--
 .../mip/configuration/CacheConfiguration.java |  13 -
 .../GalaxyAuthentication.java}                |  19 +-
 .../configuration/SecurityConfiguration.java  | 288 ++----------------
 .../SecurityUtils/CORSFilter.java             |  23 --
 .../CustomAccessDeniedHandler.java            |  32 --
 ...ustomLoginUrlAuthenticationEntryPoint.java |  20 --
 .../mip/configuration/WebConfiguration.java   |   5 -
 .../java/eu/hbp/mip/controllers/UsersApi.java |   3 +-
 .../hbp/mip/services/ActiveUserService.java   |   8 +-
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |   4 +-
 src/main/resources/application.yml            |  26 +-
 12 files changed, 59 insertions(+), 416 deletions(-)
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/CacheConfiguration.java
 rename src/main/java/eu/hbp/mip/{controllers/SecurityApi.java => configuration/GalaxyAuthentication.java} (74%)
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index d685d2f2f..257bfa087 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -1,6 +1,6 @@
 # Configuration template for the portal running inside a Docker container
 
-# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
     url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://88.197.53.106:5432/portal" }}
@@ -8,7 +8,6 @@ spring:
     username: {{ default .Env.PORTAL_DB_USER "postgres" }}
     password: {{ .Env.PORTAL_DB_PASSWORD }}
     driver-class-name: org.postgresql.Driver
-
   data:
     jpa:
       repositories:
@@ -18,12 +17,7 @@ spring:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
 
-# WEB FRONTEND
-frontend:
-  loginUrl: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
-  redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/" }}
-  redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL "http://frontend/services/login/hbp" }}
-
+### LOG LEVELS ###
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
@@ -31,16 +25,14 @@ logging:
     eu:
       hbp: {{ default .Env.LOG_LEVEL "INFO" }}
 
-# EMBEDDED SERVER CONFIGURATION
+### EMBEDDED SERVER CONFIGURATION ###
 server:
   servlet:
-    contextPath: {{ default .Env.CONTEXT_PATH "/services" }}
+    contextPath: "/services"
   port: 8080
-  use-forward-headers: true
-  session:
-    timeout: {{ default .Env.SESSION_TIMEOUT "2592000" }}
+  forward-headers-strategy: native
 
-# ENDPOINTS
+### ENDPOINTS ###
 endpoints:
   enabled: true
   health:
@@ -48,7 +40,7 @@ endpoints:
     endpoint: /health
     sensitive: false
 
-# External Services
+### EXTERNAL SERVICES ###
 services:
   exareme:
     queryExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query
@@ -61,11 +53,11 @@ services:
     galaxyUsername:  {{ default .Env.GALAXY_USERNAME "admin" }}
     galaxyPassword:  {{ default .Env.GALAXY_PASSWORD "password" }}
 
-# Authentication
+### Authentication ###
 authentication:
   enabled: {{ default .Env.AUTHENTICATION "1" }}
 
-# Keycloak
+### Keycloak ###
 keycloak:
   enabled: true
   auth-server-url: {{ .Env.KEYCLOAK_AUTH_URL }}
@@ -75,14 +67,8 @@ keycloak:
   credentials:
     secret: {{ .Env.CLIENT_SECRET }}
   principal-attribute: "preferred_username"
-#  cors: true
-#  cors-max-age: 3600
-#  cors-allowed-methods: "GET, POST, PUT, PATCH, OPTIONS, DELETE"
-#  cors-allowed-headers: "*"
-#  cors-exposed-headers: "*"
-
-  # logoutUrl: {{ .Env.LOGOUT_URL }}
 
+### EXTERNAL FILES ###
 # Files are imported when building the docker image
 files:
   pathologies_json: "file:/opt/portal/api/pathologies.json"
diff --git a/src/main/java/eu/hbp/mip/configuration/CacheConfiguration.java b/src/main/java/eu/hbp/mip/configuration/CacheConfiguration.java
deleted file mode 100644
index b7300fc25..000000000
--- a/src/main/java/eu/hbp/mip/configuration/CacheConfiguration.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package eu.hbp.mip.configuration;
-
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Created by mirco on 07.11.16.
- */
-
-@Configuration
-@EnableCaching
-public class CacheConfiguration {
-}
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java
similarity index 74%
rename from src/main/java/eu/hbp/mip/controllers/SecurityApi.java
rename to src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java
index 9ee70b0be..7910e809f 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.controllers;
+package eu.hbp.mip.configuration;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
@@ -21,24 +21,11 @@ import java.io.IOException;
 import java.util.Base64;
 
 @RestController
-public class SecurityApi {
-
-    private static final Gson gson = new Gson();
+public class GalaxyAuthentication {
 
     @Autowired
     private ActiveUserService activeUserService;
 
-    @Autowired
-    private SecurityConfiguration securityConfiguration;
-
-    // TODO Fix no authentication instance
-    @RequestMapping(path = "/login/hbp", method = RequestMethod.GET)
-    @ConditionalOnExpression("${authentication.enabled:0}")
-    public void noLogin(HttpServletResponse httpServletResponse) throws IOException {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login.");
-        httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin());
-    }
-
     @Value("#{'${services.galaxy.galaxyUsername:admin}'}")
     private String galaxyUsername;
 
@@ -63,6 +50,6 @@ public class SecurityApi {
         object.addProperty("context", galaxyContext);
         Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/galaxy", "Successfully Loaded galaxy information.");
 
-        return ResponseEntity.ok(gson.toJson(object));
+        return ResponseEntity.ok(new Gson().toJson(object));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 8ebf2c376..796f900a5 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -1,14 +1,10 @@
 package eu.hbp.mip.configuration;
 
-import eu.hbp.mip.configuration.SecurityUtils.CORSFilter;
 import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
 import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
 import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
-import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler;
 import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -16,67 +12,54 @@ import org.springframework.security.config.annotation.authentication.builders.Au
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
 import org.springframework.security.core.session.SessionRegistryImpl;
-import org.springframework.security.web.access.channel.ChannelProcessingFilter;
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
-import org.springframework.security.web.csrf.CsrfToken;
-import org.springframework.security.web.csrf.CsrfTokenRepository;
-import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.OncePerRequestFilter;
-import org.springframework.web.util.WebUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
 
-import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
 
 
-// Reference for OAuth2 login: https://spring.io/guides/tutorials/spring-boot-oauth2/
-// also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
-// Security with Keycloak: https://www.thomasvitale.com/keycloak-authentication-flow-sso-client/
+// Keycloak security with keycloak-spring-boot-starter
 
+@Controller
 @KeycloakConfiguration
 public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
-
-    /**
-     * Enable HBP collab authentication (1) or disable it (0). Default is 1
-     */
     @Value("#{'${authentication.enabled}'}")
     private boolean authenticationEnabled;
 
-    /**
-     * Absolute URL to redirect to when login is required
-     */
-    @Value("#{'${frontend.loginUrl}'}")
-    private String loginUrl;
-
-    /**
-     * Absolute URL to redirect to after successful login
-     */
-    @Value("#{'${frontend.redirectAfterLoginUrl}'}")
-    private String frontendRedirectAfterLogin;
+    // Redirect to login page url
+    private static final String logoutRedirectURL = "/sso/login";
 
-    /**
-     * Absolute URL to redirect to after successful logout
-     */
-    @Value("#{'${frontend.redirectAfterLogoutUrl}'}")
-    private String redirectAfterLogoutUrl;
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        super.configure(http);
 
-    public boolean getAuthenticationEnabled() {
-        return authenticationEnabled;
+        if (authenticationEnabled) {
+            http.authorizeRequests()
+                    .antMatchers(
+                            "/sso/login", "/webjars/**",
+                            "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**"  // Swagger URLs
+                    ).permitAll()
+                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
+                    .anyRequest().hasRole("RESEARCHER");
+        } else {
+            http.antMatcher("/**")
+                    .authorizeRequests()
+                    .antMatchers("/**").permitAll()
+                    .and().csrf().disable();
+        }
     }
 
-    public String getFrontendRedirectAfterLogin() {
-        return frontendRedirectAfterLogin;
+    @Autowired
+    private HttpServletRequest request;
+
+    @GetMapping(value = "/logout")
+    public String logout() throws ServletException {
+        request.logout();
+        return "redirect:" + logoutRedirectURL;
     }
 
     @Bean
@@ -99,215 +82,4 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         auth.authenticationProvider(keycloakAuthenticationProvider);
     }
 
-    @Override
-    protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception {
-        return super.keycloakLogoutHandler();
-    }
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        super.configure(http);
-        //disableCertificateValidation();  //  TODO needed?
-
-        // TODO Is that needed for development? On Galaxy?
-//        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
-//        http.cors();
-
-        if (authenticationEnabled) {
-            http.antMatcher("/**")
-                    .authorizeRequests()
-                    .antMatchers("/**").permitAll()
-                    .and().csrf().disable();
-//                    .antMatchers(
-//                            "/login**", "/health/**", "/info/**", "/metrics/**",
-//                            "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs",
-//                            "/swagger-ui.html", "/swagger-resources/**"
-//                    ).permitAll()
-//                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
-//                    .anyRequest().hasRole("RESEARCHER")
-            // .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
-            // .accessDeniedHandler(new CustomAccessDeniedHandler())
-//                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-//                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf();
-//                    .and().logout().logoutSuccessUrl("/logout");
-//
-//
-//                    // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
-//                    .and().logout().permitAll()
-            // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
-        } else {
-            http.antMatcher("/**")
-                    .authorizeRequests()
-                    .antMatchers("/**").permitAll()
-                    .and().csrf().disable();
-        }
-    }
-
-
-//    @Bean
-//    public FilterRegistrationBean corsFilter() {
-//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-//        CorsConfiguration config = new CorsConfiguration();
-//        config.setAllowCredentials(true);
-//        config.addAllowedOrigin("*");
-//        config.addAllowedHeader("*");
-//        config.addAllowedMethod("*");
-//        source.registerCorsConfiguration("/**", config);
-//
-//        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
-//        bean.setOrder(-100);
-//        return bean;
-//    }
-
-//    private Filter ssoFilter() {
-//        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
-//        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
-//        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
-//        hbpFilter.setRestTemplate(hbpTemplate);
-//        hbpFilter.setTokenServices(new activeUserServiceTokenServices(hbpResource().getactiveUserServiceUri(), hbp().getClientId()));
-//        return hbpFilter;
-//    }
-
-//    @Bean
-//    public FilterRegistrationBean oauth2ClientFilterRegistration(
-//            OAuth2ClientContextFilter filter) {
-//        FilterRegistrationBean registration = new FilterRegistrationBean();
-//        registration.setFilter(filter);
-//        registration.setOrder(-100);
-//        return registration;
-//    }
-
-//    @Bean(name = "hbp")
-//    @ConfigurationProperties("hbp.client")
-//    public BaseOAuth2ProtectedResourceDetails hbp() {
-//        return new AuthorizationCodeResourceDetails();
-//    }
-//
-//    @Bean(name = "hbpResource")
-//    @ConfigurationProperties("hbp.resource")
-//    public ResourceServerProperties hbpResource() {
-//        return new ResourceServerProperties();
-//    }
-
-
-    private OncePerRequestFilter csrfHeaderFilter() {
-        return new OncePerRequestFilter() {
-            @Override
-            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
-                                            FilterChain filterChain) throws ServletException, IOException {
-                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
-                if (csrf != null) {
-                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
-                    String token = csrf.getToken();
-                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
-                        cookie = new Cookie("XSRF-TOKEN", token);
-                        cookie.setPath("/");
-                        response.addCookie(cookie);
-                    }
-                }
-                filterChain.doFilter(request, response);
-            }
-        };
-    }
-
-    private CsrfTokenRepository csrfTokenRepository() {
-        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
-        repository.setHeaderName("X-XSRF-TOKEN");
-        return repository;
-    }
-
-//    @Bean
-//    public AuthoritiesExtractor keycloakAuthoritiesExtractor() {
-//        return new KeycloakAuthoritiesExtractor();
-//    }
-//
-//
-//    public class KeycloakAuthoritiesExtractor
-//            implements AuthoritiesExtractor {
-//
-//        @Override
-//        public List<GrantedAuthority> extractAuthorities
-//                (Map<String, Object> map) {
-//            return AuthorityUtils
-//                    .commaSeparatedStringToAuthorityList(asAuthorities(map));
-//        }
-//
-//        private String asAuthorities(Map<String, Object> map) {
-//            List<String> authorities = new ArrayList<>();
-////            authorities.add("BAELDUNG_USER");
-//            List<LinkedHashMap<String, String>> authz;
-//            authz = (List<LinkedHashMap<String, String>>) map.get("authorities");
-//            for (LinkedHashMap<String, String> entry : authz) {
-//                authorities.add(entry.get("authority"));
-//            }
-//            return String.join(",", authorities);
-//        }
-//    }
-
-
-//    private LogoutHandler authLogoutHandler() {
-//        return (request, response, authentication) -> {
-//            logout();
-//        };
-//    }
-
-
-//    public void logout() {
-//        // TODO Try removing
-//
-//        RestTemplate restTemplate = new RestTemplate();
-//        MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
-//        formParams.add("client_id", hbp().getClientId());
-//        formParams.add("client_secret", hbp().getClientSecret());
-//        formParams.add("refresh_token", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
-//
-//        HttpHeaders httpHeaders = new HttpHeaders();
-//        httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
-//        RequestEntity<MultiValueMap<String, String>> requestEntity =
-//                new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
-//                        URI.create(logoutUrl));
-//        restTemplate.exchange(requestEntity, String.class);
-//    }
-
-    // TODO needed?
-//    @Value("#{'${keycloak.auth-server-url}'}")
-//    private String keycloakUrl;
-//
-//    public void disableCertificateValidation() {
-//
-//        //TODO Refactor logging
-//
-//        LOGGER.info("disabling certificate validation host : " + keycloakUrl);
-//
-//        // Create a trust manager that does not validate certificate chains
-//        TrustManager[] trustAllCerts = new TrustManager[]{
-//                new X509TrustManager() {
-//                    public X509Certificate[] getAcceptedIssuers() {
-//                        return new X509Certificate[0];
-//                    }
-//
-//                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
-//                    }
-//
-//                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
-//                    }
-//                }};
-//
-//
-//        // Ignore differences between given hostname and certificate hostname
-//        HostnameVerifier hv =
-//                (hostname, session) -> hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl);
-//
-//        // Install the all-trusting trust manager
-//        try {
-//            SSLContext sc = SSLContext.getInstance("SSL");
-//            sc.init(null, trustAllCerts, new SecureRandom());
-//            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-//            HttpsURLConnection.setDefaultHostnameVerifier(hv);
-//        } catch (Exception e) {
-//            // TODO add log message
-//        }
-//
-//    }
-
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
deleted file mode 100644
index b7d3f7733..000000000
--- a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CORSFilter.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package eu.hbp.mip.configuration.SecurityUtils;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * Created by mirco on 12.02.16.
- */
-public class CORSFilter implements Filter {
-    // TODO needed?
-
-    @Override
-    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
-        HttpServletResponse response = (HttpServletResponse) res;
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
-        response.setHeader("Access-Control-Max-Age", "3600");
-        response.setHeader("Access-Control-Allow-Headers", "*");
-        response.setHeader("Access-Control-Request-Headers", "*");
-        chain.doFilter(req, res);
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
deleted file mode 100644
index 552abd29f..000000000
--- a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomAccessDeniedHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package eu.hbp.mip.configuration.SecurityUtils;
-
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.web.access.AccessDeniedHandler;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.sql.Timestamp;
-
-public class CustomAccessDeniedHandler implements AccessDeniedHandler {
-    @Override
-    public void handle(HttpServletRequest request, HttpServletResponse response,
-                       AccessDeniedException accessDeniedException) throws IOException {
-        response.setContentType("application/json;charset=UTF-8");
-        response.setStatus(403);
-        try {
-            response.getWriter().write(new JSONObject()
-                    .put("timestamp", new Timestamp(System.currentTimeMillis()))
-                    .put("status", 403)
-                    .put("error", "Forbidden")
-                    .put("message", "Access Denied. Please contact the system administrator to request access.")
-                    .put("path", request.getServletPath())
-                    .toString());
-        } catch (JSONException e) {
-            response.getWriter().write("");
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java b/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java
deleted file mode 100644
index 068ca591b..000000000
--- a/src/main/java/eu/hbp/mip/configuration/SecurityUtils/CustomLoginUrlAuthenticationEntryPoint.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package eu.hbp.mip.configuration.SecurityUtils;
-
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
-
-    public CustomLoginUrlAuthenticationEntryPoint(String url) {
-        super(url);
-    }
-
-    @Override
-    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
-        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
index 72bcad789..50fbe43ae 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
@@ -18,11 +18,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 @EnableSwagger2
 public class WebConfiguration {
 
-//    @Bean
-//    public String[] swaggerUiConfig() {
-//        return UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS;
-//    }
-
     @Bean
     public Docket swaggerDocumentation() {
         return new Docket(DocumentationType.SWAGGER_2)
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index 1c60aba1e..c8b1193f8 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -36,7 +36,7 @@ public class UsersApi {
 
         UserDAO activeUser = activeUserService.getActiveUser();
 
-        // Add the active user to a cookie
+        // Add the active user object to a cookie
         try {
             // TODO needed? Ask Manuel
             ObjectMapper mapper = new ObjectMapper();
@@ -53,7 +53,6 @@ public class UsersApi {
         return ResponseEntity.ok(activeUserService.getActiveUser());
     }
 
-    // TODO Kostas, why not working?
     @ApiOperation(value = "The active user agrees to the NDA", response = UserDAO.class)
     @RequestMapping(value = "/agreeNDA", method = RequestMethod.POST)
     public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(@RequestBody(required = false) UserDAO userDAO) {
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index d925ce3f5..3d8815373 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -18,14 +18,14 @@ import javax.inject.Named;
 @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
 public class ActiveUserService {
 
-    @Autowired
-    private UserRepository userRepository;
-
     @Value("#{'${authentication.enabled}'}")
     private boolean authentication;
 
     private UserDAO user;
 
+    @Autowired
+    private UserRepository userRepository;
+
     /**
      * Fetches the details of the active user.
      * If the user doesn't exist, it's created on the fly from the auth token.
@@ -46,7 +46,7 @@ public class ActiveUserService {
             return user;
         }
 
-        // If authentication is ON
+        // If authentication is ON get user info from Token
         KeycloakPrincipal keycloakPrincipal =
                 (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         IDToken idToken = keycloakPrincipal.getKeycloakSecurityContext().getIdToken();
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 5872819bc..cdbe41c9e 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -15,11 +15,11 @@ public class ClaimUtils {
     private static final Gson gson = new Gson();
 
     public static String allDatasetsAllowedClaim() {
-        return "dataset_all";
+        return "role_dataset_all";
     }
 
     public static String getDatasetClaim(String datasetCode) {
-        return "dataset_" + datasetCode.toLowerCase();
+        return "role_dataset_" + datasetCode.toLowerCase();
     }
 
     public static boolean userHasDatasetsAuthorization(String username, Collection<? extends GrantedAuthority> authorities,
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 7ff94d087..30c82a447 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,6 +1,6 @@
-# Configuration template for the portal running inside a Docker container
+# Configuration for development purposes
 
-# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
     url: "jdbc:postgresql://127.0.0.1:5433/portal"
@@ -8,7 +8,6 @@ spring:
     username: "portal"
     password: "portalpwd"
     driver-class-name: org.postgresql.Driver
-
   data:
     jpa:
       repositories:
@@ -18,12 +17,7 @@ spring:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
 
-# WEB FRONTEND
-frontend:
-  loginUrl: "http://127.0.0.1/services/login/hbp"
-  redirectAfterLoginUrl: "http://127.0.0.1/"
-  redirectAfterLogoutUrl: "http://127.0.0.1/services/login/hbp"
-
+### LOG LEVELS ###
 logging:
   level:
     root: "ERROR"
@@ -31,14 +25,14 @@ logging:
     eu:
       hbp: "DEBUG"
 
-# EMBEDDED SERVER CONFIGURATION
+### EMBEDDED SERVER CONFIGURATION ###
 server:
   servlet:
     contextPath: "/services"
   port: 8080
   forward-headers-strategy: native
 
-# ENDPOINTS
+### ENDPOINTS ###
 endpoints:
   enabled: true
   health:
@@ -46,12 +40,11 @@ endpoints:
     endpoint: "/health"
     sensitive: false
 
-# External Services
+### EXTERNAL SERVICES ###
 services:
   exareme:
     queryExaremeUrl: "http://127.0.0.1:9090/mining/query"
     algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json"
-
   galaxy:
     galaxyUrl: "http://127.0.0.1:8090"
     galaxyContext:  "nativeGalaxy/workflows/list"
@@ -59,11 +52,11 @@ services:
     galaxyUsername:  "admin"
     galaxyPassword:  "password"
 
-# Authentication
+### Authentication ###
 authentication:
   enabled: true
 
-# Keycloak
+### Keycloak ###
 keycloak:
   enabled: true
   auth-server-url: "http://127.0.0.1/auth"
@@ -74,8 +67,7 @@ keycloak:
     secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
   principal-attribute: "preferred_username"
 
-  # logoutUrl: {{ .Env.LOGOUT_URL }}
-
+### EXTERNAL FILES ###
 # Files are loaded from the resources
 files:
   pathologies_json: "classPath:/pathologies.json"
-- 
GitLab


From 12cbb8c2ca3b5af4af62665d8487b58de95912e7 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 17 Nov 2020 10:37:56 -0800
Subject: [PATCH 27/52] Cleanup and beautification.

---
 src/main/java/eu/hbp/mip/MIPApplication.java  |   5 -
 .../APIMetadataConfiguration.java}            |  14 +-
 .../GalaxyAuthentication.java                 |   6 +-
 .../PersistenceConfiguration.java             |   4 +-
 .../SecurityConfiguration.java                |   6 +-
 .../eu/hbp/mip/controllers/AlgorithmsApi.java |   5 +-
 .../eu/hbp/mip/controllers/ExperimentApi.java |   2 +-
 .../hbp/mip/controllers/PathologiesApi.java   |   2 +-
 .../java/eu/hbp/mip/controllers/UsersApi.java |   4 +-
 .../retrofit/RetroFitGalaxyClients.java       |   6 +-
 .../eu/hbp/mip/model/DAOs/ArticleDAO.java     | 151 ------------------
 .../{model => models}/DAOs/ExperimentDAO.java |   6 +-
 .../mip/{model => models}/DAOs/UserDAO.java   |   2 +-
 .../{model => models}/DTOs/AlgorithmDTO.java  |   2 +-
 .../{model => models}/DTOs/ExperimentDTO.java |   4 +-
 .../{model => models}/DTOs/PathologyDTO.java  |   2 +-
 .../galaxy/ErrorResponse.java                 |   2 +-
 .../galaxy/GalaxyWorkflowResult.java          |   2 +-
 .../PostWorkflowToGalaxyDtoResponse.java      |   2 +-
 .../{model => models}/galaxy/WorkflowDTO.java |   4 +-
 .../mip/repositories/ArticleRepository.java   |  17 --
 .../repositories/ExperimentRepository.java    |   2 +-
 .../hbp/mip/repositories/UserRepository.java  |   2 +-
 .../hbp/mip/services/ActiveUserService.java   |   2 +-
 .../hbp/mip/services/ExperimentService.java   |  12 +-
 .../services/ExperimentSpecifications.java    |   2 +-
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |   2 +-
 27 files changed, 41 insertions(+), 229 deletions(-)
 rename src/main/java/eu/hbp/mip/{configuration/WebConfiguration.java => configurations/APIMetadataConfiguration.java} (76%)
 rename src/main/java/eu/hbp/mip/{configuration => configurations}/GalaxyAuthentication.java (89%)
 rename src/main/java/eu/hbp/mip/{configuration => configurations}/PersistenceConfiguration.java (94%)
 rename src/main/java/eu/hbp/mip/{configuration => configurations}/SecurityConfiguration.java (96%)
 delete mode 100644 src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
 rename src/main/java/eu/hbp/mip/{model => models}/DAOs/ExperimentDAO.java (97%)
 rename src/main/java/eu/hbp/mip/{model => models}/DAOs/UserDAO.java (97%)
 rename src/main/java/eu/hbp/mip/{model => models}/DTOs/AlgorithmDTO.java (95%)
 rename src/main/java/eu/hbp/mip/{model => models}/DTOs/ExperimentDTO.java (97%)
 rename src/main/java/eu/hbp/mip/{model => models}/DTOs/PathologyDTO.java (93%)
 rename src/main/java/eu/hbp/mip/{model => models}/galaxy/ErrorResponse.java (96%)
 rename src/main/java/eu/hbp/mip/{model => models}/galaxy/GalaxyWorkflowResult.java (99%)
 rename src/main/java/eu/hbp/mip/{model => models}/galaxy/PostWorkflowToGalaxyDtoResponse.java (98%)
 rename src/main/java/eu/hbp/mip/{model => models}/galaxy/WorkflowDTO.java (95%)
 delete mode 100644 src/main/java/eu/hbp/mip/repositories/ArticleRepository.java

diff --git a/src/main/java/eu/hbp/mip/MIPApplication.java b/src/main/java/eu/hbp/mip/MIPApplication.java
index 9af69bdd9..f4001f93c 100644
--- a/src/main/java/eu/hbp/mip/MIPApplication.java
+++ b/src/main/java/eu/hbp/mip/MIPApplication.java
@@ -7,17 +7,12 @@ package eu.hbp.mip;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 @SpringBootApplication
 public class MIPApplication {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(MIPApplication.class);
-
     public static void main(String[] args) {
         SpringApplication.run(MIPApplication.class, args);
     }
 
-
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configurations/APIMetadataConfiguration.java
similarity index 76%
rename from src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
rename to src/main/java/eu/hbp/mip/configurations/APIMetadataConfiguration.java
index 50fbe43ae..7b9eab456 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/APIMetadataConfiguration.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.configuration;
+package eu.hbp.mip.configurations;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -10,13 +10,9 @@ import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spring.web.plugins.Docket;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
-/**
- * Created by mirco on 11.07.16.
- */
-
 @Configuration
 @EnableSwagger2
-public class WebConfiguration {
+public class APIMetadataConfiguration {
 
     @Bean
     public Docket swaggerDocumentation() {
@@ -31,10 +27,8 @@ public class WebConfiguration {
     private ApiInfo metadata() {
         return new ApiInfoBuilder()
                 .title("Medical Informatics Platform API")
-                .description("Serve the MIP Frontend")
-                .version("1.0")
-                .contact(new Contact("Mirco Nasuti", "https://www.unil.ch/lren/en/home.html", "mirco.nasuti@chuv.ch"))
+                .description("Serving the MIP Frontend")
+                .contact(new Contact("Kostas Filippopolitis", "https://github.com/KFilippopolitis", "kostasfilippop@gmail.com"))
                 .build();
     }
-
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java b/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
similarity index 89%
rename from src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java
rename to src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
index 7910e809f..41888d3ea 100644
--- a/src/main/java/eu/hbp/mip/configuration/GalaxyAuthentication.java
+++ b/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
@@ -1,13 +1,11 @@
-package eu.hbp.mip.configuration;
+package eu.hbp.mip.configurations;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
-import eu.hbp.mip.configuration.SecurityConfiguration;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logging;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -16,8 +14,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
 import java.util.Base64;
 
 @RestController
diff --git a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
similarity index 94%
rename from src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
rename to src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
index 909d2c1c8..181bc639c 100644
--- a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.configuration;
+package eu.hbp.mip.configurations;
 
 import org.flywaydb.core.Flyway;
 import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -36,7 +36,7 @@ public class PersistenceConfiguration {
         emfb.setDataSource(portalDataSource());
         JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
         emfb.setJpaVendorAdapter(vendorAdapter);
-        emfb.setPackagesToScan("eu.hbp.mip.model.DAOs");
+        emfb.setPackagesToScan("eu.hbp.mip.models.DAOs");
         return emfb;
     }
 
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
similarity index 96%
rename from src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
rename to src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 796f900a5..c4dc2a28b 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.configuration;
+package eu.hbp.mip.configurations;
 
 import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
@@ -21,8 +21,6 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 
 
-// Keycloak security with keycloak-spring-boot-starter
-
 @Controller
 @KeycloakConfiguration
 public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@@ -59,7 +57,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     @GetMapping(value = "/logout")
     public String logout() throws ServletException {
         request.logout();
-        return "redirect:" + logoutRedirectURL;
+        return String.format("redirect:%s", logoutRedirectURL);
     }
 
     @Bean
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
index d42720344..454007298 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
@@ -8,16 +8,15 @@ import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
-import eu.hbp.mip.model.DTOs.AlgorithmDTO;
+import eu.hbp.mip.models.DTOs.AlgorithmDTO;
 import eu.hbp.mip.services.ActiveUserService;
-import eu.hbp.mip.model.galaxy.WorkflowDTO;
+import eu.hbp.mip.models.galaxy.WorkflowDTO;
 import eu.hbp.mip.utils.CustomResourceLoader;
 import eu.hbp.mip.utils.HTTPUtil;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index d5fc161b1..79168b42a 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.controllers;
 
-import eu.hbp.mip.model.DTOs.ExperimentDTO;
+import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.ExperimentService;
 import eu.hbp.mip.utils.JsonConverters;
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 0f3f3c2bb..2c9e08a7e 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -2,7 +2,7 @@ package eu.hbp.mip.controllers;
 
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
-import eu.hbp.mip.model.DTOs.PathologyDTO;
+import eu.hbp.mip.models.DTOs.PathologyDTO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index c8b1193f8..0c07b5f05 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -2,13 +2,11 @@ package eu.hbp.mip.controllers;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import eu.hbp.mip.model.DAOs.UserDAO;
-import eu.hbp.mip.repositories.UserRepository;
+import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logging;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
diff --git a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java b/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java
index 612dce6ca..609163e89 100644
--- a/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java
+++ b/src/main/java/eu/hbp/mip/controllers/galaxy/retrofit/RetroFitGalaxyClients.java
@@ -1,9 +1,9 @@
 package eu.hbp.mip.controllers.galaxy.retrofit;
 
 import com.google.gson.JsonObject;
-import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
-import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
-import eu.hbp.mip.model.galaxy.WorkflowDTO;
+import eu.hbp.mip.models.galaxy.GalaxyWorkflowResult;
+import eu.hbp.mip.models.galaxy.PostWorkflowToGalaxyDtoResponse;
+import eu.hbp.mip.models.galaxy.WorkflowDTO;
 import retrofit2.Call;
 import retrofit2.http.*;
 
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
deleted file mode 100644
index 541c50765..000000000
--- a/src/main/java/eu/hbp/mip/model/DAOs/ArticleDAO.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Created by mirco on 04.12.15.
- */
-
-package eu.hbp.mip.model.DAOs;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import io.swagger.annotations.ApiModel;
-import org.springframework.validation.annotation.Validated;
-
-import javax.persistence.*;
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Size;
-import java.util.Date;
-
-@Entity
-@Table(name = "`article`")
-@ApiModel
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Validated
-public class ArticleDAO {
-
-    @Id
-    private String slug = null;
-
-    @NotNull
-    @Size(min = 1, max = 255)
-    private String title;
-
-    private String status = null;
-
-    @Column(columnDefinition = "text", name = "abstract")
-    private String abstractText = null;
-
-    @Column(columnDefinition = "text")
-    private String content = null;
-
-    private Date publishedAt = null;
-
-    private Date createdAt = null;
-
-    private Date updatedAt = null;
-
-    @ManyToOne
-    @JoinColumn(name = "createdby_username")
-    private UserDAO createdBy = null;
-
-    @ManyToOne
-    @JoinColumn(name = "updatedby_username")
-    private UserDAO updatedBy = null;
-
-    public ArticleDAO() {
-        /*
-         *  Empty constructor is needed by Hibernate
-         */
-        title = "";
-    }
-
-
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-
-    public String getSlug() {
-        return slug;
-    }
-
-    public void setSlug(String slug) {
-        this.slug = slug;
-    }
-
-
-    @JsonProperty("abstract")
-    public String getAbstract() {
-        return abstractText;
-    }
-
-    public void setAbstract(String abstractText) {
-        this.abstractText = abstractText;
-    }
-
-
-    public String getContent() {
-        return content;
-    }
-
-    public void setContent(String content) {
-        this.content = content;
-    }
-
-
-    public Date getPublishedAt() {
-        return publishedAt;
-    }
-
-    public void setPublishedAt(Date publishedAt) {
-        this.publishedAt = publishedAt;
-    }
-
-
-    public Date getCreatedAt() {
-        return createdAt;
-    }
-
-    public void setCreatedAt(Date createdAt) {
-        this.createdAt = createdAt;
-    }
-
-
-    public Date getUpdatedAt() {
-        return updatedAt;
-    }
-
-    public void setUpdatedAt(Date updatedAt) {
-        this.updatedAt = updatedAt;
-    }
-
-
-    public UserDAO getCreatedBy() {
-        return createdBy;
-    }
-
-    public void setCreatedBy(UserDAO createdBy) {
-        this.createdBy = createdBy;
-    }
-
-
-    public UserDAO getUpdatedBy() {
-        return updatedBy;
-    }
-
-    public void setUpdatedBy(UserDAO updatedBy) {
-        this.updatedBy = updatedBy;
-    }
-
-}
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
similarity index 97%
rename from src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
rename to src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index 2ee8e0ba4..e96f74c44 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -1,10 +1,10 @@
-package eu.hbp.mip.model.DAOs;
+package eu.hbp.mip.models.DAOs;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
-import eu.hbp.mip.model.DTOs.AlgorithmDTO;
-import eu.hbp.mip.model.DTOs.ExperimentDTO;
+import eu.hbp.mip.models.DTOs.AlgorithmDTO;
+import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.ApiModel;
 
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
similarity index 97%
rename from src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
rename to src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
index 0e1e9a9ff..a94e5da1c 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
@@ -2,7 +2,7 @@
  * Created by mirco on 04.12.15.
  */
 
-package eu.hbp.mip.model.DAOs;
+package eu.hbp.mip.models.DAOs;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.annotations.Expose;
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
similarity index 95%
rename from src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java
rename to src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
index 0a49c5ad6..1a6d8b99d 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/AlgorithmDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.model.DTOs;
+package eu.hbp.mip.models.DTOs;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
similarity index 97%
rename from src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
rename to src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 64ade455b..797fe0925 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -1,6 +1,6 @@
-package eu.hbp.mip.model.DTOs;
+package eu.hbp.mip.models.DTOs;
 
-import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.models.DAOs.ExperimentDAO;
 
 import java.util.Date;
 import java.util.List;
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
similarity index 93%
rename from src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java
rename to src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
index 6a4580e81..2a8887b5f 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/PathologyDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.model.DTOs;
+package eu.hbp.mip.models.DTOs;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java b/src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java
similarity index 96%
rename from src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java
rename to src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java
index 77a171358..2703e7425 100644
--- a/src/main/java/eu/hbp/mip/model/galaxy/ErrorResponse.java
+++ b/src/main/java/eu/hbp/mip/models/galaxy/ErrorResponse.java
@@ -3,7 +3,7 @@
  * Copyright (c) 2019. MIT License
  */
 
-package eu.hbp.mip.model.galaxy;
+package eu.hbp.mip.models.galaxy;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java b/src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java
similarity index 99%
rename from src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java
rename to src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java
index 089a6a626..ca7d98fe5 100644
--- a/src/main/java/eu/hbp/mip/model/galaxy/GalaxyWorkflowResult.java
+++ b/src/main/java/eu/hbp/mip/models/galaxy/GalaxyWorkflowResult.java
@@ -3,7 +3,7 @@
  * Copyright (c) 2019. MIT License
  */
 
-package eu.hbp.mip.model.galaxy;
+package eu.hbp.mip.models.galaxy;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java b/src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java
similarity index 98%
rename from src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java
rename to src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java
index edefd6326..96d8aa8ef 100644
--- a/src/main/java/eu/hbp/mip/model/galaxy/PostWorkflowToGalaxyDtoResponse.java
+++ b/src/main/java/eu/hbp/mip/models/galaxy/PostWorkflowToGalaxyDtoResponse.java
@@ -3,7 +3,7 @@
  * Copyright (c) 2019. MIT License
  */
 
-package eu.hbp.mip.model.galaxy;
+package eu.hbp.mip.models.galaxy;
 
 import com.google.gson.annotations.SerializedName;
 
diff --git a/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java b/src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java
similarity index 95%
rename from src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java
rename to src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java
index 4b01b3819..496ee2dfe 100644
--- a/src/main/java/eu/hbp/mip/model/galaxy/WorkflowDTO.java
+++ b/src/main/java/eu/hbp/mip/models/galaxy/WorkflowDTO.java
@@ -1,8 +1,8 @@
-package eu.hbp.mip.model.galaxy;
+package eu.hbp.mip.models.galaxy;
 
 import com.google.gson.Gson;
 import com.google.gson.annotations.SerializedName;
-import eu.hbp.mip.model.DTOs.AlgorithmDTO;
+import eu.hbp.mip.models.DTOs.AlgorithmDTO;
 
 import java.util.*;
 
diff --git a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java b/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java
deleted file mode 100644
index 5f6589ab5..000000000
--- a/src/main/java/eu/hbp/mip/repositories/ArticleRepository.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package eu.hbp.mip.repositories;
-
-import eu.hbp.mip.model.DAOs.ArticleDAO;
-import eu.hbp.mip.model.DAOs.UserDAO;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Created by mirco on 11.07.16.
- */
-
-public interface ArticleRepository extends CrudRepository<ArticleDAO, String> {
-    Long countByTitle(String title);
-
-    Iterable<ArticleDAO> findByCreatedBy(UserDAO user);
-
-    Iterable<ArticleDAO> findByStatusOrCreatedBy(String status, UserDAO user);
-}
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index 5f2c8dc76..4efb1613b 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.repositories;
 
-import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.models.DAOs.ExperimentDAO;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 
diff --git a/src/main/java/eu/hbp/mip/repositories/UserRepository.java b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
index 4a3a7c698..99ae0b1dc 100644
--- a/src/main/java/eu/hbp/mip/repositories/UserRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.repositories;
 
-import eu.hbp.mip.model.DAOs.UserDAO;
+import eu.hbp.mip.models.DAOs.UserDAO;
 import org.springframework.data.repository.CrudRepository;
 
 /**
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index 3d8815373..e1a4a7350 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.services;
 
-import eu.hbp.mip.model.DAOs.UserDAO;
+import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.repositories.UserRepository;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.representations.IDToken;
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 3f6bb87b0..829b4bfa0 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -12,12 +12,12 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
-import eu.hbp.mip.model.DAOs.ExperimentDAO;
-import eu.hbp.mip.model.DAOs.UserDAO;
-import eu.hbp.mip.model.DTOs.AlgorithmDTO;
-import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.galaxy.GalaxyWorkflowResult;
-import eu.hbp.mip.model.galaxy.PostWorkflowToGalaxyDtoResponse;
+import eu.hbp.mip.models.DAOs.ExperimentDAO;
+import eu.hbp.mip.models.DAOs.UserDAO;
+import eu.hbp.mip.models.DTOs.AlgorithmDTO;
+import eu.hbp.mip.models.DTOs.ExperimentDTO;
+import eu.hbp.mip.models.galaxy.GalaxyWorkflowResult;
+import eu.hbp.mip.models.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.Exceptions.*;
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index 076249e0b..8a79bf61e 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -1,6 +1,6 @@
 package eu.hbp.mip.services;
 
-import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.models.DAOs.ExperimentDAO;
 import org.springframework.data.jpa.domain.Specification;
 
 import javax.persistence.criteria.CriteriaBuilder;
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index cdbe41c9e..117bead85 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -1,7 +1,7 @@
 package eu.hbp.mip.utils;
 
 import com.google.gson.Gson;
-import eu.hbp.mip.model.DTOs.PathologyDTO;
+import eu.hbp.mip.models.DTOs.PathologyDTO;
 import org.springframework.security.core.GrantedAuthority;
 
 import java.util.ArrayList;
-- 
GitLab


From f2a273e1d9ab50ed364066cf6e8bf8a420874af3 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 17 Nov 2020 10:45:42 -0800
Subject: [PATCH 28/52] Small beautifications.

---
 .../{UsersApi.java => ActiveUserAPI.java}     | 28 ++++---------------
 ...{AlgorithmsApi.java => AlgorithmsAPI.java} |  2 +-
 ...{ExperimentApi.java => ExperimentAPI.java} |  2 +-
 ...athologiesApi.java => PathologiesAPI.java} |  2 +-
 4 files changed, 8 insertions(+), 26 deletions(-)
 rename src/main/java/eu/hbp/mip/controllers/{UsersApi.java => ActiveUserAPI.java} (60%)
 rename src/main/java/eu/hbp/mip/controllers/{AlgorithmsApi.java => AlgorithmsAPI.java} (99%)
 rename src/main/java/eu/hbp/mip/controllers/{ExperimentApi.java => ExperimentAPI.java} (99%)
 rename src/main/java/eu/hbp/mip/controllers/{PathologiesApi.java => PathologiesAPI.java} (99%)

diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
similarity index 60%
rename from src/main/java/eu/hbp/mip/controllers/UsersApi.java
rename to src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
index 0c07b5f05..7e5209b75 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
@@ -1,7 +1,5 @@
 package eu.hbp.mip.controllers;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logging;
@@ -9,19 +7,19 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
 
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
 @RestController
 @RequestMapping(value = "/activeUser", produces = {APPLICATION_JSON_VALUE})
 @Api(value = "/activeUser")
-public class UsersApi {
+public class ActiveUserAPI {
 
     @Autowired
     private ActiveUserService activeUserService;
@@ -32,22 +30,6 @@ public class UsersApi {
         Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser",
                 "Loading the details of the activeUser");
 
-        UserDAO activeUser = activeUserService.getActiveUser();
-
-        // Add the active user object to a cookie
-        try {
-            // TODO needed? Ask Manuel
-            ObjectMapper mapper = new ObjectMapper();
-            String userJSON = mapper.writeValueAsString(activeUser);
-            Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8"));
-            cookie.setSecure(true);
-            cookie.setPath("/");
-            response.addCookie(cookie);
-        } catch (JsonProcessingException | UnsupportedEncodingException e) {
-            Logging.LogUserAction(activeUser.getUsername(),
-                    "(GET) /activeUser", "Failed to add Cookie. Exception: " + e.getMessage());
-        }
-
         return ResponseEntity.ok(activeUserService.getActiveUser());
     }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
similarity index 99%
rename from src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
rename to src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
index 454007298..001409d25 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
@@ -37,7 +37,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @RestController
 @RequestMapping(value = "/algorithms", produces = {APPLICATION_JSON_VALUE})
 @Api(value = "/algorithms")
-public class AlgorithmsApi {
+public class AlgorithmsAPI {
 
     private static final Gson gson = new Gson();
 
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
similarity index 99%
rename from src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
rename to src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index 79168b42a..9c77111aa 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -25,7 +25,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @RestController
 @RequestMapping(value = "/experiments", produces = {APPLICATION_JSON_VALUE})
 @Api(value = "/experiments")
-public class ExperimentApi {
+public class ExperimentAPI {
 
     @Autowired
     private ActiveUserService activeUserService;
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
similarity index 99%
rename from src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
rename to src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
index 2c9e08a7e..f79052ff5 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
@@ -27,7 +27,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @RestController
 @RequestMapping(value = "/pathologies", produces = {APPLICATION_JSON_VALUE})
 @Api(value = "/pathologies")
-public class PathologiesApi {
+public class PathologiesAPI {
 
     private static final Gson gson = new Gson();
 
-- 
GitLab


From 79ac778641580deecb2d948eaa1b61789816918d Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 18 Nov 2020 00:24:50 -0800
Subject: [PATCH 29/52] Removing webjars endpoint.

---
 .../eu/hbp/mip/configurations/SecurityConfiguration.java  | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index c4dc2a28b..dfc5d4e47 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -25,12 +25,12 @@ import javax.servlet.http.HttpServletRequest;
 @KeycloakConfiguration
 public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
 
-    @Value("#{'${authentication.enabled}'}")
-    private boolean authenticationEnabled;
-
     // Redirect to login page url
     private static final String logoutRedirectURL = "/sso/login";
 
+    @Value("#{'${authentication.enabled}'}")
+    private boolean authenticationEnabled;
+
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         super.configure(http);
@@ -38,7 +38,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         if (authenticationEnabled) {
             http.authorizeRequests()
                     .antMatchers(
-                            "/sso/login", "/webjars/**",
+                            "/sso/login",
                             "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**"  // Swagger URLs
                     ).permitAll()
                     .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
-- 
GitLab


From ab5c32f93ba94cf55a04e5eb74283c65f546cd17 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Wed, 18 Nov 2020 00:45:35 -0800
Subject: [PATCH 30/52] Added filter order by on get /experiments and added
 property updated on experiment.

---
 pom.xml                                       |  37 +-
 .../eu/hbp/mip/controllers/ExperimentApi.java |  27 +-
 .../eu/hbp/mip/model/DAOs/ExperimentDAO.java  |  40 ++-
 .../eu/hbp/mip/model/DTOs/ExperimentDTO.java  |  56 +--
 .../repositories/ExperimentRepository.java    |   2 +-
 .../hbp/mip/services/ExperimentService.java   | 319 ++++++++++--------
 .../services/ExperimentSpecifications.java    |  45 ++-
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |   6 +-
 .../java/eu/hbp/mip/utils/JsonConverters.java |   4 +-
 .../migration/V7_0__NewDatabaseStructure.sql  |   3 +
 10 files changed, 335 insertions(+), 204 deletions(-)

diff --git a/pom.xml b/pom.xml
index 0c3f8a8c2..97d528b78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -251,20 +251,31 @@
             <artifactId>java-jwt</artifactId>
             <version>3.11.0</version>
         </dependency>
-    </dependencies>
 
-    <build>
-        <finalName>portal-backend</finalName>
-        <resources>
-            <resource>
-                <directory>src/main/resources</directory>
-                <includes>
-                    <include>**/*.xml</include>
-                    <include>**/*.json</include>
-                    <include>**/*.csv</include>
-                    <include>**/*.sql</include>
-                    <include>**/*.conf</include>
-                    <include>**/*.yml</include>    <!--  Only for development -->
+        <dependency>
+            <groupId>com.google.code.svenson</groupId>
+            <artifactId>svenson</artifactId>
+            <version>1.5.8</version>
+        </dependency>
+        <!--<dependency>
+           <groupId>eu.hbp.mip</groupId>
+           <artifactId>portal-backend</artifactId>
+           <version>4.0.0</version>
+       </dependency>-->
+   </dependencies>
+
+   <build>
+       <finalName>portal-backend</finalName>
+       <resources>
+           <resource>
+               <directory>src/main/resources</directory>
+               <includes>
+                   <include>**/*.xml</include>
+                   <include>**/*.json</include>
+                   <include>**/*.csv</include>
+                   <include>**/*.sql</include>
+                   <include>**/*.conf</include>
+                   <!--  <include>**/*.yml</include>     Only for development -->
                 </includes>
                 <filtering>true</filtering>
 
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index 322f33f4f..803c47572 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -1,13 +1,11 @@
 package eu.hbp.mip.controllers;
 
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
-import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.services.ExperimentService;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
@@ -27,23 +25,34 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/experiments")
 public class ExperimentApi {
 
-    @Autowired
-    private UserInfo userInfo;
+    private final ExperimentService experimentService;
 
-    @Autowired
-    private ExperimentService experimentService;
+    public ExperimentApi(ExperimentService experimentService) {
+        this.experimentService = experimentService;
+    }
 
-    @ApiOperation(value = "Get experiments", response = ExperimentDTO.class, responseContainer = "List")
+    @ApiOperation(value = "Get experiments", response = Map.class, responseContainer = "List")
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<String> getExperiments(
             @RequestParam(name = "name", required = false) String name,
             @RequestParam(name = "algorithm", required = false) String algorithm,
             @RequestParam(name = "shared", required = false) Boolean shared,
             @RequestParam(name = "viewed", required = false) Boolean viewed,
+            @RequestParam(name = "orderBy", required = false, defaultValue = "created") String  orderBy,
+            @RequestParam(name = "descending", required = false, defaultValue = "true") Boolean  descending,
             @RequestParam(defaultValue = "0") int page,
             @RequestParam(defaultValue = "3") int size
     ) {
-        Map experiments = experimentService.getExperiments(name, algorithm, shared, viewed, page, size, "(GET) /experiments");
+        Map experiments = experimentService.getExperiments(
+                name,
+                algorithm,
+                shared,
+                viewed,
+                page,
+                size,
+                orderBy,
+                descending,
+                "(GET) /experiments");
         return new ResponseEntity(experiments, HttpStatus.OK);
     }
 
@@ -66,7 +75,7 @@ public class ExperimentApi {
 
 
     @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
-    @RequestMapping(value = "/{transient}",method = RequestMethod.POST)
+    @RequestMapping(value = "/transient",method = RequestMethod.POST)
     public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
             experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
 
diff --git a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
index 2ee8e0ba4..f10f88742 100644
--- a/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/model/DAOs/ExperimentDAO.java
@@ -7,10 +7,10 @@ import eu.hbp.mip.model.DTOs.AlgorithmDTO;
 import eu.hbp.mip.model.DTOs.ExperimentDTO;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.ApiModel;
+import org.svenson.JSONParser;
 
 import javax.persistence.*;
-import java.util.Date;
-import java.util.UUID;
+import java.util.*;
 
 /**
  * Created by habfast on 21/04/16.
@@ -65,6 +65,10 @@ public class ExperimentDAO {
     @Expose
     @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
     private Date created = new Date();
+    
+    @Expose
+    @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
+    private Date updated;
 
     @Expose
     @Column(columnDefinition = "BOOLEAN")
@@ -81,7 +85,7 @@ public class ExperimentDAO {
         success
     }
 
-    public enum MimeTypes {
+    public enum Type {
         ERROR("text/plain+error"),
         WARNING("text/plain+warning"),
         USER_WARNING("text/plain+user_error"),
@@ -93,15 +97,15 @@ public class ExperimentDAO {
         HTML("text/html"),
         TEXT("text/plain");
 
-        private String types;
+        private String type;
 
         //Constructor to initialize the instance variable
-        MimeTypes(String types) {
-            this.types = types;
+        Type(String type) {
+            this.type = type;
         }
 
-        public String getTypes() {
-            return this.types;
+        public String getType() {
+            return this.type;
         }
     }
 
@@ -116,15 +120,25 @@ public class ExperimentDAO {
         ExperimentDTO experimentDTO = new ExperimentDTO();
         experimentDTO.setAlgorithmDetails(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
         experimentDTO.setCreated(this.created);
+        experimentDTO.setUpdated(this.updated);
+        experimentDTO.setFinished(this.finished);
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
-        experimentDTO.setResult(JsonConverters.convertJsonStringToObject(this.result, ExperimentDTO.ResultDTO.class));
+        experimentDTO.setResult(convertJsonStringToResult(this.result));
+        experimentDTO.setStatus(this.status);
         experimentDTO.setShared(this.shared);
         experimentDTO.setUuid(this.uuid);
         experimentDTO.setViewed(this.viewed);
         return experimentDTO;
     }
 
+    public static Map convertJsonStringToResult(String jsonResult)  {
+        if(jsonResult == null || jsonResult.isEmpty())
+            return null;
+        JSONParser parser = new JSONParser();
+        parser.addTypeHint("Result[]", ExperimentDTO.ResultDTO.class);
+        return parser.parse(Map.class, jsonResult);
+    }
     public String getAlgorithmDetails() {
         return algorithmDetails;
     }
@@ -180,6 +194,14 @@ public class ExperimentDAO {
     public void setCreated(Date created) {
         this.created = created;
     }
+    
+    public Date getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(Date updated) {
+        this.updated = updated;
+    }
 
     public UUID getUuid() {
         return uuid;
diff --git a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
index 64ade455b..037ab5767 100644
--- a/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/model/DTOs/ExperimentDTO.java
@@ -3,7 +3,7 @@ package eu.hbp.mip.model.DTOs;
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
 
 import java.util.Date;
-import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 public class ExperimentDTO {
@@ -12,9 +12,11 @@ public class ExperimentDTO {
     private String name;
     private String createdBy;
     private Date created;
+    private Date updated;
+    private Date finished;
     private Boolean shared;
     private Boolean viewed;
-    private ExperimentDTO.ResultDTO result;
+    private Map result;
     private ExperimentDAO.Status status;
 
     private String algorithm;
@@ -71,6 +73,22 @@ public class ExperimentDTO {
     public void setCreated(Date created) {
         this.created = created;
     }
+    
+    public Date getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(Date updated) {
+        this.updated = updated;
+    }
+    
+    public Date getFinished() {
+        return finished;
+    }
+
+    public void setFinished(Date finished) {
+        this.finished = finished;
+    }
 
     public Boolean getShared() {
         return shared;
@@ -88,11 +106,11 @@ public class ExperimentDTO {
         this.viewed = viewed;
     }
 
-    public ExperimentDTO.ResultDTO getResult() {
+    public Map getResult() {
         return result;
     }
 
-    public void setResult(ExperimentDTO.ResultDTO result) {
+    public void setResult(Map result) {
         this.result = result;
     }
 
@@ -104,37 +122,25 @@ public class ExperimentDTO {
         this.status = status;
     }
 
-    public static class OutputDTO {
+    public static class ResultDTO {
 
-        private String data;
-        private ExperimentDAO.MimeTypes mimeTypes;
+        private Object data;
+        private ExperimentDAO.Type type;
 
-        public String getData() {
+        public Object getData() {
             return this.data;
         }
 
-        public void setData(String data) {
+        public void setData(Object data) {
             this.data = data;
         }
 
-        public ExperimentDAO.MimeTypes getMimeTypes() {
-            return mimeTypes;
-        }
-
-        public void setMimeTypes(ExperimentDAO.MimeTypes mimeTypes) {
-            this.mimeTypes = mimeTypes;
-        }
-    }
-
-    public static class ResultDTO {
-        private List<OutputDTO> result;
-
-        public List<OutputDTO> getResult() {
-            return this.result;
+        public ExperimentDAO.Type getType() {
+            return type;
         }
 
-        public void setResult(List<OutputDTO> result) {
-            this.result = result;
+        public void setType(ExperimentDAO.Type type) {
+            this.type = type;
         }
     }
 }
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index 5f2c8dc76..7b30600e5 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -13,5 +13,5 @@ import java.util.UUID;
 
 public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID>, JpaSpecificationExecutor<ExperimentDAO>
 {
-    Optional<ExperimentDAO> findByUuid(UUID experimentUuid);
+    ExperimentDAO findByUuid(UUID experimentUuid);
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 2590e1edd..12c0d1269 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -27,7 +27,7 @@ import eu.hbp.mip.utils.JsonConverters;
 import eu.hbp.mip.utils.Logging;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
@@ -46,8 +46,6 @@ import static java.lang.Thread.sleep;
 @Service
 public class ExperimentService {
 
-    @Autowired
-    private UserInfo userInfo;
 
     @Value("#{'${services.exareme.queryExaremeUrl}'}")
     private String queryExaremeUrl;
@@ -62,11 +60,16 @@ public class ExperimentService {
     @Value("#{'${hbp.authentication.enabled:1}'}")
     private boolean authenticationIsEnabled;
 
-    @Autowired
-    private ExperimentRepository experimentRepository;
-
     private static final Gson gson = new Gson();
 
+    private final UserInfo userInfo;
+    private final ExperimentRepository experimentRepository;
+
+    public ExperimentService(@Qualifier("userInfo") UserInfo userInfo, ExperimentRepository experimentRepository) {
+        this.userInfo = userInfo;
+        this.experimentRepository = experimentRepository;
+    }
+
     /**
      * The getExperiments will retrieve the experiments from database according to the filters.
      *
@@ -76,23 +79,26 @@ public class ExperimentService {
      * @param viewed is optional, in case it is required to filter the experiments by viewed
      * @param page is the page that is required to be retrieve
      * @param size is the size of each page
+     * @param orderBy is the column that is required to ordered by
+     * @param descending is a boolean to determine if the experiments will be order by descending or ascending
      * @param endpoint is the endpoint that called the function
      * @return a list of mapped experiments
      */
-    public Map getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String endpoint) {
+    public Map getExperiments(String name,String algorithm, Boolean shared,Boolean viewed, int page, int size, String  orderBy, Boolean descending, String endpoint) {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
         if(size > 10 )
             throw new BadRequestException("Invalid size input, max size is 10.");
 
-
-        Specification<ExperimentDAO> spec = Specification.where(new ExperimentSpecifications.ExperimentWithName(name))
+        Specification<ExperimentDAO> spec = Specification
+                .where(new ExperimentSpecifications.ExperimentWithName(name))
                 .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
                 .and(new ExperimentSpecifications.ExperimentWithShared(shared))
-                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed));
+                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
+                .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
 
         Pageable paging = PageRequest.of(page, size);
-        Page<ExperimentDAO> pageExperiments = experimentRepository.findAll(spec, paging);
+         Page<ExperimentDAO> pageExperiments = experimentRepository.findAll(spec, paging);
         List<ExperimentDAO> experimentDAOs = pageExperiments.getContent();
 
         if (experimentDAOs.isEmpty())
@@ -124,7 +130,7 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
-        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
+        experimentDAO = loadExperiment(uuid, endpoint);
 
         if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())) {
             Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
@@ -148,45 +154,16 @@ public class ExperimentService {
         UserDAO user = userInfo.getUser();
 
         //Checking if check (POST) /experiments has proper input.
-        if (checkPostExperimentProperInput(experimentDTO)){
-            Logging.LogUserAction(user.getUsername(), endpoint,
-                    "Invalid input.");
-            throw new BadRequestException("Please provide proper input.");
-        }
+        checkPostExperimentProperInput(experimentDTO, endpoint);
+
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithmDetails().getType();
-        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
-        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        experimentDTO.getAlgorithmDetails().getParameters().forEach(
-            params -> parametersLogMessage
-                .append("  ")
-                .append(params.getLabel())
-                .append(" -> ")
-                .append(params.getValue())
-                .append("\n") );
-        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+        algorithmParametersLogging(experimentDTO, endpoint);
 
         if (authenticationIsEnabled) {
-            // Getting the dataset from the experiment parameters
-            String experimentDatasets = null;
-            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
-                if (parameter.getLabel().equals("dataset")) {
-                    experimentDatasets = parameter.getValue();
-                    break;
-                }
-            }
-
-            if (experimentDatasets == null || experimentDatasets.equals("")) {
-                Logging.LogUserAction(user.getUsername(), endpoint,
-                        "A dataset should be specified to run an algorithm.");
-                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
-            }
-
-            // --- Validating proper access rights on the datasets  ---
-            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
-                throw new BadRequestException("You are not authorized to use these datasets.");
-            }
+            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets);
         }
 
         // Run with the appropriate engine
@@ -211,11 +188,7 @@ public class ExperimentService {
         UserDAO user = userInfo.getUser();
 
         //Checking if check (POST) /experiments has proper input.
-        if (checkPostExperimentProperInput(experimentDTO)){
-            Logging.LogUserAction(user.getUsername(), endpoint,
-                    "Invalid input.");
-            throw new BadRequestException("Please provide proper input.");
-        }
+        checkPostExperimentProperInput(experimentDTO, endpoint);
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
@@ -224,42 +197,17 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmName = experimentDTO.getAlgorithmDetails().getName();
 
-        if (!loadProperAlgorithms().contains(algorithmName)){
+        if (!allowedTransientAlgorithms(algorithmName)){
             Logging.LogUserAction(user.getUsername(), endpoint,
                     "Not proper algorithm.");
             throw new BadRequestException("Please provide proper algorithm.");
         }
 
-        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        experimentDTO.getAlgorithmDetails().getParameters().forEach(
-            params -> parametersLogMessage
-                .append("  ")
-                .append(params.getLabel())
-                .append(" -> ")
-                .append(params.getValue())
-                .append("\n") );
-        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+        algorithmParametersLogging(experimentDTO, endpoint);
 
         if (authenticationIsEnabled) {
-            // Getting the dataset from the experiment parameters
-            String experimentDatasets = null;
-            for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
-                if (parameter.getLabel().equals("dataset")) {
-                    experimentDatasets = parameter.getValue();
-                    break;
-                }
-            }
-
-            if (experimentDatasets == null || experimentDatasets.equals("")) {
-                Logging.LogUserAction(user.getUsername(), endpoint,
-                        "A dataset should be specified to run an algorithm.");
-                throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
-            }
-
-            // --- Validating proper access rights on the datasets  ---
-            if (!ClaimUtils.userHasDatasetsAuthorization(user.getUsername(), authentication.getAuthorities(), experimentDatasets)) {
-                throw new BadRequestException("You are not authorized to use these datasets.");
-            }
+            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets);
         }
 
         String body = gson.toJson(algorithmParameters);
@@ -271,8 +219,11 @@ public class ExperimentService {
 
         // Results are stored in the experiment object
         ExaremeResult exaremeResult = runExaremeExperiment(url, body, experimentDTO);
-        experimentDTO.setResult(exaremeResult.result);
-        experimentDTO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " +exaremeResult.getCode() + " and result: "+ exaremeResult.getResults());
+
+        experimentDTO.setResult((exaremeResult.getCode()>= 400)? null: exaremeResult.getResults());
+        experimentDTO.setStatus((exaremeResult.getCode()>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
 
         return experimentDTO;
     }
@@ -289,41 +240,26 @@ public class ExperimentService {
     {
         ExperimentDAO experimentDAO;
         UserDAO user = userInfo.getUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + experimentDTO.getUuid() + ".");
-        //Checking if check (PUT) /experiments has proper input.
-        if (checkPutExperimentProperInput(experimentDTO)){
-            Logging.LogUserAction(user.getUsername(), endpoint,
-                    "Invalid input.");
-            throw new BadRequestException("Please provide proper input.");
-        }
-
-        if((experimentDTO.getName() == null || experimentDTO.getName().length() == 0)
-                && experimentDTO.getShared() == null
-                && experimentDTO.getViewed() == null
-                && experimentDTO.getAlgorithmDetails() == null)
-        {
-            throw new BadRequestException("Input is required.");
-        }
+        Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
+        experimentDAO = loadExperiment(uuid, endpoint);
 
+        //Verify (PATCH) /experiments non editable fields.
+        verifyPatchExperimentNonEditableFields(uuid, experimentDTO, experimentDAO, endpoint);
+        
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             throw new UnauthorizedException("You don't have access to the experiment.");
 
         if(experimentDTO.getName() != null && experimentDTO.getName().length() != 0)
-        {
             experimentDAO.setName(experimentDTO.getName());
-        }
 
         if(experimentDTO.getShared() != null)
-        {
             experimentDAO.setShared(experimentDTO.getShared());
-        }
 
         if(experimentDTO.getViewed() != null)
-        {
             experimentDAO.setViewed(experimentDTO.getViewed());
-        }
+
+        experimentDAO.setUpdated(new Date());
 
         try {
             experimentRepository.save(experimentDAO);
@@ -332,7 +268,8 @@ public class ExperimentService {
             Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
-        Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + experimentDTO.getUuid() + ".");
+
+        Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + uuid + ".");
 
         experimentDTO = experimentDAO.convertToDTO();
         return experimentDTO;
@@ -350,42 +287,125 @@ public class ExperimentService {
         UserDAO user = userInfo.getUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid).orElseThrow(() -> new ExperimentNotFoundException("Not found Experimnet with id = " + uuid));
+        experimentDAO = loadExperiment(uuid, endpoint);
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             throw new UnauthorizedException("You don't have access to the experiment.");
 
-        experimentRepository.delete(experimentDAO);
+        try {
+            experimentRepository.delete(experimentDAO);
+        }
+        catch (Exception e){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to delete an experiment to database but an error ocurred  : " + e.getMessage() + ".");
+            throw new InternalServerError(e.getMessage());
+        }
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
     }
 
     //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
-    private boolean checkPostExperimentProperInput(ExperimentDTO experimentDTO)
+
+    private void checkPostExperimentProperInput(ExperimentDTO experimentDTO, String endpoint)
     {
-        return  experimentDTO.getShared() != null
-                || experimentDTO.getViewed() != null
-                || experimentDTO.getCreated() != null
-                || experimentDTO.getCreatedBy() != null
-                || experimentDTO.getResult() != null
-                || experimentDTO.getStatus() != null
-                || experimentDTO.getUuid() != null;
+
+        boolean properInput =
+            experimentDTO.getShared() == null
+            && experimentDTO.getViewed() == null
+            && experimentDTO.getCreated() == null
+            && experimentDTO.getCreatedBy() == null
+            && experimentDTO.getResult() == null
+            && experimentDTO.getStatus() == null
+            && experimentDTO.getUuid() == null;
+
+        if (!properInput){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Invalid input.");
+            throw new BadRequestException("Please provide proper input.");
+        }
     }
 
-    private List<String> loadProperAlgorithms()
+    private boolean allowedTransientAlgorithms(String algorithmName)
     {
         List<String> properAlgorithms = new ArrayList<>();
-        properAlgorithms.add("histograms");
-        properAlgorithms.add("descriptive_stats");
-        return properAlgorithms;
+        properAlgorithms.add("MULTIPLE_HISTOGRAMS");
+        properAlgorithms.add("DESCRIPTIVE_STATS");
+        return properAlgorithms.contains(algorithmName);
     }
 
-    private boolean checkPutExperimentProperInput(ExperimentDTO experimentDTO)
+    private void verifyPatchExperimentNonEditableFields(String uuid , ExperimentDTO experimentDTO, ExperimentDAO experimentDAO, String endpoint)
     {
-        return experimentDTO.getUuid() != null
-                || experimentDTO.getCreated() != null
-                || experimentDTO.getResult() != null
-                || experimentDTO.getStatus() != null;
+        if(experimentDTO.getUuid() !=  null && experimentDTO.getUuid().toString().compareTo(uuid) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Uuid is not editable.");
+            throw new BadRequestException("Uuid is not editable.");
+        }
+        
+        if(experimentDTO.getAlgorithm() !=  null && experimentDTO.getAlgorithm().compareTo(experimentDAO.getAlgorithm()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Algorithm is not editable.");
+            throw new BadRequestException("Algorithm is not editable.");
+        }
+
+        if(experimentDTO.getCreated() !=  null && experimentDTO.getCreatedBy().compareTo(experimentDAO.getCreatedBy().getUsername()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "CreatedBy is not editable.");
+            throw new BadRequestException("CreatedBy is not editable.");
+        }
+
+        if(experimentDTO.getAlgorithmDetails() !=  null && JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()).compareTo(experimentDAO.getAlgorithmDetails()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "AlgorithmDetails is not editable.");
+            throw new BadRequestException("AlgorithmDetails is not editable.");
+        }
+        
+        if(experimentDTO.getCreated() !=  null && experimentDTO.getAlgorithm().compareTo(experimentDAO.getAlgorithm()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Created is not editable.");
+            throw new BadRequestException("Created is not editable.");
+        }
+        
+        if(experimentDTO.getResult() !=  null && JsonConverters.convertObjectToJsonString(experimentDTO.getResult()).compareTo(experimentDAO.getResult()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Status is not editable.");
+            throw new BadRequestException("Status is not editable.");
+        }
+        
+        if(experimentDTO.getStatus() !=  null && experimentDTO.getStatus().compareTo(experimentDAO.getStatus()) != 0){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Status is not editable.");
+            throw new BadRequestException("Status is not editable.");
+        }
+    }
+
+    private void algorithmParametersLogging(ExperimentDTO experimentDTO, String endpoint) {
+        UserDAO user = userInfo.getUser() ;
+        String algorithmName = experimentDTO.getAlgorithm();
+        StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
+        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+                params -> parametersLogMessage
+                        .append("  ")
+                        .append(params.getLabel())
+                        .append(" -> ")
+                        .append(params.getValue())
+                        .append("\n") );
+        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+    }
+
+    /**
+     * The getDatasetFromExperimentParameters will retrieve the dataset from the experiment parameters
+     *
+     * @param experimentDTO is the experiment information
+     * @param endpoint is the endpoint that called the function
+     * @return the dataset from the experiment
+     */
+    private String getDatasetFromExperimentParameters(ExperimentDTO experimentDTO, String endpoint) {
+
+        String experimentDatasets = null;
+        for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
+            if (parameter.getLabel().equals("dataset")) {
+                experimentDatasets = parameter.getValue();
+                break;
+            }
+        }
+
+        if (experimentDatasets == null || experimentDatasets.equals("")) {
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint,
+                    "A dataset should be specified to run an algorithm.");
+            throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
+        }
+        return experimentDatasets;
     }
 
     /**
@@ -394,14 +414,26 @@ public class ExperimentService {
      * @param uuid is the id of the experiment to be retrieved
      * @return the experiment information that was retrieved from database
      */
-    private Optional<ExperimentDAO> loadExperiment(String uuid){
-
-
+    private ExperimentDAO loadExperiment(String uuid, String endpoint){
         UUID experimentUuid ;
+        ExperimentDAO experimentDAO;
+
+        try {
+            experimentUuid = UUID.fromString(uuid);
+        }
+        catch (Exception e)
+        {
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, e.getMessage());
+            throw new BadRequestException(e.getMessage());
+        }
 
-        experimentUuid = Optional.of(UUID.fromString(uuid)).orElseThrow(() -> new IllegalArgumentException("Invalid input uuid:"+ uuid));
+        experimentDAO = experimentRepository.findByUuid(experimentUuid);
+        if (experimentDAO == null){
+            Logging.LogUserAction(userInfo.getUser().getUsername(), endpoint, "Experiment with uuid : " + uuid + "was not found.");
+            throw new ExperimentNotFoundException("Experiment with uuid : " + uuid + " was not found.");
+        }
 
-        return experimentRepository.findByUuid(experimentUuid);
+        return experimentDAO;
     }
 
     /**
@@ -411,6 +443,7 @@ public class ExperimentService {
      * @return the experiment information that was inserted into the database
      */
     private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
+
         UserDAO user = userInfo.getUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
@@ -420,6 +453,7 @@ public class ExperimentService {
         experimentDAO.setAlgorithm(experimentDTO.getAlgorithm());
         experimentDAO.setName(experimentDTO.getName());
         experimentDAO.setStatus(ExperimentDAO.Status.pending);
+
         try {
             experimentRepository.save(experimentDAO);
         }
@@ -456,6 +490,7 @@ public class ExperimentService {
 
     private void finishExperiment(ExperimentDAO experimentDAO, String endpoint) {
         experimentDAO.setFinished(new Date());
+
         try {
             experimentRepository.save(experimentDAO);
         }
@@ -508,8 +543,10 @@ public class ExperimentService {
                 // Results are stored in the experiment object
                 ExaremeResult exaremeResult = runExaremeExperiment(url, body, finalExperimentDTO);
 
-                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(exaremeResult.result));
-                experimentDAO.setStatus((exaremeResult.code>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
+                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " +exaremeResult.getCode() + " and result: "+ exaremeResult.getResults());
+
+                experimentDAO.setResult((exaremeResult.getCode()>= 400)? null : JsonConverters.convertObjectToJsonString(exaremeResult.getResults()));
+                experimentDAO.setStatus((exaremeResult.getCode()>= 400)? ExperimentDAO.Status.error: ExperimentDAO.Status.success);
             } catch (Exception e) {
                 Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
 
@@ -539,13 +576,13 @@ public class ExperimentService {
             code = HTTPUtil.sendPost(url, body, results);
         }
         catch (Exception e){
-            throw new InternalServerError("Error occured : "+ e.getMessage());
+            throw new InternalServerError("Error occurred : "+ e.getMessage());
         }
         Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
 
         // Results are stored in the experiment object
-        ExperimentDTO.ResultDTO resultDTO = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.ResultDTO.class);
-        return new ExaremeResult(code, resultDTO);
+        Map resultsDTO = ExperimentDAO.convertJsonStringToResult(String.valueOf(results));
+        return new ExaremeResult(code, resultsDTO);
     }
 
 
@@ -952,21 +989,21 @@ public class ExperimentService {
         return returnError;
     }
 
-    final class ExaremeResult {
-        private final int code;
-        private final ExperimentDTO.ResultDTO result;
+    static class ExaremeResult {
+        private int code;
+        private Map results;
 
-        public ExaremeResult(int code, ExperimentDTO.ResultDTO result) {
+        public ExaremeResult(int code, Map results) {
             this.code = code;
-            this.result = result;
+            this.results = results;
         }
 
         public int getCode() {
             return code;
         }
 
-        public ExperimentDTO.ResultDTO getResult() {
-            return result;
+        public Map getResults() {
+            return results;
         }
     }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index 076249e0b..f59faa9ed 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -1,12 +1,15 @@
 package eu.hbp.mip.services;
 
 import eu.hbp.mip.model.DAOs.ExperimentDAO;
+import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import org.springframework.data.jpa.domain.Specification;
 
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import java.util.ArrayList;
+import java.util.List;
 
 public class ExperimentSpecifications {
     public static class ExperimentWithName implements Specification<ExperimentDAO> {
@@ -65,7 +68,7 @@ public class ExperimentSpecifications {
         }
     }
 
-    public static class ExperimentWithShared implements org.springframework.data.jpa.domain.Specification<ExperimentDAO> {
+    public static class ExperimentWithShared implements Specification<ExperimentDAO> {
 
         private Boolean shared;
 
@@ -79,7 +82,47 @@ public class ExperimentSpecifications {
             }
             return cb.equal(root.get("shared"), this.shared);
         }
+    }
+
+    public static class ExperimentOrderBy implements Specification<ExperimentDAO> {
+
+        private String orderBy;
+        private Boolean descending ;
+        public  ExperimentOrderBy(String orderBy, Boolean descending){
+            if (properColumnToBeOrderedBy(orderBy))
+                this.orderBy = orderBy;
+            else
+                throw new BadRequestException("Please provide proper column to order by.");
+            if(descending == null)
+                this.descending = true;
+            else
+                this.descending = descending;
+        }
 
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+            if (descending) {
+                criteriaQuery.orderBy(cb.desc(root.get(orderBy)));
+            } else {
+                criteriaQuery.orderBy(cb.asc(root.get(orderBy)));
+            }
+            return cb.isTrue(cb.literal(true));
+        }
+
+    }
+
+    public static boolean properColumnToBeOrderedBy(String column){
+        {
+            List<String> properColumns = new ArrayList<>();
+            properColumns.add("uuid");
+            properColumns.add("name");
+            properColumns.add("created_by_username");
+            properColumns.add("algorithm");
+            properColumns.add("created");
+            properColumns.add("status");
+            properColumns.add("shared");
+            properColumns.add("viewed");
+            return properColumns.contains(column);
+        }
     }
 }
 
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 5872819bc..dea4cd0b5 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -2,6 +2,7 @@ package eu.hbp.mip.utils;
 
 import com.google.gson.Gson;
 import eu.hbp.mip.model.DTOs.PathologyDTO;
+import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import org.springframework.security.core.GrantedAuthority;
 
 import java.util.ArrayList;
@@ -22,7 +23,7 @@ public class ClaimUtils {
         return "dataset_" + datasetCode.toLowerCase();
     }
 
-    public static boolean userHasDatasetsAuthorization(String username, Collection<? extends GrantedAuthority> authorities,
+    public static void validateAccessRightsOnDatasets(String username, Collection<? extends GrantedAuthority> authorities,
                                                        String experimentDatasets) {
 
         List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
@@ -37,13 +38,12 @@ public class ClaimUtils {
                 if (!userClaims.contains(datasetRole.toLowerCase())) {
                     Logging.LogUserAction(username, "(POST) /experiments/runAlgorithm",
                             "You are not allowed to use dataset: " + dataset);
-                    return false;
+                    throw new BadRequestException("You are not authorized to use these datasets.");
                 }
             }
             Logging.LogUserAction(username, "(POST) /experiments/runAlgorithm",
                     "User is authorized to use the datasets: " + experimentDatasets);
         }
-        return true;
     }
 
     public static String getAuthorizedPathologies(String username, Collection<? extends GrantedAuthority> authorities,
diff --git a/src/main/java/eu/hbp/mip/utils/JsonConverters.java b/src/main/java/eu/hbp/mip/utils/JsonConverters.java
index 52305124a..74d01b851 100644
--- a/src/main/java/eu/hbp/mip/utils/JsonConverters.java
+++ b/src/main/java/eu/hbp/mip/utils/JsonConverters.java
@@ -7,7 +7,7 @@ import com.google.gson.Gson;
 import java.lang.reflect.Type;
 
 public class JsonConverters {
-    Gson gson = new Gson();
+    private static final Gson gson = new Gson();
 
     public static String convertObjectToJsonString(Object object)  {
         ObjectMapper mapper = new ObjectMapper();
@@ -22,6 +22,6 @@ public class JsonConverters {
     public static  <T> T convertJsonStringToObject(String jsonString, Type typeOfT)  {
         if(jsonString == null || jsonString.isEmpty())
             return null;
-        return new Gson().fromJson(jsonString, typeOfT);
+        return gson.fromJson(jsonString, typeOfT);
     }
 }
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index 73a15addd..5e1bcc6fb 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -15,6 +15,9 @@ RENAME resultsviewed TO viewed;
 ALTER TABLE experiment
 RENAME workflowstatus TO status;
 
+ALTER TABLE experiment
+ADD COLUMN updated timestamp without time zone;
+
 ALTER TABLE experiment
 ADD COLUMN algorithm text;
 
-- 
GitLab


From 511c4f3979acccbb6ddfa0f40604e73bd8589e30 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 18 Nov 2020 01:55:25 -0800
Subject: [PATCH 31/52] User updated if info changed and csrf disabled on
 development.

---
 docker/README.md                                   |  3 ++-
 .../mip/configurations/SecurityConfiguration.java  |  7 ++++++-
 .../eu/hbp/mip/services/ActiveUserService.java     | 14 +++++---------
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/docker/README.md b/docker/README.md
index da8299413..361c5ae56 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -74,4 +74,5 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 * DATA_CENTER_LOCATION: Location of the datacenter, used when reporting errors to Bugsnag
 
 
-# TODO Refactor variables
\ No newline at end of file
+# TODO Refactor variables
+# TODO Refactor variables on mip-deployent as well
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index dfc5d4e47..21a494b88 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -25,7 +25,7 @@ import javax.servlet.http.HttpServletRequest;
 @KeycloakConfiguration
 public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
 
-    // Redirect to login page url
+    // Upon logout, redirect to login page url
     private static final String logoutRedirectURL = "/sso/login";
 
     @Value("#{'${authentication.enabled}'}")
@@ -36,6 +36,11 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         super.configure(http);
 
         if (authenticationEnabled) {
+
+            // Used for development with authentication turned on.
+            // Should not be enabled on production.
+            http.csrf().disable();
+
             http.authorizeRequests()
                     .antMatchers(
                             "/sso/login",
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index 5004e1f7f..61bad973c 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -46,19 +46,15 @@ public class ActiveUserService {
             return user;
         }
 
-
-        // TODO Update user if new values are providedTO
         // If authentication is ON get user info from Token
         KeycloakPrincipal keycloakPrincipal =
                 (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         IDToken idToken = keycloakPrincipal.getKeycloakSecurityContext().getIdToken();
-        UserDAO userInDatabase = userRepository.findByUsername(idToken.getPreferredUsername());
-        if (userInDatabase != null) {
-            user = userInDatabase;
-        } else {
-            UserDAO newUser = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail());
-            userRepository.save(newUser);
-            user = newUser;
+        user = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail());
+
+        UserDAO userInDatabase = userRepository.findByUsername(user.getUsername());
+        if (userInDatabase == null || !userInDatabase.equals(user)) {
+            userRepository.save(user);
         }
         return user;
     }
-- 
GitLab


From 411d8f95b7e413395dd0916c5138605c8edd5284 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 18 Nov 2020 04:37:38 -0800
Subject: [PATCH 32/52] Env variables cleanup.

---
 docker/README.md                              | 77 +++++--------------
 docker/config/application.tmpl                | 69 ++++++++++-------
 .../configurations/SecurityConfiguration.java |  8 +-
 .../eu/hbp/mip/controllers/ExperimentAPI.java | 19 +++--
 src/main/resources/application.yml            | 64 ++++++++-------
 5 files changed, 113 insertions(+), 124 deletions(-)

diff --git a/docker/README.md b/docker/README.md
index 361c5ae56..eb3c76498 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -7,72 +7,37 @@
 To use this image, you need a running instance of PostgreSQL and to configure the software using the following environment variables.
 
 
-### DATABASES
-
-* PORTAL_DB_URL: JDBC URL to connect to the portal database, default value is "jdbc:postgresql://172.22.0.1:5432/portal".
-* PORTAL_DB_SCHEMA: Database schema, default value is "public".
-* PORTAL_DB_USER: User to use when connecting to the portal database, default value is "postgres".
-* PORTAL_DB_PASSWORD: Password to use when connecting to the portal database.
-
-* META_DB_URL: JDBC URL to connect to the metadata database, default value is "jdbc:postgresql://172.22.0.1:5432/meta".
-* META_DB_SCHEMA: Database schema, default value is "public".
-* META_DB_USER: User to use when connecting to the metadata database.
-* META_DB_PASSWORD: Password to use when connecting to the metadata database.
-
-* FEATURES_DB_URL: JDBC URL to connect to the science database, default value is "jdbc:postgresql://172.22.0.1:5433/features".
-* FEATURES_DB_SCHEMA: Database schema, default value is "public".
-* 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_MAIN_TABLE: Table that contains the scientific data to use, default value is "features".
-
-
-### OAUTH2 LOGIN
-
-* AUTHENTICATION: "0" to disable authentication or "1" to enable authentication, default value is "1".
-* CLIENT_ID: required when authentication is turned on, client ID for the [OpenID server of HBP](https://services.humanbrainproject.eu/oidc/).
-* CLIENT_SECRET: required when authentication is turned on, client secret for the [OpenID server of HBP](https://services.humanbrainproject.eu/oidc/).
-* TOKEN_URI: default to "https://services.humanbrainproject.eu/oidc/token".
-* AUTH_URI: default to "https://services.humanbrainproject.eu/oidc/authorize".
-* USER_INFO_URI: default to "https://services.humanbrainproject.eu/oidc/userInfo".
-* REVOKE_TOKEN_URI "https://services.humanbrainproject.eu/oidc/slo".
-
-
-### WEB FRONTEND
-
-* FRONTEND_LOGIN_URL: URL to redirect to when login is required. Default to "http://frontend/services/login/hbp".
-* FRONTEND_AFTER_LOGIN_URL: URL to redirect after login. Default to "http://frontend/home".
-* FRONTEND_AFTER_LOGOUT_URL: URL to redirect to after logout. Default to "http://frontend/services/login/hbp".
-
-
-### LOGGING
-
+### LOG LEVELS ###
 * LOG_LEVEL: log level for the developer added logs. Default is "ERROR".
 * LOG_LEVEL_FRAMEWORK: log level for all the framework logs. Default is "ERROR".
 
 
-### ENDPOINTS
+### AUTHENTICATION ###
+* AUTHENTICATION: true for production, false for development.
 
-* EXAREME_URL: URL to Exareme server, default value is "http://hbps2.chuv.ch:9090".
-* WORKFLOW_URL: URL to Workflow server
-* JWT_SECRET: "secret"
 
-### EMBEDDED SERVER CONFIGURATION
+### RELEASE STAGE ###
+* PRODUCTION: Deployed on production? (True/False) Default is True.
 
-* CONTEXT_PATH:  context path appended to all services running in this container. Default to "/services".
-* SESSION_TIMEOUT: Timeout in milliseconds for session expiration. Default to 2592000.
 
-### PROXY
+### DATABASE CONFIGURATION ###
+* PORTAL_DB_URL: JDBC URL to connect to the portal database, default value is "jdbc:postgresql://127.0.0.1:5432/portal".
+* PORTAL_DB_SCHEMA: Database schema, default value is "public".
+* PORTAL_DB_USER: User to use when connecting to the portal database, default value is "postgres".
+* PORTAL_DB_PASSWORD: Password to use when connecting to the portal database.
 
-* HTTP_PROXY_HOST: HTTP proxy host
-* HTTP_PROXY_PORT: HTTP proxy port
-* HTTPS_PROXY_HOST: HTTPS proxy host
-* HTTPS_PROXY_PORT: HTTPS proxy port
 
-## ERROR REPORTING
+### EXTERNAL SERVICES ###
+* EXAREME_URL: URL to Exareme server. Default is "http://localhost:9090" .
 
-* RELEASE_STAGE: Release stage used when reporting errors to Bugsnag. Values are dev, staging, production
-* DATA_CENTER_LOCATION: Location of the datacenter, used when reporting errors to Bugsnag
+* GALAXY_URL: URL to Workflow server. Default is "http://localhost:8090/" .
+* GALAXY_API_KEY: The api key to authorize galaxy requests.
+* GALAXY_USERNAME: The username of galaxy user to be able to embed the frame.
+* GALAXY_PASSWORD: The password of galaxy user.
 
 
-# TODO Refactor variables
-# TODO Refactor variables on mip-deployent as well
\ No newline at end of file
+### KEYCLOAK ###
+* KEYCLOAK_AUTH_URL: Keycloak authentication URL.
+* KEYCLOAK_REALM: Keycloak realm user for authentication.
+* KEYCLOAK_CLIENT_ID: The keycloak client id.
+* KEYCLOAK_CLIENT_SECRET: The keycloak secret to be able to authenticate.
\ No newline at end of file
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 257bfa087..423baccff 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -1,5 +1,24 @@
 # Configuration template for the portal running inside a Docker container
 
+### LOG LEVELS ###
+logging:
+  level:
+    root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
+    org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
+    eu:
+      hbp: {{ default .Env.LOG_LEVEL "INFO" }}
+
+
+### AUTHENTICATION ###
+authentication:
+  enabled: {{ default .Env.AUTHENTICATION "true" }}
+
+
+### RELEASE STAGE ###
+release_stage:
+  production: {{ default .Env.PRODUCTION "true" }}
+
+
 ### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
@@ -17,28 +36,6 @@ spring:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
 
-### LOG LEVELS ###
-logging:
-  level:
-    root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
-    org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
-    eu:
-      hbp: {{ default .Env.LOG_LEVEL "INFO" }}
-
-### EMBEDDED SERVER CONFIGURATION ###
-server:
-  servlet:
-    contextPath: "/services"
-  port: 8080
-  forward-headers-strategy: native
-
-### ENDPOINTS ###
-endpoints:
-  enabled: true
-  health:
-    enabled: true
-    endpoint: /health
-    sensitive: false
 
 ### EXTERNAL SERVICES ###
 services:
@@ -48,24 +45,21 @@ services:
 
   galaxy:
     galaxyUrl:      {{ default .Env.GALAXY_URL "http://localhost:8090/" }}
-    galaxyContext:  {{ default .Env.GALAXY_CONTEXT "nativeGalaxy/workflows/list" }}
+    galaxyContext:  "nativeGalaxy/workflows/list"
     galaxyApiKey:   {{ .Env.GALAXY_API_KEY }}
     galaxyUsername:  {{ default .Env.GALAXY_USERNAME "admin" }}
     galaxyPassword:  {{ default .Env.GALAXY_PASSWORD "password" }}
 
-### Authentication ###
-authentication:
-  enabled: {{ default .Env.AUTHENTICATION "1" }}
 
-### Keycloak ###
+### KEYCLOAK ###
 keycloak:
   enabled: true
   auth-server-url: {{ .Env.KEYCLOAK_AUTH_URL }}
   realm: {{ .Env.KEYCLOAK_REALM }}
-  resource: {{ .Env.CLIENT_ID }}
+  resource: {{ .Env.KEYCLOAK_CLIENT_ID }}
   enable-basic-auth: true
   credentials:
-    secret: {{ .Env.CLIENT_SECRET }}
+    secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
   principal-attribute: "preferred_username"
 
 ### EXTERNAL FILES ###
@@ -73,3 +67,20 @@ keycloak:
 files:
   pathologies_json: "file:/opt/portal/api/pathologies.json"
   disabledAlgorithms_json: "file:/opt/portal/api/disabledAlgorithms.json"
+
+
+### EMBEDDED SERVER CONFIGURATION ###
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+
+
+### ENDPOINTS ###
+endpoints:
+  enabled: true
+  health:
+    enabled: true
+    endpoint: /health
+    sensitive: false
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 21a494b88..82f237726 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -31,15 +31,17 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     @Value("#{'${authentication.enabled}'}")
     private boolean authenticationEnabled;
 
+    @Value("#{'${release_stage.production}'}")
+    private boolean deployedOnProduction;
+
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         super.configure(http);
 
         if (authenticationEnabled) {
 
-            // Used for development with authentication turned on.
-            // Should not be enabled on production.
-            http.csrf().disable();
+            if(!deployedOnProduction)
+                http.csrf().disable();
 
             http.authorizeRequests()
                     .antMatchers(
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index 78f6032e0..21669bf94 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -2,7 +2,6 @@ package eu.hbp.mip.controllers;
 
 
 import eu.hbp.mip.models.DTOs.ExperimentDTO;
-import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.ExperimentService;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.Api;
@@ -76,15 +75,6 @@ public class ExperimentAPI {
     }
 
 
-    @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
-    @RequestMapping(value = "/transient", method = RequestMethod.POST)
-    public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
-
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
-    }
-
-
     @ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
     public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO, @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
@@ -100,4 +90,13 @@ public class ExperimentAPI {
         experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
         return new ResponseEntity<>(HttpStatus.OK);
     }
+
+
+    @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
+    @RequestMapping(value = "/transient", method = RequestMethod.POST)
+    public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+        experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
+
+        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    }
 }
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 30c82a447..076ed3b59 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,5 +1,24 @@
 # Configuration for development purposes
 
+### LOG LEVELS ###
+logging:
+  level:
+    root: "ERROR"
+    org: "ERROR"
+    eu:
+      hbp: "DEBUG"
+
+
+### AUTHENTICATION ###
+authentication:
+  enabled: true
+
+
+### RELEASE STAGE ###
+release_stage:
+  production: false
+
+
 ### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
@@ -17,28 +36,6 @@ spring:
       dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
 
-### LOG LEVELS ###
-logging:
-  level:
-    root: "ERROR"
-    org: "ERROR"
-    eu:
-      hbp: "DEBUG"
-
-### EMBEDDED SERVER CONFIGURATION ###
-server:
-  servlet:
-    contextPath: "/services"
-  port: 8080
-  forward-headers-strategy: native
-
-### ENDPOINTS ###
-endpoints:
-  enabled: true
-  health:
-    enabled: true
-    endpoint: "/health"
-    sensitive: false
 
 ### EXTERNAL SERVICES ###
 services:
@@ -52,11 +49,8 @@ services:
     galaxyUsername:  "admin"
     galaxyPassword:  "password"
 
-### Authentication ###
-authentication:
-  enabled: true
 
-### Keycloak ###
+### KEYCLOAK ###
 keycloak:
   enabled: true
   auth-server-url: "http://127.0.0.1/auth"
@@ -67,8 +61,26 @@ keycloak:
     secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
   principal-attribute: "preferred_username"
 
+
 ### EXTERNAL FILES ###
 # Files are loaded from the resources
 files:
   pathologies_json: "classPath:/pathologies.json"
   disabledAlgorithms_json: "classPath:/disabledAlgorithms.json"
+
+
+### EMBEDDED SERVER CONFIGURATION ###
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+
+
+### ENDPOINTS ###
+endpoints:
+  enabled: true
+  health:
+    enabled: true
+    endpoint: "/health"
+    sensitive: false
\ No newline at end of file
-- 
GitLab


From d8351d20ffb85dfe3b32bb342cd6b69d2d19f7b7 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 18 Nov 2020 06:20:19 -0800
Subject: [PATCH 33/52] Removed uneccessary dependency.

---
 pom.xml | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/pom.xml b/pom.xml
index 60a5d582c..bc18ad55a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -189,7 +189,6 @@
             <artifactId>aspectjweaver</artifactId>
             <version>${aspectjweaver.version}</version>
         </dependency>
-        
         <dependency>
             <groupId>javax.inject</groupId>
             <artifactId>javax.inject</artifactId>
@@ -221,42 +220,32 @@
             <artifactId>blend4j</artifactId>
             <version>0.2.0</version>
         </dependency>
-
         <dependency>
             <groupId>com.squareup.retrofit2</groupId>
             <artifactId>retrofit</artifactId>
             <version>2.9.0</version>
         </dependency>
-
         <!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
         <dependency>
             <groupId>com.squareup.retrofit2</groupId>
             <artifactId>converter-gson</artifactId>
             <version>2.9.0</version>
         </dependency>
-
         <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor -->
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>
             <artifactId>logging-interceptor</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.auth0</groupId>
             <artifactId>java-jwt</artifactId>
             <version>3.11.0</version>
         </dependency>
-
         <dependency>
             <groupId>com.google.code.svenson</groupId>
             <artifactId>svenson</artifactId>
             <version>1.5.8</version>
         </dependency>
-        <dependency>
-           <groupId>eu.hbp.mip</groupId>
-           <artifactId>portal-backend</artifactId>
-           <version>4.0.0</version>
-       </dependency>
    </dependencies>
 
    <build>
-- 
GitLab


From 041681b27cc018a0cf95e8842e1751b660eb8482 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Wed, 18 Nov 2020 08:02:28 -0800
Subject: [PATCH 34/52] XSRF protection added.

---
 .../configurations/SecurityConfiguration.java | 52 ++++++++++++++++---
 src/main/resources/application.yml            |  2 +-
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 82f237726..4e2905945 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -14,11 +14,22 @@ import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper
 import org.springframework.security.core.session.SessionRegistryImpl;
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
+import org.springframework.security.web.csrf.CsrfFilter;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.util.WebUtils;
 
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 
 
 @Controller
@@ -39,10 +50,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         super.configure(http);
 
         if (authenticationEnabled) {
-
-            if(!deployedOnProduction)
-                http.csrf().disable();
-
             http.authorizeRequests()
                     .antMatchers(
                             "/sso/login",
@@ -53,11 +60,44 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         } else {
             http.antMatcher("/**")
                     .authorizeRequests()
-                    .antMatchers("/**").permitAll()
-                    .and().csrf().disable();
+                    .antMatchers("/**").permitAll();
+        }
+
+        if (!deployedOnProduction) {
+            // If deployed for development, csrf can be disabled
+            http.csrf().disable();
+        } else {
+            http.csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
         }
     }
 
+    private Filter csrfHeaderFilter() {
+        return new OncePerRequestFilter() {
+            @Override
+            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
+                                            FilterChain filterChain) throws ServletException, IOException {
+                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
+                if (csrf != null) {
+                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
+                    String token = csrf.getToken();
+                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
+                        cookie = new Cookie("XSRF-TOKEN", token);
+                        cookie.setPath("/");
+                        response.addCookie(cookie);
+                    }
+                }
+                filterChain.doFilter(request, response);
+            }
+        };
+    }
+
+    private CsrfTokenRepository csrfTokenRepository() {
+        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
+        repository.setHeaderName("X-XSRF-TOKEN");
+        return repository;
+    }
+
     @Autowired
     private HttpServletRequest request;
 
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 076ed3b59..a62d819f6 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -16,7 +16,7 @@ authentication:
 
 ### RELEASE STAGE ###
 release_stage:
-  production: false
+  production: true
 
 
 ### DATABASE CONFIGURATION ###
-- 
GitLab


From 7482e7f58c19e9489ed7d2dc71879de48336177b Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Thu, 19 Nov 2020 18:22:00 +0200
Subject: [PATCH 35/52] Removing deployed on production env variable, not
 needed.

---
 docker/README.md                               |  4 ----
 docker/config/application.tmpl                 |  5 -----
 .../configurations/SecurityConfiguration.java  | 18 +++++-------------
 src/main/resources/application.yml             |  5 -----
 4 files changed, 5 insertions(+), 27 deletions(-)

diff --git a/docker/README.md b/docker/README.md
index eb3c76498..9636ff324 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -16,10 +16,6 @@ To use this image, you need a running instance of PostgreSQL and to configure th
 * AUTHENTICATION: true for production, false for development.
 
 
-### RELEASE STAGE ###
-* PRODUCTION: Deployed on production? (True/False) Default is True.
-
-
 ### DATABASE CONFIGURATION ###
 * PORTAL_DB_URL: JDBC URL to connect to the portal database, default value is "jdbc:postgresql://127.0.0.1:5432/portal".
 * PORTAL_DB_SCHEMA: Database schema, default value is "public".
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 423baccff..5859f78a8 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -14,11 +14,6 @@ authentication:
   enabled: {{ default .Env.AUTHENTICATION "true" }}
 
 
-### RELEASE STAGE ###
-release_stage:
-  production: {{ default .Env.PRODUCTION "true" }}
-
-
 ### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 4e2905945..59929212b 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -42,9 +42,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     @Value("#{'${authentication.enabled}'}")
     private boolean authenticationEnabled;
 
-    @Value("#{'${release_stage.production}'}")
-    private boolean deployedOnProduction;
-
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         super.configure(http);
@@ -56,19 +53,14 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
                             "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**"  // Swagger URLs
                     ).permitAll()
                     .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
-                    .anyRequest().hasRole("RESEARCHER");
+                    .anyRequest().hasRole("RESEARCHER")
+                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
         } else {
             http.antMatcher("/**")
                     .authorizeRequests()
-                    .antMatchers("/**").permitAll();
-        }
-
-        if (!deployedOnProduction) {
-            // If deployed for development, csrf can be disabled
-            http.csrf().disable();
-        } else {
-            http.csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
+                    .antMatchers("/**").permitAll()
+                    .and().csrf().disable();
         }
     }
 
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a62d819f6..84053f912 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -14,11 +14,6 @@ authentication:
   enabled: true
 
 
-### RELEASE STAGE ###
-release_stage:
-  production: true
-
-
 ### DATABASE CONFIGURATION ###
 spring:
   portal-datasource:
-- 
GitLab


From 92d603a6f208f42eaa900c1267876254c03bbddc Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 19 Nov 2020 10:40:26 -0800
Subject: [PATCH 36/52] Remove article from database.Made GET /experiments
 return only my experiments or the shared and wont print the result of the
 experiment.

---
 pom.xml                                       |  6 +-
 .../eu/hbp/mip/controllers/ExperimentAPI.java |  4 +-
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java | 14 ++---
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java | 10 ++-
 .../hbp/mip/services/ExperimentService.java   | 62 +++++++++++--------
 .../services/ExperimentSpecifications.java    | 39 ++++++++++--
 .../java/eu/hbp/mip/utils/ClaimUtils.java     | 11 ++--
 src/main/resources/application.yml            |  2 +-
 .../migration/V7_0__NewDatabaseStructure.sql  |  5 +-
 9 files changed, 99 insertions(+), 54 deletions(-)

diff --git a/pom.xml b/pom.xml
index 60a5d582c..a9f07d9c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -252,11 +252,11 @@
             <artifactId>svenson</artifactId>
             <version>1.5.8</version>
         </dependency>
-        <dependency>
+        <!-- <dependency>
            <groupId>eu.hbp.mip</groupId>
            <artifactId>portal-backend</artifactId>
            <version>4.0.0</version>
-       </dependency>
+       </dependency>-->
    </dependencies>
 
    <build>
@@ -270,7 +270,7 @@
                    <include>**/*.csv</include>
                    <include>**/*.sql</include>
                    <include>**/*.conf</include>
-                   <include>**/*.yml</include>  <!--     Only for development -->
+                   <!-- <include>**/*.yml</include>       Only for development -->
                 </includes>
                 <filtering>true</filtering>
             </resource>
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index 78f6032e0..886c59232 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -40,16 +40,18 @@ public class ExperimentAPI {
             @RequestParam(name = "algorithm", required = false) String algorithm,
             @RequestParam(name = "shared", required = false) Boolean shared,
             @RequestParam(name = "viewed", required = false) Boolean viewed,
+            @RequestParam(name = "includeShared", required = false, defaultValue = "true") boolean includeShared,
             @RequestParam(name = "orderBy", required = false, defaultValue = "created") String orderBy,
             @RequestParam(name = "descending", required = false, defaultValue = "true") Boolean descending,
             @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "3") int size
+            @RequestParam(defaultValue = "10") int size
     ) {
         Map experiments = experimentService.getExperiments(
                 name,
                 algorithm,
                 shared,
                 viewed,
+                includeShared,
                 page,
                 size,
                 orderBy,
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index 1cf4864bd..f43c34960 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -86,7 +86,6 @@ public class ExperimentDAO {
     }
 
     public enum Type {
-        ERROR("text/plain+error"),
         WARNING("text/plain+warning"),
         USER_WARNING("text/plain+user_error"),
         HIGHCHARTS("application/vnd.highcharts+json"),
@@ -115,7 +114,7 @@ public class ExperimentDAO {
          */
     }
 
-    public ExperimentDTO convertToDTO()
+    public ExperimentDTO convertToDTO(boolean includeResult)
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
         experimentDTO.setAlgorithmDetails(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
@@ -124,7 +123,9 @@ public class ExperimentDAO {
         experimentDTO.setFinished(this.finished);
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
-        experimentDTO.setResult(convertJsonStringToResult(this.result));
+        if(includeResult){
+            experimentDTO.setResult(JsonConverters.convertJsonStringToObject(String.valueOf(this.result), new ArrayList<ExperimentDTO.ResultDTO>().getClass()));
+        }
         experimentDTO.setStatus(this.status);
         experimentDTO.setShared(this.shared);
         experimentDTO.setUuid(this.uuid);
@@ -132,13 +133,6 @@ public class ExperimentDAO {
         return experimentDTO;
     }
 
-    public static Map convertJsonStringToResult(String jsonResult)  {
-        if(jsonResult == null || jsonResult.isEmpty())
-            return null;
-        JSONParser parser = new JSONParser();
-        parser.addTypeHint("Result[]", ExperimentDTO.ResultDTO.class);
-        return parser.parse(Map.class, jsonResult);
-    }
     public String getAlgorithmDetails() {
         return algorithmDetails;
     }
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 8c6073a1f..5707b75d0 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -1,11 +1,15 @@
 package eu.hbp.mip.models.DTOs;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
 
+import java.lang.reflect.Array;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+@JsonInclude(JsonInclude.Include.NON_NULL)
 public class ExperimentDTO {
 
     private UUID uuid;
@@ -16,7 +20,7 @@ public class ExperimentDTO {
     private Date finished;
     private Boolean shared;
     private Boolean viewed;
-    private Map result;
+    private List<ExperimentDTO.ResultDTO> result;
     private ExperimentDAO.Status status;
 
     private String algorithm;
@@ -106,11 +110,11 @@ public class ExperimentDTO {
         this.viewed = viewed;
     }
 
-    public Map getResult() {
+    public List<ExperimentDTO.ResultDTO> getResult() {
         return result;
     }
 
-    public void setResult(Map result) {
+    public void setResult(List<ExperimentDTO.ResultDTO> result) {
         this.result = result;
     }
 
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index ed5c8edd8..a79db1016 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -74,6 +74,7 @@ public class ExperimentService {
      * @param algorithm  is optional, in case it is required to filter the experiments by algorithm name
      * @param shared     is optional, in case it is required to filter the experiments by shared
      * @param viewed     is optional, in case it is required to filter the experiments by viewed
+     * @param includeShared     is optional, in case it is required to retrieve the experiment that is shared
      * @param page       is the page that is required to be retrieve
      * @param size       is the size of each page
      * @param orderBy    is the column that is required to ordered by
@@ -82,18 +83,29 @@ public class ExperimentService {
      * @return a list of mapped experiments
      */
 
-    public Map getExperiments(String name, String algorithm, Boolean shared, Boolean viewed, int page, int size, String orderBy, Boolean descending, String endpoint) {
+    public Map getExperiments(String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, String endpoint) {
         UserDAO user = activeUserService.getActiveUser();
         Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
-        if (size > 10)
-            throw new BadRequestException("Invalid size input, max size is 10.");
-
+        if (size > 50)
+            throw new BadRequestException("Invalid size input, max size is 50.");
+        /*TODO:if(role == master){
         Specification<ExperimentDAO> spec = Specification
                 .where(new ExperimentSpecifications.ExperimentWithName(name))
                 .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
                 .and(new ExperimentSpecifications.ExperimentWithShared(shared))
                 .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
                 .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
+        }
+        else
+         */
+        Specification<ExperimentDAO> spec = Specification
+                .where(new ExperimentSpecifications.MyExperiment(user.getUsername()))
+                .or(new ExperimentSpecifications.SharedExperiment(includeShared))
+                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
+                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
+                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
+                .and(new ExperimentSpecifications.ExperimentWithName(name))
+                .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
 
         Pageable paging = PageRequest.of(page, size);
         Page<ExperimentDAO> pageExperiments = experimentRepository.findAll(spec, paging);
@@ -103,7 +115,7 @@ public class ExperimentService {
             throw new NoContent("No experiment found with the filters provided.");
 
         List<ExperimentDTO> experimentDTOs = new ArrayList<>();
-        experimentDAOs.forEach(experimentDAO -> experimentDTOs.add(experimentDAO.convertToDTO()));
+        experimentDAOs.forEach(experimentDAO -> experimentDTOs.add(experimentDAO.convertToDTO(false)));
 
         Map<String, Object> response = new HashMap<>();
         response.put("experiments", experimentDTOs);
@@ -129,12 +141,12 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
 
         experimentDAO = loadExperiment(uuid, endpoint);
-
-        if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())) {
+        //TODO: if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) && if not master) {
+        if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) ) {
             Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
             throw new UnauthorizedException("You don't have access to the experiment.");
         }
-        ExperimentDTO experimentDTO = experimentDAO.convertToDTO();
+        ExperimentDTO experimentDTO = experimentDAO.convertToDTO(true);
         Logging.LogUserAction(user.getUsername(), endpoint, "Experiment was Loaded with uuid : " + uuid + ".");
 
         return experimentDTO;
@@ -161,7 +173,7 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, endpoint);
         }
 
         // Run with the appropriate engine
@@ -205,7 +217,7 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, endpoint);
         }
 
         String body = gson.toJson(algorithmParameters);
@@ -267,7 +279,7 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + uuid + ".");
 
-        experimentDTO = experimentDAO.convertToDTO();
+        experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
     }
 
@@ -324,37 +336,37 @@ public class ExperimentService {
     }
 
     private void verifyPatchExperimentNonEditableFields(String uuid, ExperimentDTO experimentDTO, ExperimentDAO experimentDAO, String endpoint) {
-        if (experimentDTO.getUuid() != null && experimentDTO.getUuid().toString().compareTo(uuid) != 0) {
+        if (experimentDTO.getUuid() != null ) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Uuid is not editable.");
             throw new BadRequestException("Uuid is not editable.");
         }
 
-        if (experimentDTO.getAlgorithm() != null && experimentDTO.getAlgorithm().compareTo(experimentDAO.getAlgorithm()) != 0) {
+        if (experimentDTO.getAlgorithm() != null ) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Algorithm is not editable.");
             throw new BadRequestException("Algorithm is not editable.");
         }
 
-        if (experimentDTO.getCreated() != null && experimentDTO.getCreatedBy().compareTo(experimentDAO.getCreatedBy().getUsername()) != 0) {
+        if (experimentDTO.getCreated() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "CreatedBy is not editable.");
             throw new BadRequestException("CreatedBy is not editable.");
         }
 
-        if (experimentDTO.getAlgorithmDetails() != null && JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()).compareTo(experimentDAO.getAlgorithmDetails()) != 0) {
+        if (experimentDTO.getAlgorithmDetails() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "AlgorithmDetails is not editable.");
             throw new BadRequestException("AlgorithmDetails is not editable.");
         }
 
-        if (experimentDTO.getCreated() != null && experimentDTO.getAlgorithm().compareTo(experimentDAO.getAlgorithm()) != 0) {
+        if (experimentDTO.getCreated() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Created is not editable.");
             throw new BadRequestException("Created is not editable.");
         }
 
-        if (experimentDTO.getResult() != null && JsonConverters.convertObjectToJsonString(experimentDTO.getResult()).compareTo(experimentDAO.getResult()) != 0) {
+        if (experimentDTO.getResult() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Status is not editable.");
             throw new BadRequestException("Status is not editable.");
         }
 
-        if (experimentDTO.getStatus() != null && experimentDTO.getStatus().compareTo(experimentDAO.getStatus()) != 0) {
+        if (experimentDTO.getStatus() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Status is not editable.");
             throw new BadRequestException("Status is not editable.");
         }
@@ -541,7 +553,7 @@ public class ExperimentService {
             finishExperiment(experimentDAO, endpoint);
             Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
         }).start();
-        experimentDTO = experimentDAO.convertToDTO();
+        experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
     }
 
@@ -565,8 +577,8 @@ public class ExperimentService {
         Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
 
         // Results are stored in the experiment object
-        Map resultsDTO = ExperimentDAO.convertJsonStringToResult(String.valueOf(results));
-        return new ExaremeResult(code, resultsDTO);
+        List<ExperimentDTO.ResultDTO> resultDTOS = JsonConverters.convertJsonStringToObject(String.valueOf(results), new ArrayList<ExperimentDTO.ResultDTO>().getClass());
+        return new ExaremeResult(code, resultDTOS);
     }
 
 
@@ -668,7 +680,7 @@ public class ExperimentService {
 
         Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
 
-        experimentDTO = experimentDAO.convertToDTO();
+        experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
     }
 
@@ -974,9 +986,9 @@ public class ExperimentService {
 
     static class ExaremeResult {
         private int code;
-        private Map results;
+        private List<ExperimentDTO.ResultDTO> results;
 
-        public ExaremeResult(int code, Map results) {
+        public ExaremeResult(int code, List<ExperimentDTO.ResultDTO> results) {
             this.code = code;
             this.results = results;
         }
@@ -985,7 +997,7 @@ public class ExperimentService {
             return code;
         }
 
-        public Map getResults() {
+        public List<ExperimentDTO.ResultDTO> getResults() {
             return results;
         }
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index 45169c09d..cfc6a5769 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -1,13 +1,11 @@
 package eu.hbp.mip.services;
 
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
+import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import org.springframework.data.jpa.domain.Specification;
 
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
+import javax.persistence.criteria.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -82,6 +80,39 @@ public class ExperimentSpecifications {
         }
     }
 
+    public static class MyExperiment implements Specification<ExperimentDAO> {
+
+        private String username;
+
+        public MyExperiment(String username) {
+            this.username = username;
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+            if (username == null) {
+                return cb.isTrue(cb.literal(true));
+            }
+            Join<ExperimentDAO, UserDAO> experimentDAOUserDAOJoin = root.join("createdBy");
+            return cb.equal(experimentDAOUserDAOJoin.get("username"), username);
+        }
+    }
+
+    public static class SharedExperiment implements Specification<ExperimentDAO> {
+
+        private boolean shared;
+
+        public SharedExperiment(boolean shared) {
+            this.shared = shared;
+        }
+
+        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+            if (shared == false) {
+                return cb.isTrue(cb.literal(false));
+            }
+            return cb.equal(root.get("shared"), shared);
+        }
+    }
+
     public static class ExperimentOrderBy implements Specification<ExperimentDAO> {
 
         private String orderBy;
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 4e4f95c9d..5eb90a2d0 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -3,6 +3,7 @@ package eu.hbp.mip.utils;
 import com.google.gson.Gson;
 import eu.hbp.mip.models.DTOs.PathologyDTO;
 import eu.hbp.mip.utils.Exceptions.BadRequestException;
+import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
 import org.springframework.security.core.GrantedAuthority;
 
 import java.util.ArrayList;
@@ -24,11 +25,11 @@ public class ClaimUtils {
     }
 
     public static void validateAccessRightsOnDatasets(String username, Collection<? extends GrantedAuthority> authorities,
-                                                       String experimentDatasets) {
+                                                       String experimentDatasets, String endpoint) {
 
         List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
                 .replaceAll("[\\s+\\]\\[]", "").split(","));
-        Logging.LogUserAction(username, "(POST) /experiments/runAlgorithm", userClaims.toString());
+        Logging.LogUserAction(username, endpoint, userClaims.toString());
 
         // Don't check for dataset claims if "super" claim exists allowing everything
         if (!userClaims.contains(ClaimUtils.allDatasetsAllowedClaim())) {
@@ -36,12 +37,12 @@ public class ClaimUtils {
             for (String dataset : experimentDatasets.split(",")) {
                 String datasetRole = ClaimUtils.getDatasetClaim(dataset);
                 if (!userClaims.contains(datasetRole.toLowerCase())) {
-                    Logging.LogUserAction(username, "(POST) /experiments/runAlgorithm",
+                    Logging.LogUserAction(username, endpoint,
                             "You are not allowed to use dataset: " + dataset);
-                    throw new BadRequestException("You are not authorized to use these datasets.");
+                    throw new UnauthorizedException("You are not authorized to use these datasets.");
                 }
             }
-            Logging.LogUserAction(username, "(POST) /experiments/runAlgorithm",
+            Logging.LogUserAction(username, endpoint,
                     "User is authorized to use the datasets: " + experimentDatasets);
         }
     }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 30c82a447..366f1c340 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -54,7 +54,7 @@ services:
 
 ### Authentication ###
 authentication:
-  enabled: true
+  enabled: false
 
 ### Keycloak ###
 keycloak:
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index 5e1bcc6fb..a1c728e96 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -33,12 +33,13 @@ DROP COLUMN password,
 DROP COLUMN phone,
 DROP COLUMN picture,
 DROP COLUMN team,
-DROP COLUMN web;
+DROP COLUMN web,
+DROP COLUMN apikey;
 
 DROP TABLE "config_title", "config_yaxisvariables";
 DROP TABLE "dataset_variable", "dataset_grouping", "dataset_data", "dataset_header";
 DROP TABLE "query_variable", "query_grouping", "query_filter", "query_covariable";
-DROP TABLE "article_tag", "tag";
+DROP TABLE "article_tag", "tag","article";
 DROP TABLE "variable_value";
 DROP TABLE "query_training_datasets", "query_validation_datasets", "query_testing_datasets";
 DROP TABLE "variable", "value";
-- 
GitLab


From f20948890ed0a88e1d2b275942f04eec78edd8ea Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Sun, 29 Nov 2020 04:02:55 -0800
Subject: [PATCH 37/52] Application.yml can always be included.

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index b9da79480..5d8467960 100644
--- a/pom.xml
+++ b/pom.xml
@@ -259,7 +259,7 @@
                    <include>**/*.csv</include>
                    <include>**/*.sql</include>
                    <include>**/*.conf</include>
-                   <!-- <include>**/*.yml</include>       Only for development -->
+                   <include>**/*.yml</include>    <!--   Only for development -->
                 </includes>
                 <filtering>true</filtering>
             </resource>
-- 
GitLab


From c570c5b010475ec61129ad5710e9f5d6f3417c34 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Sun, 29 Nov 2020 04:12:32 -0800
Subject: [PATCH 38/52] CORS Filter added when authentication is disabled.

---
 .../configurations/SecurityConfiguration.java |  8 +++---
 .../java/eu/hbp/mip/utils/CORSFilter.java     | 25 +++++++++++++++++++
 2 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/utils/CORSFilter.java

diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 59929212b..ea5cf7860 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -1,5 +1,6 @@
 package eu.hbp.mip.configurations;
 
+import eu.hbp.mip.utils.CORSFilter;
 import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
 import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
@@ -12,6 +13,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
 import org.springframework.security.core.session.SessionRegistryImpl;
+import org.springframework.security.web.access.channel.ChannelProcessingFilter;
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
 import org.springframework.security.web.csrf.CsrfFilter;
@@ -20,12 +22,11 @@ import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.filter.CorsFilter;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
 
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
+import javax.servlet.*;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -57,6 +58,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
                     .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
                     .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
         } else {
+            http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
             http.antMatcher("/**")
                     .authorizeRequests()
                     .antMatchers("/**").permitAll()
diff --git a/src/main/java/eu/hbp/mip/utils/CORSFilter.java b/src/main/java/eu/hbp/mip/utils/CORSFilter.java
new file mode 100644
index 000000000..1a0696fa5
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/CORSFilter.java
@@ -0,0 +1,25 @@
+package eu.hbp.mip.utils;
+
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+/**
+ * CORS Filter used only for development.
+ *
+ * Allows requests from all possible origins.
+ */
+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", "*");
+        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
+        response.setHeader("Access-Control-Max-Age", "3600");
+        response.setHeader("Access-Control-Allow-Headers", "*");
+        response.setHeader("Access-Control-Request-Headers", "*");
+        chain.doFilter(req, res);
+    }
+}
\ No newline at end of file
-- 
GitLab


From 95dfe1d7bafbb7ed083a0faa19ee565905ade865 Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Sun, 29 Nov 2020 04:42:10 -0800
Subject: [PATCH 39/52] Fix for CORS allowed requests.

---
 src/main/java/eu/hbp/mip/utils/CORSFilter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/eu/hbp/mip/utils/CORSFilter.java b/src/main/java/eu/hbp/mip/utils/CORSFilter.java
index 1a0696fa5..7d77b9022 100644
--- a/src/main/java/eu/hbp/mip/utils/CORSFilter.java
+++ b/src/main/java/eu/hbp/mip/utils/CORSFilter.java
@@ -16,7 +16,7 @@ public class CORSFilter implements Filter {
     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
         HttpServletResponse response = (HttpServletResponse) res;
         response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
+        response.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE");
         response.setHeader("Access-Control-Max-Age", "3600");
         response.setHeader("Access-Control-Allow-Headers", "*");
         response.setHeader("Access-Control-Request-Headers", "*");
-- 
GitLab


From 3c08abe796f42da2eb244f89abf881406b04a991 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 3 Dec 2020 04:51:33 -0800
Subject: [PATCH 40/52] Added badrequest in case  algorithm type is null and
 fix the convertion of the json that exareme provides to a list of results.

---
 src/main/java/eu/hbp/mip/services/ExperimentService.java | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index a79db1016..eb4001665 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -169,6 +169,11 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithmDetails().getType();
 
+        if(algorithmType == null){
+            Logging.LogUserAction(user.getUsername(), endpoint, "Please provide algorithm type.");
+            throw new BadRequestException("Please provide algorithm type.");
+        }
+
         algorithmParametersLogging(experimentDTO, endpoint);
 
         if (authenticationIsEnabled) {
@@ -577,7 +582,8 @@ public class ExperimentService {
         Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
 
         // Results are stored in the experiment object
-        List<ExperimentDTO.ResultDTO> resultDTOS = JsonConverters.convertJsonStringToObject(String.valueOf(results), new ArrayList<ExperimentDTO.ResultDTO>().getClass());
+        ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class);
+        List<ExperimentDTO.ResultDTO> resultDTOS = experimentDTOWithOnlyResult.getResult();
         return new ExaremeResult(code, resultDTOS);
     }
 
-- 
GitLab


From 1b55430100fc2924a65a38f4910878adeb332900 Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Thu, 3 Dec 2020 05:17:02 -0800
Subject: [PATCH 41/52] Removed the algorithm name  from experimentDTO so it
 wont be required or will return algorithm name twice but the algorithm name
 still exists in the database to help with the filtering on the GET
 /experiments request.

---
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java |  3 +--
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java | 18 +++----------
 .../hbp/mip/services/ExperimentService.java   | 26 +++++++++----------
 3 files changed, 17 insertions(+), 30 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index f43c34960..cd3f50757 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -7,7 +7,6 @@ import eu.hbp.mip.models.DTOs.AlgorithmDTO;
 import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.ApiModel;
-import org.svenson.JSONParser;
 
 import javax.persistence.*;
 import java.util.*;
@@ -117,7 +116,7 @@ public class ExperimentDAO {
     public ExperimentDTO convertToDTO(boolean includeResult)
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
-        experimentDTO.setAlgorithmDetails(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
+        experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
         experimentDTO.setCreated(this.created);
         experimentDTO.setUpdated(this.updated);
         experimentDTO.setFinished(this.finished);
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 5707b75d0..5f554dbe6 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -3,10 +3,8 @@ package eu.hbp.mip.models.DTOs;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
 
-import java.lang.reflect.Array;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
@@ -23,29 +21,19 @@ public class ExperimentDTO {
     private List<ExperimentDTO.ResultDTO> result;
     private ExperimentDAO.Status status;
 
-    private String algorithm;
-    private AlgorithmDTO algorithmDetails;
+    private AlgorithmDTO algorithm;
 
     public ExperimentDTO() {
     }
 
-    public String getAlgorithm() {
+    public AlgorithmDTO getAlgorithm() {
         return algorithm;
     }
 
-    public void setAlgorithm(String algorithm) {
+    public void setAlgorithm(AlgorithmDTO algorithm) {
         this.algorithm = algorithm;
     }
 
-    public AlgorithmDTO getAlgorithmDetails() {
-        return algorithmDetails;
-    }
-
-    public void setAlgorithmDetails(AlgorithmDTO algorithmDetails) {
-        this.algorithmDetails = algorithmDetails;
-        this.algorithm = algorithmDetails.getName();
-    }
-
     public UUID getUuid() {
         return uuid;
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index eb4001665..f92efef0d 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -167,7 +167,7 @@ public class ExperimentService {
         checkPostExperimentProperInput(experimentDTO, endpoint);
 
         // Get the type and name of algorithm
-        String algorithmType = experimentDTO.getAlgorithmDetails().getType();
+        String algorithmType = experimentDTO.getAlgorithm().getType();
 
         if(algorithmType == null){
             Logging.LogUserAction(user.getUsername(), endpoint, "Please provide algorithm type.");
@@ -207,10 +207,10 @@ public class ExperimentService {
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
-                = experimentDTO.getAlgorithmDetails().getParameters();
+                = experimentDTO.getAlgorithm().getParameters();
 
         // Get the type and name of algorithm
-        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
+        String algorithmName = experimentDTO.getAlgorithm().getName();
 
         if (!allowedTransientAlgorithms(algorithmName)) {
             Logging.LogUserAction(user.getUsername(), endpoint,
@@ -356,7 +356,7 @@ public class ExperimentService {
             throw new BadRequestException("CreatedBy is not editable.");
         }
 
-        if (experimentDTO.getAlgorithmDetails() != null) {
+        if (experimentDTO.getAlgorithm() != null) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "AlgorithmDetails is not editable.");
             throw new BadRequestException("AlgorithmDetails is not editable.");
         }
@@ -379,9 +379,9 @@ public class ExperimentService {
 
     private void algorithmParametersLogging(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = activeUserService.getActiveUser();
-        String algorithmName = experimentDTO.getAlgorithm();
+        String algorithmName = experimentDTO.getAlgorithm().getName();
         StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
-        experimentDTO.getAlgorithmDetails().getParameters().forEach(
+        experimentDTO.getAlgorithm().getParameters().forEach(
                 params -> parametersLogMessage
                         .append("  ")
                         .append(params.getLabel())
@@ -401,7 +401,7 @@ public class ExperimentService {
     private String getDatasetFromExperimentParameters(ExperimentDTO experimentDTO, String endpoint) {
 
         String experimentDatasets = null;
-        for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithmDetails().getParameters()) {
+        for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithm().getParameters()) {
             if (parameter.getLabel().equals("dataset")) {
                 experimentDatasets = parameter.getValue();
                 break;
@@ -454,8 +454,8 @@ public class ExperimentService {
         ExperimentDAO experimentDAO = new ExperimentDAO();
         experimentDAO.setUuid(UUID.randomUUID());
         experimentDAO.setCreatedBy(user);
-        experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithmDetails()));
-        experimentDAO.setAlgorithm(experimentDTO.getAlgorithm());
+        experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm()));
+        experimentDAO.setAlgorithm(experimentDTO.getAlgorithm().getName());
         experimentDAO.setName(experimentDTO.getName());
         experimentDAO.setStatus(ExperimentDAO.Status.pending);
 
@@ -520,11 +520,11 @@ public class ExperimentService {
         Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
 
         // Run the 1st algorithm from the list
-        String algorithmName = experimentDTO.getAlgorithmDetails().getName();
+        String algorithmName = experimentDTO.getAlgorithm().getName();
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
-                = experimentDTO.getAlgorithmDetails().getParameters();
+                = experimentDTO.getAlgorithm().getParameters();
 
         String body = gson.toJson(algorithmParameters);
         String url = queryExaremeUrl + "/" + algorithmName;
@@ -606,11 +606,11 @@ public class ExperimentService {
 
 
         // Run the 1st algorithm from the list
-        String workflowId = experimentDTO.getAlgorithmDetails().getName();
+        String workflowId = experimentDTO.getAlgorithm().getName();
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
-                = experimentDTO.getAlgorithmDetails().getParameters();
+                = experimentDTO.getAlgorithm().getParameters();
 
         // Convert the parameters to workflow parameters
         HashMap<String, String> algorithmParamsIncludingEmpty = new HashMap<>();
-- 
GitLab


From d76db5b90f577e8869a2b2d0ee9d878c0fd7a9ae Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Tue, 8 Dec 2020 02:55:19 -0800
Subject: [PATCH 42/52] Updated database calls to be case insensitive.

---
 .../java/eu/hbp/mip/services/ExperimentSpecifications.java    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
index cfc6a5769..e5b51a692 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
@@ -27,7 +27,7 @@ public class ExperimentSpecifications {
                 regExp = (name.contains("%") ? name : name + "%");
             }
 
-            return cb.like(root.get("name"), this.regExp);
+            return cb.like(cb.lower(root.get("name")), this.regExp.toLowerCase());
         }
     }
 
@@ -44,7 +44,7 @@ public class ExperimentSpecifications {
                 return cb.isTrue(cb.literal(true));
             }
 
-            return cb.equal(root.get("algorithm"), this.algorithm);
+            return cb.equal(cb.lower(root.get("algorithm")), this.algorithm.toLowerCase());
         }
     }
 
-- 
GitLab


From bc44206bffc73f6f31078fe4fe9518f1553fdc2f Mon Sep 17 00:00:00 2001
From: kfilippopolitis <kostasfilippop@gmail.com>
Date: Tue, 8 Dec 2020 03:25:44 -0800
Subject: [PATCH 43/52] Documentation about the algorithm name column that will
 be stored in the database.

---
 src/main/java/eu/hbp/mip/services/ExperimentService.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index f92efef0d..6039d577f 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -447,6 +447,8 @@ public class ExperimentService {
      *
      * @param experimentDTO is the experiment information to inserted in the database
      * @return the experiment information that was inserted into the database
+     * @Note In the database there will be stored Algorithm Details that is the whole information about the algorithm
+     * and an Algorithm column that is required for the filtering with algorithm name  in the GET /experiments.
      */
     private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
         UserDAO user = activeUserService.getActiveUser();
-- 
GitLab


From d9d4703dadcfae6d41e5f5b1ab2f46d16befd1d2 Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Fri, 11 Dec 2020 06:52:50 -0800
Subject: [PATCH 44/52] Made so the transient endpoint will work with any
 algorithm.

---
 build.sh                                      |  2 +-
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java | 23 -------------------
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java |  6 ++---
 .../hbp/mip/services/ExperimentService.java   | 13 -----------
 4 files changed, 4 insertions(+), 40 deletions(-)

diff --git a/build.sh b/build.sh
index 458b5c085..6a18d98ec 100755
--- a/build.sh
+++ b/build.sh
@@ -26,7 +26,7 @@ else
   DOCKER="sudo docker"
 fi
 
-IMAGE="thanasulas/portal-backend"
+IMAGE="kfilippopolitis/portal-backend"
 VCS_REF=$(git describe --tags --dirty)
 VERSION=$(git describe --tags --dirty)
 
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index cd3f50757..f634c77a2 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -84,29 +84,6 @@ public class ExperimentDAO {
         success
     }
 
-    public enum Type {
-        WARNING("text/plain+warning"),
-        USER_WARNING("text/plain+user_error"),
-        HIGHCHARTS("application/vnd.highcharts+json"),
-        JSON("application/json"),
-        JSONBTREE("application/binary-tree+json"),
-        PFA("application/pfa+json"),
-        JSONDATA("application/vnd.dataresource+json"),
-        HTML("text/html"),
-        TEXT("text/plain");
-
-        private String type;
-
-        //Constructor to initialize the instance variable
-        Type(String type) {
-            this.type = type;
-        }
-
-        public String getType() {
-            return this.type;
-        }
-    }
-
     public ExperimentDAO() {
         /*
          *  Empty constructor is needed by Hibernate
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 5f554dbe6..a1c6e916c 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -117,7 +117,7 @@ public class ExperimentDTO {
     public static class ResultDTO {
 
         private Object data;
-        private ExperimentDAO.Type type;
+        private Object type;
 
         public Object getData() {
             return this.data;
@@ -127,11 +127,11 @@ public class ExperimentDTO {
             this.data = data;
         }
 
-        public ExperimentDAO.Type getType() {
+        public Object getType() {
             return type;
         }
 
-        public void setType(ExperimentDAO.Type type) {
+        public void setType(Object type) {
             this.type = type;
         }
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 6039d577f..56861903c 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -212,12 +212,6 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmName = experimentDTO.getAlgorithm().getName();
 
-        if (!allowedTransientAlgorithms(algorithmName)) {
-            Logging.LogUserAction(user.getUsername(), endpoint,
-                    "Not proper algorithm.");
-            throw new BadRequestException("Please provide proper algorithm.");
-        }
-
         algorithmParametersLogging(experimentDTO, endpoint);
 
         if (authenticationIsEnabled) {
@@ -333,13 +327,6 @@ public class ExperimentService {
         }
     }
 
-    private boolean allowedTransientAlgorithms(String algorithmName) {
-        List<String> properAlgorithms = new ArrayList<>();
-        properAlgorithms.add("MULTIPLE_HISTOGRAMS");
-        properAlgorithms.add("DESCRIPTIVE_STATS");
-        return properAlgorithms.contains(algorithmName);
-    }
-
     private void verifyPatchExperimentNonEditableFields(String uuid, ExperimentDTO experimentDTO, ExperimentDAO experimentDAO, String endpoint) {
         if (experimentDTO.getUuid() != null ) {
             Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Uuid is not editable.");
-- 
GitLab


From 49e1b19e6ae81d80cd3aa26a80b9d3e3f2828c5e Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Thu, 17 Dec 2020 05:27:24 -0800
Subject: [PATCH 45/52] Update the ClaimUtils according to the keycloak
 refactoring.

---
 .../configurations/GalaxyAuthentication.java  |  15 +-
 .../configurations/SecurityConfiguration.java |  10 +-
 .../eu/hbp/mip/controllers/ActiveUserAPI.java |  18 +-
 .../eu/hbp/mip/controllers/AlgorithmsAPI.java |  75 ++--
 .../eu/hbp/mip/controllers/ExperimentAPI.java |  29 +-
 .../hbp/mip/controllers/PathologiesAPI.java   |  28 +-
 .../hbp/mip/services/ActiveUserService.java   |  14 +-
 .../hbp/mip/services/ExperimentService.java   | 360 +++++++++---------
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |  67 ++--
 .../mip/utils/{Logging.java => Logger.java}   |  17 +-
 10 files changed, 315 insertions(+), 318 deletions(-)
 rename src/main/java/eu/hbp/mip/utils/{Logging.java => Logger.java} (53%)

diff --git a/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java b/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
index 41888d3ea..e8a5df4bc 100644
--- a/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
+++ b/src/main/java/eu/hbp/mip/configurations/GalaxyAuthentication.java
@@ -3,8 +3,7 @@ package eu.hbp.mip.configurations;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import eu.hbp.mip.services.ActiveUserService;
-import eu.hbp.mip.utils.Logging;
-import org.springframework.beans.factory.annotation.Autowired;
+import eu.hbp.mip.utils.Logger;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -19,8 +18,7 @@ import java.util.Base64;
 @RestController
 public class GalaxyAuthentication {
 
-    @Autowired
-    private ActiveUserService activeUserService;
+    private final ActiveUserService activeUserService;
 
     @Value("#{'${services.galaxy.galaxyUsername:admin}'}")
     private String galaxyUsername;
@@ -31,20 +29,25 @@ public class GalaxyAuthentication {
     @Value("#{'${services.galaxy.galaxpathoyContext:nativeGalaxy}'}")
     private String galaxyContext;
 
+    public GalaxyAuthentication(ActiveUserService activeUserService) {
+        this.activeUserService = activeUserService;
+    }
+
     /**
      * Get Galaxy Reverse Proxy basic access token.
      *
      * @return Return a @{@link ResponseEntity} with the token.
      */
     @RequestMapping(path = "/galaxy", method = RequestMethod.GET, produces = "application/json")
-    @PreAuthorize("hasRole('Data Manager')")
+    @PreAuthorize("hasRole('WORKFLOW_ADMIN')")
     @ResponseStatus(value = HttpStatus.OK)
     public ResponseEntity getGalaxyConfiguration() {
+        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /user/galaxy");
         String stringEncoded = Base64.getEncoder().encodeToString((galaxyUsername + ":" + galaxyPassword).getBytes());
         JsonObject object = new JsonObject();
         object.addProperty("authorization", stringEncoded);
         object.addProperty("context", galaxyContext);
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/galaxy", "Successfully Loaded galaxy information.");
+        logger.LogUserAction("Successfully Loaded galaxy information.");
 
         return ResponseEntity.ok(new Gson().toJson(object));
     }
diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index ea5cf7860..2b2e549d4 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -22,7 +22,6 @@ import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.filter.CorsFilter;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
 
@@ -43,6 +42,10 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
     @Value("#{'${authentication.enabled}'}")
     private boolean authenticationEnabled;
 
+    public SecurityConfiguration(HttpServletRequest request) {
+        this.request = request;
+    }
+
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         super.configure(http);
@@ -54,7 +57,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
                             "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**"  // Swagger URLs
                     ).permitAll()
                     .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
-                    .anyRequest().hasRole("RESEARCHER")
+                    .antMatchers("/**").authenticated()
                     .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
                     .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
         } else {
@@ -92,8 +95,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
         return repository;
     }
 
-    @Autowired
-    private HttpServletRequest request;
+    private final HttpServletRequest request;
 
     @GetMapping(value = "/logout")
     public String logout() throws ServletException {
diff --git a/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
index 7e5209b75..aca62c4b6 100644
--- a/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
@@ -2,10 +2,9 @@ package eu.hbp.mip.controllers;
 
 import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.services.ActiveUserService;
-import eu.hbp.mip.utils.Logging;
+import eu.hbp.mip.utils.Logger;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -21,14 +20,17 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/activeUser")
 public class ActiveUserAPI {
 
-    @Autowired
-    private ActiveUserService activeUserService;
+    private final ActiveUserService activeUserService;
+
+    public ActiveUserAPI(ActiveUserService activeUserService) {
+        this.activeUserService = activeUserService;
+    }
 
     @ApiOperation(value = "Get the active user", response = UserDAO.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<UserDAO> getTheActiveUser(HttpServletResponse response) {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser",
-                "Loading the details of the activeUser");
+        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser");
+        logger.LogUserAction("Loading the details of the activeUser");
 
         return ResponseEntity.ok(activeUserService.getActiveUser());
     }
@@ -36,8 +38,8 @@ public class ActiveUserAPI {
     @ApiOperation(value = "The active user agrees to the NDA", response = UserDAO.class)
     @RequestMapping(value = "/agreeNDA", method = RequestMethod.POST)
     public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(@RequestBody(required = false) UserDAO userDAO) {
-        Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser/agreeNDA",
-                "The user agreed to the NDA");
+        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser/agreeNDA");
+        logger.LogUserAction("The user agreed to the NDA");
 
         return ResponseEntity.ok(activeUserService.agreeToNDA());
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
index 001409d25..48500bb10 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
@@ -9,14 +9,13 @@ import com.google.gson.reflect.TypeToken;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.models.DTOs.AlgorithmDTO;
-import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.models.galaxy.WorkflowDTO;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.CustomResourceLoader;
 import eu.hbp.mip.utils.HTTPUtil;
-import eu.hbp.mip.utils.Logging;
+import eu.hbp.mip.utils.Logger;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
@@ -41,8 +40,7 @@ public class AlgorithmsAPI {
 
     private static final Gson gson = new Gson();
 
-    @Autowired
-    private ActiveUserService activeUserService;
+    private final ActiveUserService activeUserService;
 
     @Value("#{'${services.exareme.algorithmsUrl}'}")
     private String exaremeAlgorithmsUrl;
@@ -56,38 +54,40 @@ public class AlgorithmsAPI {
     @Value("#{'${files.disabledAlgorithms_json}'}")
     private String disabledAlgorithmsFilePath;
 
+    public AlgorithmsAPI(ActiveUserService activeUserService, CustomResourceLoader resourceLoader) {
+        this.activeUserService = activeUserService;
+        this.resourceLoader = resourceLoader;
+    }
+
     @ApiOperation(value = "List all algorithms", response = String.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() {
-        String username = activeUserService.getActiveUser().getUsername();
-        String endpoint = "(GET) /algorithms";
-        Logging.LogUserAction(username, endpoint, "Executing...");
+        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms");
+
+        logger.LogUserAction("Executing...");
 
-        LinkedList<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms();
-        Logging.LogUserAction(username, endpoint, "Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
-        LinkedList<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows();
-        Logging.LogUserAction(username, endpoint, "Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
+        LinkedList<AlgorithmDTO> exaremeAlgorithms = getExaremeAlgorithms(logger);
+        logger.LogUserAction("Loaded " + exaremeAlgorithms.size() + " exareme algorithms");
+        LinkedList<AlgorithmDTO> galaxyAlgorithms = getGalaxyWorkflows(logger);
+        logger.LogUserAction("Loaded " + galaxyAlgorithms.size() + " galaxy algorithms");
 
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         if (exaremeAlgorithms != null) {
             algorithms.addAll(exaremeAlgorithms);
         } else {
-            Logging.LogUserAction(username, endpoint,
-                    "Getting exareme algorithms failed and returned null");
+            logger.LogUserAction("Getting exareme algorithms failed and returned null");
         }
         if (galaxyAlgorithms != null) {
             algorithms.addAll(galaxyAlgorithms);
         } else {
-            Logging.LogUserAction(username, endpoint,
-                    "Getting galaxy workflows failed and returned null");
+            logger.LogUserAction("Getting galaxy workflows failed and returned null");
         }
 
         List<String> disabledAlgorithms = new ArrayList<>();
         try {
             disabledAlgorithms = getDisabledAlgorithms();
         } catch (IOException e) {
-            Logging.LogUserAction(username, endpoint,
-                    "The disabled algorithms could not be loaded.");
+            logger.LogUserAction("The disabled algorithms could not be loaded.");
         }
 
         // Remove any disabled algorithm
@@ -97,8 +97,7 @@ public class AlgorithmsAPI {
                 allowedAlgorithms.add(algorithm);
             }
         }
-        Logging.LogUserAction(username, endpoint,
-                "Successfully listed " + allowedAlgorithms.size() + " algorithms");
+        logger.LogUserAction("Successfully listed " + allowedAlgorithms.size() + " algorithms");
         return ResponseEntity.ok(allowedAlgorithms);
     }
 
@@ -107,10 +106,8 @@ public class AlgorithmsAPI {
      *
      * @return a list of AlgorithmDTOs or null if something fails
      */
-    public LinkedList<AlgorithmDTO> getExaremeAlgorithms() {
-        String username = activeUserService.getActiveUser().getUsername();
-        String endpoint = "(GET) /algorithms";
-        LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
+    public LinkedList<AlgorithmDTO> getExaremeAlgorithms(Logger logger) {
+        LinkedList<AlgorithmDTO> algorithms;
         // Get exareme algorithms
         try {
             StringBuilder response = new StringBuilder();
@@ -122,12 +119,11 @@ public class AlgorithmsAPI {
                     }.getType()
             );
         } catch (IOException e) {
-            Logging.LogUserAction(username, endpoint, "An exception occurred: " + e.getMessage());
+            logger.LogUserAction("An exception occurred: " + e.getMessage());
             return null;
         }
 
-        Logging.LogUserAction(username, endpoint,
-                "Completed, returned " + algorithms.size() + " algorithms.");
+        logger.LogUserAction("Completed, returned " + algorithms.size() + " algorithms.");
         return algorithms;
     }
 
@@ -136,9 +132,7 @@ public class AlgorithmsAPI {
      *
      * @return a list of AlgorithmDTOs or null if something fails
      */
-    public LinkedList<AlgorithmDTO> getGalaxyWorkflows() {
-        String username = activeUserService.getActiveUser().getUsername();
-        String endpoint = "(GET) /algorithms";
+    public LinkedList<AlgorithmDTO> getGalaxyWorkflows(Logger logger) {
         List<Workflow> workflowList;
         try {
             // Get all the workflows with the galaxy client
@@ -147,7 +141,7 @@ public class AlgorithmsAPI {
 
             workflowList = new ArrayList<>(workflowsClient.getWorkflows());
         } catch (Exception e) {
-            Logging.LogUserAction(username, endpoint, "Error when calling list galaxy workflows: " + e.getMessage());
+            logger.LogUserAction("Error when calling list galaxy workflows: " + e.getMessage());
             return null;
         }
 
@@ -166,33 +160,31 @@ public class AlgorithmsAPI {
 
                 } else {     // Something unexpected happened
                     String msgErr = gson.toJson(response.errorBody());
-                    Logging.LogUserAction(username, endpoint, "Error Response: " + msgErr);
+                    logger.LogUserAction("Error Response: " + msgErr);
                     return null;
                 }
             } catch (Exception e) {
-                Logging.LogUserAction(username, endpoint, "An exception occurred: " + e.getMessage());
+                logger.LogUserAction("An exception occurred: " + e.getMessage());
                 return null;
             }
         }
-        Logging.LogUserAction(username, endpoint, "Workflows fetched: " + workflows.size());
+        logger.LogUserAction("Workflows fetched: " + workflows.size());
 
         // Convert the workflows to algorithms
         LinkedList<AlgorithmDTO> algorithms = new LinkedList<>();
         for (WorkflowDTO workflow : workflows) {
-            Logging.LogUserAction(username, endpoint, "Converting workflow: " + workflow);
+            logger.LogUserAction("Converting workflow: " + workflow);
 
             algorithms.add(workflow.convertToAlgorithmDTO());
 
-            Logging.LogUserAction(username, endpoint,
-                    "Converted algorithm: " + algorithms.get(algorithms.size() - 1));
+            logger.LogUserAction("Converted algorithm: " + algorithms.get(algorithms.size() - 1));
         }
 
-        Logging.LogUserAction(username, endpoint, "Completed!");
+        logger.LogUserAction("Completed!");
         return algorithms;
     }
 
-    @Autowired
-    private CustomResourceLoader resourceLoader;
+    private final CustomResourceLoader resourceLoader;
 
     /**
      * Fetches the disabled algorithms from a .json file
@@ -204,11 +196,10 @@ public class AlgorithmsAPI {
 
         Resource resource = resourceLoader.getResource(disabledAlgorithmsFilePath);
 
-        List<String> response = gson.fromJson(convertInputStreamToString(
+        return gson.fromJson(convertInputStreamToString(
                 resource.getInputStream()),
                 new TypeToken<List<String>>() {
                 }.getType()
         );
-        return response;
     }
 }
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index 5c002c0b8..e5d0b04c5 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -2,8 +2,10 @@ package eu.hbp.mip.controllers;
 
 
 import eu.hbp.mip.models.DTOs.ExperimentDTO;
+import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.ExperimentService;
 import eu.hbp.mip.utils.JsonConverters;
+import eu.hbp.mip.utils.Logger;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -27,14 +29,18 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 public class ExperimentAPI {
 
     private final ExperimentService experimentService;
-
-    public ExperimentAPI(ExperimentService experimentService) {
+    private final ActiveUserService activeUserService;
+    public ExperimentAPI(
+            ExperimentService experimentService,
+            ActiveUserService activeUserService
+    ) {
         this.experimentService = experimentService;
+        this.activeUserService = activeUserService;
     }
 
     @ApiOperation(value = "Get experiments", response = Map.class, responseContainer = "List")
     @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<String> getExperiments(
+    public ResponseEntity<String> getExperiments(Authentication authentication,
             @RequestParam(name = "name", required = false) String name,
             @RequestParam(name = "algorithm", required = false) String algorithm,
             @RequestParam(name = "shared", required = false) Boolean shared,
@@ -45,7 +51,7 @@ public class ExperimentAPI {
             @RequestParam(defaultValue = "0") int page,
             @RequestParam(defaultValue = "10") int size
     ) {
-        Map experiments = experimentService.getExperiments(
+        Map experiments = experimentService.getExperiments(authentication,
                 name,
                 algorithm,
                 shared,
@@ -55,16 +61,16 @@ public class ExperimentAPI {
                 size,
                 orderBy,
                 descending,
-                "(GET) /experiments");
+                new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments"));
         return new ResponseEntity(experiments, HttpStatus.OK);
     }
 
 
     @ApiOperation(value = "Get an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
-    public ResponseEntity<String> getExperiment(
+    public ResponseEntity<String> getExperiment(Authentication authentication,
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        ExperimentDTO experimentDTO = experimentService.getExperiment(uuid, "(GET) /experiments/{uuid}");
+        ExperimentDTO experimentDTO = experimentService.getExperiment(authentication, uuid, new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments/{uuid}"));
         return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
@@ -72,7 +78,7 @@ public class ExperimentAPI {
     @ApiOperation(value = "Create an experiment", response = ExperimentDTO.class)
     @RequestMapping(method = RequestMethod.POST)
     public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.createExperiment(authentication, experimentDTO, "(POST) /experiments");
+        experimentDTO = experimentService.createExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(POST) /experiments"));
         return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
     }
 
@@ -80,7 +86,7 @@ public class ExperimentAPI {
     @ApiOperation(value = "Update an experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
     public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO, @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, "(PATCH) /experiments/{uuid}");
+        experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(PATCH) /experiments/{uuid}"));
         return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 
@@ -89,7 +95,7 @@ public class ExperimentAPI {
     @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
     public ResponseEntity<String> deleteExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        experimentService.deleteExperiment(uuid, "(DELETE) /experiments/{uuid}");
+        experimentService.deleteExperiment(uuid, new Logger(activeUserService.getActiveUser().getUsername(), "(DELETE) /experiments/{uuid}"));
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -97,8 +103,7 @@ public class ExperimentAPI {
     @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/transient", method = RequestMethod.POST)
     public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, "(POST) /experiments/transient");
-
+        experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(), "(POST) /experiments/transient"));
         return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
index f79052ff5..175ad2977 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
@@ -8,9 +8,8 @@ import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.CustomResourceLoader;
 import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import eu.hbp.mip.utils.InputStreamConverter;
-import eu.hbp.mip.utils.Logging;
+import eu.hbp.mip.utils.Logger;
 import io.swagger.annotations.Api;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
@@ -31,8 +30,6 @@ public class PathologiesAPI {
 
     private static final Gson gson = new Gson();
 
-    @Autowired
-    private ActiveUserService activeUserService;
 
     // Enable HBP collab authentication (1) or disable it (0). Default is 1
     @Value("#{'${authentication.enabled}'}")
@@ -41,14 +38,19 @@ public class PathologiesAPI {
     @Value("#{'${files.pathologies_json}'}")
     private String pathologiesFilePath;
 
-    @Autowired
-    private CustomResourceLoader resourceLoader;
+    private final ActiveUserService activeUserService;
+
+    private final CustomResourceLoader resourceLoader;
+
+    public PathologiesAPI(ActiveUserService activeUserService, CustomResourceLoader resourceLoader) {
+        this.activeUserService = activeUserService;
+        this.resourceLoader = resourceLoader;
+    }
 
     @RequestMapping(name = "/pathologies", method = RequestMethod.GET)
     public ResponseEntity<String> getPathologies(Authentication authentication) {
-        String endpoint = "(GET) /pathologies";
-        String username = activeUserService.getActiveUser().getUsername();
-        Logging.LogUserAction(username, endpoint, "Loading pathologies ...");
+        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies");
+        logger.LogUserAction("Loading pathologies ...");
 
         // Load pathologies from file
         Resource resource = resourceLoader.getResource(pathologiesFilePath);
@@ -57,18 +59,18 @@ public class PathologiesAPI {
             allPathologies = gson.fromJson(InputStreamConverter.convertInputStreamToString(resource.getInputStream()), new TypeToken<List<PathologyDTO>>() {
             }.getType());
         } catch (IOException e) {
-            Logging.LogUserAction(username, endpoint, "Unable to load pathologies");
+            logger.LogUserAction("Unable to load pathologies");
             throw new BadRequestException("The pathologies could not be loaded.");
         }
 
         // If authentication is disabled return everything
         if (!authenticationIsEnabled) {
-            Logging.LogUserAction(username, endpoint, "Successfully loaded " + allPathologies.size() + " pathologies");
+            logger.LogUserAction("Successfully loaded " + allPathologies.size() + " pathologies");
             return ResponseEntity.ok().body(gson.toJson(allPathologies));
         }
 
-        Logging.LogUserAction(username, endpoint, "Successfully loaded all authorized pathologies");
+        logger.LogUserAction("Successfully loaded all authorized pathologies");
         return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies(
-                username, authentication.getAuthorities(), allPathologies));
+                activeUserService.getActiveUser().getUsername(), logger,  authentication.getAuthorities(), allPathologies));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index 61bad973c..f1fe049c2 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
@@ -19,12 +20,15 @@ import javax.inject.Named;
 public class ActiveUserService {
 
     @Value("#{'${authentication.enabled}'}")
-    private boolean authentication;
+    private boolean authenticationIsEnabled;
 
     private UserDAO user;
 
-    @Autowired
-    private UserRepository userRepository;
+    private final UserRepository userRepository;
+
+    public ActiveUserService(UserRepository userRepository) {
+        this.userRepository = userRepository;
+    }
 
     /**
      * Fetches the details of the active user.
@@ -39,13 +43,13 @@ public class ActiveUserService {
             return user;
 
         // If Authentication is OFF, create anonymous user with accepted NDA
-        if (!authentication) {
+        if (!authenticationIsEnabled) {
             user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com");
             user.setAgreeNDA(true);
             userRepository.save(user);
             return user;
         }
-
+        //TODO:
         // If authentication is ON get user info from Token
         KeycloakPrincipal keycloakPrincipal =
                 (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 56861903c..e12c0b858 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -23,7 +23,7 @@ import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.Exceptions.*;
 import eu.hbp.mip.utils.HTTPUtil;
 import eu.hbp.mip.utils.JsonConverters;
-import eu.hbp.mip.utils.Logging;
+import eu.hbp.mip.utils.Logger;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.springframework.beans.factory.annotation.Value;
@@ -79,34 +79,36 @@ public class ExperimentService {
      * @param size       is the size of each page
      * @param orderBy    is the column that is required to ordered by
      * @param descending is a boolean to determine if the experiments will be order by descending or ascending
-     * @param endpoint   is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return a list of mapped experiments
      */
 
-    public Map getExperiments(String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, String endpoint) {
+    public Map getExperiments(Authentication authentication, String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, Logger logger) {
+
         UserDAO user = activeUserService.getActiveUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Listing my experiments.");
+        logger.LogUserAction("Listing my experiments.");
         if (size > 50)
             throw new BadRequestException("Invalid size input, max size is 50.");
-        /*TODO:if(role == master){
-        Specification<ExperimentDAO> spec = Specification
-                .where(new ExperimentSpecifications.ExperimentWithName(name))
-                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
-                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
-                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
-                .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
-        }
-        else
-         */
-        Specification<ExperimentDAO> spec = Specification
-                .where(new ExperimentSpecifications.MyExperiment(user.getUsername()))
-                .or(new ExperimentSpecifications.SharedExperiment(includeShared))
-                .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
-                .and(new ExperimentSpecifications.ExperimentWithShared(shared))
-                .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
-                .and(new ExperimentSpecifications.ExperimentWithName(name))
-                .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
-
+        Specification<ExperimentDAO> spec;
+        if(authenticationIsEnabled  && ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger))
+        {
+            spec = Specification
+                    .where(new ExperimentSpecifications.ExperimentWithName(name))
+                    .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
+                    .and(new ExperimentSpecifications.ExperimentWithShared(shared))
+                    .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
+                    .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
+        }
+        else {
+            spec = Specification
+                    .where(new ExperimentSpecifications.MyExperiment(user.getUsername()))
+                    .or(new ExperimentSpecifications.SharedExperiment(includeShared))
+                    .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
+                    .and(new ExperimentSpecifications.ExperimentWithShared(shared))
+                    .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
+                    .and(new ExperimentSpecifications.ExperimentWithName(name))
+                    .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
+        }
         Pageable paging = PageRequest.of(page, size);
         Page<ExperimentDAO> pageExperiments = experimentRepository.findAll(spec, paging);
         List<ExperimentDAO> experimentDAOs = pageExperiments.getContent();
@@ -130,24 +132,27 @@ public class ExperimentService {
      * The getExperiment will retrieve the experiment from database according to the input uuid
      *
      * @param uuid     is the id of the experiment to be retrieved
-     * @param endpoint is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return the experiment information that was retrieved from the database
      */
-    public ExperimentDTO getExperiment(String uuid, String endpoint) {
+    public ExperimentDTO getExperiment(Authentication authentication, String uuid, Logger logger) {
 
         ExperimentDAO experimentDAO;
         UserDAO user = activeUserService.getActiveUser();
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Loading Experiment with uuid : " + uuid);
+        logger.LogUserAction("Loading Experiment with uuid : " + uuid);
 
-        experimentDAO = loadExperiment(uuid, endpoint);
-        //TODO: if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) && if not master) {
-        if (!experimentDAO.isShared() && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()) ) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Accessing Experiment is unauthorized.");
+        experimentDAO = loadExperiment(uuid, logger);
+        if (
+                !experimentDAO.isShared()
+                && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
+                && ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger)
+        ) {
+            logger.LogUserAction("Accessing Experiment is unauthorized.");
             throw new UnauthorizedException("You don't have access to the experiment.");
         }
         ExperimentDTO experimentDTO = experimentDAO.convertToDTO(true);
-        Logging.LogUserAction(user.getUsername(), endpoint, "Experiment was Loaded with uuid : " + uuid + ".");
+        logger.LogUserAction("Experiment was Loaded with uuid : " + uuid + ".");
 
         return experimentDTO;
     }
@@ -157,37 +162,37 @@ public class ExperimentService {
      *
      * @param authentication is the role of the user
      * @param experimentDTO  is the experiment information
-     * @param endpoint       is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return the experiment information which was created
      */
-    public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
         UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
-        checkPostExperimentProperInput(experimentDTO, endpoint);
+        checkPostExperimentProperInput(experimentDTO, logger);
 
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithm().getType();
 
         if(algorithmType == null){
-            Logging.LogUserAction(user.getUsername(), endpoint, "Please provide algorithm type.");
+            logger.LogUserAction("Please provide algorithm type.");
             throw new BadRequestException("Please provide algorithm type.");
         }
 
-        algorithmParametersLogging(experimentDTO, endpoint);
+        algorithmParametersLogging(experimentDTO, logger);
 
         if (authenticationIsEnabled) {
-            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, endpoint);
+            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, logger);
         }
 
         // Run with the appropriate engine
         if (algorithmType.equals("workflow")) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Algorithm runs on Galaxy.");
-            return runGalaxyWorkflow(experimentDTO, endpoint);
+            logger.LogUserAction("Algorithm runs on Galaxy.");
+            return runGalaxyWorkflow(experimentDTO, logger);
         } else {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Algorithm runs on Exareme.");
-            return createExaremeExperiment(experimentDTO, endpoint);
+            logger.LogUserAction("Algorithm runs on Exareme.");
+            return createExaremeExperiment(experimentDTO, logger);
         }
     }
 
@@ -196,14 +201,14 @@ public class ExperimentService {
      *
      * @param authentication is the role of the user
      * @param experimentDTO  is the experiment information
-     * @param endpoint       is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return the experiment information which was created
      */
-    public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
         UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
-        checkPostExperimentProperInput(experimentDTO, endpoint);
+        checkPostExperimentProperInput(experimentDTO, logger);
 
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
@@ -212,24 +217,23 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmName = experimentDTO.getAlgorithm().getName();
 
-        algorithmParametersLogging(experimentDTO, endpoint);
+        algorithmParametersLogging(experimentDTO, logger);
 
         if (authenticationIsEnabled) {
-            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, endpoint);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, endpoint);
+            String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
+            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, logger);
         }
 
         String body = gson.toJson(algorithmParameters);
         String url = queryExaremeUrl + "/" + algorithmName;
-        Logging.LogUserAction(user.getUsername(), endpoint, "url: " + url + ", body: " + body);
+        logger.LogUserAction("url: " + url + ", body: " + body);
 
-        Logging.LogUserAction(user.getUsername(), endpoint,
-                "Completed, returning: " + experimentDTO.toString());
+        logger.LogUserAction("Completed, returning: " + experimentDTO.toString());
 
         // Results are stored in the experiment object
         ExaremeResult exaremeResult = runExaremeExperiment(url, body, experimentDTO);
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
+        logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
         experimentDTO.setResult((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults());
         experimentDTO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
@@ -242,18 +246,17 @@ public class ExperimentService {
      *
      * @param uuid          is the id of the experiment to be updated
      * @param experimentDTO is the experiment information to be updated
-     * @param endpoint      is the endpoint that called the function
-     * @return the updated experiment information
+     * @param logger    contains username and the endpoint.
      */
-    public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, String endpoint) {
+    public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, Logger logger) {
         ExperimentDAO experimentDAO;
         UserDAO user = activeUserService.getActiveUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Updating experiment with uuid : " + uuid + ".");
+        logger.LogUserAction("Updating experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid, endpoint);
+        experimentDAO = loadExperiment(uuid, logger);
 
         //Verify (PATCH) /experiments non editable fields.
-        verifyPatchExperimentNonEditableFields(uuid, experimentDTO, experimentDAO, endpoint);
+        verifyPatchExperimentNonEditableFields(experimentDTO, logger);
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             throw new UnauthorizedException("You don't have access to the experiment.");
@@ -272,11 +275,11 @@ public class ExperimentService {
         try {
             experimentRepository.save(experimentDAO);
         } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction("Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Updated experiment with uuid : " + uuid + ".");
+        logger.LogUserAction("Updated experiment with uuid : " + uuid + ".");
 
         experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
@@ -286,14 +289,14 @@ public class ExperimentService {
      * The deleteExperiment will delete an experiment from the database
      *
      * @param uuid     is the id of the experiment to be deleted
-     * @param endpoint is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      */
-    public void deleteExperiment(String uuid, String endpoint) {
+    public void deleteExperiment(String uuid, Logger logger) {
         ExperimentDAO experimentDAO;
         UserDAO user = activeUserService.getActiveUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Deleting experiment with uuid : " + uuid + ".");
+        logger.LogUserAction("Deleting experiment with uuid : " + uuid + ".");
 
-        experimentDAO = loadExperiment(uuid, endpoint);
+        experimentDAO = loadExperiment(uuid, logger);
 
         if (!experimentDAO.getCreatedBy().getUsername().equals(user.getUsername()))
             throw new UnauthorizedException("You don't have access to the experiment.");
@@ -301,16 +304,16 @@ public class ExperimentService {
         try {
             experimentRepository.delete(experimentDAO);
         } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to delete an experiment to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction("Attempted to delete an experiment to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Deleted experiment with uuid : " + uuid + ".");
+        logger.LogUserAction("Deleted experiment with uuid : " + uuid + ".");
     }
 
     //    /* -------------------------------  PRIVATE METHODS  ----------------------------------------------------*/
 
-    private void checkPostExperimentProperInput(ExperimentDTO experimentDTO, String endpoint) {
+    private void checkPostExperimentProperInput(ExperimentDTO experimentDTO, Logger logger) {
 
         boolean properInput =
                 experimentDTO.getShared() == null
@@ -322,50 +325,39 @@ public class ExperimentService {
                         && experimentDTO.getUuid() == null;
 
         if (!properInput) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Invalid input.");
+            logger.LogUserAction( "Invalid input.");
             throw new BadRequestException("Please provide proper input.");
         }
     }
 
-    private void verifyPatchExperimentNonEditableFields(String uuid, ExperimentDTO experimentDTO, ExperimentDAO experimentDAO, String endpoint) {
+    private void verifyPatchExperimentNonEditableFields(ExperimentDTO experimentDTO, Logger logger) {
         if (experimentDTO.getUuid() != null ) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Uuid is not editable.");
+            logger.LogUserAction( "Uuid is not editable.");
             throw new BadRequestException("Uuid is not editable.");
         }
 
         if (experimentDTO.getAlgorithm() != null ) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Algorithm is not editable.");
+            logger.LogUserAction( "Algorithm is not editable.");
             throw new BadRequestException("Algorithm is not editable.");
         }
 
         if (experimentDTO.getCreated() != null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "CreatedBy is not editable.");
-            throw new BadRequestException("CreatedBy is not editable.");
-        }
-
-        if (experimentDTO.getAlgorithm() != null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "AlgorithmDetails is not editable.");
-            throw new BadRequestException("AlgorithmDetails is not editable.");
-        }
-
-        if (experimentDTO.getCreated() != null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Created is not editable.");
+            logger.LogUserAction( "Created is not editable.");
             throw new BadRequestException("Created is not editable.");
         }
 
         if (experimentDTO.getResult() != null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Status is not editable.");
+            logger.LogUserAction( "Status is not editable.");
             throw new BadRequestException("Status is not editable.");
         }
 
         if (experimentDTO.getStatus() != null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Status is not editable.");
+            logger.LogUserAction( "Status is not editable.");
             throw new BadRequestException("Status is not editable.");
         }
     }
 
-    private void algorithmParametersLogging(ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = activeUserService.getActiveUser();
+    private void algorithmParametersLogging(ExperimentDTO experimentDTO, Logger logger) {
         String algorithmName = experimentDTO.getAlgorithm().getName();
         StringBuilder parametersLogMessage = new StringBuilder(", Parameters:\n");
         experimentDTO.getAlgorithm().getParameters().forEach(
@@ -375,17 +367,17 @@ public class ExperimentService {
                         .append(" -> ")
                         .append(params.getValue())
                         .append("\n"));
-        Logging.LogUserAction(user.getUsername(), endpoint, "Executing " + algorithmName + parametersLogMessage);
+        logger.LogUserAction("Executing " + algorithmName + parametersLogMessage);
     }
 
     /**
      * The getDatasetFromExperimentParameters will retrieve the dataset from the experiment parameters
      *
      * @param experimentDTO is the experiment information
-     * @param endpoint      is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return the dataset from the experiment
      */
-    private String getDatasetFromExperimentParameters(ExperimentDTO experimentDTO, String endpoint) {
+    private String getDatasetFromExperimentParameters(ExperimentDTO experimentDTO, Logger logger) {
 
         String experimentDatasets = null;
         for (AlgorithmDTO.AlgorithmParamDTO parameter : experimentDTO.getAlgorithm().getParameters()) {
@@ -396,8 +388,7 @@ public class ExperimentService {
         }
 
         if (experimentDatasets == null || experimentDatasets.equals("")) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint,
-                    "A dataset should be specified to run an algorithm.");
+            logger.LogUserAction("A dataset should be specified to run an algorithm.");
             throw new BadRequestException("Please provide at least one dataset to run the algorithm.");
         }
         return experimentDatasets;
@@ -409,20 +400,20 @@ public class ExperimentService {
      * @param uuid is the id of the experiment to be retrieved
      * @return the experiment information that was retrieved from database
      */
-    private ExperimentDAO loadExperiment(String uuid, String endpoint) {
+    private ExperimentDAO loadExperiment(String uuid, Logger logger) {
         UUID experimentUuid;
         ExperimentDAO experimentDAO;
 
         try {
             experimentUuid = UUID.fromString(uuid);
         } catch (Exception e) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, e.getMessage());
+            logger.LogUserAction( e.getMessage());
             throw new BadRequestException(e.getMessage());
         }
 
         experimentDAO = experimentRepository.findByUuid(experimentUuid);
         if (experimentDAO == null) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Experiment with uuid : " + uuid + "was not found.");
+            logger.LogUserAction( "Experiment with uuid : " + uuid + "was not found.");
             throw new ExperimentNotFoundException("Experiment with uuid : " + uuid + " was not found.");
         }
 
@@ -437,7 +428,7 @@ public class ExperimentService {
      * @Note In the database there will be stored Algorithm Details that is the whole information about the algorithm
      * and an Algorithm column that is required for the filtering with algorithm name  in the GET /experiments.
      */
-    private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, String endpoint) {
+    private ExperimentDAO createExperimentInTheDatabase(ExperimentDTO experimentDTO, Logger logger) {
         UserDAO user = activeUserService.getActiveUser();
 
         ExperimentDAO experimentDAO = new ExperimentDAO();
@@ -451,42 +442,41 @@ public class ExperimentService {
         try {
             experimentRepository.save(experimentDAO);
         } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction("Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
-        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
-        Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
+        logger.LogUserAction(" id : " + experimentDAO.getUuid());
+        logger.LogUserAction(" algorithms : " + experimentDAO.getAlgorithmDetails());
+        logger.LogUserAction(" name : " + experimentDAO.getName());
         return experimentDAO;
     }
 
-    private void saveExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        UserDAO user = activeUserService.getActiveUser();
+    private void saveExperiment(ExperimentDAO experimentDAO, Logger logger) {
 
-        Logging.LogUserAction(user.getUsername(), endpoint, " id : " + experimentDAO.getUuid());
-        Logging.LogUserAction(user.getUsername(), endpoint, " algorithms : " + experimentDAO.getAlgorithmDetails());
-        Logging.LogUserAction(user.getUsername(), endpoint, " name : " + experimentDAO.getName());
-        Logging.LogUserAction(user.getUsername(), endpoint, " historyId : " + experimentDAO.getWorkflowHistoryId());
-        Logging.LogUserAction(user.getUsername(), endpoint, " status : " + experimentDAO.getStatus());
+        logger.LogUserAction(" id : " + experimentDAO.getUuid());
+        logger.LogUserAction(" algorithms : " + experimentDAO.getAlgorithmDetails());
+        logger.LogUserAction(" name : " + experimentDAO.getName());
+        logger.LogUserAction(" historyId : " + experimentDAO.getWorkflowHistoryId());
+        logger.LogUserAction(" status : " + experimentDAO.getStatus());
 
         try {
             experimentRepository.save(experimentDAO);
         } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction("Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Saved experiment");
+        logger.LogUserAction("Saved experiment");
     }
 
-    private void finishExperiment(ExperimentDAO experimentDAO, String endpoint) {
+    private void finishExperiment(ExperimentDAO experimentDAO, Logger logger) {
         experimentDAO.setFinished(new Date());
 
         try {
             experimentRepository.save(experimentDAO);
         } catch (Exception e) {
-            Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), endpoint, "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction( "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
     }
@@ -497,16 +487,15 @@ public class ExperimentService {
      * The createExaremeExperiment will POST the algorithm to the exareme client
      *
      * @param experimentDTO is the request with the experiment information
-     * @param endpoint      is the endpoint that called the function
+     * @param logger    contains username and the endpoint.
      * @return the experiment information that was retrieved from exareme
      */
-    public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = activeUserService.getActiveUser();
+    public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, Logger logger) {
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm...");
+        logger.LogUserAction("Running the algorithm...");
 
-        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
-        Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, logger);
+        logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid());
 
         // Run the 1st algorithm from the list
         String algorithmName = experimentDTO.getAlgorithm().getName();
@@ -517,35 +506,33 @@ public class ExperimentService {
 
         String body = gson.toJson(algorithmParameters);
         String url = queryExaremeUrl + "/" + algorithmName;
-        Logging.LogUserAction(user.getUsername(), endpoint, "url: " + url + ", body: " + body);
+        logger.LogUserAction("url: " + url + ", body: " + body);
 
-        Logging.LogUserAction(user.getUsername(), endpoint,
-                "Completed, returning: " + experimentDTO.toString());
+        logger.LogUserAction("Completed, returning: " + experimentDTO.toString());
 
-        Logging.LogUserAction(user.getUsername(), endpoint,
-                "Starting exareme execution thread");
+        logger.LogUserAction("Starting exareme execution thread");
         ExperimentDTO finalExperimentDTO = experimentDTO;
         new Thread(() -> {
 
             // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
-            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
+            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
             try {
                 // Results are stored in the experiment object
                 ExaremeResult exaremeResult = runExaremeExperiment(url, body, finalExperimentDTO);
 
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
+                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
                 experimentDAO.setResult((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(exaremeResult.getResults()));
                 experimentDAO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
             } catch (Exception e) {
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
+                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
 
                 experimentDAO.setStatus(ExperimentDAO.Status.error);
             }
 
-            finishExperiment(experimentDAO, endpoint);
-            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
+            finishExperiment(experimentDAO, logger);
+            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO.toString());
         }).start();
         experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
@@ -568,7 +555,7 @@ public class ExperimentService {
         } catch (Exception e) {
             throw new InternalServerError("Error occurred : " + e.getMessage());
         }
-        Logging.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
+        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
 
         // Results are stored in the experiment object
         ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class);
@@ -586,12 +573,11 @@ public class ExperimentService {
      * @param experimentDTO is the request with the experiment information
      * @return the response to be returned
      */
-    public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, String endpoint) {
-        UserDAO user = activeUserService.getActiveUser();
-        Logging.LogUserAction(user.getUsername(), endpoint, "Running a workflow...");
+    public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, Logger logger) {
+        logger.LogUserAction("Running a workflow...");
 
-        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint);
-        Logging.LogUserAction(user.getUsername(), endpoint, "Created experiment with uuid :" + experimentDAO.getUuid());
+        ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, logger);
+        logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid());
 
 
         // Run the 1st algorithm from the list
@@ -620,8 +606,7 @@ public class ExperimentService {
             }
         }
         if (workflow == null) {
-            Logging.LogUserAction(user.getUsername(), endpoint,
-                    "Could not find algorithm code: " + workflowId);
+            logger.LogUserAction("Could not find algorithm code: " + workflowId);
             throw new BadRequestException("Could not find galaxy algorithm.");
         }
         final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(workflow.getId());
@@ -638,7 +623,7 @@ public class ExperimentService {
 
         // Create the request client
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
-        Logging.LogUserAction(user.getUsername(), endpoint, "Running Galaxy workflow with id: " + workflow.getId());
+        logger.LogUserAction("Running Galaxy workflow with id: " + workflow.getId());
 
         // Call Galaxy to run the workflow
         Call<PostWorkflowToGalaxyDtoResponse> call = service.postWorkflowToGalaxy(workflow.getId(), galaxyApiKey, requestBodyJson);
@@ -647,7 +632,7 @@ public class ExperimentService {
 
             if (response.code() == 200) {       // Call succeeded
                 String responseBody = gson.toJson(response.body());
-                Logging.LogUserAction(user.getUsername(), endpoint, "Response: " + responseBody);
+                logger.LogUserAction("Response: " + responseBody);
 
                 String historyId = (String) new JSONObject(responseBody).get("history_id");
                 experimentDAO.setWorkflowHistoryId(historyId);
@@ -655,7 +640,7 @@ public class ExperimentService {
 
             } else {     // Something unexpected happened
                 String msgErr = gson.toJson(response.errorBody());
-                Logging.LogUserAction(user.getUsername(), endpoint, "Error Response: " + msgErr);
+                logger.LogUserAction("Error Response: " + msgErr);
 
                 // Values are read from streams.
                 JSONObject jObjectError = new JSONObject(msgErr);
@@ -665,15 +650,15 @@ public class ExperimentService {
             }
 
         } catch (Exception e) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "An exception occurred: " + e.getMessage());
+            logger.LogUserAction("An exception occurred: " + e.getMessage());
             experimentDAO.setStatus(ExperimentDAO.Status.error);
         }
-        saveExperiment(experimentDAO, endpoint);
+        saveExperiment(experimentDAO, logger);
 
         // Start the process of fetching the status
-        updateWorkflowExperiment(experimentDAO, endpoint);
+        updateWorkflowExperiment(experimentDAO, logger);
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Run workflow completed!");
+        logger.LogUserAction("Run workflow completed!");
 
         experimentDTO = experimentDAO.convertToDTO(true);
         return experimentDTO;
@@ -685,59 +670,56 @@ public class ExperimentService {
      *
      * @param experimentDAO will be used to fetch it's workflow status, it should have the workflowHistoryId initialized
      *                      and the result should not already be fetched
-     * @return nothing, just updates the experiment
      */
-    public void updateWorkflowExperiment(ExperimentDAO experimentDAO, String endpoint) {
-        UserDAO user = activeUserService.getActiveUser();
+    public void updateWorkflowExperiment(ExperimentDAO experimentDAO, Logger logger) {
 
         if (experimentDAO == null) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "The experiment does not exist.");
+            logger.LogUserAction("The experiment does not exist.");
             return;
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint,
-                " Experiment id : " + experimentDAO.getUuid());
+        logger.LogUserAction(" Experiment id : " + experimentDAO.getUuid());
         if (experimentDAO.getWorkflowHistoryId() == null) {
-            Logging.LogUserAction(user.getUsername(), endpoint, "History Id does not exist.");
+            logger.LogUserAction("History Id does not exist.");
             return;
         }
 
-        Logging.LogUserAction(user.getUsername(), endpoint, "Starting Thread...");
+        logger.LogUserAction("Starting Thread...");
         new Thread(() -> {
             while (true) {
                 // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogExperimentAction!
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running...");
+                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running...");
 
                 try {
                     sleep(2000);
                 } catch (InterruptedException e) {
-                    Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage());
+                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage());
                 }
 
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid());
+                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid());
 
                 String state = getWorkflowStatus(experimentDAO);
-                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
+                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
 
                 switch (state) {
                     case "running":
                         // Do nothing, when the experiment is created the status is set to running
-                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
+                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
                         break;
 
                     case "completed":
                         // Get only the job result that is visible
                         List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experimentDAO);
-                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
+                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
 
                         boolean resultFound = false;
                         for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
                             if (jobResult.getVisible()) {
-                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId());
+                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId());
 
                                 String result = getWorkflowResultBody(experimentDAO, jobResult.getId());
 
-                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result);
+                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result);
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 } else {
@@ -749,26 +731,26 @@ public class ExperimentService {
                         }
 
                         if (!resultFound) {      // If there is no visible result
-                            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
+                            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
 
-                        finishExperiment(experimentDAO, endpoint);
+                        finishExperiment(experimentDAO, logger);
                         break;
 
                     case "error":
                         // Get the job result that failed
                         workflowJobsResults = getWorkflowResults(experimentDAO);
-                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString());
+                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString());
 
                         boolean failedJobFound = false;
                         for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
                             if (jobResult.getState().equals("error")) {
-                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId());
+                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId());
 
                                 String result = getWorkflowJobError(jobResult.getId(), experimentDAO);
 
-                                Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result);
+                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result);
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
@@ -778,22 +760,22 @@ public class ExperimentService {
                         }
 
                         if (!failedJobFound) {      // If there is no visible failed job
-                            Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
+                            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
-                        finishExperiment(experimentDAO, endpoint);
+                        finishExperiment(experimentDAO, logger);
                         break;
 
                     default:        // InternalError or unexpected result
-                        Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
+                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
                         experimentDAO.setStatus(ExperimentDAO.Status.error);
-                        finishExperiment(experimentDAO, endpoint);
+                        finishExperiment(experimentDAO, logger);
                         break;
                 }
 
                 // If result exists return
                 if (experimentDAO.getResult() != null) {
-                    Logging.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
+                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
                     return;
                 }
             }
@@ -814,7 +796,7 @@ public class ExperimentService {
         UUID experimentId = experimentDAO.getUuid();
 
         // ATTENTION: This function is used from a Thread. Only LogExperimentAction should be used, not LogUserAction!
-        Logging.LogExperimentAction(experimentName, experimentId, " History Id : " + historyId);
+        Logger.LogExperimentAction(experimentName, experimentId, " History Id : " + historyId);
 
         // Create the request client
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
@@ -824,15 +806,15 @@ public class ExperimentService {
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return "internalError";
             }
             result = new Gson().toJson(response.body());
-            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + result);
+            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + result);
 
         } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return "internalError";
         }
 
@@ -841,11 +823,11 @@ public class ExperimentService {
             JSONObject resultJson = new JSONObject(result);
             state = resultJson.getString("state");
         } catch (JSONException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return "internalError";
         }
 
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
         switch (state) {
             case "ok":
                 return "completed";
@@ -870,7 +852,7 @@ public class ExperimentService {
         String historyId = experimentDAO.getWorkflowHistoryId();
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
-        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+        Logger.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
 
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
@@ -879,19 +861,19 @@ public class ExperimentService {
         try {
             Response<List<GalaxyWorkflowResult>> response = call.execute();
             if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
             getGalaxyWorkflowResultList = response.body();
-            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + response.body());
+            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + response.body());
 
         } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return null;
         }
 
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
         return getGalaxyWorkflowResultList;
 
     }
@@ -907,7 +889,7 @@ public class ExperimentService {
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
 
-        Logging.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+        Logger.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
 
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> call =
@@ -917,20 +899,20 @@ public class ExperimentService {
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
             resultJson = new Gson().toJson(response.body());
-            Logging.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
+            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
 
         } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId,
+            Logger.LogExperimentAction(experimentName, experimentId,
                     " An exception happened: " + e.getMessage());
             return null;
         }
 
-        Logging.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
         return resultJson;
     }
 
@@ -943,7 +925,7 @@ public class ExperimentService {
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
 
-        Logging.LogExperimentAction(experimentName, experimentId, " jobId : " + jobId);
+        Logger.LogExperimentAction(experimentName, experimentId, " jobId : " + jobId);
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
 
@@ -952,7 +934,7 @@ public class ExperimentService {
         try {
             Response<Object> response = callError.execute();
             if (response.code() >= 400) {
-                Logging.LogExperimentAction(experimentName, experimentId, "Response code: "
+                Logger.LogExperimentAction(experimentName, experimentId, "Response code: "
                         + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
@@ -962,19 +944,19 @@ public class ExperimentService {
             JsonElement jsonElement = new JsonParser().parse(jsonString);
             JsonObject rootObject = jsonElement.getAsJsonObject();
             fullError = rootObject.get("stderr").getAsString();
-            Logging.LogExperimentAction(experimentName, experimentId, "Error: " + fullError);
+            Logger.LogExperimentAction(experimentName, experimentId, "Error: " + fullError);
 
             String[] arrOfStr = fullError.split("ValueError", 0);
             String specError = arrOfStr[arrOfStr.length - 1];
             returnError = specError.substring(1);
-            Logging.LogExperimentAction(experimentName, experimentId, "Parsed Error: " + returnError);
+            Logger.LogExperimentAction(experimentName, experimentId, "Parsed Error: " + returnError);
 
         } catch (IOException e) {
-            Logging.LogExperimentAction(experimentName, experimentId, "Exception: " + e.getMessage());
+            Logger.LogExperimentAction(experimentName, experimentId, "Exception: " + e.getMessage());
             return null;
         }
 
-        Logging.LogExperimentAction(experimentName, experimentId, "Completed successfully!");
+        Logger.LogExperimentAction(experimentName, experimentId, "Completed successfully!");
 
         return returnError;
     }
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 5eb90a2d0..501cea1b0 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -2,14 +2,10 @@ package eu.hbp.mip.utils;
 
 import com.google.gson.Gson;
 import eu.hbp.mip.models.DTOs.PathologyDTO;
-import eu.hbp.mip.utils.Exceptions.BadRequestException;
 import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
 import org.springframework.security.core.GrantedAuthority;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 
 
 public class ClaimUtils {
@@ -17,67 +13,62 @@ public class ClaimUtils {
     private static final Gson gson = new Gson();
 
     public static String allDatasetsAllowedClaim() {
-        return "role_dataset_all";
+        return "role_research_dataset_all";
+    }
+
+    public static String allExperimentsAllowedClaim() {
+        return "role_research_experiment_all";
     }
 
     public static String getDatasetClaim(String datasetCode) {
-        return "role_dataset_" + datasetCode.toLowerCase();
+        return "role_research_dataset_" + datasetCode.toLowerCase();
     }
 
     public static void validateAccessRightsOnDatasets(String username, Collection<? extends GrantedAuthority> authorities,
-                                                       String experimentDatasets, String endpoint) {
-
-        List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
-                .replaceAll("[\\s+\\]\\[]", "").split(","));
-        Logging.LogUserAction(username, endpoint, userClaims.toString());
+                                                       String experimentDatasets, Logger logger) {
 
         // Don't check for dataset claims if "super" claim exists allowing everything
-        if (!userClaims.contains(ClaimUtils.allDatasetsAllowedClaim())) {
+        if (!hasRoleAccess(username, authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
 
             for (String dataset : experimentDatasets.split(",")) {
                 String datasetRole = ClaimUtils.getDatasetClaim(dataset);
-                if (!userClaims.contains(datasetRole.toLowerCase())) {
-                    Logging.LogUserAction(username, endpoint,
-                            "You are not allowed to use dataset: " + dataset);
+                if (!hasRoleAccess(username, authorities, datasetRole, logger)) {
+                    logger.LogUserAction("You are not allowed to use dataset: " + dataset);
                     throw new UnauthorizedException("You are not authorized to use these datasets.");
                 }
             }
-            Logging.LogUserAction(username, endpoint,
-                    "User is authorized to use the datasets: " + experimentDatasets);
+            logger.LogUserAction("User is authorized to use the datasets: " + experimentDatasets);
         }
     }
 
-    public static String getAuthorizedPathologies(String username, Collection<? extends GrantedAuthority> authorities,
-                                                  List<PathologyDTO> allPathologies) {
-        // --- Providing only the allowed pathologies/datasets to the user  ---
-        Logging.LogUserAction(username,
-                "(GET) /pathologies", "Filter out the unauthorised datasets.");
+    public static boolean validateAccessRightsOnExperiments(String username, Collection<? extends GrantedAuthority> authorities, Logger logger) {
 
-        List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
-                .replaceAll("[\\s+\\]\\[]", "").split(","));
+        // Check for experiment_all claims
+        return  hasRoleAccess(username, authorities, ClaimUtils.allExperimentsAllowedClaim(), logger);
+    }
 
-        Logging.LogUserAction(username,
-                "(GET) /pathologies", "User Claims: " + userClaims);
+    public static String getAuthorizedPathologies(String username, Logger logger, Collection<? extends GrantedAuthority> authorities,
+                                                  List<PathologyDTO> allPathologies) {
+        // --- Providing only the allowed pathologies/datasets to the user  ---
+        logger.LogUserAction("Filter out the unauthorised datasets.");
 
         // If the "dataset_all" claim exists then return everything
-        if (userClaims.contains(ClaimUtils.allDatasetsAllowedClaim())) {
+        if (hasRoleAccess(username, authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
             return gson.toJson(allPathologies);
         }
 
         List<PathologyDTO> userPathologies = new ArrayList<>();
         for (PathologyDTO curPathology : allPathologies) {
-            List<PathologyDTO.PathologyDatasetDTO> userPathologyDatasets = new ArrayList<PathologyDTO.PathologyDatasetDTO>();
+            List<PathologyDTO.PathologyDatasetDTO> userPathologyDatasets = new ArrayList<>();
             for (PathologyDTO.PathologyDatasetDTO dataset : curPathology.getDatasets()) {
-                if (userClaims.contains(ClaimUtils.getDatasetClaim(dataset.getCode()))) {
-                    Logging.LogUserAction(username, "(GET) /pathologies",
-                            "Added dataset: " + dataset.getCode());
+                if (hasRoleAccess(username, authorities, ClaimUtils.getDatasetClaim(dataset.getCode()), logger)) {
+                    logger.LogUserAction("Added dataset: " + dataset.getCode());
                     userPathologyDatasets.add(dataset);
                 }
             }
 
             if (userPathologyDatasets.size() > 0) {
-                Logging.LogUserAction(username, "(GET) /pathologies",
-                        "Added pathology '" + curPathology.getLabel()
+                logger.LogUserAction("Added pathology '" + curPathology.getLabel()
                                 + "' with datasets: '" + userPathologyDatasets + "'");
 
                 PathologyDTO userPathology = new PathologyDTO();
@@ -92,4 +83,12 @@ public class ClaimUtils {
         return gson.toJson(userPathologies);
     }
 
+    private static boolean  hasRoleAccess(String username, Collection<? extends GrantedAuthority> authorities,String role, Logger logger)
+    {
+        List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
+                .replaceAll("[\\s+\\]\\[]", "").split(","));
+
+        logger.LogUserAction("User Claims: " + userClaims);
+        return userClaims.contains(role.toLowerCase());
+    }
 }
diff --git a/src/main/java/eu/hbp/mip/utils/Logging.java b/src/main/java/eu/hbp/mip/utils/Logger.java
similarity index 53%
rename from src/main/java/eu/hbp/mip/utils/Logging.java
rename to src/main/java/eu/hbp/mip/utils/Logger.java
index 9b75de636..1e25d2c92 100644
--- a/src/main/java/eu/hbp/mip/utils/Logging.java
+++ b/src/main/java/eu/hbp/mip/utils/Logger.java
@@ -1,16 +1,23 @@
 package eu.hbp.mip.utils;
 
-import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.UUID;
 
-public class Logging {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(Logging.class);
+public class Logger {
 
-    public static void LogUserAction(String userName, String endpoint, String actionInfo) {
-        LOGGER.info(" User -> " + userName + " ,"
+    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(Logger.class);
+    private  String username;
+    private  String endpoint;
+
+    public Logger(String username, String endpoint){
+        this.username = username;
+        this.endpoint = endpoint;
+    }
+
+    public void LogUserAction(String actionInfo) {
+        LOGGER.info(" User -> " + username + " ,"
                 + "Endpoint -> " + endpoint + " ,"
                 + "Info ->  " + actionInfo);
     }
-- 
GitLab


From ba11d26d5004957f559276bb1ba514c1df468106 Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Wed, 23 Dec 2020 04:08:23 -0800
Subject: [PATCH 46/52] Updated the migration so that is backwards compatible.

---
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java | 25 +++++++------
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java |  6 +--
 .../hbp/mip/services/ExperimentService.java   | 34 ++++++++++++-----
 src/main/resources/application.yml            |  2 +-
 .../migration/V7_0__NewDatabaseStructure.sql  | 37 +++++++++++++++++--
 5 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index f634c77a2..30d5ee123 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -43,6 +43,7 @@ public class ExperimentDAO {
 
     @Expose
     @Column(columnDefinition = "TEXT")
+    @Enumerated(EnumType.STRING)
     private Status status;
 
     @Expose
@@ -55,11 +56,11 @@ public class ExperimentDAO {
 
     @Expose
     @Column(columnDefinition = "TEXT")
-    private String algorithmDetails;
+    private String algorithm;
 
     @Expose
     @Column(columnDefinition = "TEXT")
-    private String algorithm;
+    private String algorithmId;
 
     @Expose
     @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
@@ -93,14 +94,14 @@ public class ExperimentDAO {
     public ExperimentDTO convertToDTO(boolean includeResult)
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
-        experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithmDetails, AlgorithmDTO.class));
+        experimentDTO.setAlgorithm(JsonConverters.convertJsonStringToObject(this.algorithm, AlgorithmDTO.class));
         experimentDTO.setCreated(this.created);
         experimentDTO.setUpdated(this.updated);
         experimentDTO.setFinished(this.finished);
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
         if(includeResult){
-            experimentDTO.setResult(JsonConverters.convertJsonStringToObject(String.valueOf(this.result), new ArrayList<ExperimentDTO.ResultDTO>().getClass()));
+            experimentDTO.setResult(JsonConverters.convertJsonStringToObject(String.valueOf(this.result),  new ArrayList<ExperimentDTO.ResultDTO>().getClass()));
         }
         experimentDTO.setStatus(this.status);
         experimentDTO.setShared(this.shared);
@@ -109,14 +110,6 @@ public class ExperimentDAO {
         return experimentDTO;
     }
 
-    public String getAlgorithmDetails() {
-        return algorithmDetails;
-    }
-
-    public void setAlgorithmDetails(String algorithmDetails) {
-        this.algorithmDetails = algorithmDetails;
-    }
-
     public String getAlgorithm() {
         return algorithm;
     }
@@ -125,6 +118,14 @@ public class ExperimentDAO {
         this.algorithm = algorithm;
     }
 
+    public String getAlgorithmId() {
+        return algorithmId;
+    }
+
+    public void setAlgorithmId(String algorithmId) {
+        this.algorithmId = algorithmId;
+    }
+
     public String getWorkflowHistoryId() {
         return workflowHistoryId;
     }
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index a1c6e916c..2840f669f 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -117,7 +117,7 @@ public class ExperimentDTO {
     public static class ResultDTO {
 
         private Object data;
-        private Object type;
+        private String type;
 
         public Object getData() {
             return this.data;
@@ -127,11 +127,11 @@ public class ExperimentDTO {
             this.data = data;
         }
 
-        public Object getType() {
+        public String getType() {
             return type;
         }
 
-        public void setType(Object type) {
+        public void setType(String type) {
             this.type = type;
         }
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index e12c0b858..869db8836 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -59,7 +59,7 @@ public class ExperimentService {
 
     private static final Gson gson = new Gson();
 
-    private ActiveUserService activeUserService;
+    private final ActiveUserService activeUserService;
     private final ExperimentRepository experimentRepository;
 
     public ExperimentService(ActiveUserService activeUserService, ExperimentRepository experimentRepository) {
@@ -90,7 +90,7 @@ public class ExperimentService {
         if (size > 50)
             throw new BadRequestException("Invalid size input, max size is 50.");
         Specification<ExperimentDAO> spec;
-        if(authenticationIsEnabled  && ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger))
+        if(!authenticationIsEnabled  || ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger))
         {
             spec = Specification
                     .where(new ExperimentSpecifications.ExperimentWithName(name))
@@ -146,6 +146,7 @@ public class ExperimentService {
         if (
                 !experimentDAO.isShared()
                 && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
+                && authenticationIsEnabled
                 && ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger)
         ) {
             logger.LogUserAction("Accessing Experiment is unauthorized.");
@@ -346,9 +347,24 @@ public class ExperimentService {
             throw new BadRequestException("Created is not editable.");
         }
 
+        if (experimentDTO.getCreatedBy() != null) {
+            logger.LogUserAction( "CreatedBy is not editable.");
+            throw new BadRequestException("CreatedBy is not editable.");
+        }
+
+        if (experimentDTO.getUpdated() != null) {
+            logger.LogUserAction( "Updated is not editable.");
+            throw new BadRequestException("Updated is not editable.");
+        }
+
+        if (experimentDTO.getFinished() != null) {
+            logger.LogUserAction( "Finished is not editable.");
+            throw new BadRequestException("Finished is not editable.");
+        }
+
         if (experimentDTO.getResult() != null) {
-            logger.LogUserAction( "Status is not editable.");
-            throw new BadRequestException("Status is not editable.");
+            logger.LogUserAction( "Result is not editable.");
+            throw new BadRequestException("Result is not editable.");
         }
 
         if (experimentDTO.getStatus() != null) {
@@ -369,7 +385,7 @@ public class ExperimentService {
                         .append("\n"));
         logger.LogUserAction("Executing " + algorithmName + parametersLogMessage);
     }
-
+    
     /**
      * The getDatasetFromExperimentParameters will retrieve the dataset from the experiment parameters
      *
@@ -434,8 +450,8 @@ public class ExperimentService {
         ExperimentDAO experimentDAO = new ExperimentDAO();
         experimentDAO.setUuid(UUID.randomUUID());
         experimentDAO.setCreatedBy(user);
-        experimentDAO.setAlgorithmDetails(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm()));
-        experimentDAO.setAlgorithm(experimentDTO.getAlgorithm().getName());
+        experimentDAO.setAlgorithm(JsonConverters.convertObjectToJsonString(experimentDTO.getAlgorithm()));
+        experimentDAO.setAlgorithmId(experimentDTO.getAlgorithm().getName());
         experimentDAO.setName(experimentDTO.getName());
         experimentDAO.setStatus(ExperimentDAO.Status.pending);
 
@@ -447,7 +463,7 @@ public class ExperimentService {
         }
 
         logger.LogUserAction(" id : " + experimentDAO.getUuid());
-        logger.LogUserAction(" algorithms : " + experimentDAO.getAlgorithmDetails());
+        logger.LogUserAction(" algorithm : " + experimentDAO.getAlgorithm());
         logger.LogUserAction(" name : " + experimentDAO.getName());
         return experimentDAO;
     }
@@ -455,7 +471,7 @@ public class ExperimentService {
     private void saveExperiment(ExperimentDAO experimentDAO, Logger logger) {
 
         logger.LogUserAction(" id : " + experimentDAO.getUuid());
-        logger.LogUserAction(" algorithms : " + experimentDAO.getAlgorithmDetails());
+        logger.LogUserAction(" algorithm : " + experimentDAO.getAlgorithm());
         logger.LogUserAction(" name : " + experimentDAO.getName());
         logger.LogUserAction(" historyId : " + experimentDAO.getWorkflowHistoryId());
         logger.LogUserAction(" status : " + experimentDAO.getStatus());
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 84053f912..b44e1ae9e 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -11,7 +11,7 @@ logging:
 
 ### AUTHENTICATION ###
 authentication:
-  enabled: true
+  enabled: false
 
 
 ### DATABASE CONFIGURATION ###
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index a1c728e96..04c6f3f99 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -1,11 +1,37 @@
+UPDATE experiment
+SET algorithms =
+    (
+        SELECT SUBSTR(algorithms, 2, LENGTH(algorithms) - 2)
+    );
+
+UPDATE experiment
+SET workflowstatus = 'error'
+WHERE workflowstatus IS NULL AND haserror;
+
+UPDATE experiment
+SET workflowstatus = 'completed'
+WHERE workflowstatus IS NULL AND NOT haserror;
+
+UPDATE experiment
+SET workflowstatus = 'success'
+WHERE workflowstatus = 'completed';
+
+UPDATE experiment
+SET workflowstatus = 'pending'
+WHERE workflowstatus = 'running';
+
 ALTER TABLE experiment
 DROP COLUMN haserror,
 DROP COLUMN hasservererror,
 DROP COLUMN validations,
 DROP COLUMN model_slug;
 
+UPDATE experiment
+SET algorithms = REPLACE(algorithms, '"name"', '"id"');
 ALTER TABLE experiment
-RENAME algorithms TO algorithmDetails;
+RENAME algorithms TO algorithm;
+ALTER TABLE experiment
+ALTER COLUMN algorithm TYPE json USING algorithm::json;
 ALTER TABLE experiment
 RENAME createdby_username TO created_by_username;
 ALTER TABLE experiment
@@ -16,10 +42,15 @@ ALTER TABLE experiment
 RENAME workflowstatus TO status;
 
 ALTER TABLE experiment
-ADD COLUMN updated timestamp without time zone;
+ADD COLUMN algorithmId text;
+
+UPDATE experiment
+SET algorithmId = (algorithm ->> 'id');
 
 ALTER TABLE experiment
-ADD COLUMN algorithm text;
+ALTER COLUMN algorithm TYPE text;
+ALTER TABLE experiment
+ADD COLUMN updated timestamp without time zone;
 
 ALTER TABLE "user"
 DROP COLUMN birthday,
-- 
GitLab


From 943ac2cf83019b8fbfd840a5d19902fd397c208f Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Tue, 29 Dec 2020 08:23:11 -0800
Subject: [PATCH 47/52] Added lombok.Updated claim utils to match the
 qakeycloak

---
 pom.xml                                       |   9 +-
 .../hbp/mip/controllers/PathologiesAPI.java   |   3 +-
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java | 108 +-----------------
 .../java/eu/hbp/mip/models/DAOs/UserDAO.java  |  41 ++-----
 .../hbp/mip/services/ActiveUserService.java   |   6 +-
 .../hbp/mip/services/ExperimentService.java   |  10 +-
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |  42 ++++---
 src/main/resources/application.yml            |   2 +-
 .../migration/V7_0__NewDatabaseStructure.sql  |   3 +
 9 files changed, 62 insertions(+), 162 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5d8467960..d92ff1f2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -246,7 +246,14 @@
             <artifactId>svenson</artifactId>
             <version>1.5.8</version>
         </dependency>
-   </dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.16</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
 
    <build>
        <finalName>portal-backend</finalName>
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
index 175ad2977..5e9a9d344 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
@@ -70,7 +70,6 @@ public class PathologiesAPI {
         }
 
         logger.LogUserAction("Successfully loaded all authorized pathologies");
-        return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies(
-                activeUserService.getActiveUser().getUsername(), logger,  authentication.getAuthorities(), allPathologies));
+        return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies(logger,  authentication, allPathologies));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index 30d5ee123..e369e5cf6 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -7,6 +7,8 @@ import eu.hbp.mip.models.DTOs.AlgorithmDTO;
 import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.utils.JsonConverters;
 import io.swagger.annotations.ApiModel;
+import lombok.Getter;
+import lombok.Setter;
 
 import javax.persistence.*;
 import java.util.*;
@@ -15,6 +17,8 @@ import java.util.*;
  * Created by habfast on 21/04/16.
  */
 @Entity
+@Getter
+@Setter
 @Table(name = "`experiment`")
 @ApiModel
 @JsonInclude(JsonInclude.Include.NON_NULL)
@@ -109,108 +113,4 @@ public class ExperimentDAO {
         experimentDTO.setViewed(this.viewed);
         return experimentDTO;
     }
-
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setAlgorithm(String algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    public String getAlgorithmId() {
-        return algorithmId;
-    }
-
-    public void setAlgorithmId(String algorithmId) {
-        this.algorithmId = algorithmId;
-    }
-
-    public String getWorkflowHistoryId() {
-        return workflowHistoryId;
-    }
-
-    public void setWorkflowHistoryId(String workflowHistoryId) {
-        this.workflowHistoryId = workflowHistoryId;
-    }
-
-    public Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(Status status) {
-        this.status = status;
-    }
-
-    public String getResult() {
-        return result;
-    }
-
-    public void setResult(String result) {
-        this.result = result;
-    }
-
-    public Date getFinished() {
-        return finished;
-    }
-
-    public void setFinished(Date finished) {
-        this.finished = finished;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-    
-    public Date getUpdated() {
-        return updated;
-    }
-
-    public void setUpdated(Date updated) {
-        this.updated = updated;
-    }
-
-    public UUID getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(UUID uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public UserDAO getCreatedBy() {
-        return createdBy;
-    }
-
-    public void setCreatedBy(UserDAO createdBy) {
-        this.createdBy = createdBy;
-    }
-
-    public boolean isViewed() {
-        return viewed;
-    }
-
-    public void setViewed(boolean viewed) {
-        this.viewed = viewed;
-    }
-
-    public boolean isShared() {
-        return shared;
-    }
-
-    public void setShared(boolean shared) {
-        this.shared = shared;
-    }
 }
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
index a94e5da1c..9279b3793 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
@@ -7,12 +7,16 @@ package eu.hbp.mip.models.DAOs;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.annotations.Expose;
 import io.swagger.annotations.ApiModel;
+import lombok.Getter;
+import lombok.Setter;
 
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
 @Entity
+@Getter
+@Setter
 @Table(name = "`user`")
 @ApiModel
 @JsonInclude(JsonInclude.Include.NON_NULL)
@@ -22,6 +26,9 @@ public class UserDAO {
     @Expose
     private String username;
 
+    @Expose
+    private String subjectId;
+
     @Expose
     private String fullname;
 
@@ -35,42 +42,12 @@ public class UserDAO {
         // Empty constructor is needed by Hibernate
     }
 
-    public UserDAO(String username, String fullname, String email) {
+    public UserDAO(String username, String fullname, String email, String subjectId) {
         this.username = username;
         this.fullname = fullname;
         this.email = email;
         this.agreeNDA = false;
-    }
-
-    public String getFullname() {
-        return fullname;
-    }
-
-    public void setFullname(String fullname) {
-        this.fullname = fullname;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public Boolean getAgreeNDA() {
-        return agreeNDA;
-    }
+        this.subjectId = subjectId;
 
-    public void setAgreeNDA(Boolean agreeNDA) {
-        this.agreeNDA = agreeNDA;
     }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index f1fe049c2..ee65c170a 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -44,17 +44,17 @@ public class ActiveUserService {
 
         // If Authentication is OFF, create anonymous user with accepted NDA
         if (!authenticationIsEnabled) {
-            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com");
+            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com","anonymousId");
             user.setAgreeNDA(true);
             userRepository.save(user);
             return user;
         }
-        //TODO:
+
         // If authentication is ON get user info from Token
         KeycloakPrincipal keycloakPrincipal =
                 (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         IDToken idToken = keycloakPrincipal.getKeycloakSecurityContext().getIdToken();
-        user = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail());
+        user = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail(), idToken.getId());
 
         UserDAO userInDatabase = userRepository.findByUsername(user.getUsername());
         if (userInDatabase == null || !userInDatabase.equals(user)) {
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 869db8836..2bc16b0f9 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -90,7 +90,7 @@ public class ExperimentService {
         if (size > 50)
             throw new BadRequestException("Invalid size input, max size is 50.");
         Specification<ExperimentDAO> spec;
-        if(!authenticationIsEnabled  || ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger))
+        if(!authenticationIsEnabled  || ClaimUtils.validateAccessRightsOnExperiments(authentication, logger))
         {
             spec = Specification
                     .where(new ExperimentSpecifications.ExperimentWithName(name))
@@ -147,7 +147,7 @@ public class ExperimentService {
                 !experimentDAO.isShared()
                 && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
                 && authenticationIsEnabled
-                && ClaimUtils.validateAccessRightsOnExperiments(user.getUsername(), authentication.getAuthorities(), logger)
+                && ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)
         ) {
             logger.LogUserAction("Accessing Experiment is unauthorized.");
             throw new UnauthorizedException("You don't have access to the experiment.");
@@ -184,7 +184,7 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, logger);
+            ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
         }
 
         // Run with the appropriate engine
@@ -222,7 +222,7 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
-            ClaimUtils.validateAccessRightsOnDatasets(user.getUsername(), authentication.getAuthorities(), experimentDatasets, logger);
+            ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
         }
 
         String body = gson.toJson(algorithmParameters);
@@ -739,7 +739,7 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 } else {
-                                    experimentDAO.setResult("[" + result + "]");
+                                    experimentDAO.setResult(result);
                                     experimentDAO.setStatus(ExperimentDAO.Status.success);
                                     resultFound = true;
                                 }
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 501cea1b0..902bf9f9f 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -3,7 +3,9 @@ package eu.hbp.mip.utils;
 import com.google.gson.Gson;
 import eu.hbp.mip.models.DTOs.PathologyDTO;
 import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
-import org.springframework.security.core.GrantedAuthority;
+import org.keycloak.KeycloakPrincipal;
+import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
+import org.springframework.security.core.Authentication;
 
 import java.util.*;
 
@@ -13,26 +15,28 @@ public class ClaimUtils {
     private static final Gson gson = new Gson();
 
     public static String allDatasetsAllowedClaim() {
-        return "role_research_dataset_all";
+        return "research_dataset_all";
     }
 
     public static String allExperimentsAllowedClaim() {
-        return "role_research_experiment_all";
+        return "research_experiment_all";
     }
 
     public static String getDatasetClaim(String datasetCode) {
-        return "role_research_dataset_" + datasetCode.toLowerCase();
+        return "research_dataset_" + datasetCode.toLowerCase();
     }
 
-    public static void validateAccessRightsOnDatasets(String username, Collection<? extends GrantedAuthority> authorities,
-                                                       String experimentDatasets, Logger logger) {
+    public static void validateAccessRightsOnDatasets(Authentication authentication,
+                                                      String experimentDatasets, Logger logger) {
+
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
 
         // Don't check for dataset claims if "super" claim exists allowing everything
-        if (!hasRoleAccess(username, authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
+        if (!hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
 
             for (String dataset : experimentDatasets.split(",")) {
                 String datasetRole = ClaimUtils.getDatasetClaim(dataset);
-                if (!hasRoleAccess(username, authorities, datasetRole, logger)) {
+                if (!hasRoleAccess(authorities, datasetRole, logger)) {
                     logger.LogUserAction("You are not allowed to use dataset: " + dataset);
                     throw new UnauthorizedException("You are not authorized to use these datasets.");
                 }
@@ -41,19 +45,23 @@ public class ClaimUtils {
         }
     }
 
-    public static boolean validateAccessRightsOnExperiments(String username, Collection<? extends GrantedAuthority> authorities, Logger logger) {
+    public static boolean validateAccessRightsOnExperiments(Authentication authentication, Logger logger) {
+
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
 
         // Check for experiment_all claims
-        return  hasRoleAccess(username, authorities, ClaimUtils.allExperimentsAllowedClaim(), logger);
+        return  hasRoleAccess(authorities, ClaimUtils.allExperimentsAllowedClaim(), logger);
     }
 
-    public static String getAuthorizedPathologies(String username, Logger logger, Collection<? extends GrantedAuthority> authorities,
+    public static String getAuthorizedPathologies(Logger logger, Authentication authentication,
                                                   List<PathologyDTO> allPathologies) {
         // --- Providing only the allowed pathologies/datasets to the user  ---
         logger.LogUserAction("Filter out the unauthorised datasets.");
 
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
+
         // If the "dataset_all" claim exists then return everything
-        if (hasRoleAccess(username, authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
+        if (hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
             return gson.toJson(allPathologies);
         }
 
@@ -61,7 +69,7 @@ public class ClaimUtils {
         for (PathologyDTO curPathology : allPathologies) {
             List<PathologyDTO.PathologyDatasetDTO> userPathologyDatasets = new ArrayList<>();
             for (PathologyDTO.PathologyDatasetDTO dataset : curPathology.getDatasets()) {
-                if (hasRoleAccess(username, authorities, ClaimUtils.getDatasetClaim(dataset.getCode()), logger)) {
+                if (hasRoleAccess(authorities, ClaimUtils.getDatasetClaim(dataset.getCode()), logger)) {
                     logger.LogUserAction("Added dataset: " + dataset.getCode());
                     userPathologyDatasets.add(dataset);
                 }
@@ -83,7 +91,7 @@ public class ClaimUtils {
         return gson.toJson(userPathologies);
     }
 
-    private static boolean  hasRoleAccess(String username, Collection<? extends GrantedAuthority> authorities,String role, Logger logger)
+    private static boolean  hasRoleAccess(ArrayList<String> authorities, String role, Logger logger)
     {
         List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
                 .replaceAll("[\\s+\\]\\[]", "").split(","));
@@ -91,4 +99,10 @@ public class ClaimUtils {
         logger.LogUserAction("User Claims: " + userClaims);
         return userClaims.contains(role.toLowerCase());
     }
+
+    private static ArrayList<String> getKeycloakAuthorities(Authentication authentication){
+        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
+        KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) token.getPrincipal();
+        return (ArrayList<String>)keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities");
+    }
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index b44e1ae9e..84053f912 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -11,7 +11,7 @@ logging:
 
 ### AUTHENTICATION ###
 authentication:
-  enabled: false
+  enabled: true
 
 
 ### DATABASE CONFIGURATION ###
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index 04c6f3f99..c39158269 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -67,6 +67,9 @@ DROP COLUMN team,
 DROP COLUMN web,
 DROP COLUMN apikey;
 
+ALTER TABLE "user"
+ADD COLUMN subjectID text;
+
 DROP TABLE "config_title", "config_yaxisvariables";
 DROP TABLE "dataset_variable", "dataset_grouping", "dataset_data", "dataset_header";
 DROP TABLE "query_variable", "query_grouping", "query_filter", "query_covariable";
-- 
GitLab


From 1ea0ceb32c4b7be2df6a97e5b99f81d10b2aab6a Mon Sep 17 00:00:00 2001
From: ThanKarab <tkarabatsis@hotmail.com>
Date: Tue, 29 Dec 2020 18:31:16 +0200
Subject: [PATCH 48/52] Added ssl-required.

---
 docker/config/application.tmpl     | 1 +
 src/main/resources/application.yml | 1 +
 2 files changed, 2 insertions(+)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 5859f78a8..2cd8bc0c4 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -56,6 +56,7 @@ keycloak:
   credentials:
     secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
   principal-attribute: "preferred_username"
+  ssl-required: {{ .Env.KEYCLOAK_SSL_REQUIRED }}
 
 ### EXTERNAL FILES ###
 # Files are imported when building the docker image
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 84053f912..e77b80358 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -55,6 +55,7 @@ keycloak:
   credentials:
     secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
   principal-attribute: "preferred_username"
+  ssl-required: none
 
 
 ### EXTERNAL FILES ###
-- 
GitLab


From 36ca121d231822d458475d52f1bfd4321428fd6d Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Fri, 8 Jan 2021 12:13:29 -0800
Subject: [PATCH 49/52] Updated result to results to be able to save multiple
 results and fixed agreedNDA so the property is up to date even when you
 logout and login again.

---
 .../configurations/SecurityConfiguration.java |   2 +-
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java |  26 ++-
 .../eu/hbp/mip/models/DTOs/AlgorithmDTO.java  | 159 +-----------------
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java | 116 +------------
 .../eu/hbp/mip/models/DTOs/PathologyDTO.java  |  55 +-----
 .../hbp/mip/services/ActiveUserService.java   |  18 +-
 .../hbp/mip/services/ExperimentService.java   | 123 ++++++++------
 .../ExperimentSpecifications.java             |   2 +-
 .../java/eu/hbp/mip/utils/ClaimUtils.java     |  17 +-
 src/main/resources/application.yml            |   9 +-
 .../migration/V7_0__NewDatabaseStructure.sql  |   6 +-
 11 files changed, 152 insertions(+), 381 deletions(-)
 rename src/main/java/eu/hbp/mip/services/{ => Specifications}/ExperimentSpecifications.java (99%)

diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index 2b2e549d4..9f583da4e 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -56,7 +56,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
                             "/sso/login",
                             "/v2/api-docs", "/swagger-ui/**", "/swagger-resources/**"  // Swagger URLs
                     ).permitAll()
-                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER")
+                    .antMatchers("/galaxy*", "/galaxy/*").hasRole("WORKFLOW_ADMIN")
                     .antMatchers("/**").authenticated()
                     .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
                     .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index e369e5cf6..a696ab52d 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -52,7 +52,7 @@ public class ExperimentDAO {
 
     @Expose
     @Column(columnDefinition = "TEXT")
-    private String result;
+    private String results;
 
     @Expose
     @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
@@ -95,6 +95,28 @@ public class ExperimentDAO {
          */
     }
 
+
+    public String getResults() {
+        return results;
+    }
+
+    public void setResults(String result) {
+        this.results = result;
+    }
+
+    public class ResultObjectDTO {
+
+        ArrayList<Object> result;
+
+        public ArrayList<Object> getResult() {
+            return this.result;
+        }
+
+        public void setResult(ArrayList<Object> results) {
+            this.result = results;
+        }
+    }
+
     public ExperimentDTO convertToDTO(boolean includeResult)
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
@@ -105,7 +127,7 @@ public class ExperimentDAO {
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
         if(includeResult){
-            experimentDTO.setResult(JsonConverters.convertJsonStringToObject(String.valueOf(this.result),  new ArrayList<ExperimentDTO.ResultDTO>().getClass()));
+            experimentDTO.setResults(JsonConverters.convertJsonStringToObject(this.results,  new ArrayList<ArrayList<Object>>().getClass()));
         }
         experimentDTO.setStatus(this.status);
         experimentDTO.setShared(this.shared);
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
index 1a6d8b99d..52db979d5 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/AlgorithmDTO.java
@@ -1,51 +1,15 @@
 package eu.hbp.mip.models.DTOs;
 
 import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.Setter;
 
 import java.util.List;
 
+@Getter
+@Setter
 public class AlgorithmDTO {
 
-    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 getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public List<AlgorithmParamDTO> getParameters() {
-        return parameters;
-    }
-
-    public void setParameters(List<AlgorithmParamDTO> parameters) {
-        this.parameters = parameters;
-    }
-
     @SerializedName("name")
     private String name;
 
@@ -61,6 +25,8 @@ public class AlgorithmDTO {
     @SerializedName("parameters")
     private List<AlgorithmParamDTO> parameters;
 
+    @Getter
+    @Setter
     public static class AlgorithmParamDTO {
         @SerializedName("name")
         private String name;
@@ -103,118 +69,5 @@ public class AlgorithmDTO {
 
         @SerializedName("valueEnumerations")
         private List<String> valueEnumerations;
-
-        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 getLabel() {
-            return label;
-        }
-
-        public void setLabel(String label) {
-            this.label = label;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public void setType(String type) {
-            this.type = type;
-        }
-
-        public String getColumnValuesSQLType() {
-            return columnValuesSQLType;
-        }
-
-        public void setColumnValuesSQLType(String columnValuesSQLType) {
-            this.columnValuesSQLType = columnValuesSQLType;
-        }
-
-        public String getColumnValuesIsCategorical() {
-            return columnValuesIsCategorical;
-        }
-
-        public void setColumnValuesIsCategorical(String columnValuesIsCategorical) {
-            this.columnValuesIsCategorical = columnValuesIsCategorical;
-        }
-
-        public String getValue() {
-            return value;
-        }
-
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        public String getDefaultValue() {
-            return defaultValue;
-        }
-
-        public void setDefaultValue(String defaultValue) {
-            this.defaultValue = defaultValue;
-        }
-
-        public String getValueType() {
-            return valueType;
-        }
-
-        public void setValueType(String valueType) {
-            this.valueType = valueType;
-        }
-
-        public String getValueNotBlank() {
-            return valueNotBlank;
-        }
-
-        public void setValueNotBlank(String valueNotBlank) {
-            this.valueNotBlank = valueNotBlank;
-        }
-
-        public String getValueMultiple() {
-            return valueMultiple;
-        }
-
-        public void setValueMultiple(String valueMultiple) {
-            this.valueMultiple = valueMultiple;
-        }
-
-        public String getValueMin() {
-            return valueMin;
-        }
-
-        public void setValueMin(String valueMin) {
-            this.valueMin = valueMin;
-        }
-
-        public String getValueMax() {
-            return valueMax;
-        }
-
-        public void setValueMax(String valueMax) {
-            this.valueMax = valueMax;
-        }
-
-        public List<String> getValueEnumerations() {
-            return valueEnumerations;
-        }
-
-        public void setValueEnumerations(List<String> valueEnumerations) {
-            this.valueEnumerations = valueEnumerations;
-        }
     }
-
 }
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 2840f669f..34a1bee9c 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -2,11 +2,15 @@ package eu.hbp.mip.models.DTOs;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
+import lombok.Getter;
+import lombok.Setter;
 
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+@Getter
+@Setter
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class ExperimentDTO {
 
@@ -18,121 +22,11 @@ public class ExperimentDTO {
     private Date finished;
     private Boolean shared;
     private Boolean viewed;
-    private List<ExperimentDTO.ResultDTO> result;
+    private List<List<Object>> results;
     private ExperimentDAO.Status status;
-
     private AlgorithmDTO algorithm;
 
     public ExperimentDTO() {
-    }
-
-    public AlgorithmDTO getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setAlgorithm(AlgorithmDTO algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    public UUID getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(UUID uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getCreatedBy() {
-        return createdBy;
-    }
-
-    public void setCreatedBy(String createdBy) {
-        this.createdBy = createdBy;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-    
-    public Date getUpdated() {
-        return updated;
-    }
-
-    public void setUpdated(Date updated) {
-        this.updated = updated;
-    }
-    
-    public Date getFinished() {
-        return finished;
-    }
-
-    public void setFinished(Date finished) {
-        this.finished = finished;
-    }
-
-    public Boolean getShared() {
-        return shared;
-    }
-
-    public void setShared(Boolean shared) {
-        this.shared = shared;
-    }
-
-    public Boolean getViewed() {
-        return viewed;
-    }
-
-    public void setViewed(Boolean viewed) {
-        this.viewed = viewed;
-    }
-
-    public List<ExperimentDTO.ResultDTO> getResult() {
-        return result;
-    }
-
-    public void setResult(List<ExperimentDTO.ResultDTO> result) {
-        this.result = result;
-    }
-
-    public ExperimentDAO.Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(ExperimentDAO.Status status) {
-        this.status = status;
-    }
-
-    public static class ResultDTO {
-
-        private Object data;
-        private String type;
-
-        public Object getData() {
-            return this.data;
-        }
-
-        public void setData(Object data) {
-            this.data = data;
-        }
-
-        public String getType() {
-            return type;
-        }
 
-        public void setType(String type) {
-            this.type = type;
-        }
     }
 }
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
index 2a8887b5f..aa78ef8b0 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/PathologyDTO.java
@@ -1,43 +1,15 @@
 package eu.hbp.mip.models.DTOs;
 
 import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.Setter;
 
 import java.util.List;
 
+@Getter
+@Setter
 public class PathologyDTO {
 
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    public Object getMetadataHierarchy() {
-        return metadataHierarchy;
-    }
-
-    public void setMetadataHierarchy(Object metadataHierarchy) {
-        this.metadataHierarchy = metadataHierarchy;
-    }
-
-    public List<PathologyDatasetDTO> getDatasets() {
-        return datasets;
-    }
-
-    public void setDatasets(List<PathologyDatasetDTO> datasets) {
-        this.datasets = datasets;
-    }
-
     @SerializedName("code")
     private String code;
 
@@ -50,6 +22,8 @@ public class PathologyDTO {
     @SerializedName("datasets")
     private List<PathologyDatasetDTO> datasets;
 
+    @Getter
+    @Setter
     public static class PathologyDatasetDTO {
         @SerializedName("code")
         private String code;
@@ -57,22 +31,6 @@ public class PathologyDTO {
         @SerializedName("label")
         private String label;
 
-        public String getCode() {
-            return code;
-        }
-
-        public void setCode(String code) {
-            this.code = code;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        public void setLabel(String label) {
-            this.label = label;
-        }
-
         public String toString() {
             return code;
         }
@@ -81,5 +39,4 @@ public class PathologyDTO {
     public String toString() {
         return code;
     }
-
 }
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index ee65c170a..bc3c8ced7 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -4,15 +4,14 @@ import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.repositories.UserRepository;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.representations.IDToken;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
-import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
 import javax.inject.Named;
+import java.util.Objects;
 
 @Component
 @Named("ActiveUserService")
@@ -44,7 +43,7 @@ public class ActiveUserService {
 
         // If Authentication is OFF, create anonymous user with accepted NDA
         if (!authenticationIsEnabled) {
-            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com","anonymousId");
+            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com", "anonymousId");
             user.setAgreeNDA(true);
             userRepository.save(user);
             return user;
@@ -57,9 +56,20 @@ public class ActiveUserService {
         user = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail(), idToken.getId());
 
         UserDAO userInDatabase = userRepository.findByUsername(user.getUsername());
-        if (userInDatabase == null || !userInDatabase.equals(user)) {
+        if (userInDatabase == null) {
             userRepository.save(user);
+            return user;
+        }
+
+        if (!Objects.equals(user.getEmail(),userInDatabase.getEmail())
+            || !Objects.equals(user.getFullname(),userInDatabase.getFullname())
+        ) {
+            userInDatabase.setFullname(user.getFullname());
+            userInDatabase.setEmail(user.getEmail());
         }
+
+        user = userInDatabase;
+        userRepository.save(user);
         return user;
     }
 
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 2bc16b0f9..1ef7c09d7 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -10,6 +10,7 @@ import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import com.google.gson.internal.LinkedTreeMap;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetroFitGalaxyClients;
 import eu.hbp.mip.controllers.galaxy.retrofit.RetrofitClientInstance;
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
@@ -19,6 +20,7 @@ import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.models.galaxy.GalaxyWorkflowResult;
 import eu.hbp.mip.models.galaxy.PostWorkflowToGalaxyDtoResponse;
 import eu.hbp.mip.repositories.ExperimentRepository;
+import eu.hbp.mip.services.Specifications.ExperimentSpecifications;
 import eu.hbp.mip.utils.ClaimUtils;
 import eu.hbp.mip.utils.Exceptions.*;
 import eu.hbp.mip.utils.HTTPUtil;
@@ -211,6 +213,14 @@ public class ExperimentService {
         //Checking if check (POST) /experiments has proper input.
         checkPostExperimentProperInput(experimentDTO, logger);
 
+        // Get the type and name of algorithm
+        String algorithmType = experimentDTO.getAlgorithm().getType();
+
+        if(algorithmType == "workflow"){
+            logger.LogUserAction("You can not run workflow algorithms transiently.");
+            throw new BadRequestException("You can not run workflow algorithms transiently.");
+        }
+
         // Get the parameters
         List<AlgorithmDTO.AlgorithmParamDTO> algorithmParameters
                 = experimentDTO.getAlgorithm().getParameters();
@@ -236,7 +246,7 @@ public class ExperimentService {
 
         logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
-        experimentDTO.setResult((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults());
+        experimentDTO.setResults((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertJsonStringToObject(exaremeResult.getResults(), new ArrayList<ArrayList<Object>>().getClass()));
         experimentDTO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
 
         return experimentDTO;
@@ -244,10 +254,10 @@ public class ExperimentService {
 
     /**
      * The updateExperiment will update the experiment's properties
-     *
      * @param uuid          is the id of the experiment to be updated
      * @param experimentDTO is the experiment information to be updated
      * @param logger    contains username and the endpoint.
+     * @return
      */
     public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, Logger logger) {
         ExperimentDAO experimentDAO;
@@ -321,7 +331,7 @@ public class ExperimentService {
                         && experimentDTO.getViewed() == null
                         && experimentDTO.getCreated() == null
                         && experimentDTO.getCreatedBy() == null
-                        && experimentDTO.getResult() == null
+                        && experimentDTO.getResults() == null
                         && experimentDTO.getStatus() == null
                         && experimentDTO.getUuid() == null;
 
@@ -362,7 +372,7 @@ public class ExperimentService {
             throw new BadRequestException("Finished is not editable.");
         }
 
-        if (experimentDTO.getResult() != null) {
+        if (experimentDTO.getResults() != null) {
             logger.LogUserAction( "Result is not editable.");
             throw new BadRequestException("Result is not editable.");
         }
@@ -497,6 +507,50 @@ public class ExperimentService {
         }
     }
 
+    private String formattingExaremeResult(String result) {
+        List<LinkedTreeMap<String,Object>> jsonObject = JsonConverters.convertJsonStringToObject(result, new ArrayList<ExperimentDAO.ResultObjectDTO>().getClass());
+        LinkedTreeMap<String,Object> firstResult = jsonObject.get(0);
+        return "[" + JsonConverters.convertObjectToJsonString(firstResult.get("result")) + "]";
+    }
+
+    private String formattingGalaxyResult(String result) {
+        List<LinkedTreeMap<String,Object>> jsonObjects = JsonConverters.convertJsonStringToObject(result, new ArrayList<ExperimentDAO.ResultObjectDTO>().getClass());
+        List<Object> objects = new ArrayList<>();
+        for (int i = 0; i < jsonObjects.size(); i++) {
+            LinkedTreeMap<String,Object> k = jsonObjects.get(i);
+            objects.add(k.get("result"));
+        }
+        return JsonConverters.convertObjectToJsonString(objects);
+    }
+
+
+    /**
+     * The runExaremeExperiment will run to exareme the experiment
+     *
+     * @param url           is the url that contain the results of the experiment
+     * @param body          is the parameters of the algorithm
+     * @param experimentDTO is the experiment information to be executed in the exareme
+     * @return the result of exareme as well as the http status that was retrieved
+     */
+    private ExaremeResult runExaremeExperiment(String url, String body, ExperimentDTO experimentDTO) {
+
+        StringBuilder results = new StringBuilder();
+        int code;
+        try {
+            code = HTTPUtil.sendPost(url, body, results);
+        } catch (Exception e) {
+            throw new InternalServerError("Error occurred : " + e.getMessage());
+        }
+
+        String resultToMatchGalaxy = "[" + results + "]";
+        String formattedResult = formattingExaremeResult(resultToMatchGalaxy);
+        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code + "and result :" + formattedResult);
+
+        return new ExaremeResult(code, formattedResult);
+    }
+
+
+
     /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
 
     /**
@@ -539,7 +593,7 @@ public class ExperimentService {
 
                 Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
-                experimentDAO.setResult((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(exaremeResult.getResults()));
+                experimentDAO.setResults((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults());
                 experimentDAO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
             } catch (Exception e) {
                 Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
@@ -554,32 +608,6 @@ public class ExperimentService {
         return experimentDTO;
     }
 
-    /**
-     * The runExaremeExperiment will run to exareme the experiment
-     *
-     * @param url           is the url that contain the results of the experiment
-     * @param body          is the parameters of the algorithm
-     * @param experimentDTO is the experiment information to be executed in the exareme
-     * @return the result of exareme as well as the http status that was retrieved
-     */
-    public ExaremeResult runExaremeExperiment(String url, String body, ExperimentDTO experimentDTO) {
-
-        StringBuilder results = new StringBuilder();
-        int code;
-        try {
-            code = HTTPUtil.sendPost(url, body, results);
-        } catch (Exception e) {
-            throw new InternalServerError("Error occurred : " + e.getMessage());
-        }
-        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code);
-
-        // Results are stored in the experiment object
-        ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class);
-        List<ExperimentDTO.ResultDTO> resultDTOS = experimentDTOWithOnlyResult.getResult();
-        return new ExaremeResult(code, resultDTOS);
-    }
-
-
     /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
 
 
@@ -718,12 +746,12 @@ public class ExperimentService {
                 Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
 
                 switch (state) {
-                    case "running":
+                    case "pending":
                         // Do nothing, when the experiment is created the status is set to running
                         Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
                         break;
 
-                    case "completed":
+                    case "success":
                         // Get only the job result that is visible
                         List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experimentDAO);
                         Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
@@ -739,7 +767,7 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 } else {
-                                    experimentDAO.setResult(result);
+                                    experimentDAO.setResults(result);
                                     experimentDAO.setStatus(ExperimentDAO.Status.success);
                                     resultFound = true;
                                 }
@@ -790,8 +818,8 @@ public class ExperimentService {
                 }
 
                 // If result exists return
-                if (experimentDAO.getResult() != null) {
-                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
+                if (experimentDAO.getResults() != null) {
+                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResults());
                     return;
                 }
             }
@@ -801,10 +829,10 @@ public class ExperimentService {
 
     /**
      * @param experimentDAO The experiment of the workflow
-     * @return "running"           ->      When the workflow is still running
+     * @return "pending"           ->      When the workflow is still running
      * "internalError"     ->      When an exception or a bad request occurred
      * "error"             ->      When the workflow produced an error
-     * "completed"         ->      When the workflow completed successfully
+     * "success"         ->      When the workflow completed successfully
      */
     public String getWorkflowStatus(ExperimentDAO experimentDAO) {
         String historyId = experimentDAO.getWorkflowHistoryId();
@@ -846,14 +874,14 @@ public class ExperimentService {
         Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
         switch (state) {
             case "ok":
-                return "completed";
+                return "success";
             case "error":
                 return "error";
-            case "running":
+            case "pending":
             case "new":
             case "waiting":
             case "queued":
-                return "running";
+                return "pending";
             default:
                 return "internalError";
         }
@@ -919,7 +947,8 @@ public class ExperimentService {
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
-            resultJson = new Gson().toJson(response.body());
+
+            resultJson = gson.toJson(response.body());
             Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
 
         } catch (IOException e) {
@@ -928,8 +957,8 @@ public class ExperimentService {
             return null;
         }
 
-        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
-        return resultJson;
+
+        return formattingGalaxyResult(resultJson);
     }
 
 
@@ -979,9 +1008,9 @@ public class ExperimentService {
 
     static class ExaremeResult {
         private int code;
-        private List<ExperimentDTO.ResultDTO> results;
+        private String results;
 
-        public ExaremeResult(int code, List<ExperimentDTO.ResultDTO> results) {
+        public ExaremeResult(int code, String results) {
             this.code = code;
             this.results = results;
         }
@@ -990,7 +1019,7 @@ public class ExperimentService {
             return code;
         }
 
-        public List<ExperimentDTO.ResultDTO> getResults() {
+        public String getResults() {
             return results;
         }
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/services/Specifications/ExperimentSpecifications.java
similarity index 99%
rename from src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
rename to src/main/java/eu/hbp/mip/services/Specifications/ExperimentSpecifications.java
index e5b51a692..c1e6a13ac 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/services/Specifications/ExperimentSpecifications.java
@@ -1,4 +1,4 @@
-package eu.hbp.mip.services;
+package eu.hbp.mip.services.Specifications;
 
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
 import eu.hbp.mip.models.DAOs.UserDAO;
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 902bf9f9f..f5676b52c 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -2,6 +2,7 @@ package eu.hbp.mip.utils;
 
 import com.google.gson.Gson;
 import eu.hbp.mip.models.DTOs.PathologyDTO;
+import eu.hbp.mip.utils.Exceptions.InternalServerError;
 import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
@@ -29,7 +30,7 @@ public class ClaimUtils {
     public static void validateAccessRightsOnDatasets(Authentication authentication,
                                                       String experimentDatasets, Logger logger) {
 
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
 
         // Don't check for dataset claims if "super" claim exists allowing everything
         if (!hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
@@ -47,7 +48,7 @@ public class ClaimUtils {
 
     public static boolean validateAccessRightsOnExperiments(Authentication authentication, Logger logger) {
 
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
 
         // Check for experiment_all claims
         return  hasRoleAccess(authorities, ClaimUtils.allExperimentsAllowedClaim(), logger);
@@ -58,7 +59,7 @@ public class ClaimUtils {
         // --- Providing only the allowed pathologies/datasets to the user  ---
         logger.LogUserAction("Filter out the unauthorised datasets.");
 
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication);
+        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
 
         // If the "dataset_all" claim exists then return everything
         if (hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
@@ -100,9 +101,15 @@ public class ClaimUtils {
         return userClaims.contains(role.toLowerCase());
     }
 
-    private static ArrayList<String> getKeycloakAuthorities(Authentication authentication){
+    private static ArrayList<String> getKeycloakAuthorities(Authentication authentication, Logger logger){
         KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
         KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) token.getPrincipal();
-        return (ArrayList<String>)keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities");
+        if(keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities") == null)
+        {
+            logger.LogUserAction("Your user has no roles.");
+            throw new InternalServerError("Your user has no roles.");
+        }
+
+         return (ArrayList<String>)keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities");
     }
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index e77b80358..58ecf45e1 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -11,7 +11,7 @@ logging:
 
 ### AUTHENTICATION ###
 authentication:
-  enabled: true
+  enabled: false
 
 
 ### DATABASE CONFIGURATION ###
@@ -48,14 +48,13 @@ services:
 ### KEYCLOAK ###
 keycloak:
   enabled: true
-  auth-server-url: "http://127.0.0.1/auth"
+  auth-server-url: "https://iam.humanbrainproject.eu/auth"
   realm: "MIP"
-  resource: "MIP"
+  resource: "mipfedqa"
   enable-basic-auth: true
   credentials:
-    secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
+    secret: "492ddb7d-a7c6-4143-89ae-dbfa6f970aca"
   principal-attribute: "preferred_username"
-  ssl-required: none
 
 
 ### EXTERNAL FILES ###
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index c39158269..6a3b0c364 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -26,8 +26,8 @@ DROP COLUMN hasservererror,
 DROP COLUMN validations,
 DROP COLUMN model_slug;
 
-UPDATE experiment
-SET algorithms = REPLACE(algorithms, '"name"', '"id"');
+ALTER TABLE experiment
+RENAME result TO results;
 ALTER TABLE experiment
 RENAME algorithms TO algorithm;
 ALTER TABLE experiment
@@ -45,7 +45,7 @@ ALTER TABLE experiment
 ADD COLUMN algorithmId text;
 
 UPDATE experiment
-SET algorithmId = (algorithm ->> 'id');
+SET algorithmId = (algorithm ->> 'name');
 
 ALTER TABLE experiment
 ALTER COLUMN algorithm TYPE text;
-- 
GitLab


From 854b1853e9f1637b7b808dc7148fffa8061d7cbb Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Mon, 11 Jan 2021 08:06:17 -0800
Subject: [PATCH 50/52] Reverting results to result and accessing only the
 first result from galaxy.

---
 .../eu/hbp/mip/models/DAOs/ExperimentDAO.java | 26 +------
 .../eu/hbp/mip/models/DTOs/ExperimentDTO.java |  3 +-
 .../hbp/mip/services/ExperimentService.java   | 71 +++++++------------
 .../migration/V7_0__NewDatabaseStructure.sql  |  2 -
 4 files changed, 30 insertions(+), 72 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index a696ab52d..585bd8bd6 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -52,7 +52,7 @@ public class ExperimentDAO {
 
     @Expose
     @Column(columnDefinition = "TEXT")
-    private String results;
+    private String result;
 
     @Expose
     @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
@@ -95,28 +95,6 @@ public class ExperimentDAO {
          */
     }
 
-
-    public String getResults() {
-        return results;
-    }
-
-    public void setResults(String result) {
-        this.results = result;
-    }
-
-    public class ResultObjectDTO {
-
-        ArrayList<Object> result;
-
-        public ArrayList<Object> getResult() {
-            return this.result;
-        }
-
-        public void setResult(ArrayList<Object> results) {
-            this.result = results;
-        }
-    }
-
     public ExperimentDTO convertToDTO(boolean includeResult)
     {
         ExperimentDTO experimentDTO = new ExperimentDTO();
@@ -127,7 +105,7 @@ public class ExperimentDAO {
         experimentDTO.setCreatedBy(this.createdBy.getUsername());
         experimentDTO.setName(this.name);
         if(includeResult){
-            experimentDTO.setResults(JsonConverters.convertJsonStringToObject(this.results,  new ArrayList<ArrayList<Object>>().getClass()));
+            experimentDTO.setResult(JsonConverters.convertJsonStringToObject(String.valueOf(this.result),  new ArrayList<>().getClass()));
         }
         experimentDTO.setStatus(this.status);
         experimentDTO.setShared(this.shared);
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
index 34a1bee9c..e64c6f75e 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/ExperimentDTO.java
@@ -22,11 +22,10 @@ public class ExperimentDTO {
     private Date finished;
     private Boolean shared;
     private Boolean viewed;
-    private List<List<Object>> results;
+    private List<Object> result;
     private ExperimentDAO.Status status;
     private AlgorithmDTO algorithm;
 
     public ExperimentDTO() {
-
     }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 1ef7c09d7..bf989c4ac 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -169,7 +169,6 @@ public class ExperimentService {
      * @return the experiment information which was created
      */
     public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
-        UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
         checkPostExperimentProperInput(experimentDTO, logger);
@@ -208,7 +207,6 @@ public class ExperimentService {
      * @return the experiment information which was created
      */
     public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
-        UserDAO user = activeUserService.getActiveUser();
 
         //Checking if check (POST) /experiments has proper input.
         checkPostExperimentProperInput(experimentDTO, logger);
@@ -216,7 +214,7 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithm().getType();
 
-        if(algorithmType == "workflow"){
+        if(algorithmType.equals("workflow")){
             logger.LogUserAction("You can not run workflow algorithms transiently.");
             throw new BadRequestException("You can not run workflow algorithms transiently.");
         }
@@ -246,7 +244,7 @@ public class ExperimentService {
 
         logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
-        experimentDTO.setResults((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertJsonStringToObject(exaremeResult.getResults(), new ArrayList<ArrayList<Object>>().getClass()));
+        experimentDTO.setResult((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults());
         experimentDTO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
 
         return experimentDTO;
@@ -254,10 +252,10 @@ public class ExperimentService {
 
     /**
      * The updateExperiment will update the experiment's properties
+     *
      * @param uuid          is the id of the experiment to be updated
      * @param experimentDTO is the experiment information to be updated
      * @param logger    contains username and the endpoint.
-     * @return
      */
     public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, Logger logger) {
         ExperimentDAO experimentDAO;
@@ -331,7 +329,7 @@ public class ExperimentService {
                         && experimentDTO.getViewed() == null
                         && experimentDTO.getCreated() == null
                         && experimentDTO.getCreatedBy() == null
-                        && experimentDTO.getResults() == null
+                        && experimentDTO.getResult() == null
                         && experimentDTO.getStatus() == null
                         && experimentDTO.getUuid() == null;
 
@@ -372,7 +370,7 @@ public class ExperimentService {
             throw new BadRequestException("Finished is not editable.");
         }
 
-        if (experimentDTO.getResults() != null) {
+        if (experimentDTO.getResult() != null) {
             logger.LogUserAction( "Result is not editable.");
             throw new BadRequestException("Result is not editable.");
         }
@@ -507,23 +505,15 @@ public class ExperimentService {
         }
     }
 
-    private String formattingExaremeResult(String result) {
-        List<LinkedTreeMap<String,Object>> jsonObject = JsonConverters.convertJsonStringToObject(result, new ArrayList<ExperimentDAO.ResultObjectDTO>().getClass());
-        LinkedTreeMap<String,Object> firstResult = jsonObject.get(0);
-        return "[" + JsonConverters.convertObjectToJsonString(firstResult.get("result")) + "]";
-    }
-
     private String formattingGalaxyResult(String result) {
-        List<LinkedTreeMap<String,Object>> jsonObjects = JsonConverters.convertJsonStringToObject(result, new ArrayList<ExperimentDAO.ResultObjectDTO>().getClass());
-        List<Object> objects = new ArrayList<>();
-        for (int i = 0; i < jsonObjects.size(); i++) {
-            LinkedTreeMap<String,Object> k = jsonObjects.get(i);
-            objects.add(k.get("result"));
-        }
-        return JsonConverters.convertObjectToJsonString(objects);
+        List<LinkedTreeMap<String,Object>> jsonObject = JsonConverters.convertJsonStringToObject(result, new ArrayList<ArrayList<Object>>().getClass());
+        LinkedTreeMap<String,Object> firstResult = jsonObject.get(0);
+        jsonObject = (List<LinkedTreeMap<String, Object>>) firstResult.get("result");
+        List<LinkedTreeMap<String,Object>> finalJsonObject = new ArrayList<>();
+        finalJsonObject.add(jsonObject.get(0));
+        return JsonConverters.convertObjectToJsonString(finalJsonObject);
     }
 
-
     /**
      * The runExaremeExperiment will run to exareme the experiment
      *
@@ -532,7 +522,7 @@ public class ExperimentService {
      * @param experimentDTO is the experiment information to be executed in the exareme
      * @return the result of exareme as well as the http status that was retrieved
      */
-    private ExaremeResult runExaremeExperiment(String url, String body, ExperimentDTO experimentDTO) {
+    public ExaremeResult runExaremeExperiment(String url, String body, ExperimentDTO experimentDTO) {
 
         StringBuilder results = new StringBuilder();
         int code;
@@ -542,15 +532,14 @@ public class ExperimentService {
             throw new InternalServerError("Error occurred : " + e.getMessage());
         }
 
-        String resultToMatchGalaxy = "[" + results + "]";
-        String formattedResult = formattingExaremeResult(resultToMatchGalaxy);
-        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Algorithm finished with code: " + code + "and result :" + formattedResult);
+        // Results are stored in the experiment object
+        ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class);
+        List<Object> resultDTOS = experimentDTOWithOnlyResult.getResult();
+        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
-        return new ExaremeResult(code, formattedResult);
+        return new ExaremeResult(code, resultDTOS);
     }
 
-
-
     /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
 
     /**
@@ -593,7 +582,7 @@ public class ExperimentService {
 
                 Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeResult.getCode() + " and result: " + exaremeResult.getResults());
 
-                experimentDAO.setResults((exaremeResult.getCode() >= 400) ? null : exaremeResult.getResults());
+                experimentDAO.setResult((exaremeResult.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(exaremeResult.getResults()));
                 experimentDAO.setStatus((exaremeResult.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
             } catch (Exception e) {
                 Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
@@ -685,11 +674,6 @@ public class ExperimentService {
             } else {     // Something unexpected happened
                 String msgErr = gson.toJson(response.errorBody());
                 logger.LogUserAction("Error Response: " + msgErr);
-
-                // Values are read from streams.
-                JSONObject jObjectError = new JSONObject(msgErr);
-                String errMsg = jObjectError.get("err_msg").toString();
-
                 experimentDTO.setStatus((response.code() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
             }
 
@@ -767,7 +751,7 @@ public class ExperimentService {
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 } else {
-                                    experimentDAO.setResults(result);
+                                    experimentDAO.setResult(result);
                                     experimentDAO.setStatus(ExperimentDAO.Status.success);
                                     resultFound = true;
                                 }
@@ -818,8 +802,8 @@ public class ExperimentService {
                 }
 
                 // If result exists return
-                if (experimentDAO.getResults() != null) {
-                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResults());
+                if (experimentDAO.getResult() != null) {
+                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
                     return;
                 }
             }
@@ -947,8 +931,7 @@ public class ExperimentService {
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
-
-            resultJson = gson.toJson(response.body());
+            resultJson = new Gson().toJson(response.body());
             Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
 
         } catch (IOException e) {
@@ -957,7 +940,7 @@ public class ExperimentService {
             return null;
         }
 
-
+        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
         return formattingGalaxyResult(resultJson);
     }
 
@@ -1007,10 +990,10 @@ public class ExperimentService {
     }
 
     static class ExaremeResult {
-        private int code;
-        private String results;
+        private final int code;
+        private final List<Object> results;
 
-        public ExaremeResult(int code, String results) {
+        public ExaremeResult(int code, List<Object> results) {
             this.code = code;
             this.results = results;
         }
@@ -1019,7 +1002,7 @@ public class ExperimentService {
             return code;
         }
 
-        public String getResults() {
+        public List<Object> getResults() {
             return results;
         }
     }
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index 6a3b0c364..e4791c68c 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -26,8 +26,6 @@ DROP COLUMN hasservererror,
 DROP COLUMN validations,
 DROP COLUMN model_slug;
 
-ALTER TABLE experiment
-RENAME result TO results;
 ALTER TABLE experiment
 RENAME algorithms TO algorithm;
 ALTER TABLE experiment
-- 
GitLab


From 68ff221abe0fa896029c839245d3ce6b52ed2f01 Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Thu, 14 Jan 2021 04:49:03 -0800
Subject: [PATCH 51/52] Remove a log and small change to 7.0 migration script.

---
 src/main/java/eu/hbp/mip/services/ExperimentService.java       | 1 -
 src/main/resources/application.yml                             | 2 +-
 src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index bf989c4ac..45345c8a5 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -535,7 +535,6 @@ public class ExperimentService {
         // Results are stored in the experiment object
         ExperimentDTO experimentDTOWithOnlyResult = JsonConverters.convertJsonStringToObject(String.valueOf(results), ExperimentDTO.class);
         List<Object> resultDTOS = experimentDTOWithOnlyResult.getResult();
-        Logger.LogExperimentAction(experimentDTO.getName(), experimentDTO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
 
         return new ExaremeResult(code, resultDTOS);
     }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 58ecf45e1..345fc4bfa 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -53,7 +53,7 @@ keycloak:
   resource: "mipfedqa"
   enable-basic-auth: true
   credentials:
-    secret: "492ddb7d-a7c6-4143-89ae-dbfa6f970aca"
+    secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
   principal-attribute: "preferred_username"
 
 
diff --git a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
index e4791c68c..c1732c9e9 100644
--- a/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
+++ b/src/main/resources/db/migration/V7_0__NewDatabaseStructure.sql
@@ -9,7 +9,7 @@ SET workflowstatus = 'error'
 WHERE workflowstatus IS NULL AND haserror;
 
 UPDATE experiment
-SET workflowstatus = 'completed'
+SET workflowstatus = 'success'
 WHERE workflowstatus IS NULL AND NOT haserror;
 
 UPDATE experiment
-- 
GitLab


From 2ab92b77ba59b7982e64435bc839937964a2190a Mon Sep 17 00:00:00 2001
From: kostas <kostasfilippop@gmail.com>
Date: Fri, 15 Jan 2021 10:20:40 -0800
Subject: [PATCH 52/52] Set the ssl-required to none

---
 docker/config/application.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 2cd8bc0c4..ae10744aa 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -56,7 +56,7 @@ keycloak:
   credentials:
     secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
   principal-attribute: "preferred_username"
-  ssl-required: {{ .Env.KEYCLOAK_SSL_REQUIRED }}
+  ssl-required: none
 
 ### EXTERNAL FILES ###
 # Files are imported when building the docker image
-- 
GitLab