From 115cde1e09aff157c0848b60c0be410a9ee82371 Mon Sep 17 00:00:00 2001 From: Konstantinos <kostas24061992@yahoo.com> Date: Wed, 4 Dec 2019 11:52:10 +0200 Subject: [PATCH] Merge Galaxy_Middleware_API with back end.KK On branch dev_merge_middleware Changes to be committed: modified: build.sh modified: pom.xml new file: src/main/java/eu/hbp/mip/controllers/GalaxyAPI.java new file: src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java new file: src/main/java/eu/hbp/mip/controllers/retrofit/RetrofitClientInstance.java new file: src/main/java/eu/hbp/mip/dto/ErrorResponse.java new file: src/main/java/eu/hbp/mip/dto/GetWorkflowResultsFromGalaxyDtoResponse.java new file: src/main/java/eu/hbp/mip/dto/JwtResponse.java new file: src/main/java/eu/hbp/mip/dto/LoginDto.java new file: src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java new file: src/main/java/eu/hbp/mip/dto/SignUpDto.java new file: src/main/java/eu/hbp/mip/dto/StringDtoResponse.java new file: src/main/java/eu/hbp/mip/helpers/GenParameters.java new file: src/main/java/eu/hbp/mip/helpers/LogHelper.java --- build.sh | 5 +- pom.xml | 29 ++ .../eu/hbp/mip/controllers/GalaxyAPI.java | 470 ++++++++++++++++++ .../retrofit/RetroFitGalaxyClients.java | 30 ++ .../retrofit/RetrofitClientInstance.java | 30 ++ .../java/eu/hbp/mip/dto/ErrorResponse.java | 41 ++ ...tWorkflowResultsFromGalaxyDtoResponse.java | 208 ++++++++ src/main/java/eu/hbp/mip/dto/JwtResponse.java | 31 ++ src/main/java/eu/hbp/mip/dto/LoginDto.java | 36 ++ .../dto/PostWorkflowToGalaxyDtoResponse.java | 93 ++++ src/main/java/eu/hbp/mip/dto/SignUpDto.java | 73 +++ .../eu/hbp/mip/dto/StringDtoResponse.java | 26 + .../eu/hbp/mip/helpers/GenParameters.java | 129 +++++ .../java/eu/hbp/mip/helpers/LogHelper.java | 10 + 14 files changed, 1210 insertions(+), 1 deletion(-) create mode 100644 src/main/java/eu/hbp/mip/controllers/GalaxyAPI.java create mode 100644 src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java create mode 100644 src/main/java/eu/hbp/mip/controllers/retrofit/RetrofitClientInstance.java create mode 100644 src/main/java/eu/hbp/mip/dto/ErrorResponse.java create mode 100644 src/main/java/eu/hbp/mip/dto/GetWorkflowResultsFromGalaxyDtoResponse.java create mode 100644 src/main/java/eu/hbp/mip/dto/JwtResponse.java create mode 100644 src/main/java/eu/hbp/mip/dto/LoginDto.java create mode 100644 src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java create mode 100644 src/main/java/eu/hbp/mip/dto/SignUpDto.java create mode 100644 src/main/java/eu/hbp/mip/dto/StringDtoResponse.java create mode 100644 src/main/java/eu/hbp/mip/helpers/GenParameters.java create mode 100644 src/main/java/eu/hbp/mip/helpers/LogHelper.java diff --git a/build.sh b/build.sh index 5df0e1ce8..796a240e3 100755 --- a/build.sh +++ b/build.sh @@ -26,7 +26,7 @@ else DOCKER="sudo docker" fi -IMAGE="hbpmip/portal-backend" +IMAGE="kkech/portal_backend" VCS_REF=$(git describe --tags --dirty) VERSION=$(git describe --tags --dirty) @@ -37,6 +37,9 @@ docker build --build-arg BUILD_DATE=$(date -Iseconds) \ --tag "$IMAGE:$VERSION" \ . +docker push kkech/portal_backend:latest + + BUGSNAG_KEY="" eval $(grep -e "^\\s*BUGSNAG_KEY" Dockerfile | tr '\\' ' ') diff --git a/pom.xml b/pom.xml index 33287a67e..aa37b02bc 100644 --- a/pom.xml +++ b/pom.xml @@ -249,6 +249,35 @@ <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> + <artifactId>blend4j</artifactId> + <version>0.2.0</version> + </dependency> + + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>retrofit</artifactId> + <version>2.5.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> + </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> + </dependency> + </dependencies> <build> diff --git a/src/main/java/eu/hbp/mip/controllers/GalaxyAPI.java b/src/main/java/eu/hbp/mip/controllers/GalaxyAPI.java new file mode 100644 index 000000000..b78b60d34 --- /dev/null +++ b/src/main/java/eu/hbp/mip/controllers/GalaxyAPI.java @@ -0,0 +1,470 @@ +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.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import eu.hbp.mip.controllers.retrofit.RetroFitGalaxyClients; +import eu.hbp.mip.controllers.retrofit.RetrofitClientInstance; +import eu.hbp.mip.dto.ErrorResponse; +import eu.hbp.mip.dto.GetWorkflowResultsFromGalaxyDtoResponse; +import eu.hbp.mip.dto.PostWorkflowToGalaxyDtoResponse; +import eu.hbp.mip.dto.StringDtoResponse; +import eu.hbp.mip.helpers.GenParameters; +import eu.hbp.mip.helpers.LogHelper; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.*; +import retrofit2.Call; +import retrofit2.Response; + +import java.io.IOException; +import java.util.*; + +@RestController +@RequestMapping("/galaxyApi/") +class GalaxyAPI { + + private static final Logger logger = LoggerFactory.getLogger(GalaxyAPI.class); + + //The galaxy URL + private final String url = GenParameters.getGenParamInstance().getGalaxyURL(); + + //The galaxy ApiKey + private final String apiKey = GenParameters.getGenParamInstance().getGalaxyApiKey(); + + /** + * Test if integration works. + * + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "getTestIntegration", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getTestIntegration(@AuthenticationPrincipal UserDetails userDetails){ + logger.info(LogHelper.logUser(userDetails) + "Get Test Integration called"); + return ResponseEntity.ok(new StringDtoResponse("success")); + } + + /** + * Get Galaxy Reverse Proxy basic access token. + * + * @return Return a @{@link ResponseEntity} with the token. + */ + @RequestMapping(method = RequestMethod.GET, value = "getGalaxyBasicAccessToken", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getGalaxyBasicAccessToken(@AuthenticationPrincipal UserDetails userDetails){ + logger.info(LogHelper.logUser(userDetails) + "Get Galaxy Basic Access Token called"); + String username = GenParameters.getGenParamInstance().getGalaxyReverseProxyUsername(); + String password = GenParameters.getGenParamInstance().getGalaxyReverseProxyPassword(); + + String stringEncoded = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + logger.info(LogHelper.logUser(userDetails) + "Get Galaxy Basic Access Token completed"); + return ResponseEntity.ok(username + ":" + password); + // return ResponseEntity.ok(new StringDtoResponse(stringEncoded)); + } + + /** + * Get all the workflows with few details. + * + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "getWorkflows", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getWorkflows(@AuthenticationPrincipal UserDetails userDetails) { + logger.info(LogHelper.logUser(userDetails) + "Get workflows called"); + + final GalaxyInstance instance = GalaxyInstanceFactory.get(url, apiKey); + final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); + + ArrayList<Workflow> workflowArrayList = new ArrayList<>(); + workflowArrayList.addAll(workflowsClient.getWorkflows()); + logger.info(LogHelper.logUser(userDetails) + "Get workflows completed"); + + return ResponseEntity.ok(workflowArrayList); + } + + /** + * Get details for a specific workflow. + * + * @param id : The id as @{@link String} for the specific workflow. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getDetailWorkflow/{id}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getDetailWorkflow(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id) { + logger.info(LogHelper.logUser(userDetails) + "Get detail workflow called"); + + final GalaxyInstance instance = GalaxyInstanceFactory.get(url, apiKey); + final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); + + Workflow matchingWorkflow = null; + for(Workflow workflow : workflowsClient.getWorkflows()) { + if(workflow.getId().equals(id)) { + matchingWorkflow = workflow; + } + } + if(matchingWorkflow == null){ + logger.error(LogHelper.logUser(userDetails) + "Get detail workflow could not find workflow with id : " + id); + return ResponseEntity.notFound().build(); + } + final WorkflowDetails workflowDetails = workflowsClient.showWorkflow(matchingWorkflow.getId()); + logger.info(LogHelper.logUser(userDetails) + "Get detail workflow completed"); + + return ResponseEntity.ok(workflowDetails); + } + + /** + * Get all the workflows with details. + * + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "getAllWorkflowWithDetails", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getAllWorkflowWithDetails(@AuthenticationPrincipal UserDetails userDetails) { + logger.info(LogHelper.logUser(userDetails) + "Get all workflow with details called"); + + final GalaxyInstance instance = GalaxyInstanceFactory.get(url, apiKey); + final WorkflowsClient workflowsClient = instance.getWorkflowsClient(); + + List<Workflow> workflowList = new ArrayList<Workflow>(); + for(Workflow workflow : workflowsClient.getWorkflows()) { + workflowList.add(workflow); + } + + List<WorkflowDetails> workflowDetailsList = new ArrayList<>(); + for(Workflow workflow : workflowList){ + workflowDetailsList.add(workflowsClient.showWorkflow(workflow.getId())); + } + logger.info(LogHelper.logUser(userDetails) + "Get all workflow with details completed"); + + return ResponseEntity.ok(workflowDetailsList); + } + + /** + * Invoke a workflow. + * + * @param id : The id as @{@link String} of the workflow. + * @param httpEntity : The @{@link HttpEntity} to get the body of the request which is the parameter of the workflow. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.POST, value = "/runWorkflow/{id}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity runWorkflow(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id, HttpEntity<String> httpEntity) { + logger.info(LogHelper.logUser(userDetails) + "Run workflow called"); + + //In order to parse Json with undefined number of value/key + String json = httpEntity.getBody(); + JSONObject jObject = null; + try { + jObject = new JSONObject(json); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot parse JSON", e); + } + Map<String,String> allJsonParams = new HashMap<String,String>(); + Iterator iter = jObject.keys(); + while(iter.hasNext()){ + String key = (String)iter.next(); + String value = null; + try { + value = jObject.getString(key); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot parse JSON", e); + } + logger.info(LogHelper.logUser(userDetails) + "Put to map: " + key + " : " + value); + allJsonParams.put(key,value); + } + + StringBuffer stringBuffer = new StringBuffer("{\n" + + "\t\"inputs\": {\n"); + for (Map.Entry<String, String> entry : allJsonParams.entrySet()) { + stringBuffer.append("\t\t\"" + entry.getKey() + "\" " + " : \"" + entry.getValue() + "\",\n"); + logger.debug(LogHelper.logUser(userDetails) + entry.getKey() + "/" + entry.getValue()); + } + //Remove Last Comma + stringBuffer.deleteCharAt(stringBuffer.length() - 2); + stringBuffer.append("\t}\n"); + stringBuffer.append("}"); + logger.info(LogHelper.logUser(userDetails) + stringBuffer.toString()); + + JsonObject jsonObject = new JsonParser().parse(stringBuffer.toString()).getAsJsonObject(); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<PostWorkflowToGalaxyDtoResponse> call = service.postWorkflowToGalaxy(id, apiKey, jsonObject); + + PostWorkflowToGalaxyDtoResponse postWorkflowToGalaxyDtoResponse = null; + try { + Response<PostWorkflowToGalaxyDtoResponse> response = call.execute(); + if(response.code() >= 400){ + //Value are read it from streams. + Integer codeErr = response.code(); + String msgErr = response.errorBody().string(); + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + codeErr + "" + " with body: " + msgErr); + logger.info("---" + msgErr); + JSONObject jObjectError = null; + try { + jObjectError = new JSONObject(msgErr); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot parse Error JSON", e); + } + logger.info(jObjectError.toString()); + String errMsg = jObjectError.get("err_msg").toString(); + String errCode = jObjectError.get("err_code").toString(); + + response.errorBody(); + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(new ErrorResponse(errMsg,errCode)); + } + postWorkflowToGalaxyDtoResponse = response.body(); + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(new ErrorResponse("An error has been occurred","99")); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot find field in Error Json", e); + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(new ErrorResponse("An error has been occurred","99")); + } + logger.info(LogHelper.logUser(userDetails) + "Run workflow completed"); + + return ResponseEntity.ok(postWorkflowToGalaxyDtoResponse); + } + + /** + * Get the status of a specific workflow. + * + * @param id : The id as @{@link String} of the workflow. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getWorkflowStatus/{id}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getWorkflowStatus(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id) { + logger.info(LogHelper.logUser(userDetails) + "Get workflow status called"); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<Object> call = service.getWorkflowStatusFromGalaxy(id,apiKey); + + String jsonString = null; + try { + Response<Object> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + jsonString = new Gson().toJson(response.body()); + logger.info(LogHelper.logUser(userDetails) + jsonString); + + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + logger.info(LogHelper.logUser(userDetails) + "Get workflow status completed"); + + return ResponseEntity.ok(jsonString); + } + + /** + * Get the status of a multiple workflows. + * @param httpEntity : The @{@link HttpEntity} to get the body of the request which is the workflow ID. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getMultipleWorkflowStatus", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getMultipleWorkflowStatus(@AuthenticationPrincipal UserDetails userDetails, HttpEntity<String> httpEntity) { + logger.info(LogHelper.logUser(userDetails) + "Get Multiple workflow status called"); + + //In order to parse Json with undefined number of value/key + String json = httpEntity.getBody(); + JSONObject jObject = null; + try { + jObject = new JSONObject(json); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot parse JSON", e); + } + Map<String,String> allJsonParams = new HashMap<String,String>(); + Iterator iter = jObject.keys(); + + while(iter.hasNext()){ + String key = (String)iter.next(); + String value = null; + try { + value = jObject.getString(key); + System.out.println(key + ":" + value); + } catch (JSONException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot parse JSON", e); + } + logger.info(LogHelper.logUser(userDetails) + "Put to map: " + key + " : " + value); + allJsonParams.put(key,value); + } + + StringBuffer stringBuffer = new StringBuffer(); + for (Map.Entry<String, String> entry : allJsonParams.entrySet()) { + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<Object> call = service.getWorkflowStatusFromGalaxy(entry.getValue(),apiKey); + + String jsonString = null; + try { + Response<Object> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + jsonString = new Gson().toJson(response.body()); + logger.info(LogHelper.logUser(userDetails) + jsonString); + stringBuffer.append(jsonString + ","); + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + } + stringBuffer.deleteCharAt(stringBuffer.length() - 1); + logger.info(LogHelper.logUser(userDetails) + "Get Multiple workflow status completed"); + return ResponseEntity.ok(stringBuffer.toString()); + } + + /** + * Get the result of a specific workflow. + * + * @param id : The id as @{@link String} of the workflow. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getWorkflowResults/{id}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getWorkflowResults(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id) { + logger.info(LogHelper.logUser(userDetails) + "Get workflow results called"); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<List<GetWorkflowResultsFromGalaxyDtoResponse>> call = service.getWorkflowResultsFromGalaxy(id,apiKey); + + List<GetWorkflowResultsFromGalaxyDtoResponse> getWorkflowResultsFromGalaxyDtoResponsesList = null; + try { + Response<List<GetWorkflowResultsFromGalaxyDtoResponse>> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + getWorkflowResultsFromGalaxyDtoResponsesList = response.body(); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + logger.info(LogHelper.logUser(userDetails) + "Get workflow results completed"); + + return ResponseEntity.ok(getWorkflowResultsFromGalaxyDtoResponsesList); + } + + /** + * Get the result body of a specific workflow. + * + * @param id : The id as @{@link String} of the workflow. + * @param contentId : The content id as @{@link String}. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getWorkflowResultsBody/{id}/contents/{contentId}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getWorkflowResultsBody(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id, @PathVariable String contentId) { + logger.info(LogHelper.logUser(userDetails) + "Get workflow results body called"); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<Object> call = service.getWorkflowResultsBodyFromGalaxy(id,contentId,apiKey); + + String jsonString = null; + try { + Response<Object> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + jsonString = new Gson().toJson(response.body()); + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + logger.info(LogHelper.logUser(userDetails) + "Get workflow results body completed"); + + return ResponseEntity.ok(jsonString); + } + + /** + * Get the result body of a specific workflow with details. + * + * @param id : The id as @{@link String} of the workflow. + * @param contentId : The content id as @{@link String}. + * @return Return a @{@link ResponseEntity}. + */ + @RequestMapping(method = RequestMethod.GET, value = "/getWorkflowResultsDetails/{id}/contents/{contentId}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getWorkflowResultsDetails(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id, @PathVariable String contentId) { + logger.info(LogHelper.logUser(userDetails) + "Get workflow results details called"); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<Object> call = service.getWorkflowResultsDetailsFromGalaxy(id,contentId,apiKey); + + String jsonString = null; + try { + Response<Object> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + jsonString = new Gson().toJson(response.body()); + System.out.println(jsonString); + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + logger.info(LogHelper.logUser(userDetails) + "Get workflow results details completed"); + + return ResponseEntity.ok(jsonString); + } + + @RequestMapping(method = RequestMethod.GET, value = "getErrorMessageOfWorkflow/{id}", produces = "application/json") + @ResponseStatus(value = HttpStatus.OK) + public ResponseEntity getErrorMessageOfWorkflow(@AuthenticationPrincipal UserDetails userDetails, @PathVariable String id) { + logger.info(LogHelper.logUser(userDetails) + "Get error message of workflow called"); + + RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class); + Call<Object> call = service.getErrorMessageOfWorkflowFromGalaxy(id,apiKey); + + String fullError = null; + String returnError = null; + try { + Response<Object> response = call.execute(); + if(response.code() >= 400){ + logger.error(LogHelper.logUser(userDetails) + "Resonse code: " + response.code() + "" + " with body: " + response.errorBody().string()); + return ResponseEntity.badRequest().build(); + } + JsonParser parser = new JsonParser(); + String jsonString = new Gson().toJson(response.body()); + System.out.println(jsonString); + JsonElement jsonElement = parser.parse(jsonString); + JsonObject rootObject = jsonElement.getAsJsonObject(); + fullError = rootObject.get("stderr").getAsString(); + String[] arrOfStr = fullError.split("ValueError", 0); + String specError = arrOfStr[arrOfStr.length-1]; + returnError = specError.substring(1); + + logger.info(LogHelper.logUser(userDetails) + "----" + response.body() + "----" + response.code()); + } catch (IOException e) { + logger.error(LogHelper.logUser(userDetails) + "Cannot make the call to Galaxy API", e); + } + + logger.info(LogHelper.logUser(userDetails) + "Get error message of workflow completed"); + + return ResponseEntity.ok(returnError); + } +} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java b/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java new file mode 100644 index 000000000..23143bf89 --- /dev/null +++ b/src/main/java/eu/hbp/mip/controllers/retrofit/RetroFitGalaxyClients.java @@ -0,0 +1,30 @@ +package eu.hbp.mip.controllers.retrofit; + +import com.google.gson.JsonObject; +import eu.hbp.mip.dto.GetWorkflowResultsFromGalaxyDtoResponse; +import eu.hbp.mip.dto.PostWorkflowToGalaxyDtoResponse; +import retrofit2.Call; +import retrofit2.http.*; + +import java.util.List; + +public interface RetroFitGalaxyClients { + + @POST("workflows/{workflowId}/invocations") + Call<PostWorkflowToGalaxyDtoResponse> postWorkflowToGalaxy(@Path("workflowId") String workflowId, @Query("key") String key, @Body JsonObject body); + + @GET("histories/{historyId}") + Call<Object> getWorkflowStatusFromGalaxy(@Path("historyId") String historyId, @Query("key") String key); + + @GET("histories/{historyId}/contents") + Call<List<GetWorkflowResultsFromGalaxyDtoResponse>> getWorkflowResultsFromGalaxy(@Path("historyId") String historyId, @Query("key") String key); + + @GET("histories/{historyId}/contents/{contentId}/display") + Call<Object> getWorkflowResultsBodyFromGalaxy(@Path("historyId") String historyId, @Path("contentId") String contentId, @Query("key") String key); + + @GET("histories/{historyId}/contents/{contentId}") + Call<Object> getWorkflowResultsDetailsFromGalaxy(@Path("historyId") String historyId, @Path("contentId") String contentId, @Query("key") String key); + + @GET("jobs/{jobId}?full=true") + Call<Object> getErrorMessageOfWorkflowFromGalaxy(@Path("jobId") String historyId, @Query("key") String key); +} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/controllers/retrofit/RetrofitClientInstance.java b/src/main/java/eu/hbp/mip/controllers/retrofit/RetrofitClientInstance.java new file mode 100644 index 000000000..46328df33 --- /dev/null +++ b/src/main/java/eu/hbp/mip/controllers/retrofit/RetrofitClientInstance.java @@ -0,0 +1,30 @@ +package eu.hbp.mip.controllers.retrofit; + +import eu.hbp.mip.helpers.GenParameters; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class RetrofitClientInstance { + + private static Retrofit retrofit; + + private static final String BASE_URL = GenParameters.getGenParamInstance().getGalaxyURL() + "/api/"; + + public static Retrofit getRetrofitInstance() { + if (retrofit == null) { + + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); + + retrofit = new retrofit2.Retrofit.Builder() + .baseUrl(BASE_URL) + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + } + return retrofit; + } +} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/dto/ErrorResponse.java b/src/main/java/eu/hbp/mip/dto/ErrorResponse.java new file mode 100644 index 000000000..1051340ac --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/ErrorResponse.java @@ -0,0 +1,41 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +import com.google.gson.annotations.SerializedName; + +public class ErrorResponse { + + @SerializedName("err_msg") + String errMsg; + + @SerializedName("err_code") + String errCode; + + public ErrorResponse() { + } + + public ErrorResponse(String errMsg, String errCode) { + this.errMsg = errMsg; + this.errCode = errCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } + + public String getErrCode() { + return errCode; + } + + public void setErrCode(String errCode) { + this.errCode = errCode; + } +} diff --git a/src/main/java/eu/hbp/mip/dto/GetWorkflowResultsFromGalaxyDtoResponse.java b/src/main/java/eu/hbp/mip/dto/GetWorkflowResultsFromGalaxyDtoResponse.java new file mode 100644 index 000000000..a81660ac4 --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/GetWorkflowResultsFromGalaxyDtoResponse.java @@ -0,0 +1,208 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class GetWorkflowResultsFromGalaxyDtoResponse { + + @SerializedName("history_content_type") + private String historyContentType; + @SerializedName("update_time") + private String updateTime; + @SerializedName("name") + private String name; + @SerializedName("extension") + private String extension; + @SerializedName("type_id") + private String typeId; + @SerializedName("deleted") + private Boolean deleted; + @SerializedName("history_id") + private String historyId; + @SerializedName("tags") + private List<Object> tags = null; + @SerializedName("id") + private String id; + @SerializedName("visible") + private Boolean visible; + @SerializedName("state") + private String state; + @SerializedName("create_time") + private String createTime; + @SerializedName("hid") + private Integer hid; + @SerializedName("url") + private String url; + @SerializedName("dataset_id") + private String datasetId; + @SerializedName("type") + private String type; + @SerializedName("purged") + private Boolean purged; + + public GetWorkflowResultsFromGalaxyDtoResponse() { + } + + public GetWorkflowResultsFromGalaxyDtoResponse(String historyContentType, String updateTime, String name, String extension, String typeId, Boolean deleted, String historyId, List<Object> tags, String id, Boolean visible, String state, String createTime, Integer hid, String url, String datasetId, String type, Boolean purged) { + this.historyContentType = historyContentType; + this.updateTime = updateTime; + this.name = name; + this.extension = extension; + this.typeId = typeId; + this.deleted = deleted; + this.historyId = historyId; + this.tags = tags; + this.id = id; + this.visible = visible; + this.state = state; + this.createTime = createTime; + this.hid = hid; + this.url = url; + this.datasetId = datasetId; + this.type = type; + this.purged = purged; + } + + public String getHistoryContentType() { + return historyContentType; + } + + public void setHistoryContentType(String historyContentType) { + this.historyContentType = historyContentType; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getExtension() { + return extension; + } + + public void setExtension(String extension) { + this.extension = extension; + } + + public String getTypeId() { + return typeId; + } + + public void setTypeId(String typeId) { + this.typeId = typeId; + } + + public Boolean getDeleted() { + return deleted; + } + + public void setDeleted(Boolean deleted) { + this.deleted = deleted; + } + + public String getHistoryId() { + return historyId; + } + + public void setHistoryId(String historyId) { + this.historyId = historyId; + } + + public List<Object> getTags() { + return tags; + } + + public void setTags(List<Object> tags) { + this.tags = tags; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Boolean getVisible() { + return visible; + } + + public void setVisible(Boolean visible) { + this.visible = visible; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public Integer getHid() { + return hid; + } + + public void setHid(Integer hid) { + this.hid = hid; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDatasetId() { + return datasetId; + } + + public void setDatasetId(String datasetId) { + this.datasetId = datasetId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Boolean getPurged() { + return purged; + } + + public void setPurged(Boolean purged) { + this.purged = purged; + } +} + diff --git a/src/main/java/eu/hbp/mip/dto/JwtResponse.java b/src/main/java/eu/hbp/mip/dto/JwtResponse.java new file mode 100644 index 000000000..2007a8f60 --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/JwtResponse.java @@ -0,0 +1,31 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +public class JwtResponse { + private String token; + private String type = "Bearer"; + + public JwtResponse(String accessToken) { + this.token = accessToken; + } + + public String getAccessToken() { + return token; + } + + public void setAccessToken(String accessToken) { + this.token = accessToken; + } + + public String getTokenType() { + return type; + } + + public void setTokenType(String tokenType) { + this.type = tokenType; + } +} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/dto/LoginDto.java b/src/main/java/eu/hbp/mip/dto/LoginDto.java new file mode 100644 index 000000000..5fada1e1f --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/LoginDto.java @@ -0,0 +1,36 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +import org.hibernate.validator.constraints.NotBlank; + +import javax.validation.constraints.Size; + +public class LoginDto { + @NotBlank + @Size(min=3, max = 60) + private String username; + + @NotBlank + @Size(min = 6, max = 40) + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java b/src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java new file mode 100644 index 000000000..bc504c5f5 --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/PostWorkflowToGalaxyDtoResponse.java @@ -0,0 +1,93 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +import com.google.gson.annotations.SerializedName; + +public class PostWorkflowToGalaxyDtoResponse { + + + @SerializedName("update_time") + String updateTime; + String uuid; + @SerializedName("history_id") + String historyId; + String stake; + @SerializedName("workflow_id") + String workflowId; + @SerializedName("model_class") + String modelClass; + String id; + + public PostWorkflowToGalaxyDtoResponse() { + } + + public PostWorkflowToGalaxyDtoResponse(String updateTime, String uuid, String historyId, String stake, String workflowId, String modelClass, String id) { + this.updateTime = updateTime; + this.uuid = uuid; + this.historyId = historyId; + this.stake = stake; + this.workflowId = workflowId; + this.modelClass = modelClass; + this.id = id; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHistoryId() { + return historyId; + } + + public void setHistoryId(String historyId) { + this.historyId = historyId; + } + + public String getStake() { + return stake; + } + + public void setStake(String stake) { + this.stake = stake; + } + + public String getWorkflowId() { + return workflowId; + } + + public void setWorkflowId(String workflowId) { + this.workflowId = workflowId; + } + + public String getModelClass() { + return modelClass; + } + + public void setModelClass(String modelClass) { + this.modelClass = modelClass; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/eu/hbp/mip/dto/SignUpDto.java b/src/main/java/eu/hbp/mip/dto/SignUpDto.java new file mode 100644 index 000000000..c7129853c --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/SignUpDto.java @@ -0,0 +1,73 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +import org.hibernate.validator.constraints.Email; +import org.hibernate.validator.constraints.NotBlank; + +import javax.validation.constraints.Size; +import java.util.Set; + +public class SignUpDto { + @NotBlank + @Size(min = 3, max = 50) + private String name; + + @NotBlank + @Size(min = 3, max = 50) + private String username; + + @NotBlank + @Size(max = 60) + @Email + private String email; + + private Set<String> role; + + @NotBlank + @Size(min = 6, max = 40) + private String password; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + 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 String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Set<String> getRole() { + return this.role; + } + + public void setRole(Set<String> role) { + this.role = role; + } +} diff --git a/src/main/java/eu/hbp/mip/dto/StringDtoResponse.java b/src/main/java/eu/hbp/mip/dto/StringDtoResponse.java new file mode 100644 index 000000000..ce5eb9700 --- /dev/null +++ b/src/main/java/eu/hbp/mip/dto/StringDtoResponse.java @@ -0,0 +1,26 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.dto; + +public class StringDtoResponse { + + private String response; + + public StringDtoResponse() { + } + + public StringDtoResponse(String response) { + this.response = response; + } + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } +} diff --git a/src/main/java/eu/hbp/mip/helpers/GenParameters.java b/src/main/java/eu/hbp/mip/helpers/GenParameters.java new file mode 100644 index 000000000..92de05524 --- /dev/null +++ b/src/main/java/eu/hbp/mip/helpers/GenParameters.java @@ -0,0 +1,129 @@ +/* + * Developed by Kechagias Konstantinos. + * Copyright (c) 2019. MIT License + */ + +package eu.hbp.mip.helpers; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class GenParameters { + + private static final Logger logger = LoggerFactory.getLogger(GenParameters.class); + + private static GenParameters genParams; + + private String jwtSecret; + + private String jwtIssuer; + + private String galaxyURL; + + private String galaxyApiKey; + + private String galaxyReverseProxyUsername; + + private String galaxyReverseProxyPassword; + + private GenParameters(){ + + } + + public static GenParameters getGenParamInstance() { + if (genParams == null) { + logger.info("->>>>>>>Reading Enviroment variables"); + genParams = new GenParameters(); + + genParams.setJwtSecret(System.getenv("JWT_SECRET")); + genParams.setJwtIssuer(System.getenv("JWT_ISSUER")); + genParams.setGalaxyURL(System.getenv("GALAXY_URL")); + genParams.setGalaxyApiKey(System.getenv("GALAXY_API_KEY")); + genParams.setGalaxyReverseProxyUsername(System.getenv("GALAXY_REVERSE_PROXY_USERNAME")); + genParams.setGalaxyReverseProxyPassword(System.getenv("GALAXY_REVERSE_PROXY_PASSWORD")); + + + //If environment variable not exists read from file. + if (genParams.getJwtSecret() == null){ + throw new RuntimeException("Cannot find Enviroment Variables"); +// logger.info("->>>>>>>Reading from file"); +// +// File file = null; +// try { +// file = new ClassPathResource("config.properties").getFile(); +// InputStream input = new FileInputStream(file); +// Properties prop = new Properties(); +// +// // load a properties file +// prop.load(input); +// +// // get the property value and print it out +// genParams.setJwtSecret(prop.getProperty("jwtSecret")); +// genParams.setJwtIssuer(prop.getProperty("jwtIssuer")); +// genParams.setGalaxyURL(prop.getProperty("galaxyURL")); +// genParams.setGalaxyApiKey(prop.getProperty("galaxyApiKey")); +// genParams.setGalaxyReverseProxyUsername(prop.getProperty("galaxyReverseProxyUsername")); +// genParams.setGalaxyReverseProxyPassword(prop.getProperty("galaxyReverseProxyPassword")); +// } catch (IOException e) { +// logger.error("Cannot initialize GenParameters from config file", e); +// } + } + } + return genParams; + } + + public String getJwtSecret() { + return jwtSecret; + } + + private void setJwtSecret(String jwtSecret) { + this.jwtSecret = jwtSecret; + } + + public String getJwtIssuer() { + return jwtIssuer; + } + + private void setJwtIssuer(String jwtIssuer) { + this.jwtIssuer = jwtIssuer; + } + + public String getGalaxyURL() { + return galaxyURL; + } + + private void setGalaxyURL(String galaxyURL) { + this.galaxyURL = galaxyURL; + } + + public String getGalaxyApiKey() { + return galaxyApiKey; + } + + private void setGalaxyApiKey(String galaxyApiKey) { + this.galaxyApiKey = galaxyApiKey; + } + + public String getGalaxyReverseProxyUsername() { + return galaxyReverseProxyUsername; + } + + public void setGalaxyReverseProxyUsername(String galaxyReverseProxyUsername) { + this.galaxyReverseProxyUsername = galaxyReverseProxyUsername; + } + + public String getGalaxyReverseProxyPassword() { + return galaxyReverseProxyPassword; + } + + public void setGalaxyReverseProxyPassword(String galaxyReverseProxyPassword) { + this.galaxyReverseProxyPassword = galaxyReverseProxyPassword; + } +} \ No newline at end of file diff --git a/src/main/java/eu/hbp/mip/helpers/LogHelper.java b/src/main/java/eu/hbp/mip/helpers/LogHelper.java new file mode 100644 index 000000000..9fa950c2d --- /dev/null +++ b/src/main/java/eu/hbp/mip/helpers/LogHelper.java @@ -0,0 +1,10 @@ +package eu.hbp.mip.helpers; + + +import org.springframework.security.core.userdetails.UserDetails; + +public class LogHelper { + public static String logUser(UserDetails userDetails){ + return ("User(subject)->User(" + userDetails.getUsername() + ") : "); + } +} \ No newline at end of file -- GitLab