From ef589336ade50127870c0ab1121dc038233731e4 Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:42:59 +0200 Subject: [PATCH 01/49] Create README.md --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c5c5cd --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# vp-dp-backend + + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Configuration](#configuration) +- [Features](#features) +- [Examples](#examples) +- [Troubleshooting](#troubleshooting) +- [License](#license) +- [Contact Information](#contact-information) +- [Acknowledgments](#acknowledgments) + +## Installation + + +## Usage + +## Configuration + +## Features + +## Examples + +## Troubleshooting + +## License + +## Contact Information + +## Acknowledgments + + From a69ee09a61c4797f09d0193f31f1dfb84c0ddab7 Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:57:14 +0200 Subject: [PATCH 02/49] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From ac1fa4253845b47939263506aa65769759d2b10f Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:01:37 +0200 Subject: [PATCH 03/49] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7c5c5cd..897e885 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ ## Troubleshooting ## License +This project is licensed under the (Apache License 2.0)[https://github.com/ejp-rd-vp/vp-dp-backend/blob/develop/LICENSE]. ## Contact Information From a962f20c0583169db71b285e53fccdb0cac9b87b Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:02:23 +0200 Subject: [PATCH 04/49] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 897e885..537aee6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ ## Troubleshooting ## License -This project is licensed under the (Apache License 2.0)[https://github.com/ejp-rd-vp/vp-dp-backend/blob/develop/LICENSE]. +This project is licensed under the [Apache License 2.0](https://github.com/ejp-rd-vp/vp-dp-backend/blob/develop/LICENSE). ## Contact Information From 83b0f56d4242602e1a12dc9e01d7d8463166bf3a Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Fri, 25 Aug 2023 14:00:01 +0200 Subject: [PATCH 05/49] #1 - Documentation Updates for OpenAPI Annotations - Added OAS3 annotations using io.swagger.v3.oas.annotations package to describe the API metadata, operations, parameters, and responses. --- .../vpdpbackend/VpDpBackendApplication.java | 25 +++++++++++++ .../disease/v1/DiseaseController.java | 27 +++++++++++++- .../hierarchy/v1/HierarchyController.java | 32 +++++++++++++++++ .../mapping/v1/MappingController.java | 27 +++++++++++++- .../resource/v1/ResourceController.java | 24 +++++++++++++ .../v1/ResourceMonitoringController.java | 25 ++++++++++++- .../search/v1/SearchController.java | 35 +++++++++++++++++++ .../v1/SearchAutocompleteController.java | 18 ++++++++++ 8 files changed, 210 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java index ad2a0f8..e6109a9 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java @@ -1,8 +1,33 @@ package org.ejprarediseases.vpdpbackend; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.info.License; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +@OpenAPIDefinition( + info = @Info( + title = "VP-Portal Backend", + description = "The EJP VP-Portal Backend serves as the foundational engine powering " + + "the EJP VP-Portal ecosystem. It offers an array of sophisticated functionalities, " + + "including advanced disease search capabilities, comprehensive disease hierarchy retrieval, " + + "precision gene mapping, efficient search autocompletion, robust resource monitoring " + + "service, seamless resource notification service, and an array of other distinctive " + + "features. These capabilities collectively aim to ensure an unparalleled user experience " + + "within the VP-Portal environment.", + version = "v0.1.0", + license = @License( + name = "Apache License 2.0", + url = "https://github.com/ejp-rd-vp/vp-dp-backend/blob/develop/LICENSE" + ), + contact = @Contact( + name = "VP-Portal Team", + url = "https://vp.ejprarediseases.org/" + ) + ) +) @SpringBootApplication public class VpDpBackendApplication { diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseController.java b/src/main/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseController.java index c771ab0..1328646 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseController.java @@ -1,5 +1,12 @@ package org.ejprarediseases.vpdpbackend.disease.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.ejprarediseases.vpdpbackend.disease.v1.model.Disease; import org.ejprarediseases.vpdpbackend.disease.v1.model.DiseaseDto; @@ -15,6 +22,7 @@ @RequestMapping("v1/disease") @RequiredArgsConstructor @Validated +@Tag(name = "Disease", description = "Endpoints for retrieving disease information") public class DiseaseController { private final DiseaseService service; @@ -32,8 +40,25 @@ public class DiseaseController { * @return A ResponseEntity containing the DiseaseDto if found, * or an empty response with HTTP status 404 if not found. */ + @Operation( + summary = "Get Disease by OrphaCode", + description = "Retrieves disease information based on the provided OrphaCode." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Disease information retrieved successfully", + content = @Content(schema = @Schema(implementation = DiseaseDto.class)) + ), + @ApiResponse( + responseCode = "404", + description = "Disease not found" + ) + }) @GetMapping() - public ResponseEntity getDiseaseByOrphaCode(@RequestParam String orphaCode) { + public ResponseEntity getDiseaseByOrphaCode( + @Parameter(description = "OrphaCode representing the disease to be retrieved") + @RequestParam String orphaCode) { try { Disease disease = service.getDiseaseByOrphaCode(orphaCode); DiseaseDto diseaseDto = service.diseaseToDto(disease); diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java b/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java index 233e7a3..ada3aa0 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java @@ -1,6 +1,12 @@ package org.ejprarediseases.vpdpbackend.hierarchy.v1; import com.fasterxml.jackson.core.JsonProcessingException; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.ConstraintViolationException; import jakarta.validation.Valid; import jakarta.validation.constraints.Min; @@ -25,6 +31,7 @@ @RequestMapping("v1/hierarchy") @RequiredArgsConstructor @Validated +@Tag(name = "Hierarchy", description = "Endpoints for handling orphanet hierarchy operations") public class HierarchyController { private final HierarchyService hierarchyService; @@ -60,10 +67,35 @@ ResponseEntity handleMissingServletRequestParameterException(MissingServ * @param numberOfLevels The number of hierarchy levels to retrieve (default: 100). * @return ResponseEntity containing the hierarchical representation as a list of OrphaCodeHierarchyDto objects. */ + @Operation( + summary = "Get OrphaCode Hierarchy", + description = "Retrieves the hierarchical representation of the OrphaCode." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "OrphaCode hierarchy retrieved successfully", + content = @io.swagger.v3.oas.annotations.media.Content( + array = @ArraySchema(schema = + @io.swagger.v3.oas.annotations.media.Schema(implementation = OrphaCodeHierarchyDto.class)) + ) + ), + @ApiResponse( + responseCode = "400", + description = "Bad request" + ), + @ApiResponse( + responseCode = "406", + description = "Not Acceptable" + ) + }) @GetMapping() public ResponseEntity getOrphaCodeHierarchy( + @Parameter(description = "List of hierarchical ways (e.g. UP or DOWN) to be used") @RequestParam @Valid List ways, + @Parameter(description = "OrphaCode for which the hierarchy needs to be retrieved") @RequestParam @Valid String orphaCode, + @Parameter(description = "Number of hierarchy levels to retrieve (default: 100)", example = "100") @RequestParam(required = false, defaultValue = "100") @Valid @Min(1) int numberOfLevels ) { List response = null; diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingController.java b/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingController.java index 4548138..ceccfc8 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingController.java @@ -1,5 +1,12 @@ package org.ejprarediseases.vpdpbackend.mapping.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.ConstraintViolationException; import jakarta.validation.Valid; import jakarta.validation.constraints.Size; @@ -13,6 +20,7 @@ @RestController @Validated @RequestMapping("v1/mapping") +@Tag(name = "Mapping", description = "Endpoints for gene mapping") public class MappingController { MappingService mappingService; @@ -51,8 +59,25 @@ ResponseEntity handleMissingServletRequestParameterException(MissingServ * @param hgncId The HGNC (HUGO Gene Nomenclature Committee) ID of the gene to fetch mapping for. * @return A ResponseEntity containing the GeneMapping object as the response body with HTTP status OK (200) */ + @Operation( + summary = "Get Gene Mapping", + description = "Retrieves gene mapping information for the specified HGNC ID." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Gene mapping retrieved successfully", + content = @Content(schema = @Schema(implementation = GeneMapping.class)) + ), + @ApiResponse( + responseCode = "400", + description = "Bad request" + ) + }) @GetMapping("/gene/{hgncId}") - public ResponseEntity getGeneMapping(@PathVariable @Valid @Size(min = 1) String hgncId) { + public ResponseEntity getGeneMapping( + @Parameter(description = "HGNC ID of the gene to fetch mapping for") + @PathVariable @Valid @Size(min = 1) String hgncId) { return new ResponseEntity<>(mappingService.getGeneMapping(hgncId), HttpStatus.OK); } } diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceController.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceController.java index 80978fd..618432c 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceController.java @@ -1,6 +1,11 @@ package org.ejprarediseases.vpdpbackend.resource.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; import org.springframework.http.HttpStatus; @@ -15,6 +20,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("v1/resources") +@Tag(name = "Resources", description = "Endpoints for retrieving resources") public class ResourceController { private final ResourceService resourceService; @@ -27,6 +33,24 @@ public class ResourceController { * If there's an error reading the resources file, returns a ResponseEntity * with the error message in the response body and HTTP status 406 (NOT_ACCEPTABLE). */ + @Operation( + summary = "Get All Resources", + description = "Retrieves a list of all resources." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Resources retrieved successfully", + content = @io.swagger.v3.oas.annotations.media.Content( + array = @ArraySchema(schema = + @io.swagger.v3.oas.annotations.media.Schema(implementation = Resource.class)) + ) + ), + @ApiResponse( + responseCode = "406", + description = "Not Acceptable" + ) + }) @GetMapping() public ResponseEntity getResources() { List resources; diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringController.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringController.java index 58ca2b2..4319057 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringController.java @@ -1,5 +1,12 @@ package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Period; import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.ResourceMonitoringSummary; @@ -15,6 +22,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("v1/monitoring") +@Tag(name = "Monitoring", description = "Endpoints for resource monitoring") public class ResourceMonitoringController { private final ResourceMonitoringService monitoringService; @@ -29,8 +37,23 @@ public class ResourceMonitoringController { * @see ResponseEntity * @see HttpStatus */ + @Operation( + summary = "Get Resource Monitoring Summary", + description = "Retrieves the resource monitoring summary for a given resource ID and specified period." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Resource monitoring summary retrieved successfully", + content = @Content(schema = @Schema(implementation = ResourceMonitoringSummary.class)) + ) + }) @GetMapping() - public ResponseEntity getMonitoringStatus(@RequestParam String resourceId, @RequestParam int periodInDays) { + public ResponseEntity getMonitoringStatus( + @Parameter(description = "ID of the resource for monitoring") + @RequestParam String resourceId, + @Parameter(description = "Time period in days for monitoring") + @RequestParam int periodInDays) { Period period = new Period(periodInDays, ChronoUnit.DAYS); ResourceMonitoringSummary summary = monitoringService.getResourceMonitoringSummary(resourceId, period); return new ResponseEntity<>(summary, HttpStatus.OK); diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java index 9198fca..d7116a9 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java @@ -1,5 +1,12 @@ package org.ejprarediseases.vpdpbackend.search.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.ConstraintViolationException; import lombok.RequiredArgsConstructor; import org.ejprarediseases.vpdpbackend.resource.v1.model.ResourceType; @@ -21,6 +28,7 @@ @RequestMapping("v1/search") @RequiredArgsConstructor @Validated +@Tag(name = "Search", description = "Endpoints for searching diseases") public class SearchController { private final SearchService searchService; @@ -77,15 +85,42 @@ ResponseEntity handleMethodArgumentTypeMismatchException(MethodArgumentT * @param resourceId The resource ID. * @return A ResponseEntity containing the search response and OK status. */ + @Operation( + summary = "Search Diseases", + description = "Searches for diseases based on various criteria." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Search successful", + content = @Content(schema = @Schema(implementation = SearchResponse.class)) + ), + @ApiResponse( + responseCode = "400", + description = "Bad request" + ), + @ApiResponse( + responseCode = "406", + description = "Not Acceptable" + ) + }) @GetMapping public ResponseEntity searchForDiseasesByOrphaCode( + @Parameter(description = "List of resource types") @RequestParam(required = false) List resourceTypes, + @Parameter(description = "List of countries") @RequestParam(required = false) List countries, + @Parameter(description = "List of sexes") @RequestParam(required = false) List sexes, + @Parameter(description = "Age criteria for the current year [min, max]") @RequestParam(required = false) List ageThisYear, + @Parameter(description = "Symptom onset ages [min, max]") @RequestParam(required = false) List symptomOnset, + @Parameter(description = "Age at diagnosis criteria [min, max]") @RequestParam(required = false) List ageAtDiagnoses, + @Parameter(description = "List of disease codes") @RequestParam List diseases, + @Parameter(description = "Resource ID") @RequestParam String resourceId ) { SearchRequest searchRequest = new SearchRequest(); diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search_autocomplete/v1/SearchAutocompleteController.java b/src/main/java/org/ejprarediseases/vpdpbackend/search_autocomplete/v1/SearchAutocompleteController.java index c7edb7a..f098561 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search_autocomplete/v1/SearchAutocompleteController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search_autocomplete/v1/SearchAutocompleteController.java @@ -1,5 +1,11 @@ package org.ejprarediseases.vpdpbackend.search_autocomplete.v1; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -11,6 +17,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("v1/autocomplete") +@Tag(name = "Autocomplete", description = "Endpoints for search autocomplete") public class SearchAutocompleteController { final SearchAutocompleteService searchAutocompleteService; @@ -23,6 +30,17 @@ public class SearchAutocompleteController { * @param size The number of results per page. * @return The ResponseEntity containing the search autocomplete results. */ + @Operation( + summary = "Execute Search Autocomplete", + description = "Executes a search for autocomplete results based on the given query and pagination parameters." + ) + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "Autocomplete results retrieved successfully", + content = @Content(schema = @Schema(implementation = SearchAutocompleteResult.class)) + ) + }) @GetMapping() public ResponseEntity executeSearch( @RequestParam String query, From 9eea10daa7d4d4fb8d315505f7cef7d1836b2373 Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:53:43 +0200 Subject: [PATCH 06/49] Update README.md --- README.md | 64 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 537aee6..08905bc 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,60 @@ -# vp-dp-backend +# VP-Portal Backend: Federated Discovery and Query Platform for Rare Disease Research +Welcome to the vp-dp-backend GitHub repository! This repository contains the codebase for the backend of the Virtual Platform, a revolutionary initiative that aims to provide a federated ecosystem for discovering, querying, and accessing a wide range of resources relevant to rare disease (RD) research. -## Table of Contents +## About VP-Portal Backend + +The EJP VP-Portal Backend serves as the foundational engine powering the EJP VP-Portal ecosystem. It offers an array of sophisticated functionalities, including advanced disease search capabilities, comprehensive disease hierarchy retrieval, precision gene mapping, efficient search autocompletion, robust resource monitoring service, seamless resource notification service, and an array of other distinctive features. These capabilities collectively aim to ensure an unparalleled user experience within the VP-Portal environment. +## Table of Contents - [Installation](#installation) -- [Usage](#usage) -- [Configuration](#configuration) -- [Features](#features) -- [Examples](#examples) -- [Troubleshooting](#troubleshooting) +- [Dependencies](#dependencies) - [License](#license) - [Contact Information](#contact-information) -- [Acknowledgments](#acknowledgments) ## Installation +To set up the VP-Portal Backend on your local environment, follow these steps: + +Clone this repository: +```bash +git clone https://github.com/ejp-rd-vp/vp-dp-backend.git +``` +Navigate to the project directory: +```bash +cd vp-dp-backend +``` +Build the application using Maven: +```bash +mvn clean install +``` +Run the application: +```bash +java -jar target/vp-dp-backend.jar +``` +The backend server will start, and you can access it at http://localhost:8095. + +## Dependencies + +The VP-Portal Backend is built using the Spring Boot framework and utilizes the following key dependencies: + + +* Spring Boot: Apache License 2.0 +* Project Lombok: MIT License +* PostgreSQL JDBC Driver: PostgreSQL License +* Jackson Core: Apache License 2.0 +* JUnit Jupiter Engine: Eclipse Public License - v 1.0 +* H2 Database: H2 License +* SpringDoc OpenAPI Starter WebMvc UI: Apache License 2.0 +* JavaMail API: Common Development and Distribution License (CDDL) v1.1 + GNU General Public License (GPL) v2 -## Usage - -## Configuration - -## Features - -## Examples - -## Troubleshooting - ## License + This project is licensed under the [Apache License 2.0](https://github.com/ejp-rd-vp/vp-dp-backend/blob/develop/LICENSE). -## Contact Information -## Acknowledgments +## Contact Information +Stay connected with the VP-Portal community to receive updates, announcements, and insights. Follow us on [Twitter](https://twitter.com/ejprarediseases?lang=de) | [Instagram](https://www.instagram.com/ejprarediseases/?hl=de) and participate in discussions. +If you encounter any issues, have questions, or need assistance, feel free to reach out to our community through GitHub issues or our communication channels. We're here to support you on your journey with VP-Portal Backend! From ee6c535b5457cf12b592914c842b530f96d38142 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 29 Aug 2023 15:17:34 +0200 Subject: [PATCH 07/49] #3 - Update ResourceType Format - Modify the resourceType field to follow the new formatting guidelines. --- .../resource/v1/model/ResourceType.java | 6 --- src/main/resources/static/resources.txt | 44 +++++++++---------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java index 9134981..0c417e7 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java @@ -1,16 +1,10 @@ package org.ejprarediseases.vpdpbackend.resource.v1.model; -import com.fasterxml.jackson.annotation.JsonProperty; - public enum ResourceType { - @JsonProperty("patientRegistry") PATIENT_REGISTRY, - @JsonProperty("bioBank") BIO_BANK, - @JsonProperty("knowledgeBase") KNOWLEDGE_BASE, - @JsonProperty("catalog") CATALOG; } diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index b82c94e..cb7c7f7 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -6,7 +6,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The RD‐Connect Genome‐Phenome Analysis Platform (GPAP) is a collaborative platform to accelerate rare disease diagnosis and gene discovery, that enables authorised users to submit, share, analyse and interpret integrated genome-phenome data from Rare Disease patients and relatives.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "0", "created": "2021-10-13T06:25:33.898Z", @@ -25,7 +25,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The main objective of this WP is to set up an interoperable registry dedicated to rare diseases within the scope of ITHACA called ILIAD Rare Diseases patient registry: an International Library of Intellectual disability and Anomalies of Development.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "1", "created": "2021-10-13T06:25:33.898Z", @@ -44,7 +44,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The European Rare Kidney Disease Registry.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "2", "created": "2021-10-13T06:25:33.898Z", @@ -63,8 +63,8 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The BBMRI-Eric catalogue of rare disease registries and biobanks.", "resourceType": [ - "patientRegistry", - "bioBank" + "PATIENT_REGISTRY", + "BIO_BANK" ], "id": "3", "created": "2020-12-02T10:42:09.170Z", @@ -83,8 +83,8 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The Orphanet catalogue of rare disease registries and biobanks.", "resourceType": [ - "patientRegistry", - "bioBank" + "PATIENT_REGISTRY", + "BIO_BANK" ], "id": "4", "created": "2020-10-26T15:26:15.891Z", @@ -103,7 +103,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The Duchenne Data Platform is a patient-led registry. Health information collected is stored in 'personal datalockers' for easy access at all times by patients through wearables or online.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "5", "created": "2020-11-07T05:12:55.898Z", @@ -122,7 +122,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "A collaborative platform for contributing and maintaining pathway information.", "resourceType": [ - "knowledgeBase" + "KNOWLEDGE_BASE" ], "id": "6", "created": "2020-10-26T15:26:15.892Z", @@ -141,7 +141,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": ": The Care and Trial Site Registry (CTSR) is an online self-entry database of specialised sites seeing patients with neuromuscular and neurodegenerative diseases. It holds site-level information relevant to clinical studies and care provision, including facilities, equipment, personnel, and trial experience, as well aggregate data about their patient population. It does not hold patient-level data.", "resourceType": [ - "knowledgeBase" + "KNOWLEDGE_BASE" ], "id": "7", "created": "2020-10-26T15:26:15.898Z", @@ -160,7 +160,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "hPSCreg is a global registry for human pluripotent stem cell lines (hPSC-lines). It aims to provide to the community\n\n1) a central and searchable hub for available hPSC-lines\n2) a central registry of clinical studies based on hPSC-lines\n3) a standardized identifier for hPSC-lines and register of these standard names\n4) a trustworthy data source for hPSC-lines by verifying the ethical and biological conformity of registered lines based on community standards\n5) comparability of quality standards in hPSC research\n6) certification of quality and ethical provenance of hPSC-lines\n7) a platform where any scientist or institution generating or working with PSC lines can register their cell lines, projects or clinical studies.", "resourceType": [ - "knowledgeBase" + "KNOWLEDGE_BASE" ], "id": "8", "created": "2020-10-26T15:26:15.893Z", @@ -179,7 +179,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "INFRAFRONTIER, the European Research Infrastructure for modelling human diseases, provides the scientific community with access to valuable mouse and rat strains including resources and services for their generation, phenotyping, and application in specific research pipelines. INFRAFRONTIER archives and distributes transgenic lines via the European Mouse Mutant Archive (EMMA), which currently has more than 8700 strains available for distribution to researchers. EMMA is a core resource of INFRAFRONTIER and is part of its expanding resources and services portfolio.", "resourceType": [ - "bioBank" + "BIO_BANK" ], "id": "9", "created": "", @@ -198,7 +198,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "A catalog to contain all metabolights study resources.", "resourceType": [ - "knowledgeBase" + "KNOWLEDGE_BASE" ], "id": "10", "created": "", @@ -217,7 +217,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The EGA provides a service for the permanent archiving and distribution of personally identifiable genetic and phenotypic data resulting from biomedical research projects. Data at EGA was collected from individuals whose consent agreements authorise data release only for specific research use to bona fide researchers. Strict protocols govern how information is managed, stored and distributed by the EGA project.", "resourceType": [ - "catalog" + "CATALOG" ], "id": "11", "created": "", @@ -236,7 +236,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "Databases of the ERN vascular anomalies", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "12", "created": "", @@ -256,7 +256,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "ERN CRANIO is the European Reference Network for rare and/or complex craniofacial anomalies and ear, nose and throat (ENT) disorders. The network was officially launched in March 2017. There are 29 European hospitals involved in ERN CRANIO, from 11 EU member states. It is a multi-disciplinary network of highly specialised healthcare professionals. Patient representatives also play an active role in the network and its activities.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "13", "created": "", @@ -275,7 +275,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The aim of ERN-Skin is to have a central European registry for all cases of rare dermatological diseases, which will be a useful tool for clinical research, simplify the development of cohorts and answer the specific questions of each Disease Group.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "14", "created": "", @@ -294,7 +294,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "EURO-NMD is a European reference network for the thematic grouping of rare neuromuscular diseases (NMDs), a broad group of related disorders that represent a major cause of mortality and lifelong disability in children and adults.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "15", "created": "", @@ -313,7 +313,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "The GENTURIS registry is the European registry for patients with one of the genetic tumour risk syndromes (genturis). The registry is affiliated to the European Reference Network for all patients with one of the genetic tumour risk syndromes (ERN GENTURIS).", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "16", "created": "2021-10-13T06:25:33.898Z", @@ -332,7 +332,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "FAIRVASC is a research project of the European Vasculitis Society (EUVAS) and RITA European Reference Network, bringing together leading scientists, clinicians and patient organisations. The FAIRVASC consortium is made up of 10 partners who represent all of these areas of patient care, also substantial support from VIFOR PHARMA should be acknowledged. There are many important gaps in our knowledge about why and how vasculitis occurs, why some people seem to be more susceptible than others, how the disease process acts inside the body and whether different kinds of vasculitis should be treated in different ways.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "17", "created": "", @@ -351,7 +351,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "18", "created": "2021-10-13T06:25:33.898Z", @@ -370,7 +370,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "Registry from ERN eUROGEN on rare uro-recto-genital diseases and complex conditions.", "resourceType": [ - "patientRegistry" + "PATIENT_REGISTRY" ], "id": "19", "created": "", From c863a3490badfe4a29fe189d2510a12fc301da68 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 29 Aug 2023 15:22:28 +0200 Subject: [PATCH 08/49] no issue - add issue & pr template --- .github/ISSUE_TEMPLATE.md | 29 +++++++++++++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 5 +++++ .github/semantic.yml | 5 +++++ 3 files changed, 39 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/semantic.yml diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..a9ae69f --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,29 @@ +**Describe your problem.** + +A clear and concise description of what the problem is. + + +**If it is a bug name steps to reproduce** + +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + + +**If it is a bug complete the following information:** + +- Version: [e.g. 1.2.3] +- OS: [e.g. Windows, Linux, OS X] +- Browser: [e.g. chrome, firefox, safari] + + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6e5061a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,5 @@ +**What's in the PR** +* ... + +**How to test manually** +* ... diff --git a/.github/semantic.yml b/.github/semantic.yml new file mode 100644 index 0000000..40b6927 --- /dev/null +++ b/.github/semantic.yml @@ -0,0 +1,5 @@ +# Always validate the PR title AND all the commits +titleAndCommits: true +# Allows use of Merge commits (eg on github: "Merge branch 'master' into feature/ride-unicorns") +# this is only relevant when using commitsOnly: true (or titleAndCommits: true) +allowMergeCommits: true From 5a9012d93031b423ff37939d76c8493a7fd84bb2 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 29 Aug 2023 15:39:08 +0200 Subject: [PATCH 09/49] #5 - Update the Exception Handling for the Hierarchy Service - Add solution where the Hierarchy Service is equipped to handle MethodArgumentTypeMismatchException exceptions gracefully. --- .../hierarchy/v1/HierarchyController.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java b/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java index ada3aa0..22bf5eb 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/hierarchy/v1/HierarchyController.java @@ -18,6 +18,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.*; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import java.util.List; import java.util.NoSuchElementException; @@ -37,9 +38,10 @@ public class HierarchyController { private final HierarchyService hierarchyService; /** - * Exception handler for ConstraintViolationException. - * @param e The ConstraintViolationException instance. - * @return ResponseEntity containing the error message and HTTP status code. + * Handles ConstraintViolationException by returning a BAD_REQUEST response with error message. + * + * @param e The ConstraintViolationException. + * @return A ResponseEntity containing the error message and BAD_REQUEST status. */ @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @@ -49,9 +51,10 @@ ResponseEntity handleConstraintViolationException(ConstraintViolationExc } /** - * Exception handler for MissingServletRequestParameterException. - * @param e The MissingServletRequestParameterException instance. - * @return ResponseEntity containing the error message and HTTP status code. + * Handles MissingServletRequestParameterException by returning a BAD_REQUEST response with error message. + * + * @param e The MissingServletRequestParameterException. + * @return A ResponseEntity containing the error message and BAD_REQUEST status. */ @ExceptionHandler(MissingServletRequestParameterException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @@ -60,6 +63,19 @@ ResponseEntity handleMissingServletRequestParameterException(MissingServ (e.getMessage(), HttpStatus.BAD_REQUEST); } + /** + * Handles MethodArgumentTypeMismatchException by returning a BAD_REQUEST response with error message. + * + * @param e The MethodArgumentTypeMismatchException. + * @return A ResponseEntity containing the error message and BAD_REQUEST status. + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + ResponseEntity handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { + return new ResponseEntity<> + (e.getMessage(), HttpStatus.BAD_REQUEST); + } + /** * Retrieve the hierarchical representation of the OrphaCode. * @param ways The list of hierarchical ways (e.g. UP or DOWN) to be used. @@ -92,7 +108,7 @@ ResponseEntity handleMissingServletRequestParameterException(MissingServ @GetMapping() public ResponseEntity getOrphaCodeHierarchy( @Parameter(description = "List of hierarchical ways (e.g. UP or DOWN) to be used") - @RequestParam @Valid List ways, + @RequestParam @Valid List ways, @Parameter(description = "OrphaCode for which the hierarchy needs to be retrieved") @RequestParam @Valid String orphaCode, @Parameter(description = "Number of hierarchy levels to retrieve (default: 100)", example = "100") @@ -100,9 +116,8 @@ public ResponseEntity getOrphaCodeHierarchy( ) { List response = null; try { - List hierarchyWays = ways.stream().map(HierarchyWay::getNameFromValue).toList(); response = hierarchyService.convertOrphaCodeHierarchyToListOfOrphaCodeDto( - hierarchyService.getOrphaCodeHierarchy(orphaCode, hierarchyWays, numberOfLevels)); + hierarchyService.getOrphaCodeHierarchy(orphaCode, ways, numberOfLevels)); } catch (JsonProcessingException e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_ACCEPTABLE); } catch (NoSuchElementException e) { From 3ec4c2cc4b8b74780c3a20a22070c6283ce71d6a Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Wed, 30 Aug 2023 09:50:41 +0200 Subject: [PATCH 10/49] #7 - Verify Search Filters Are Provided Before Processing Them --- .../v1/handler/BeaconCatalogQueryHandler.java | 8 +++++-- .../BeaconIndividualsQueryHandler.java | 22 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java index 901775a..3511168 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java @@ -61,8 +61,12 @@ private static BeaconRequestBodyQuerySection buildQuerySection(SearchRequest sea BeaconRequestBodyQuerySection querySection = new BeaconRequestBodyQuerySection(); List filters = new ArrayList<>(); filters.add(buildDiseaseFilter(searchRequest.getDiseases())); - filters.add(buildResourceTypesFilter(searchRequest.getResourceTypes())); - filters.add(buildCountryFilter(searchRequest.getCountries())); + if(searchRequest.getResourceTypes() != null && !searchRequest.getResourceTypes().isEmpty()) { + filters.add(buildResourceTypesFilter(searchRequest.getResourceTypes())); + } + if(searchRequest.getCountries() != null && !searchRequest.getCountries().isEmpty()) { + filters.add(buildCountryFilter(searchRequest.getCountries())); + } querySection.setFilters(filters); return querySection; } diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java index db5d6b4..4c06679 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java @@ -75,14 +75,22 @@ public static BeaconRequestBodyMetaSection buildMetaSection() { private static BeaconRequestBodyQuerySection buildQuerySection(SearchRequest searchRequest) { BeaconRequestBodyQuerySection querySection = new BeaconRequestBodyQuerySection(); List filters = new ArrayList<>(); - filters.add(buildSexFilter(searchRequest.getSexes())); filters.add(buildDiseaseFilter(searchRequest.getDiseases())); - filters.add(buildMinAgeFilter(searchRequest.getAgeThisYear().get(0))); - filters.add(buildMaxAgeFilter(searchRequest.getAgeThisYear().get(1))); - filters.add(buildMinSymptomOnsetFilter(searchRequest.getSymptomOnset().get(0))); - filters.add(buildMaxSymptomOnsetFilter(searchRequest.getSymptomOnset().get(1))); - filters.add(buildMinAgeAtDiagnosisFilter(searchRequest.getAgeAtDiagnosis().get(0))); - filters.add(buildMaxAgeAtDiagnosisFilter(searchRequest.getAgeAtDiagnosis().get(1))); + if (searchRequest.getSexes() != null && !searchRequest.getSexes().isEmpty()) { + filters.add(buildSexFilter(searchRequest.getSexes())); + } + if (searchRequest.getAgeThisYear() != null && searchRequest.getAgeThisYear().size() == 2) { + filters.add(buildMinAgeFilter(searchRequest.getAgeThisYear().get(0))); + filters.add(buildMaxAgeFilter(searchRequest.getAgeThisYear().get(1))); + } + if (searchRequest.getSymptomOnset() != null && searchRequest.getSymptomOnset().size() == 2) { + filters.add(buildMinSymptomOnsetFilter(searchRequest.getSymptomOnset().get(0))); + filters.add(buildMaxSymptomOnsetFilter(searchRequest.getSymptomOnset().get(1))); + } + if (searchRequest.getAgeAtDiagnosis() != null && searchRequest.getAgeAtDiagnosis().size() == 2) { + filters.add(buildMinAgeAtDiagnosisFilter(searchRequest.getAgeAtDiagnosis().get(0))); + filters.add(buildMaxAgeAtDiagnosisFilter(searchRequest.getAgeAtDiagnosis().get(1))); + } querySection.setFilters(filters); return querySection; } From 6e1daf39b95f43ca567b8b8a7bf9b6a47e63b308 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 5 Sep 2023 09:41:32 +0200 Subject: [PATCH 11/49] #9 - Add unit and integration tests for mapping service - Add unit tests - Add integration tests --- .../mapping/v1/MappingControllerTest.java | 42 +++++++++++++++++++ .../mapping/v1/MappingIntegrationTest.java | 34 +++++++++++++++ .../mapping/v1/MappingServiceTest.java | 29 +++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingControllerTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingIntegrationTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingServiceTest.java diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingControllerTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingControllerTest.java new file mode 100644 index 0000000..5c3ce9b --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingControllerTest.java @@ -0,0 +1,42 @@ +package org.ejprarediseases.vpdpbackend.mapping.v1; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; +import reactor.core.publisher.Mono; + + +@WebFluxTest(MappingController.class) +@ActiveProfiles("test") +@Tag("UnitTest") +@DisplayName("Mapping Controller Unit Tests") +public class MappingControllerTest { + + @Autowired + WebTestClient webTestClient; + + @MockBean + MappingService mappingService; + + @Test + @WithMockUser + public void shouldGetGeneMapping() { + Mono geneMappingMono = Mono.just(new GeneMapping()); + Mockito.when(mappingService.getGeneMapping("7")) + .thenReturn(geneMappingMono.block()); + webTestClient.get().uri(uriBuilder -> + uriBuilder + .path("/v1/mapping/gene/7") + .build()) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(GeneMapping.class); + } + +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingIntegrationTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingIntegrationTest.java new file mode 100644 index 0000000..58e6bd1 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingIntegrationTest.java @@ -0,0 +1,34 @@ +package org.ejprarediseases.vpdpbackend.mapping.v1; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; + +@WebFluxTest +@ActiveProfiles("test") +@Tag("IntegrationTest") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {MappingService.class, MappingController.class}) +@DisplayName("Mapping Integration Tests") +public class MappingIntegrationTest { + + @Autowired + private MappingService mappingService; + + @Autowired + WebTestClient webTestClient; + + @Test + @WithMockUser + public void shouldGetGeneMapping() { + GeneMapping geneMapping = mappingService.getGeneMapping("9008"); + assert (geneMapping.getHgncId().equals("9008")); + assert (geneMapping.getOrphaCodes().size() == 2); + assert (geneMapping.getOrphaCodes().contains("88924")); + assert (geneMapping.getOrphaCodes().contains("730")); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingServiceTest.java new file mode 100644 index 0000000..ec85556 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/mapping/v1/MappingServiceTest.java @@ -0,0 +1,29 @@ +package org.ejprarediseases.vpdpbackend.mapping.v1; + +import org.junit.jupiter.api.*; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.mockito.Mockito.mock; + +@WebFluxTest +@ActiveProfiles("test") +@Tag("UnitTest") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {MappingService.class}) +@DisplayName("Mapping Service Unit Tests") +public class MappingServiceTest { + + private MappingService mappingService; + private WebClient webClient; + + @BeforeEach + void setUp() { + webClient = mock(WebClient.class); + WebClient.Builder webClientBuilder = mock(WebClient.Builder.class); + mappingService = new MappingService(); + } + +} From 1ba016ab2ae4bc55599a22c015b9d2335345a9a8 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 5 Sep 2023 09:42:09 +0200 Subject: [PATCH 12/49] #9 - Add unit and integration tests for mapping service - Add NoArgsConstructor for GeneMapping --- .../org/ejprarediseases/vpdpbackend/mapping/v1/GeneMapping.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/GeneMapping.java b/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/GeneMapping.java index 39cda14..51f87fa 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/GeneMapping.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/mapping/v1/GeneMapping.java @@ -2,10 +2,12 @@ import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.util.List; @Data +@NoArgsConstructor @AllArgsConstructor public class GeneMapping { private String hgncId; From bc74404e81e694d5b87008fe478c2fc7da54b484 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Wed, 6 Sep 2023 10:06:54 +0200 Subject: [PATCH 13/49] #12 - Add unit and integration tests for resource service - Add minimal tests --- .../resource/v1/ResourceControllerTest.java | 49 ++++++++++++++ .../resource/v1/ResourceIntegrationTest.java | 35 ++++++++++ .../resource/v1/ResourceServiceTest.java | 66 +++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceControllerTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceIntegrationTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceServiceTest.java diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceControllerTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceControllerTest.java new file mode 100644 index 0000000..f05a538 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceControllerTest.java @@ -0,0 +1,49 @@ +package org.ejprarediseases.vpdpbackend.resource.v1; + +import lombok.SneakyThrows; +import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.util.ArrayList; +import java.util.List; + +@WebFluxTest(ResourceController.class) +@ActiveProfiles("test") +@Tag("UnitTest") +@DisplayName("Resource Controller Unit Tests") +public class ResourceControllerTest { + + @Autowired + WebTestClient webTestClient; + + @MockBean + private ResourceService resourceService; + + @SneakyThrows + @Test + @WithMockUser + public void shouldGetResources() { + List resources = new ArrayList<>(); + Resource resource = new Resource(); + resource.setResourceName("first resource"); + resource.setEmail("someemail@domain.com"); + resources.add(resource); + Mockito.when(resourceService.getAllResources()).thenReturn(resources); + webTestClient.get().uri(uriBuilder -> + uriBuilder + .path("/v1/resources") + .build()) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody().equals(resources); + } + +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceIntegrationTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceIntegrationTest.java new file mode 100644 index 0000000..6c99640 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceIntegrationTest.java @@ -0,0 +1,35 @@ +package org.ejprarediseases.vpdpbackend.resource.v1; + +import lombok.SneakyThrows; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; + +@WebFluxTest() +@ContextConfiguration(classes = {ResourceService.class, ResourceController.class}) +@ActiveProfiles("test") +@Tag("IntegrationTest") +@DisplayName("Resource Integration Tests") +public class ResourceIntegrationTest { + + @Autowired + WebTestClient webTestClient; + + @SneakyThrows + @Test + @WithMockUser + public void shouldGetResources() { + webTestClient.get().uri(uriBuilder -> + uriBuilder + .path("/v1/resources") + .build()) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceServiceTest.java new file mode 100644 index 0000000..f6002d8 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource/v1/ResourceServiceTest.java @@ -0,0 +1,66 @@ +package org.ejprarediseases.vpdpbackend.resource.v1; + +import lombok.SneakyThrows; +import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; +import org.junit.jupiter.api.*; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; +import java.util.NoSuchElementException; + +import static org.junit.jupiter.api.Assertions.assertThrows; + + +@ActiveProfiles("test") +@Tag("UnitTest") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {ResourceService.class}) +@DisplayName("Resource Service Unit Tests") +public class ResourceServiceTest { + + ResourceService resourceService; + + @BeforeEach + void setUp() { + resourceService = new ResourceService(); + } + + @Test + @Order(1) + @SneakyThrows + public void shouldGetAllResources() { + List resources = resourceService.getAllResources(); + assert(resources.size() > 1); + } + + @Test + @Order(2) + @SneakyThrows + public void shouldGetAllQueryableResources() { + List allResources = resourceService.getAllResources(); + List queryableResources = resourceService.getAllQueryableResources(); + assert (allResources.size() >= queryableResources.size()); + for(Resource resource : queryableResources) { + assert (resource.isQueryable()); + } + } + + @Test + @Order(3) + @SneakyThrows + public void shouldGetResourceById() { + List allResources = resourceService.getAllResources(); + Resource firstResource = allResources.get(0); + Resource retrievedResource = resourceService.getResourceById(firstResource.getId()); + assert (firstResource.equals(retrievedResource)); + } + + @Test + @Order(4) + @SneakyThrows + public void shouldThrowExceptionWhenResourceIdDoesNotExist() { + assertThrows(NoSuchElementException.class, () -> resourceService.getResourceById("NOT_AN_ID")); + } + +} From 86cf57fe0ba8aef1992ed7c5e6447269da7436a4 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Mon, 11 Sep 2023 13:06:13 +0200 Subject: [PATCH 14/49] #14 - Add unit and integration tests for resource monitoring service - Add minimal tests --- pom.xml | 7 + .../resource_monitoring/v1/model/Monitor.java | 2 +- src/main/resources/application-test.yml | 17 +- src/main/resources/data.sql | 168 ++++++++++++++++++ .../v1/ResourceMonitoringControllerTest.java | 49 +++++ .../v1/ResourceMonitoringIntegrationTest.java | 61 +++++++ .../v1/ResourceMonitoringRepositoryTest.java | 69 +++++++ .../v1/ResourceMonitoringServiceTest.java | 89 ++++++++++ 8 files changed, 452 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/data.sql create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringControllerTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringServiceTest.java diff --git a/pom.xml b/pom.xml index cb947ca..06337dd 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ vp-dp-backend 17 + 1.18.0 @@ -102,6 +103,12 @@ javax.mail 1.6.2 + + org.testcontainers + postgresql + ${testcontainers.version} + test + diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/model/Monitor.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/model/Monitor.java index 5143fe3..cb006e1 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/model/Monitor.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/model/Monitor.java @@ -25,7 +25,7 @@ public class Monitor { @Column(name = "response_time") private long responseTime; @Basic - @Column(name = "response_body") + @Column(name = "response_body", columnDefinition="text", length=10485760) private String responseBody; @Basic @Column(name = "timestamp") diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 2f47f2b..82d8d0c 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -6,29 +6,28 @@ application: scheduledMonitoringRateInMinutes: ${MONITORING_RATE_IN_MIN:15} notification: - senderEmailAddress: ${SENDER_OUTLOOK_ADDRESS} - senderEmailPassword: ${SENDER_OUTLOOK_PASSWORD} + senderEmailAddress: ${SENDER_OUTLOOK_ADDRESS:youremail@domain.com} + senderEmailPassword: ${SENDER_OUTLOOK_PASSWORD:password} hierarchyUrl: ${HIERARCHY_URL:http://155.133.131.171:8080/ClassifTraversal/hierarchies/traverse} geneMappingUrl: ${GENE_MAPPING_URL:http://155.133.131.171:8080/GENES/gendis/find} - resourcesAuthKeys: ${RESOURCES_AUTH_KEYS} + resourcesAuthKeys: ${RESOURCES_AUTH_KEYS:{"1":"1"}} logging: level: org: hibernate: SQL: debug + type: + descriptor: + sql: + BasicBinder: TRACE springframework: jdbc: core: JdbcTemplate: debug spring: - datasource: - driver-class-name: org.postgresql.Driver - url: jdbc:postgresql://${DB_HOST:localhost}/${DB_NAME:ejp-test}?stringtype=unspecified - username: ${DB_USER_NAME:ejp-test} - password: ${DB_USER_PW:ejp-test} security: oauth2: resourceserver: @@ -39,7 +38,7 @@ spring: database-platform: org.hibernate.dialect.PostgreSQLDialect show-sql: true hibernate: - ddl-auto: create-drop + ddl-auto: create sql: init: # The default value is 'embedded', which only works for in-memory databases. diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..dd14895 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,168 @@ +CREATE ROLE ejp; + +CREATE EXTENSION pg_trgm; + +CREATE FUNCTION to_tsvector_multilang(text) RETURNS tsvector + LANGUAGE sql IMMUTABLE + AS $_$ SELECT to_tsvector('simple', $1) $_$; + + +ALTER FUNCTION to_tsvector_multilang(text) OWNER TO ejp; + + +CREATE TABLE diseases ( + id integer NOT NULL, + name text, + orphacode text NOT NULL, + synonyms text, + codes text +); + + +ALTER TABLE diseases OWNER TO ejp; + + +CREATE SEQUENCE diseases_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE diseases_id_seq OWNER TO ejp; + + +ALTER SEQUENCE diseases_id_seq OWNED BY diseases.id; + + +CREATE TABLE genes ( + id integer NOT NULL, + hgnc_id text NOT NULL, + symbol text, + name text, + status text, + previous_symbols text, + alias_symbols text, + alias_names text, + omim_id text +); + +ALTER TABLE genes OWNER TO ejp; + +CREATE SEQUENCE genes_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE genes_id_seq OWNER TO ejp; + +ALTER SEQUENCE genes_id_seq OWNED BY genes.id; + +CREATE SEQUENCE my_serial + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE my_serial OWNER TO ejp; + +ALTER SEQUENCE my_serial OWNED BY genes.id; + +CREATE TABLE notification ( + id integer NOT NULL, + channel varchar, + status varchar, + type varchar, + resource_id varchar, + content text, + "timestamp" timestamp without time zone DEFAULT (now() AT TIME ZONE 'cest'::text) NOT NULL +); + +ALTER TABLE notification OWNER TO ejp; + +CREATE SEQUENCE notification_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER TABLE notification_id_seq OWNER TO ejp; + +ALTER SEQUENCE notification_id_seq OWNED BY notification.id; + +CREATE TABLE resource_monitor ( + id integer NOT NULL, + resource_id varchar NOT NULL, + response_status_code integer, + response_time integer, + response_body text, + "timestamp" timestamp without time zone DEFAULT (now() AT TIME ZONE 'cest'::text) NOT NULL +); + + +ALTER TABLE resource_monitor OWNER TO ejp; + +CREATE SEQUENCE resource_monitor_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE resource_monitor_id_seq OWNER TO ejp; + +ALTER SEQUENCE resource_monitor_id_seq OWNED BY resource_monitor.id; + +ALTER TABLE ONLY diseases ALTER COLUMN id SET DEFAULT nextval('diseases_id_seq'::regclass); + +ALTER TABLE ONLY genes ALTER COLUMN id SET DEFAULT nextval('my_serial'::regclass); + +ALTER TABLE ONLY notification ALTER COLUMN id SET DEFAULT nextval('notification_id_seq'::regclass); + +ALTER TABLE ONLY resource_monitor ALTER COLUMN id SET DEFAULT nextval('resource_monitor_id_seq'::regclass); + + +ALTER TABLE ONLY diseases + ADD CONSTRAINT diseases_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY genes + ADD CONSTRAINT genes_pkey PRIMARY KEY (id); + +CREATE INDEX search_index_0 ON genes USING gin (to_tsvector_multilang(hgnc_id)); + + +CREATE INDEX search_index_10 ON diseases USING gin (orphacode gin_trgm_ops); + + +CREATE INDEX search_index_11 ON diseases USING gin (synonyms gin_trgm_ops); + +CREATE INDEX search_index_12 ON diseases USING gin (codes gin_trgm_ops); + +CREATE INDEX search_index_2 ON genes USING gin (to_tsvector_multilang(symbol)); + +CREATE INDEX search_index_3 ON genes USING gin (to_tsvector_multilang(name)); + +CREATE INDEX search_index_4 ON genes USING gin (to_tsvector_multilang(status)); + +CREATE INDEX search_index_5 ON genes USING gin (to_tsvector_multilang(previous_symbols)); + +CREATE INDEX search_index_6 ON genes USING gin (to_tsvector_multilang(alias_symbols)); + +CREATE INDEX search_index_7 ON genes USING gin (to_tsvector_multilang(alias_names)); + +CREATE INDEX search_index_8 ON genes USING gin (to_tsvector_multilang(omim_id)); + +CREATE INDEX search_index_9 ON diseases USING gin (name gin_trgm_ops); diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringControllerTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringControllerTest.java new file mode 100644 index 0000000..6d10b06 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringControllerTest.java @@ -0,0 +1,49 @@ +package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; + +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Period; +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.ResourceMonitoringSummary; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.time.temporal.ChronoUnit; + +@WebFluxTest(ResourceMonitoringController.class) +@ActiveProfiles("test") +@Tag("UnitTest") +@DisplayName("Resource Monitoring Controller Unit Tests") +public class ResourceMonitoringControllerTest { + + @Autowired + WebTestClient webTestClient; + + @MockBean + private ResourceMonitoringService resourceMonitoringService; + + @Test + @WithMockUser + public void shouldGetMonitoringStatus() { + Period period = new Period(1, ChronoUnit.DAYS); + ResourceMonitoringSummary summary = new ResourceMonitoringSummary(); + summary.setResourceId("1"); + summary.setPeriod(period); + summary.setNumberOfTests(1); + summary.setAverageResponseTimeInMilliSeconds(99); + Mockito.when(resourceMonitoringService.getResourceMonitoringSummary("1", period)).thenReturn(summary); + webTestClient.get().uri(uriBuilder -> + uriBuilder + .path("/v1/monitoring") + .queryParam("resourceId", "1") + .queryParam("periodInDays", 1) + .build()) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody().equals(summary); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java new file mode 100644 index 0000000..631c9a3 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java @@ -0,0 +1,61 @@ +package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.testcontainers.containers.PostgreSQLContainer; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureWebTestClient +@ActiveProfiles("test") +@Tag("IntegrationTest") +@DisplayName("Resource Monitoring Integration Tests") +public class ResourceMonitoringIntegrationTest { + + @LocalServerPort + private Integer port; + + static PostgreSQLContainer postgres = new PostgreSQLContainer<>( + "postgres:15-alpine" + ); + + @BeforeAll + static void beforeAll() { + postgres.start(); + } + + @AfterAll + static void afterAll() { + postgres.stop(); + } + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", postgres::getJdbcUrl); + registry.add("spring.datasource.username", postgres::getUsername); + registry.add("spring.datasource.password", postgres::getPassword); + } + + @Autowired + WebTestClient webTestClient; + + @Test + public void shouldGetResourceMonitoring() { + webTestClient.get().uri(uriBuilder -> + uriBuilder + .path("/v1/monitoring") + .queryParam("resourceId", "1") + .queryParam("periodInDays", 1) + .build()) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(); + } + +} + diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java new file mode 100644 index 0000000..2904493 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java @@ -0,0 +1,69 @@ +package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; + +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Monitor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.context.ActiveProfiles; + +import java.sql.Timestamp; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Tag("UnitTest") +@DisplayName("Resource Monitoring Repository Unit Tests") +public class ResourceMonitoringRepositoryTest { + + @Autowired + private TestEntityManager entityManager; + @Autowired + ResourceMonitoringRepository repository; + + @Test + public void shouldFindNoMonitorsIfRepositoryIsEmpty() { + Iterable monitors = repository.findAll(); + assertThat(monitors).isEmpty(); + } + + @Test + public void shouldBeAbleToAddMonitor() { + Monitor monitor = new Monitor(); + monitor.setResourceId("1"); + repository.save(monitor); + assertThat(repository.findAll()).hasSize(1); + } + + @Test + public void shouldFindAllByResourceIdEqualsAndTimestampBetween() { + Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis()); + Timestamp oneDaysAgo = Timestamp.valueOf(ZonedDateTime.now() + .minus(1, ChronoUnit.DAYS).toLocalDateTime()); + Timestamp twoDaysAgo = Timestamp.valueOf(ZonedDateTime.now() + .minus(2, ChronoUnit.DAYS).toLocalDateTime()); + Timestamp threeDaysAgo = Timestamp.valueOf(ZonedDateTime.now() + .minus(3, ChronoUnit.DAYS).toLocalDateTime()); + Timestamp fourDaysAgo = Timestamp.valueOf(ZonedDateTime.now() + .minus(4, ChronoUnit.DAYS).toLocalDateTime()); + Monitor monitor1 = new Monitor(); + monitor1.setResourceId("1"); + monitor1.setTimestamp(oneDaysAgo); + entityManager.persist(monitor1); + Monitor monitor2 = new Monitor(); + monitor2.setResourceId("1"); + monitor2.setTimestamp(threeDaysAgo); + entityManager.persist(monitor2); + assertThat(repository.findAllByResourceIdEqualsAndTimestampBetween( + "1", currentTimestamp, currentTimestamp)).hasSize(0); + assertThat(repository.findAllByResourceIdEqualsAndTimestampBetween( + "1", twoDaysAgo, currentTimestamp)).hasSize(1); + assertThat(repository.findAllByResourceIdEqualsAndTimestampBetween( + "1", fourDaysAgo, currentTimestamp)).hasSize(2); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringServiceTest.java new file mode 100644 index 0000000..aa24642 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringServiceTest.java @@ -0,0 +1,89 @@ +package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; + +import org.ejprarediseases.vpdpbackend.resource.v1.ResourceService; +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Monitor; +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Period; +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.ResourceMonitoringSummary; +import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.enums.HttpStatusCategory; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +import java.sql.Timestamp; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + + +@ActiveProfiles("test") +@Tag("UnitTest") +@ExtendWith(MockitoExtension.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {ResourceMonitoringService.class}) +@DisplayName("Resource Monitoring Service Unit Tests") +public class ResourceMonitoringServiceTest { + + @Mock + private ResourceMonitoringRepository repository; + + @Mock + private ResourceService resourceService; + + @InjectMocks + private ResourceMonitoringService resourceMonitoringService; + + + @Test + public void shouldFilterMonitorsAccordingToHttpCategories() { + Monitor monitor1 = new Monitor(); + monitor1.setResourceId("3"); + monitor1.setResponseStatusCode(200); + Monitor monitor2 = new Monitor(); + monitor2.setResourceId("4"); + monitor2.setResponseStatusCode(404); + List monitors = Arrays.asList(monitor1, monitor2); + List successfulMonitors = resourceMonitoringService.filterMonitorsAccordingToHttpCategories( + monitors, List.of(HttpStatusCategory.SUCCESSFUL_RESPONSE)); + assertThat(successfulMonitors).hasSize(1); + assert (successfulMonitors.get(0).getResourceId().equals("3")); + List clientErrorMonitors = resourceMonitoringService.filterMonitorsAccordingToHttpCategories( + monitors, List.of(HttpStatusCategory.CLIENT_ERROR_RESPONSE)); + assertThat(clientErrorMonitors).hasSize(1); + assert (clientErrorMonitors.get(0).getResourceId().equals("4")); + } + + @Test + public void shouldGetResourceMonitoringSummary() { + Period period = new Period(1, ChronoUnit.DAYS); + Monitor monitor1 = new Monitor(); + monitor1.setResourceId("1"); + monitor1.setResponseStatusCode(100); + Monitor monitor2 = new Monitor(); + monitor2.setResourceId("1"); + monitor2.setResponseStatusCode(200); + Monitor monitor3 = new Monitor(); + monitor3.setResourceId("1"); + monitor3.setResponseStatusCode(300); + Monitor monitor4 = new Monitor(); + monitor4.setResourceId("1"); + monitor4.setResponseStatusCode(400); + Monitor monitor5 = new Monitor(); + monitor5.setResourceId("1"); + monitor5.setResponseStatusCode(500); + List monitors = Arrays.asList(monitor1, monitor2, monitor3, monitor4, monitor5); + Mockito.doReturn(monitors).when(repository).findAllByResourceIdEqualsAndTimestampBetween(Mockito.eq("5"), + Mockito.any(Timestamp.class), Mockito.any(Timestamp.class)); + ResourceMonitoringSummary summary = + resourceMonitoringService.getResourceMonitoringSummary("5", period); + assert(summary.getResourceId().equals("5")); + assert(summary.getNumberOfSuccessfulResponses() == 1); + assert(summary.getNumberOfClientErrorResponses() == 1); + } +} From c70d2e0241db51f8417b8811ae0b06937f0e1d68 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 12 Sep 2023 12:48:32 +0200 Subject: [PATCH 15/49] #16 - Use PostgreSQL instead of H2 database for test environment - Use PostgreSQL instead of H2 database for test environment --- pom.xml | 5 -- .../v1/NotificationRepository.java | 3 +- src/main/resources/application-test.yml | 3 +- src/main/resources/data.sql | 55 +++++++++---------- .../db/DatabaseSetupExtension.java | 21 +++++++ .../db/TestPostgresqlContainer.java | 28 ++++++++++ .../disease/v1/DiseaseRepositoryTest.java | 5 ++ .../gene/v1/GeneRepositoryTest.java | 5 ++ .../v1/ResourceMonitoringIntegrationTest.java | 32 +---------- .../v1/ResourceMonitoringRepositoryTest.java | 5 ++ 10 files changed, 96 insertions(+), 66 deletions(-) create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/db/DatabaseSetupExtension.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/db/TestPostgresqlContainer.java diff --git a/pom.xml b/pom.xml index 06337dd..80838c5 100644 --- a/pom.xml +++ b/pom.xml @@ -88,11 +88,6 @@ junit test - - com.h2database - h2 - test - org.springdoc springdoc-openapi-starter-webmvc-ui diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepository.java b/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepository.java index 2989d3d..a184f88 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepository.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepository.java @@ -2,12 +2,13 @@ import org.ejprarediseases.vpdpbackend.notification.v1.model.Notification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.sql.Timestamp; import java.util.List; +@Repository public interface NotificationRepository extends JpaRepository { - List findAllByResourceIdEqualsAndTimestampBetween( String resourceId, Timestamp startTimestamp, Timestamp endTimestamp); } diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 82d8d0c..3a9191b 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -38,13 +38,12 @@ spring: database-platform: org.hibernate.dialect.PostgreSQLDialect show-sql: true hibernate: - ddl-auto: create + ddl-auto: create-drop sql: init: # The default value is 'embedded', which only works for in-memory databases. # Since we're using a 'non-embedded' database here, we now need to set this to 'always'. mode: always - server: port: 8095 \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index dd14895..7916fc9 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,7 +1,6 @@ -CREATE ROLE ejp; - -CREATE EXTENSION pg_trgm; +CREATE EXTENSION IF NOT EXISTS pg_trgm; +DROP FUNCTION IF EXISTS to_tsvector_multilang; CREATE FUNCTION to_tsvector_multilang(text) RETURNS tsvector LANGUAGE sql IMMUTABLE AS $_$ SELECT to_tsvector('simple', $1) $_$; @@ -10,19 +9,20 @@ CREATE FUNCTION to_tsvector_multilang(text) RETURNS tsvector ALTER FUNCTION to_tsvector_multilang(text) OWNER TO ejp; -CREATE TABLE diseases ( +CREATE TABLE IF NOT EXISTS diseases ( id integer NOT NULL, name text, orphacode text NOT NULL, synonyms text, - codes text + codes text, + PRIMARY KEY (id) ); ALTER TABLE diseases OWNER TO ejp; -CREATE SEQUENCE diseases_id_seq +CREATE SEQUENCE IF NOT EXISTS diseases_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -37,7 +37,7 @@ ALTER TABLE diseases_id_seq OWNER TO ejp; ALTER SEQUENCE diseases_id_seq OWNED BY diseases.id; -CREATE TABLE genes ( +CREATE TABLE IF NOT EXISTS genes ( id integer NOT NULL, hgnc_id text NOT NULL, symbol text, @@ -46,12 +46,13 @@ CREATE TABLE genes ( previous_symbols text, alias_symbols text, alias_names text, - omim_id text + omim_id text, + PRIMARY KEY (id) ); ALTER TABLE genes OWNER TO ejp; -CREATE SEQUENCE genes_id_seq +CREATE SEQUENCE IF NOT EXISTS genes_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -64,7 +65,7 @@ ALTER TABLE genes_id_seq OWNER TO ejp; ALTER SEQUENCE genes_id_seq OWNED BY genes.id; -CREATE SEQUENCE my_serial +CREATE SEQUENCE IF NOT EXISTS my_serial AS integer START WITH 1 INCREMENT BY 1 @@ -77,7 +78,7 @@ ALTER TABLE my_serial OWNER TO ejp; ALTER SEQUENCE my_serial OWNED BY genes.id; -CREATE TABLE notification ( +CREATE TABLE IF NOT EXISTS notification ( id integer NOT NULL, channel varchar, status varchar, @@ -89,7 +90,7 @@ CREATE TABLE notification ( ALTER TABLE notification OWNER TO ejp; -CREATE SEQUENCE notification_id_seq +CREATE SEQUENCE IF NOT EXISTS notification_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -101,7 +102,7 @@ ALTER TABLE notification_id_seq OWNER TO ejp; ALTER SEQUENCE notification_id_seq OWNED BY notification.id; -CREATE TABLE resource_monitor ( +CREATE TABLE IF NOT EXISTS resource_monitor ( id integer NOT NULL, resource_id varchar NOT NULL, response_status_code integer, @@ -113,7 +114,7 @@ CREATE TABLE resource_monitor ( ALTER TABLE resource_monitor OWNER TO ejp; -CREATE SEQUENCE resource_monitor_id_seq +CREATE SEQUENCE IF NOT EXISTS resource_monitor_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -135,34 +136,30 @@ ALTER TABLE ONLY notification ALTER COLUMN id SET DEFAULT nextval('notification_ ALTER TABLE ONLY resource_monitor ALTER COLUMN id SET DEFAULT nextval('resource_monitor_id_seq'::regclass); -ALTER TABLE ONLY diseases - ADD CONSTRAINT diseases_pkey PRIMARY KEY (id); -ALTER TABLE ONLY genes - ADD CONSTRAINT genes_pkey PRIMARY KEY (id); CREATE INDEX search_index_0 ON genes USING gin (to_tsvector_multilang(hgnc_id)); -CREATE INDEX search_index_10 ON diseases USING gin (orphacode gin_trgm_ops); +CREATE INDEX IF NOT EXISTS search_index_10 ON diseases USING gin (orphacode gin_trgm_ops); -CREATE INDEX search_index_11 ON diseases USING gin (synonyms gin_trgm_ops); +CREATE INDEX IF NOT EXISTS search_index_11 ON diseases USING gin (synonyms gin_trgm_ops); -CREATE INDEX search_index_12 ON diseases USING gin (codes gin_trgm_ops); +CREATE INDEX IF NOT EXISTS search_index_12 ON diseases USING gin (codes gin_trgm_ops); -CREATE INDEX search_index_2 ON genes USING gin (to_tsvector_multilang(symbol)); +CREATE INDEX IF NOT EXISTS search_index_2 ON genes USING gin (to_tsvector_multilang(symbol)); -CREATE INDEX search_index_3 ON genes USING gin (to_tsvector_multilang(name)); +CREATE INDEX IF NOT EXISTS search_index_3 ON genes USING gin (to_tsvector_multilang(name)); -CREATE INDEX search_index_4 ON genes USING gin (to_tsvector_multilang(status)); +CREATE INDEX IF NOT EXISTS search_index_4 ON genes USING gin (to_tsvector_multilang(status)); -CREATE INDEX search_index_5 ON genes USING gin (to_tsvector_multilang(previous_symbols)); +CREATE INDEX IF NOT EXISTS search_index_5 ON genes USING gin (to_tsvector_multilang(previous_symbols)); -CREATE INDEX search_index_6 ON genes USING gin (to_tsvector_multilang(alias_symbols)); +CREATE INDEX IF NOT EXISTS search_index_6 ON genes USING gin (to_tsvector_multilang(alias_symbols)); -CREATE INDEX search_index_7 ON genes USING gin (to_tsvector_multilang(alias_names)); +CREATE INDEX IF NOT EXISTS search_index_7 ON genes USING gin (to_tsvector_multilang(alias_names)); -CREATE INDEX search_index_8 ON genes USING gin (to_tsvector_multilang(omim_id)); +CREATE INDEX IF NOT EXISTS search_index_8 ON genes USING gin (to_tsvector_multilang(omim_id)); -CREATE INDEX search_index_9 ON diseases USING gin (name gin_trgm_ops); +CREATE INDEX IF NOT EXISTS search_index_9 ON diseases USING gin (name gin_trgm_ops); diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/db/DatabaseSetupExtension.java b/src/test/java/org/ejprarediseases/vpdpbackend/db/DatabaseSetupExtension.java new file mode 100644 index 0000000..0c0ee0f --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/db/DatabaseSetupExtension.java @@ -0,0 +1,21 @@ +package org.ejprarediseases.vpdpbackend.db; + +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +public class DatabaseSetupExtension implements BeforeAllCallback { + + @Override + public void beforeAll(ExtensionContext context) { + TestPostgresqlContainer container = TestPostgresqlContainer.getInstance(); + container.start(); + updateDataSourceProps(container); + } + + private void updateDataSourceProps(TestPostgresqlContainer container) { + System.setProperty("spring.datasource.url", container.getJdbcUrl()); + System.setProperty("spring.datasource.username", container.getUsername()); + System.setProperty("spring.datasource.password", container.getPassword()); + } + +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/db/TestPostgresqlContainer.java b/src/test/java/org/ejprarediseases/vpdpbackend/db/TestPostgresqlContainer.java new file mode 100644 index 0000000..5c0428e --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/db/TestPostgresqlContainer.java @@ -0,0 +1,28 @@ +package org.ejprarediseases.vpdpbackend.db; + +import org.testcontainers.containers.PostgreSQLContainer; + +public class TestPostgresqlContainer extends PostgreSQLContainer { + + private static final String IMAGE_VERSION = "postgres:15-alpine"; + private static final String DATABASE_NAME = "ejp"; + private static final String USERNAME = "ejp"; + private static final String PASSWORD = "ejp"; + + private static TestPostgresqlContainer container; + + public static TestPostgresqlContainer getInstance() { + if (container == null) { + container = new TestPostgresqlContainer() + .withDatabaseName(DATABASE_NAME) + .withUsername(USERNAME) + .withPassword(PASSWORD); + } + return container; + } + + public TestPostgresqlContainer() { + super(IMAGE_VERSION); + } +} + diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseRepositoryTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseRepositoryTest.java index 92a2dcf..466a1db 100644 --- a/src/test/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseRepositoryTest.java +++ b/src/test/java/org/ejprarediseases/vpdpbackend/disease/v1/DiseaseRepositoryTest.java @@ -1,10 +1,13 @@ package org.ejprarediseases.vpdpbackend.disease.v1; +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; import org.ejprarediseases.vpdpbackend.disease.v1.model.Disease; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.data.domain.PageRequest; @@ -17,6 +20,8 @@ @DataJpaTest @ActiveProfiles("test") @Tag("UnitTest") +@ExtendWith(DatabaseSetupExtension.class) +@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) @DisplayName("Disease Repository Unit Tests") public class DiseaseRepositoryTest { diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/gene/v1/GeneRepositoryTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/gene/v1/GeneRepositoryTest.java index cc7ad2a..a031e44 100644 --- a/src/test/java/org/ejprarediseases/vpdpbackend/gene/v1/GeneRepositoryTest.java +++ b/src/test/java/org/ejprarediseases/vpdpbackend/gene/v1/GeneRepositoryTest.java @@ -1,9 +1,12 @@ package org.ejprarediseases.vpdpbackend.gene.v1; +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.data.domain.PageRequest; @@ -17,6 +20,8 @@ @DataJpaTest @ActiveProfiles("test") @Tag("UnitTest") +@ExtendWith(DatabaseSetupExtension.class) +@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) @DisplayName("Gene Repository Unit Tests") public class GeneRepositoryTest { diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java index 631c9a3..d848bee 100644 --- a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringIntegrationTest.java @@ -1,48 +1,23 @@ package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; -import org.testcontainers.containers.PostgreSQLContainer; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ExtendWith(DatabaseSetupExtension.class) @AutoConfigureWebTestClient @ActiveProfiles("test") @Tag("IntegrationTest") @DisplayName("Resource Monitoring Integration Tests") public class ResourceMonitoringIntegrationTest { - @LocalServerPort - private Integer port; - - static PostgreSQLContainer postgres = new PostgreSQLContainer<>( - "postgres:15-alpine" - ); - - @BeforeAll - static void beforeAll() { - postgres.start(); - } - - @AfterAll - static void afterAll() { - postgres.stop(); - } - - @DynamicPropertySource - static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("spring.datasource.url", postgres::getJdbcUrl); - registry.add("spring.datasource.username", postgres::getUsername); - registry.add("spring.datasource.password", postgres::getPassword); - } - @Autowired WebTestClient webTestClient; @@ -56,6 +31,5 @@ public void shouldGetResourceMonitoring() { .build()) .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(); } - } diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java index 2904493..a9d1394 100644 --- a/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java +++ b/src/test/java/org/ejprarediseases/vpdpbackend/resource_monitoring/v1/ResourceMonitoringRepositoryTest.java @@ -1,10 +1,13 @@ package org.ejprarediseases.vpdpbackend.resource_monitoring.v1; +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; import org.ejprarediseases.vpdpbackend.resource_monitoring.v1.model.Monitor; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.test.context.ActiveProfiles; @@ -18,6 +21,8 @@ @DataJpaTest @ActiveProfiles("test") @Tag("UnitTest") +@ExtendWith(DatabaseSetupExtension.class) +@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) @DisplayName("Resource Monitoring Repository Unit Tests") public class ResourceMonitoringRepositoryTest { From 314178a44fb269220234c091ecb9106b35d5511d Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Tue, 12 Sep 2023 13:09:37 +0200 Subject: [PATCH 16/49] #11 - Add unit and integration tests for notification service - Add minimal tests (has to be extended) --- .../v1/service/EmailNotificationService.java | 4 +- .../v1/EmailNotificationServiceTest.java | 45 ++++++++++++++ .../v1/NotificationIntegrationTest.java | 41 +++++++++++++ .../v1/NotificationRepositoryTest.java | 59 +++++++++++++++++++ .../NotificationRequirementServiceTest.java | 19 ++++++ .../v1/NotificationServiceTest.java | 19 ++++++ 6 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/EmailNotificationServiceTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationIntegrationTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepositoryTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRequirementServiceTest.java create mode 100644 src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationServiceTest.java diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/service/EmailNotificationService.java b/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/service/EmailNotificationService.java index 5ddc4fc..d777c7d 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/service/EmailNotificationService.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/notification/v1/service/EmailNotificationService.java @@ -46,8 +46,7 @@ public class EmailNotificationService { * @param resource The resource for which the notification is being sent. * @param type The type of the notification. */ - public void sendEmailNotification( - @Valid Resource resource, NotificationType type) { + public Notification sendEmailNotification(@Valid Resource resource, NotificationType type) { Notification notification = new Notification(); try { Message message = buildEmailMessage(resource, type); @@ -62,6 +61,7 @@ public void sendEmailNotification( notification.setResourceId(resource.getId()); notificationRepository.save(notification); } + return notification; } /** diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/EmailNotificationServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/EmailNotificationServiceTest.java new file mode 100644 index 0000000..fd79efb --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/EmailNotificationServiceTest.java @@ -0,0 +1,45 @@ +package org.ejprarediseases.vpdpbackend.notification.v1; + +import org.ejprarediseases.vpdpbackend.notification.v1.model.Notification; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationStatus; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationType; +import org.ejprarediseases.vpdpbackend.notification.v1.service.EmailNotificationService; +import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.test.context.ActiveProfiles; + +import java.sql.Timestamp; + +@ActiveProfiles("test") +@Tag("UnitTest") +@ExtendWith({MockitoExtension.class}) +@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) +@DisplayName("Email Notification Service Unit Tests") +public class EmailNotificationServiceTest { + + @Mock + private NotificationRepository notificationRepository; + + @InjectMocks + private EmailNotificationService emailNotificationService; + + @Test + public void shouldSendEmailNotification() { + Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis()); + Resource resource = new Resource(); + resource.setId("id"); + resource.setResourceName("test resource"); + resource.setEmail("someemail@domain.com"); + resource.setCreated(currentTimestamp); + Notification notification = + emailNotificationService.sendEmailNotification(resource, NotificationType.PERFORMANCE_ISSUE); + //TODO test case email was sent + assert(notification.getStatus().equals(NotificationStatus.FAILED)); + } + +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationIntegrationTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationIntegrationTest.java new file mode 100644 index 0000000..cebeaa4 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationIntegrationTest.java @@ -0,0 +1,41 @@ +package org.ejprarediseases.vpdpbackend.notification.v1; + +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationType; +import org.ejprarediseases.vpdpbackend.notification.v1.service.EmailNotificationService; +import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ExtendWith(DatabaseSetupExtension.class) +@AutoConfigureWebTestClient +@ActiveProfiles("test") +@Tag("IntegrationTest") +@DisplayName("Notification Integration Tests") +public class NotificationIntegrationTest { + + @Autowired + private NotificationRepository repository; + + @Autowired + private EmailNotificationService emailNotificationService; + + + @Test + public void shouldSendEmailNotification() { + Resource resource = new Resource(); + resource.setEmail("someemail@domain.com"); + resource.setResourceName("RESOURCE NAME"); + emailNotificationService.sendEmailNotification(resource, NotificationType.PERFORMANCE_ISSUE); + assertThat(repository.findAll()).hasSize(1); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepositoryTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepositoryTest.java new file mode 100644 index 0000000..8349c86 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRepositoryTest.java @@ -0,0 +1,59 @@ +package org.ejprarediseases.vpdpbackend.notification.v1; + +import org.ejprarediseases.vpdpbackend.db.DatabaseSetupExtension; +import org.ejprarediseases.vpdpbackend.notification.v1.model.Notification; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationChannel; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationStatus; +import org.ejprarediseases.vpdpbackend.notification.v1.model.enums.NotificationType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.context.ActiveProfiles; + +import java.sql.Timestamp; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Tag("UnitTest") +@ExtendWith(DatabaseSetupExtension.class) +@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) +@DisplayName("Notification Repository Unit Tests") +public class NotificationRepositoryTest { + @Autowired + private TestEntityManager entityManager; + @Autowired + NotificationRepository repository; + + @Test + public void shouldFindNoNotificationsIfRepositoryIsEmpty() { + Iterable notifications = repository.findAll(); + assertThat(notifications).isEmpty(); + } + + @Test + public void shouldFindAllByResourceIdEqualsAndTimestampBetween() { + Notification notification = new Notification(); + notification.setResourceId("2"); + notification.setStatus(NotificationStatus.SENT); + notification.setType(NotificationType.PERFORMANCE_ISSUE); + notification.setContent("TEST"); + notification.setChannel(NotificationChannel.EMAIL); + notification.setTimestamp(new Timestamp(System.currentTimeMillis())); + entityManager.persist(notification); + Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis()); + Timestamp startTimestamp = Timestamp.valueOf(ZonedDateTime.now() + .minus(2, ChronoUnit.DAYS).toLocalDateTime()); + Iterable notifications = + repository.findAllByResourceIdEqualsAndTimestampBetween("2", startTimestamp, currentTimestamp); + assertThat(notifications).hasSize(1).contains(notification); + } +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRequirementServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRequirementServiceTest.java new file mode 100644 index 0000000..44a7d16 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationRequirementServiceTest.java @@ -0,0 +1,19 @@ +package org.ejprarediseases.vpdpbackend.notification.v1; + +import org.ejprarediseases.vpdpbackend.notification.v1.service.NotificationRequirementService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.TestInstance; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +@WebFluxTest +@ActiveProfiles("test") +@Tag("UnitTest") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {NotificationRequirementService.class}) +@DisplayName("Notification Requirement Service Unit Tests") +public class NotificationRequirementServiceTest { + +} diff --git a/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationServiceTest.java b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationServiceTest.java new file mode 100644 index 0000000..8dc48f8 --- /dev/null +++ b/src/test/java/org/ejprarediseases/vpdpbackend/notification/v1/NotificationServiceTest.java @@ -0,0 +1,19 @@ +package org.ejprarediseases.vpdpbackend.notification.v1; + +import org.ejprarediseases.vpdpbackend.notification.v1.service.NotificationService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.TestInstance; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +@WebFluxTest +@ActiveProfiles("test") +@Tag("UnitTest") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ContextConfiguration(classes = {NotificationService.class}) +@DisplayName("Notification Service Unit Tests") +public class NotificationServiceTest { + +} From 4de77e3634f3e931e4617d6b52d06f7ea91907a4 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Wed, 13 Sep 2023 09:49:42 +0200 Subject: [PATCH 17/49] #19 - Allow User Authentication in Swagger Documentation - Add authorize button to the header --- .../vpdpbackend/VpDpBackendApplication.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java index e6109a9..abf61e3 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java @@ -1,13 +1,17 @@ package org.ejprarediseases.vpdpbackend; import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.License; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityScheme; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @OpenAPIDefinition( + security = @SecurityRequirement(name = "bearerAuth"), info = @Info( title = "VP-Portal Backend", description = "The EJP VP-Portal Backend serves as the foundational engine powering " + @@ -28,6 +32,12 @@ ) ) ) +@SecurityScheme( + name = "bearerAuth", + type = SecuritySchemeType.HTTP, + bearerFormat = "JWT", + scheme = "bearer" +) @SpringBootApplication public class VpDpBackendApplication { From 573030f2a76d2049826df9f8b9c998d4482c51c2 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Wed, 13 Sep 2023 10:01:07 +0200 Subject: [PATCH 18/49] #21 - Update Spring Security Config to Use Signature Algorithm ES256 - Replace the jwtDecoder --- .../vpdpbackend/config/SecurityConfig.java | 62 ++++--------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/config/SecurityConfig.java b/src/main/java/org/ejprarediseases/vpdpbackend/config/SecurityConfig.java index 7873b1f..4ab1e8b 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/config/SecurityConfig.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/config/SecurityConfig.java @@ -1,77 +1,38 @@ package org.ejprarediseases.vpdpbackend.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.convert.converter.Converter; -import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.web.SecurityFilterChain; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; @EnableWebSecurity @EnableMethodSecurity @Configuration public class SecurityConfig { - interface Jwt2AuthoritiesConverter extends Converter> { - } - - - @SuppressWarnings("unchecked") - @Bean - Jwt2AuthoritiesConverter authoritiesConverter() { - // This is a converter for roles as embedded in the JWT by a Keycloak server - // Roles are taken from both realm_access.roles & resource_access.{client}.roles - return jwt -> { - final var realmAccess = (Map) jwt.getClaims().getOrDefault("realm_access", Map.of()); - final var realmRoles = (Collection) realmAccess.getOrDefault("roles", List.of()); - - final var resourceAccess = (Map) jwt.getClaims().getOrDefault("resource_access", Map.of()); - // We assume here you have "spring-addons-confidential" and - // "spring-addons-public" clients configured with "client roles" mapper in - // Keycloak - final var confidentialClientAccess = (Map) resourceAccess - .getOrDefault("spring-addons-confidential", Map.of()); - final var confidentialClientRoles = (Collection) confidentialClientAccess.getOrDefault("roles", - List.of()); - final var publicClientAccess = (Map) resourceAccess.getOrDefault("spring-addons-public", - Map.of()); - final var publicClientRoles = (Collection) publicClientAccess.getOrDefault("roles", List.of()); - - return Stream - .concat(realmRoles.stream(), - Stream.concat(confidentialClientRoles.stream(), publicClientRoles.stream())) - .map(SimpleGrantedAuthority::new).toList(); - }; - } - - interface Jwt2AuthenticationConverter extends Converter { - } + @Value("${JWK_SET_URI}") + private String jwtSetUri; @Bean - Jwt2AuthenticationConverter authenticationConverter( - Converter> authoritiesConverter) { - return jwt -> new JwtAuthenticationToken(jwt, authoritiesConverter.convert(jwt)); + public JwtDecoder jwtDecoder() { + return NimbusJwtDecoder.withJwkSetUri(jwtSetUri) + .jwsAlgorithm(SignatureAlgorithm.ES256).build(); } @Bean public SecurityFilterChain apiFilterChain( HttpSecurity http, - ServerProperties serverProperties, - Converter authenticationConverter) throws Exception { + ServerProperties serverProperties) throws Exception { http.authorizeHttpRequests(authorize -> authorize .requestMatchers("/**") @@ -80,8 +41,7 @@ public SecurityFilterChain apiFilterChain( .authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 - .jwt(jwt -> jwt - .jwtAuthenticationConverter(authenticationConverter) + .jwt(jwt -> jwt.decoder(jwtDecoder()) ) ) .cors(Customizer.withDefaults()) From b5ad6affdc6d2a3e9093f99bab4122c6341fda2c Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Mon, 18 Sep 2023 10:46:23 +0200 Subject: [PATCH 19/49] #23 - Check unauthorized filters - Check search parametes before processing the request --- .../vpdpbackend/VpDpBackendApplication.java | 4 ++++ .../search/v1/SearchController.java | 19 +++++++++++++++---- .../vpdpbackend/utils/UserHandler.java | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java index abf61e3..e7e300a 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java @@ -7,10 +7,14 @@ import io.swagger.v3.oas.annotations.info.License; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @OpenAPIDefinition( + servers = { + @Server(url = "/", description = "Default Server URL") + }, security = @SecurityRequirement(name = "bearerAuth"), info = @Info( title = "VP-Portal Backend", diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java index d7116a9..f3b61c4 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchController.java @@ -14,6 +14,7 @@ import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.enums.Sex; import org.ejprarediseases.vpdpbackend.search.v1.model.SearchRequest; import org.ejprarediseases.vpdpbackend.search.v1.model.SearchResponse; +import org.ejprarediseases.vpdpbackend.utils.UserHandler; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; @@ -23,6 +24,8 @@ import java.io.IOException; import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; @RestController @RequestMapping("v1/search") @@ -126,13 +129,21 @@ public ResponseEntity searchForDiseasesByOrphaCode( SearchRequest searchRequest = new SearchRequest(); searchRequest.setResourceTypes(resourceTypes); searchRequest.setCountries(countries); - searchRequest.setSexes(sexes); - searchRequest.setAgeThisYear(ageThisYear); - searchRequest.setSymptomOnset(symptomOnset); - searchRequest.setAgeAtDiagnosis(ageAtDiagnoses); searchRequest.setDiseases(diseases); searchRequest.setResourceId(resourceId); SearchResponse searchResponse; + if(UserHandler.isAuthenticated() && !UserHandler.isAnonymous()) { + searchRequest.setSexes(sexes); + searchRequest.setAgeThisYear(ageThisYear); + searchRequest.setSymptomOnset(symptomOnset); + searchRequest.setAgeAtDiagnosis(ageAtDiagnoses); + } else { + if (Stream.of(sexes, ageThisYear, symptomOnset, ageAtDiagnoses).noneMatch(Objects::isNull)) { + return new ResponseEntity<>( + "Please log in to activate these filers: sexes, ageThisYear, symptomOnset, ageAtDiagnoses", + HttpStatus.UNAUTHORIZED); + } + } try { searchResponse = searchService.searchForDiseasesByOrphaCode(searchRequest); } catch (IOException e) { diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java new file mode 100644 index 0000000..95aac62 --- /dev/null +++ b/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java @@ -0,0 +1,16 @@ +package org.ejprarediseases.vpdpbackend.utils; + +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; + +public class UserHandler { + + public static boolean isAuthenticated() { + return SecurityContextHolder.getContext().getAuthentication() != null && + SecurityContextHolder.getContext().getAuthentication().isAuthenticated(); + } + + public static boolean isAnonymous() { + return (SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken); + } +} From 87f9d4df5cca161d2047b76a603493bf887cc05a Mon Sep 17 00:00:00 2001 From: Ammar Barakat <37185366+ammarbarakat@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:57:22 +0200 Subject: [PATCH 20/49] Create dev-ci-cd.yml --- .github/workflows/dev-ci-cd.yml | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/dev-ci-cd.yml diff --git a/.github/workflows/dev-ci-cd.yml b/.github/workflows/dev-ci-cd.yml new file mode 100644 index 0000000..4ef0616 --- /dev/null +++ b/.github/workflows/dev-ci-cd.yml @@ -0,0 +1,46 @@ +name: DEV-CI-CD + +on: + push: + branches: [ "develop" ] + +jobs: + + ci: + + runs-on: ubuntu-latest + environment: DEV + + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: mvn clean package -Dmaven.source.skip -Dmaven.test.skip=true + + - name: Build the Docker image + run: docker build . --file docker/Dockerfile --tag ${{ secrets.DOCKER_IMAGE_TAG }} --no-cache + + - name: Login to Registry + run: docker login ${{ secrets.REGISTRY_URL }} -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + + - name: Push the latest DEV image + run: docker push ${{ secrets.DOCKER_IMAGE_TAG }} + + cd: + name: Redeploy - Webhook call + runs-on: ubuntu-latest + environment: DEV + needs: ci + steps: + - name: Redeploy + uses: joelwmale/webhook-action@master + with: + url: ${{ secrets.WEBHOOK_URL }} + headers: ${{ secrets.WEBHOOK_HEADERS }} From 08e6045156d2383958d31446fd6fd1e7d44bcc38 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Wed, 20 Sep 2023 13:17:02 +0200 Subject: [PATCH 21/49] no issue - add Dockerfile --- docker/Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docker/Dockerfile diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..ace0532 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM openjdk:18-jdk-alpine +EXPOSE 8090 +RUN apk add sudo +RUN addgroup -S ejp && adduser -S ejp -G ejp +USER ejp:ejp +ARG JAR_FILE=target/*.jar +COPY ${JAR_FILE} /opt/app.jar +ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /opt/app.jar"] From 1f08f30fe965322464b3d87fb8954b6d9d21878e Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Thu, 21 Sep 2023 09:02:29 +0200 Subject: [PATCH 22/49] no issue - update static resources file --- src/main/resources/static/resources.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index cb7c7f7..b2c6187 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -58,7 +58,7 @@ }, { "resourceName": "BBMRI-Eric", - "resourceAddress": "http://ejprd.ref.development.bibbox.org/api/ejprd/bbmri/v3/", + "resourceAddress": "http://ejp-rd-prod1.vm.cesnet.cz:5050/api/catalogs", "resourceHomePage": "https://directory.bbmri-eric.eu/", "email": "ammar.barakat@kgu.de", "resourceDescription": "The BBMRI-Eric catalogue of rare disease registries and biobanks.", @@ -223,7 +223,7 @@ "created": "", "updated": "", "specsURL": "", - "logo": "https://ega-archive.org/images/logo.png", + "logo": "https://static.ega-archive.org/img/logo.png", "resourceContentType": "", "queryable": false, "queryType": [], From e73c824b9690066c9cad00559249b115f6f69e10 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Thu, 21 Sep 2023 09:27:54 +0200 Subject: [PATCH 23/49] no issue - update Dockerfile --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ace0532..9fd80b6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ FROM openjdk:18-jdk-alpine -EXPOSE 8090 +EXPOSE 8095 RUN apk add sudo RUN addgroup -S ejp && adduser -S ejp -G ejp USER ejp:ejp From 8f61638c66ef85ed88b332ff4207d2eb40febad5 Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Thu, 28 Sep 2023 10:55:56 +0200 Subject: [PATCH 24/49] #25 - Send the Authorization Header to Resources for Proper Authorization Handling - Send the Authorization Header to Resources for Proper Authorization Handling --- .../search/v1/handler/BeaconCatalogQueryHandler.java | 2 ++ .../v1/handler/BeaconIndividualsQueryHandler.java | 2 ++ .../ejprarediseases/vpdpbackend/utils/UserHandler.java | 10 ++++++++++ 3 files changed, 14 insertions(+) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java index 3511168..6f473fa 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconCatalogQueryHandler.java @@ -9,6 +9,7 @@ import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.filters.ontology_filter.BeaconRequestBodyOntologyFilter; import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.sections.BeaconRequestBodyMetaSection; import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.sections.BeaconRequestBodyQuerySection; +import org.ejprarediseases.vpdpbackend.utils.UserHandler; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.WebClient; @@ -34,6 +35,7 @@ public static String getResponse(Resource resource, BeaconRequestBody requestBod .uri( resource.getResourceAddress()) .bodyValue(requestBody) .accept(MediaType.APPLICATION_JSON) + .header("Authorization", UserHandler.getBearerToken()) .retrieve() .bodyToMono(String.class) .block(); diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java index 4c06679..0174eb9 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconIndividualsQueryHandler.java @@ -8,6 +8,7 @@ import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.filters.ontology_filter.BeaconRequestBodyOntologyFilter; import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.sections.BeaconRequestBodyMetaSection; import org.ejprarediseases.vpdpbackend.search.v1.model.beacon.request_body.sections.BeaconRequestBodyQuerySection; +import org.ejprarediseases.vpdpbackend.utils.UserHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; @@ -43,6 +44,7 @@ public static String getResponse(Resource resource, BeaconRequestBody requestBod .bodyValue(requestBody) .accept(MediaType.APPLICATION_JSON) .header("auth-key", authKey) + .header("Authorization", UserHandler.getBearerToken()) .retrieve() .onStatus(httpStatus -> httpStatus.value() == 403, error -> Mono.error(new RuntimeException("error Body"))) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java index 95aac62..437c399 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/utils/UserHandler.java @@ -2,6 +2,7 @@ import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; public class UserHandler { @@ -13,4 +14,13 @@ public static boolean isAuthenticated() { public static boolean isAnonymous() { return (SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken); } + + public static String getBearerToken() { + String token = null; + if (isAuthenticated() && !isAnonymous()) { + var authentication = SecurityContextHolder.getContext().getAuthentication(); + token = "Bearer " + ((JwtAuthenticationToken) authentication).getToken().getTokenValue(); + } + return token; + } } From 544ef0f74277dc0d2923e4755ad04e8c9c7d31dc Mon Sep 17 00:00:00 2001 From: BARAKAT Date: Thu, 28 Sep 2023 15:56:14 +0200 Subject: [PATCH 25/49] #27 - Allow Defining the Base URL for Swagger UI Using Environment Variables - Allow Defining the Base URL for Swagger UI Using Environment Variables --- .../ejprarediseases/vpdpbackend/VpDpBackendApplication.java | 2 +- src/main/resources/application-default.yml | 3 +++ src/main/resources/application-prod.yml | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java index e7e300a..f3a744f 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/VpDpBackendApplication.java @@ -13,7 +13,7 @@ @OpenAPIDefinition( servers = { - @Server(url = "/", description = "Default Server URL") + @Server(url = "${application.swagger.baseUrl}", description = "Default Server URL"), }, security = @SecurityRequirement(name = "bearerAuth"), info = @Info( diff --git a/src/main/resources/application-default.yml b/src/main/resources/application-default.yml index 662c4bb..d7c353a 100644 --- a/src/main/resources/application-default.yml +++ b/src/main/resources/application-default.yml @@ -9,6 +9,9 @@ application: senderEmailAddress: ${SENDER_OUTLOOK_ADDRESS} senderEmailPassword: ${SENDER_OUTLOOK_PASSWORD} + swagger: + baseUrl: ${SWAGGER_UI_BASE_URL:/} + hierarchyUrl: ${HIERARCHY_URL} geneMappingUrl: ${GENE_MAPPING_URL} resourcesAuthKeys: ${RESOURCES_AUTH_KEYS} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 662c4bb..d7c353a 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -9,6 +9,9 @@ application: senderEmailAddress: ${SENDER_OUTLOOK_ADDRESS} senderEmailPassword: ${SENDER_OUTLOOK_PASSWORD} + swagger: + baseUrl: ${SWAGGER_UI_BASE_URL:/} + hierarchyUrl: ${HIERARCHY_URL} geneMappingUrl: ${GENE_MAPPING_URL} resourcesAuthKeys: ${RESOURCES_AUTH_KEYS} From 0a73808021a6b1041e6d9c3826407a8ecec15ac1 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran Date: Mon, 27 Nov 2023 10:15:27 +0100 Subject: [PATCH 26/49] 29-Adjust-resource-type - change Knowledgebase to Dataset - add Guideline --- .../vpdpbackend/resource/v1/model/ResourceType.java | 3 ++- .../vpdpbackend/search/v1/handler/BeaconFilterHandler.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java index 0c417e7..481b537 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java @@ -4,7 +4,8 @@ public enum ResourceType { PATIENT_REGISTRY, BIO_BANK, - KNOWLEDGE_BASE, + DATASET, + GUIDELINE, CATALOG; } diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java index 513cfdf..4ea3a37 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java @@ -192,7 +192,8 @@ private static String getResourceTypeIdBasedOnApiSpec(ResourceType type) { return switch (type) { case PATIENT_REGISTRY -> "PatientRegistryDataset"; case BIO_BANK -> "BiobankDataset"; - case KNOWLEDGE_BASE -> "KnowledgeBase"; + case DATASET -> "Dataset"; + case GUIDELINE -> "Guideline"; case CATALOG -> "Catalog"; }; } From 0c433553369d40b4849bf8b677f193c91a91916d Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran Date: Mon, 27 Nov 2023 10:15:27 +0100 Subject: [PATCH 27/49] #29-Adjust-resource-type - change Knowledgebase to Dataset - add Guideline --- .../vpdpbackend/resource/v1/model/ResourceType.java | 3 ++- .../vpdpbackend/search/v1/handler/BeaconFilterHandler.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java index 0c417e7..481b537 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/resource/v1/model/ResourceType.java @@ -4,7 +4,8 @@ public enum ResourceType { PATIENT_REGISTRY, BIO_BANK, - KNOWLEDGE_BASE, + DATASET, + GUIDELINE, CATALOG; } diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java index 513cfdf..4ea3a37 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/handler/BeaconFilterHandler.java @@ -192,7 +192,8 @@ private static String getResourceTypeIdBasedOnApiSpec(ResourceType type) { return switch (type) { case PATIENT_REGISTRY -> "PatientRegistryDataset"; case BIO_BANK -> "BiobankDataset"; - case KNOWLEDGE_BASE -> "KnowledgeBase"; + case DATASET -> "Dataset"; + case GUIDELINE -> "Guideline"; case CATALOG -> "Catalog"; }; } From daa750a5059856b603880e23d93148462143d6b9 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran Date: Mon, 27 Nov 2023 10:45:40 +0100 Subject: [PATCH 28/49] #31 - update resources - update resourcetypes --- src/main/resources/static/resources.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index b2c6187..a56399e 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -122,7 +122,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "A collaborative platform for contributing and maintaining pathway information.", "resourceType": [ - "KNOWLEDGE_BASE" + "DATASET" ], "id": "6", "created": "2020-10-26T15:26:15.892Z", @@ -141,7 +141,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": ": The Care and Trial Site Registry (CTSR) is an online self-entry database of specialised sites seeing patients with neuromuscular and neurodegenerative diseases. It holds site-level information relevant to clinical studies and care provision, including facilities, equipment, personnel, and trial experience, as well aggregate data about their patient population. It does not hold patient-level data.", "resourceType": [ - "KNOWLEDGE_BASE" + "DATASET" ], "id": "7", "created": "2020-10-26T15:26:15.898Z", @@ -160,7 +160,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "hPSCreg is a global registry for human pluripotent stem cell lines (hPSC-lines). It aims to provide to the community\n\n1) a central and searchable hub for available hPSC-lines\n2) a central registry of clinical studies based on hPSC-lines\n3) a standardized identifier for hPSC-lines and register of these standard names\n4) a trustworthy data source for hPSC-lines by verifying the ethical and biological conformity of registered lines based on community standards\n5) comparability of quality standards in hPSC research\n6) certification of quality and ethical provenance of hPSC-lines\n7) a platform where any scientist or institution generating or working with PSC lines can register their cell lines, projects or clinical studies.", "resourceType": [ - "KNOWLEDGE_BASE" + "DATASET" ], "id": "8", "created": "2020-10-26T15:26:15.893Z", @@ -198,7 +198,7 @@ "email": "ammar.barakat@kgu.de", "resourceDescription": "A catalog to contain all metabolights study resources.", "resourceType": [ - "KNOWLEDGE_BASE" + "DATASET" ], "id": "10", "created": "", From 0a136c6dd0b7b8db831ce253e81cdce4f0fa048c Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran Date: Sun, 4 Feb 2024 18:25:50 +0100 Subject: [PATCH 29/49] #33 - filters are ignored - check resourcetype from resourcelist before sending a query to resource with individuals endpoint --- .../vpdpbackend/search/v1/SearchService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchService.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchService.java index 6b8a386..ee29c86 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchService.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/SearchService.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.ejprarediseases.vpdpbackend.resource.v1.ResourceService; import org.ejprarediseases.vpdpbackend.resource.v1.model.Resource; +import org.ejprarediseases.vpdpbackend.resource.v1.model.ResourceType; import org.ejprarediseases.vpdpbackend.search.v1.handler.BeaconCatalogQueryHandler; import org.ejprarediseases.vpdpbackend.search.v1.handler.BeaconIndividualsQueryHandler; import org.ejprarediseases.vpdpbackend.search.v1.model.SearchRequest; @@ -39,8 +40,12 @@ public SearchResponse searchForDiseasesByOrphaCode(SearchRequest searchRequest) throws IOException, NoSuchElementException { Resource resource = resourceService.getResourceById(searchRequest.getResourceId()); if (resource.getQueryType().contains(BEACON_INDIVIDUALS)) { - String authKey = resourceService.getResourceAuthKeyById(searchRequest.getResourceId()); - return handleBeaconIndividualsQuery(searchRequest, resource, authKey); + for (ResourceType resourceType : resource.getResourceType()){ + if (searchRequest.getResourceTypes().contains(resourceType)){ + String authKey = resourceService.getResourceAuthKeyById(searchRequest.getResourceId()); + return handleBeaconIndividualsQuery(searchRequest, resource, authKey); + } + } } else if (resource.getQueryType().contains(BEACON_CATALOG)) { return handleBeaconCatalogQuery(searchRequest, resource); } From df6beb755e059846146e35b247e07e926e4e9e55 Mon Sep 17 00:00:00 2001 From: Larie Borelle Siabou Date: Mon, 12 Feb 2024 14:51:54 +0100 Subject: [PATCH 30/49] #35-Search-results-when-searching-for-ORPHA:635-do-not-stop Resolve the search problem --- .../result_set/individuals/IndividualsResultSetInfo.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java index 13b4985..2073b5d 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java @@ -1,8 +1,10 @@ package org.ejprarediseases.vpdpbackend.search.v1.model.beacon.response_body.result_set.individuals; import lombok.Data; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class IndividualsResultSetInfo { private String contactPoint; private String contactEmail; From 0226130a2c83beacf2c8a9699f0be7d2645060d0 Mon Sep 17 00:00:00 2001 From: Larie Borelle Siabou Date: Mon, 12 Feb 2024 14:56:57 +0100 Subject: [PATCH 31/49] #35-Search-results-when-searching-for-ORPHA:635-do-not-stop Resolve the search problem --- .../result_set/individuals/IndividualsResultSetInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java index 2073b5d..99258b1 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java @@ -2,9 +2,9 @@ import lombok.Data; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@Data @JsonIgnoreProperties(ignoreUnknown = true) +@Data + public class IndividualsResultSetInfo { private String contactPoint; private String contactEmail; From 85df705e5a6ce1b700946ca8b6ab5840faeb056f Mon Sep 17 00:00:00 2001 From: Larie Borelle Siabou Date: Tue, 13 Feb 2024 09:43:04 +0100 Subject: [PATCH 32/49] #35-Search-results-when-searching-for-ORPHA:635-do-not-stop Resolve the search problem --- .../result_set/individuals/IndividualsResultSetInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java index 99258b1..2073b5d 100644 --- a/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java +++ b/src/main/java/org/ejprarediseases/vpdpbackend/search/v1/model/beacon/response_body/result_set/individuals/IndividualsResultSetInfo.java @@ -2,9 +2,9 @@ import lombok.Data; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -@JsonIgnoreProperties(ignoreUnknown = true) -@Data +@Data +@JsonIgnoreProperties(ignoreUnknown = true) public class IndividualsResultSetInfo { private String contactPoint; private String contactEmail; From 1eaa0998d607a18a88d20660ae01e5d28c9bdef8 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:26:58 +0100 Subject: [PATCH 33/49] Update resources.txt - remove endpoints from Genturis and Ithaca as the resources only provide test data --- src/main/resources/static/resources.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index a56399e..521d386 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -20,7 +20,7 @@ }, { "resourceName": "Ithaca", - "resourceAddress": "https://ithaca-emx2.molgeniscloud.org/api/beacon/individuals", + "resourceAddress": "", "resourceHomePage": "https://ithaca.molgeniscloud.org/", "email": "ammar.barakat@kgu.de", "resourceDescription": "The main objective of this WP is to set up an interoperable registry dedicated to rare diseases within the scope of ITHACA called ILIAD Rare Diseases patient registry: an International Library of Intellectual disability and Anomalies of Development.", @@ -34,7 +34,7 @@ "logo": "https://ern-ithaca.eu/wp-content/themes/ernithaca/dist/images/ern-ithaca.png", "resourceContentType": "", "queryable": true, - "queryType": ["BEACON_INDIVIDUALS"], + "queryType": [], "theme": [] }, { @@ -308,7 +308,7 @@ }, { "resourceName": "Genturis", - "resourceAddress": "https://genturis-emx2.molgeniscloud.org/api/beacon/individuals", + "resourceAddress": "", "resourceHomePage": "https://genturis.molgeniscloud.org/", "email": "ammar.barakat@kgu.de", "resourceDescription": "The GENTURIS registry is the European registry for patients with one of the genetic tumour risk syndromes (genturis). The registry is affiliated to the European Reference Network for all patients with one of the genetic tumour risk syndromes (ERN GENTURIS).", @@ -322,7 +322,7 @@ "logo": "https://genturis.molgeniscloud.org/logo/genturis-registry-logo-bg-white.png", "resourceContentType": "", "queryable": true, - "queryType": ["BEACON_INDIVIDUALS"], + "queryType": [], "theme": [] }, { @@ -382,4 +382,4 @@ "queryType": [], "theme": [] } -] \ No newline at end of file +] From b927b064dcabae5d8d1cdef5395ebdad187c0328 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:43:00 +0100 Subject: [PATCH 34/49] Update resources.txt - update queryable attribute for Genturis and Ithaca resources --- src/main/resources/static/resources.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 521d386..7ba5203 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -33,7 +33,7 @@ "specsURL": "", "logo": "https://ern-ithaca.eu/wp-content/themes/ernithaca/dist/images/ern-ithaca.png", "resourceContentType": "", - "queryable": true, + "queryable": false, "queryType": [], "theme": [] }, @@ -321,7 +321,7 @@ "specsURL": "", "logo": "https://genturis.molgeniscloud.org/logo/genturis-registry-logo-bg-white.png", "resourceContentType": "", - "queryable": true, + "queryable": false, "queryType": [], "theme": [] }, From 5a501cd601deab2cdadd9d3eb4f7cc73bc289cdf Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Sat, 24 Feb 2024 18:33:49 +0100 Subject: [PATCH 35/49] Update resources.txt Trying Git --- src/main/resources/static/resources.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index a56399e..f4596d5 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -1,6 +1,6 @@ [ { - "resourceName": "RD-Connect-GPAP", + "resourceName": "RD-Connect-GPAP-gio", "resourceAddress": "https://platform.rd-connect.eu/beacon2/api/individuals", "resourceHomePage": "https://platform.rd-connect.eu", "email": "ammar.barakat@kgu.de", @@ -382,4 +382,4 @@ "queryType": [], "theme": [] } -] \ No newline at end of file +] From 3bd1fd753bbfbf9dbf4227210b0601142585136c Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:11:00 +0100 Subject: [PATCH 36/49] Update resources.txt remove testing --- src/main/resources/static/resources.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index f4596d5..02f4147 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -1,6 +1,6 @@ [ { - "resourceName": "RD-Connect-GPAP-gio", + "resourceName": "RD-Connect-GPAP", "resourceAddress": "https://platform.rd-connect.eu/beacon2/api/individuals", "resourceHomePage": "https://platform.rd-connect.eu", "email": "ammar.barakat@kgu.de", From b42c7f602d32e20628f1001a473b67c896378838 Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:12:43 +0100 Subject: [PATCH 37/49] Update resources.txt Erkreg updated --- src/main/resources/static/resources.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index a56399e..f8a902c 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -41,8 +41,8 @@ "resourceName": "ERKReg", "resourceAddress": "https://www448.lamp.le.ac.uk/erknet/BeaconAPI/83/individuals", "resourceHomePage": "https://www.erknet.org/patients-registry/registry-mission", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "The European Rare Kidney Disease Registry.", + "email": "contact@erknet.org ", + "resourceDescription": "ERKReg, a Web-based registry for all patients with rare kidney diseases. The main objectives of this core registry are to generate epidemiological information, identify current patient cohort for clinical research, explore diagnostic and therapeutic management practices, and monitor treatment performance and patient’s outcomes.", "resourceType": [ "PATIENT_REGISTRY" ], @@ -50,7 +50,7 @@ "created": "2021-10-13T06:25:33.898Z", "updated": "2021-10-13T06:25:33.898Z", "specsURL": "", - "logo": "https://endo-ern.eu/wp-content/uploads/2018/03/eurreca-logo-768x242.jpg", + "logo": "https://www.erknet.org/typo3conf/ext/sitepackage/Resources/Public/Images/Logos/Logo_ERKNet.png", "resourceContentType": "", "queryable": true, "queryType": ["BEACON_INDIVIDUALS"], @@ -382,4 +382,4 @@ "queryType": [], "theme": [] } -] \ No newline at end of file +] From 176da1ac3801d3bec4a26983b3e552eade8b3a30 Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:16:44 +0100 Subject: [PATCH 38/49] Update resources.txt erk-reg updated --- src/main/resources/static/resources.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 02f4147..f8a902c 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -41,8 +41,8 @@ "resourceName": "ERKReg", "resourceAddress": "https://www448.lamp.le.ac.uk/erknet/BeaconAPI/83/individuals", "resourceHomePage": "https://www.erknet.org/patients-registry/registry-mission", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "The European Rare Kidney Disease Registry.", + "email": "contact@erknet.org ", + "resourceDescription": "ERKReg, a Web-based registry for all patients with rare kidney diseases. The main objectives of this core registry are to generate epidemiological information, identify current patient cohort for clinical research, explore diagnostic and therapeutic management practices, and monitor treatment performance and patient’s outcomes.", "resourceType": [ "PATIENT_REGISTRY" ], @@ -50,7 +50,7 @@ "created": "2021-10-13T06:25:33.898Z", "updated": "2021-10-13T06:25:33.898Z", "specsURL": "", - "logo": "https://endo-ern.eu/wp-content/uploads/2018/03/eurreca-logo-768x242.jpg", + "logo": "https://www.erknet.org/typo3conf/ext/sitepackage/Resources/Public/Images/Logos/Logo_ERKNet.png", "resourceContentType": "", "queryable": true, "queryType": ["BEACON_INDIVIDUALS"], From d0b197e21f04867bb6b1c088e133e2ecd3819986 Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:04:08 +0100 Subject: [PATCH 39/49] Update resources.txt Finalised: DDP, VASCA, EURO-NMD, Metabolights, eUROGEN, ERKreg, hPSCReg --- src/main/resources/static/resources.txt | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index f8a902c..42b1553 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -3,7 +3,7 @@ "resourceName": "RD-Connect-GPAP", "resourceAddress": "https://platform.rd-connect.eu/beacon2/api/individuals", "resourceHomePage": "https://platform.rd-connect.eu", - "email": "ammar.barakat@kgu.de", + "email": "help@rd-connect.eu ", "resourceDescription": "The RD‐Connect Genome‐Phenome Analysis Platform (GPAP) is a collaborative platform to accelerate rare disease diagnosis and gene discovery, that enables authorised users to submit, share, analyse and interpret integrated genome-phenome data from Rare Disease patients and relatives.", "resourceType": [ "PATIENT_REGISTRY" @@ -59,7 +59,7 @@ { "resourceName": "BBMRI-Eric", "resourceAddress": "http://ejp-rd-prod1.vm.cesnet.cz:5050/api/catalogs", - "resourceHomePage": "https://directory.bbmri-eric.eu/", + "resourceHomePage": "https://www.bbmri-eric.eu/", "email": "ammar.barakat@kgu.de", "resourceDescription": "The BBMRI-Eric catalogue of rare disease registries and biobanks.", "resourceType": [ @@ -70,7 +70,7 @@ "created": "2020-12-02T10:42:09.170Z", "updated": "2020-12-02T10:42:09.170Z", "specsURL": "", - "logo": "", + "logo": "https://www.bbmri-eric.eu/wp-content/themes/bbmri-eric/img/BBMRI-ERIC-gateway-for-health.svg", "resourceContentType": "", "queryable": true, "queryType": ["BEACON_CATALOG"], @@ -97,11 +97,11 @@ "theme": [] }, { - "resourceName": "DDP", + "resourceName": "Duchenne Data Platform", "resourceAddress": "", "resourceHomePage": "https://duchenne.nl/duchenne-data-platform-english/", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "The Duchenne Data Platform is a patient-led registry. Health information collected is stored in 'personal datalockers' for easy access at all times by patients through wearables or online.", + "email": "info@duchenne.nl", + "resourceDescription": "The Duchenne Data Platform (DDP) is a patient-led registry. Patients are the owners of their data and have their own data lockers where they can not only collect their Patient Reported Outcomes (PROs) but can also upload their data from other sources such as hospitals and wearables.", "resourceType": [ "PATIENT_REGISTRY" ], @@ -109,7 +109,7 @@ "created": "2020-11-07T05:12:55.898Z", "updated": "2020-11-07T05:12:55.898Z", "specsURL": "", - "logo": "", + "logo": "https://duchenne.nl/wp-content/uploads/2016/06/duchenne-rond-logo300.jpg", "resourceContentType": "", "queryable": false, "queryType": ["BEACON_INDIVIDUALS"], @@ -157,8 +157,8 @@ "resourceName": "hPSCreg", "resourceAddress": "https://ejp-rd-dev1.vm.cesnet.cz/grlcs/hPSCreg", "resourceHomePage": "https://hpscreg.eu/about", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "hPSCreg is a global registry for human pluripotent stem cell lines (hPSC-lines). It aims to provide to the community\n\n1) a central and searchable hub for available hPSC-lines\n2) a central registry of clinical studies based on hPSC-lines\n3) a standardized identifier for hPSC-lines and register of these standard names\n4) a trustworthy data source for hPSC-lines by verifying the ethical and biological conformity of registered lines based on community standards\n5) comparability of quality standards in hPSC research\n6) certification of quality and ethical provenance of hPSC-lines\n7) a platform where any scientist or institution generating or working with PSC lines can register their cell lines, projects or clinical studies.", + "email": "https://hpscreg.eu/contact", + "resourceDescription": "The human pluripotent stem cell registry (hPSCreg), accessible at https://hpscreg.eu, is a public registry and data portal for human embryonic and induced pluripotent stem cell lines (hESC and hiPSC).", "resourceType": [ "DATASET" ], @@ -195,7 +195,7 @@ "resourceName": "Metabolights", "resourceAddress": "", "resourceHomePage": "https://www.ebi.ac.uk/metabolights/", - "email": "ammar.barakat@kgu.de", + "email": "https://www.ebi.ac.uk/about/contact", "resourceDescription": "A catalog to contain all metabolights study resources.", "resourceType": [ "DATASET" @@ -233,8 +233,8 @@ "resourceName": "Registry VASCERN (VASCA)", "resourceAddress": "", "resourceHomePage": "https://vascern.eu/groupe/registry/", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "Databases of the ERN vascular anomalies", + "email": "vascern_registry@vascern.eu ", + "resourceDescription": "The VASCA registry collects data from patients with rare vascular diseases who are being treated at various expert centres across Europe. Its primary objective is to enhance our understanding of these rare diseases through various research endeavors, such as natural history studies, genotype-phenotype correlations, population comparisons, and cross-country care comparisons.", "resourceType": [ "PATIENT_REGISTRY" ], @@ -290,8 +290,8 @@ { "resourceName": "Registry ERN EURO-NMD (EURO-NMD Registry )", "resourceAddress": "", - "resourceHomePage": "", - "email": "ammar.barakat@kgu.de", + "resourceHomePage": "https://ern-euro-nmd.eu/", + "email": "info@ern-euro-nmd.eu", "resourceDescription": "EURO-NMD is a European reference network for the thematic grouping of rare neuromuscular diseases (NMDs), a broad group of related disorders that represent a major cause of mortality and lifelong disability in children and adults.", "resourceType": [ "PATIENT_REGISTRY" @@ -328,9 +328,9 @@ { "resourceName": "FAIRVasc", "resourceAddress": "", - "resourceHomePage": "", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "FAIRVASC is a research project of the European Vasculitis Society (EUVAS) and RITA European Reference Network, bringing together leading scientists, clinicians and patient organisations. The FAIRVASC consortium is made up of 10 partners who represent all of these areas of patient care, also substantial support from VIFOR PHARMA should be acknowledged. There are many important gaps in our knowledge about why and how vasculitis occurs, why some people seem to be more susceptible than others, how the disease process acts inside the body and whether different kinds of vasculitis should be treated in different ways.", + "resourceHomePage": "https://fairvasc.eu/ ", + "email": "fairvasc@cm-uj.krakow.pl", + "resourceDescription": "FAIRVASC is building registry interoperability to inform clinical care Vasculitis (an acquired, immune-mediated inflammatory disease involving blood vessels of many tissues and organs), needs sufficiently large quantities of data to enable well-informed conclusions about treatments and possible cures. It is thus essential to combine the databases of patient registries of several countries to build a dataset of sufficient size to enable meaningful research.", "resourceType": [ "PATIENT_REGISTRY" ], @@ -367,7 +367,7 @@ "resourceName": "Registry ERN eUROGEN", "resourceAddress": "", "resourceHomePage": "https://eurogen-ern.eu/what-we-do/registry-digital-activities/aim/", - "email": "ammar.barakat@kgu.de", + "email": "eurogen@uroweb.org", "resourceDescription": "Registry from ERN eUROGEN on rare uro-recto-genital diseases and complex conditions.", "resourceType": [ "PATIENT_REGISTRY" From b991abcad6584812915c44f633bbb08bc7731d0b Mon Sep 17 00:00:00 2001 From: HaddadTala <91144909+HaddadTala@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:49:31 +0100 Subject: [PATCH 40/49] Update resources.txt --- src/main/resources/static/resources.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 7ba5203..318798b 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -77,14 +77,13 @@ "theme": [] }, { - "resourceName": "Orphanet", + "resourceName": "Orphanet catalogue of rare disease registries and biobanks", "resourceAddress": "http://155.133.131.171:8080/OrphanetBeacon/catalogs", - "resourceHomePage": "https://www.orpha.net/consor/cgi-bin/Disease.php", - "email": "ammar.barakat@kgu.de", + "resourceHomePage": "https://www.orpha.net/", + "email": "contact.orphanet@inserm.fr", "resourceDescription": "The Orphanet catalogue of rare disease registries and biobanks.", "resourceType": [ - "PATIENT_REGISTRY", - "BIO_BANK" + "CATALOG" ], "id": "4", "created": "2020-10-26T15:26:15.891Z", From 659e54b5d0e5bbd358e1dd48958b81b33e80ae9b Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:04:57 +0100 Subject: [PATCH 41/49] Update resources.txt All were confirmed but molgenis --- src/main/resources/static/resources.txt | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 42b1553..f02028a 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -22,7 +22,7 @@ "resourceName": "Ithaca", "resourceAddress": "https://ithaca-emx2.molgeniscloud.org/api/beacon/individuals", "resourceHomePage": "https://ithaca.molgeniscloud.org/", - "email": "ammar.barakat@kgu.de", + "email": "https://ern-ithaca.eu/contact/", "resourceDescription": "The main objective of this WP is to set up an interoperable registry dedicated to rare diseases within the scope of ITHACA called ILIAD Rare Diseases patient registry: an International Library of Intellectual disability and Anomalies of Development.", "resourceType": [ "PATIENT_REGISTRY" @@ -60,11 +60,10 @@ "resourceName": "BBMRI-Eric", "resourceAddress": "http://ejp-rd-prod1.vm.cesnet.cz:5050/api/catalogs", "resourceHomePage": "https://www.bbmri-eric.eu/", - "email": "ammar.barakat@kgu.de", + "email": "contact@bbmri-eric.eu", "resourceDescription": "The BBMRI-Eric catalogue of rare disease registries and biobanks.", "resourceType": [ - "PATIENT_REGISTRY", - "BIO_BANK" + "CATALOG" ], "id": "3", "created": "2020-12-02T10:42:09.170Z", @@ -80,11 +79,10 @@ "resourceName": "Orphanet", "resourceAddress": "http://155.133.131.171:8080/OrphanetBeacon/catalogs", "resourceHomePage": "https://www.orpha.net/consor/cgi-bin/Disease.php", - "email": "ammar.barakat@kgu.de", + "email": "info@orphanet.org", "resourceDescription": "The Orphanet catalogue of rare disease registries and biobanks.", "resourceType": [ - "PATIENT_REGISTRY", - "BIO_BANK" + "CATALOG" ], "id": "4", "created": "2020-10-26T15:26:15.891Z", @@ -119,7 +117,7 @@ "resourceName": "WikiPathways", "resourceAddress": "https://ejp-rd-dev1.vm.cesnet.cz/grlcs/wikipathway", "resourceHomePage": "https://www.wikipathways.org", - "email": "ammar.barakat@kgu.de", + "email": "https://www.wikipathways.org/team.html", "resourceDescription": "A collaborative platform for contributing and maintaining pathway information.", "resourceType": [ "DATASET" @@ -138,7 +136,7 @@ "resourceName": "CTSR", "resourceAddress": "", "resourceHomePage": "https://ctsr.uniklinik-freiburg.de/", - "email": "ammar.barakat@kgu.de", + "email": "ctsr-info@uniklinik-freiburg.de", "resourceDescription": ": The Care and Trial Site Registry (CTSR) is an online self-entry database of specialised sites seeing patients with neuromuscular and neurodegenerative diseases. It holds site-level information relevant to clinical studies and care provision, including facilities, equipment, personnel, and trial experience, as well aggregate data about their patient population. It does not hold patient-level data.", "resourceType": [ "DATASET" @@ -176,7 +174,7 @@ "resourceName": "Infrafrontier", "resourceAddress": "", "resourceHomePage": "https://www.infrafrontier.eu/", - "email": "ammar.barakat@kgu.de", + "email": "info@infrafrontier.eu", "resourceDescription": "INFRAFRONTIER, the European Research Infrastructure for modelling human diseases, provides the scientific community with access to valuable mouse and rat strains including resources and services for their generation, phenotyping, and application in specific research pipelines. INFRAFRONTIER archives and distributes transgenic lines via the European Mouse Mutant Archive (EMMA), which currently has more than 8700 strains available for distribution to researchers. EMMA is a core resource of INFRAFRONTIER and is part of its expanding resources and services portfolio.", "resourceType": [ "BIO_BANK" @@ -196,7 +194,7 @@ "resourceAddress": "", "resourceHomePage": "https://www.ebi.ac.uk/metabolights/", "email": "https://www.ebi.ac.uk/about/contact", - "resourceDescription": "A catalog to contain all metabolights study resources.", + "resourceDescription": "A to contain all metabolights study resources.", "resourceType": [ "DATASET" ], @@ -214,7 +212,7 @@ "resourceName": "EGA", "resourceAddress": "", "resourceHomePage": "https://ega-archive.org/", - "email": "ammar.barakat@kgu.de", + "email": "https://ega-archive.org/need-help/", "resourceDescription": "The EGA provides a service for the permanent archiving and distribution of personally identifiable genetic and phenotypic data resulting from biomedical research projects. Data at EGA was collected from individuals whose consent agreements authorise data release only for specific research use to bona fide researchers. Strict protocols govern how information is managed, stored and distributed by the EGA project.", "resourceType": [ "CATALOG" From 04b092ab72e14516d9cc873e995b32fb6d3bc666 Mon Sep 17 00:00:00 2001 From: inesohenriques <117821729+inesohenriques@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:05:39 +0100 Subject: [PATCH 42/49] Update resources.txt From b0e044c9c42ee9ed18f472938091a2818ea857b1 Mon Sep 17 00:00:00 2001 From: Vittorio Meloni Date: Fri, 1 Mar 2024 11:25:36 +0100 Subject: [PATCH 43/49] feat: updates resource.txt with new BBMRI ERIC Directory parameters --- src/main/resources/static/resources.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index f8a902c..61fdb44 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -57,20 +57,19 @@ "theme": [] }, { - "resourceName": "BBMRI-Eric", - "resourceAddress": "http://ejp-rd-prod1.vm.cesnet.cz:5050/api/catalogs", + "resourceName": "BBMRI-ERIC Directory", + "resourceAddress": "https://collection-discovery.bbmri-eric.eu:5050/api/catalogs", "resourceHomePage": "https://directory.bbmri-eric.eu/", - "email": "ammar.barakat@kgu.de", - "resourceDescription": "The BBMRI-Eric catalogue of rare disease registries and biobanks.", + "email": "contact@bbmri-eric.eu", + "resourceDescription": "The BBMRI-ERIC Directory is a tool that collects and makes available information about biobanks throughout Europe that are willing to share their data and/or samples, and to collaborate with other research groups.", "resourceType": [ - "PATIENT_REGISTRY", "BIO_BANK" ], "id": "3", "created": "2020-12-02T10:42:09.170Z", - "updated": "2020-12-02T10:42:09.170Z", + "updated": "2024-03-01T11:23:00.000Z", "specsURL": "", - "logo": "", + "logo": "https://directory.bbmri-eric.eu/logo/bbmri-eric-logo-ohnezusatz.png", "resourceContentType": "", "queryable": true, "queryType": ["BEACON_CATALOG"], From 99b4c9a7cbe8d792aa9f92cc11f37718c936baf3 Mon Sep 17 00:00:00 2001 From: Marc Hanauer Date: Fri, 1 Mar 2024 14:54:14 +0100 Subject: [PATCH 44/49] Update resources.txt -Adding logo for Orphanet -Adding Orphadata to the list --- src/main/resources/static/resources.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 318798b..c95cea1 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -89,7 +89,7 @@ "created": "2020-10-26T15:26:15.891Z", "updated": "2020-10-26T15:26:15.891Z", "specsURL": "", - "logo": "", + "logo": "https://www.orpha.net/build/images/logo-orphanet.png", "resourceContentType": "", "queryable": true, "queryType": ["BEACON_CATALOG"], @@ -380,5 +380,24 @@ "queryable": false, "queryType": [], "theme": [] + }, + { + "resourceName": "ORPHADATA", + "resourceAddress": "", + "resourceHomePage": "https://www.orphadata.com/", + "email": "data.orphanet@inserm.fr", + "resourceDescription": "Orphadata provides the scientific community with comprehensive, massive, re-usable and computable quality data sets related to rare diseases from the Orphanet knowledge base.", + "resourceType": [ + "DATASET" + ], + "id": "20", + "created": "", + "updated": "", + "specsURL": "", + "logo": "https://eurogen-ern.eu/wp-content/uploads/2016/11/eUROGEN-Website-Logo.jpg", + "resourceContentType": "", + "queryable": false, + "queryType": [], + "theme": ["http://www.orpha.net/ORDO/Orphanet_C001","https://www.wikidata.org/wiki/Q929833"] } ] From a76e19e2983af574fa0c644b323ef04e794d2c23 Mon Sep 17 00:00:00 2001 From: Mark Wilkinson Date: Sat, 2 Mar 2024 17:24:11 +0100 Subject: [PATCH 45/49] added the DPP FAIR data point and beacon --- src/main/resources/static/resources.txt | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index f8a902c..750fe84 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -381,5 +381,45 @@ "queryable": false, "queryType": [], "theme": [] + }, + { + "resourceName": "Duchenne Parent Project", + "resourceAddress": "", + "resourceHomePage": "https://dpp.worldduchenne.org/", + "email": "info@fairdata.systems", + "resourceDescription": "https://dpp.worldduchenne.org/", + "resourceType": [ + "PATIENT_REGISTRY" + ], + "id": "20", + "created": "2024-02-07T05:12:55.898Z", + "updated": "2024-02-07T05:12:55.898Z", + "specsURL": "", + "logo": "https://dpp.worldduchenne.org/assets/dpp-logo.png", + "resourceContentType": "", + "queryable": false, + "queryType": [], + "theme": [] + }, + { + "resourceName": "Duchenne Parent Project Beacon", + "resourceAddress": "http://fairdata.services:10002/individuals", + "resourceHomePage": "https://dpp.worldduchenne.org/", + "email": "info@fairdata.systems", + "resourceDescription": "The Beacon2 Individuals endpoint for Duchenne Parent Project data and the EJP Virtual Platform", + "resourceType": [ + "PATIENT_REGISTRY" + ], + "id": "21", + "created": "2024-02-07T05:12:55.898Z", + "updated": "2024-02-07T05:12:55.898Z", + "specsURL": "http://fairdata.services:10002/openapi.json", + "logo": "https://dpp.worldduchenne.org/assets/dpp-logo.png", + "resourceContentType": "", + "queryable": true, + "queryType": ["BEACON_INDIVIDUALS"], + "theme": [] } + + ] From 05bf2381f46ce2bb70e9407e8afa0f627003d31a Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:19:59 +0100 Subject: [PATCH 46/49] #46 - remove email adresse from resource list - replace email adresses with an emaila dress to test the notification feature --- src/main/resources/static/resources.txt | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 8e71d75..02b4cc8 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -3,7 +3,7 @@ "resourceName": "RD-Connect-GPAP", "resourceAddress": "https://platform.rd-connect.eu/beacon2/api/individuals", "resourceHomePage": "https://platform.rd-connect.eu", - "email": "help@rd-connect.eu ", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The RD‐Connect Genome‐Phenome Analysis Platform (GPAP) is a collaborative platform to accelerate rare disease diagnosis and gene discovery, that enables authorised users to submit, share, analyse and interpret integrated genome-phenome data from Rare Disease patients and relatives.", "resourceType": [ "PATIENT_REGISTRY" @@ -22,7 +22,7 @@ "resourceName": "Ithaca", "resourceAddress": "", "resourceHomePage": "https://ithaca.molgeniscloud.org/", - "email": "https://ern-ithaca.eu/contact/", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The main objective of this WP is to set up an interoperable registry dedicated to rare diseases within the scope of ITHACA called ILIAD Rare Diseases patient registry: an International Library of Intellectual disability and Anomalies of Development.", "resourceType": [ "PATIENT_REGISTRY" @@ -41,7 +41,7 @@ "resourceName": "ERKReg", "resourceAddress": "https://www448.lamp.le.ac.uk/erknet/BeaconAPI/83/individuals", "resourceHomePage": "https://www.erknet.org/patients-registry/registry-mission", - "email": "contact@erknet.org ", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "ERKReg, a Web-based registry for all patients with rare kidney diseases. The main objectives of this core registry are to generate epidemiological information, identify current patient cohort for clinical research, explore diagnostic and therapeutic management practices, and monitor treatment performance and patient’s outcomes.", "resourceType": [ "PATIENT_REGISTRY" @@ -60,7 +60,7 @@ "resourceName": "BBMRI-ERIC Directory", "resourceAddress": "https://collection-discovery.bbmri-eric.eu:5050/api/catalogs", "resourceHomePage": "https://directory.bbmri-eric.eu/", - "email": "contact@bbmri-eric.eu", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The BBMRI-ERIC Directory is a tool that collects and makes available information about biobanks throughout Europe that are willing to share their data and/or samples, and to collaborate with other research groups.", "resourceType": [ "BIO_BANK" @@ -79,7 +79,7 @@ "resourceName": "Orphanet catalogue of rare disease registries and biobanks", "resourceAddress": "http://155.133.131.171:8080/OrphanetBeacon/catalogs", "resourceHomePage": "https://www.orpha.net/", - "email": "contact.orphanet@inserm.fr", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The Orphanet catalogue of rare disease registries and biobanks.", "resourceType": [ "CATALOG" @@ -98,7 +98,7 @@ "resourceName": "Duchenne Data Platform", "resourceAddress": "", "resourceHomePage": "https://duchenne.nl/duchenne-data-platform-english/", - "email": "info@duchenne.nl", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The Duchenne Data Platform (DDP) is a patient-led registry. Patients are the owners of their data and have their own data lockers where they can not only collect their Patient Reported Outcomes (PROs) but can also upload their data from other sources such as hospitals and wearables.", "resourceType": [ "PATIENT_REGISTRY" @@ -117,7 +117,7 @@ "resourceName": "WikiPathways", "resourceAddress": "https://ejp-rd-dev1.vm.cesnet.cz/grlcs/wikipathway", "resourceHomePage": "https://www.wikipathways.org", - "email": "https://www.wikipathways.org/team.html", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "A collaborative platform for contributing and maintaining pathway information.", "resourceType": [ "DATASET" @@ -136,7 +136,7 @@ "resourceName": "CTSR", "resourceAddress": "", "resourceHomePage": "https://ctsr.uniklinik-freiburg.de/", - "email": "ctsr-info@uniklinik-freiburg.de", + "email": "abishaa.vengadeswaran@ejprd-project.eue", "resourceDescription": ": The Care and Trial Site Registry (CTSR) is an online self-entry database of specialised sites seeing patients with neuromuscular and neurodegenerative diseases. It holds site-level information relevant to clinical studies and care provision, including facilities, equipment, personnel, and trial experience, as well aggregate data about their patient population. It does not hold patient-level data.", "resourceType": [ "DATASET" @@ -155,7 +155,7 @@ "resourceName": "hPSCreg", "resourceAddress": "https://ejp-rd-dev1.vm.cesnet.cz/grlcs/hPSCreg", "resourceHomePage": "https://hpscreg.eu/about", - "email": "https://hpscreg.eu/contact", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The human pluripotent stem cell registry (hPSCreg), accessible at https://hpscreg.eu, is a public registry and data portal for human embryonic and induced pluripotent stem cell lines (hESC and hiPSC).", "resourceType": [ "DATASET" @@ -174,7 +174,7 @@ "resourceName": "Infrafrontier", "resourceAddress": "", "resourceHomePage": "https://www.infrafrontier.eu/", - "email": "info@infrafrontier.eu", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "INFRAFRONTIER, the European Research Infrastructure for modelling human diseases, provides the scientific community with access to valuable mouse and rat strains including resources and services for their generation, phenotyping, and application in specific research pipelines. INFRAFRONTIER archives and distributes transgenic lines via the European Mouse Mutant Archive (EMMA), which currently has more than 8700 strains available for distribution to researchers. EMMA is a core resource of INFRAFRONTIER and is part of its expanding resources and services portfolio.", "resourceType": [ "BIO_BANK" @@ -193,7 +193,7 @@ "resourceName": "Metabolights", "resourceAddress": "", "resourceHomePage": "https://www.ebi.ac.uk/metabolights/", - "email": "https://www.ebi.ac.uk/about/contact", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "A to contain all metabolights study resources.", "resourceType": [ "DATASET" @@ -212,7 +212,7 @@ "resourceName": "EGA", "resourceAddress": "", "resourceHomePage": "https://ega-archive.org/", - "email": "https://ega-archive.org/need-help/", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The EGA provides a service for the permanent archiving and distribution of personally identifiable genetic and phenotypic data resulting from biomedical research projects. Data at EGA was collected from individuals whose consent agreements authorise data release only for specific research use to bona fide researchers. Strict protocols govern how information is managed, stored and distributed by the EGA project.", "resourceType": [ "CATALOG" @@ -231,7 +231,7 @@ "resourceName": "Registry VASCERN (VASCA)", "resourceAddress": "", "resourceHomePage": "https://vascern.eu/groupe/registry/", - "email": "vascern_registry@vascern.eu ", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The VASCA registry collects data from patients with rare vascular diseases who are being treated at various expert centres across Europe. Its primary objective is to enhance our understanding of these rare diseases through various research endeavors, such as natural history studies, genotype-phenotype correlations, population comparisons, and cross-country care comparisons.", "resourceType": [ "PATIENT_REGISTRY" @@ -251,7 +251,7 @@ "resourceName": "Registry ERN CRANIO (ERN CRANIO registry )", "resourceAddress": "", "resourceHomePage": "https://cranio.molgeniscloud.org/", - "email": "ammar.barakat@kgu.de", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "ERN CRANIO is the European Reference Network for rare and/or complex craniofacial anomalies and ear, nose and throat (ENT) disorders. The network was officially launched in March 2017. There are 29 European hospitals involved in ERN CRANIO, from 11 EU member states. It is a multi-disciplinary network of highly specialised healthcare professionals. Patient representatives also play an active role in the network and its activities.", "resourceType": [ "PATIENT_REGISTRY" @@ -270,7 +270,7 @@ "resourceName": "Registry ERN-Skin (ERN-Skin REGISTRY)", "resourceAddress": "", "resourceHomePage": "https://solve-rd.eu/", - "email": "ammar.barakat@kgu.de", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The aim of ERN-Skin is to have a central European registry for all cases of rare dermatological diseases, which will be a useful tool for clinical research, simplify the development of cohorts and answer the specific questions of each Disease Group.", "resourceType": [ "PATIENT_REGISTRY" @@ -289,7 +289,7 @@ "resourceName": "Registry ERN EURO-NMD (EURO-NMD Registry )", "resourceAddress": "", "resourceHomePage": "https://ern-euro-nmd.eu/", - "email": "info@ern-euro-nmd.eu", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "EURO-NMD is a European reference network for the thematic grouping of rare neuromuscular diseases (NMDs), a broad group of related disorders that represent a major cause of mortality and lifelong disability in children and adults.", "resourceType": [ "PATIENT_REGISTRY" @@ -308,7 +308,7 @@ "resourceName": "Genturis", "resourceAddress": "", "resourceHomePage": "https://genturis.molgeniscloud.org/", - "email": "ammar.barakat@kgu.de", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The GENTURIS registry is the European registry for patients with one of the genetic tumour risk syndromes (genturis). The registry is affiliated to the European Reference Network for all patients with one of the genetic tumour risk syndromes (ERN GENTURIS).", "resourceType": [ "PATIENT_REGISTRY" @@ -327,7 +327,7 @@ "resourceName": "FAIRVasc", "resourceAddress": "", "resourceHomePage": "https://fairvasc.eu/ ", - "email": "fairvasc@cm-uj.krakow.pl", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "FAIRVASC is building registry interoperability to inform clinical care Vasculitis (an acquired, immune-mediated inflammatory disease involving blood vessels of many tissues and organs), needs sufficiently large quantities of data to enable well-informed conclusions about treatments and possible cures. It is thus essential to combine the databases of patient registries of several countries to build a dataset of sufficient size to enable meaningful research.", "resourceType": [ "PATIENT_REGISTRY" @@ -346,7 +346,7 @@ "resourceName": "CHD7", "resourceAddress": "https://mutatiedatabases.molgeniscloud.org/api/beacon/individuals", "resourceHomePage": "", - "email": "ammar.barakat@kgu.de", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "", "resourceType": [ "PATIENT_REGISTRY" @@ -365,7 +365,7 @@ "resourceName": "Registry ERN eUROGEN", "resourceAddress": "", "resourceHomePage": "https://eurogen-ern.eu/what-we-do/registry-digital-activities/aim/", - "email": "eurogen@uroweb.org", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "Registry from ERN eUROGEN on rare uro-recto-genital diseases and complex conditions.", "resourceType": [ "PATIENT_REGISTRY" @@ -384,7 +384,7 @@ "resourceName": "ORPHADATA", "resourceAddress": "", "resourceHomePage": "https://www.orphadata.com/", - "email": "data.orphanet@inserm.fr", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "Orphadata provides the scientific community with comprehensive, massive, re-usable and computable quality data sets related to rare diseases from the Orphanet knowledge base.", "resourceType": [ "DATASET" From 8d400eb0e41ed4cd93443f5d0edc17ad24402aaf Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Mon, 4 Mar 2024 22:41:44 +0100 Subject: [PATCH 47/49] #48 - Error connecting new BBMRI endpoint - remove new L2 endpoint of BBMRI --- src/main/resources/static/resources.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 02b4cc8..14f26a7 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -58,7 +58,7 @@ }, { "resourceName": "BBMRI-ERIC Directory", - "resourceAddress": "https://collection-discovery.bbmri-eric.eu:5050/api/catalogs", + "resourceAddress": "", "resourceHomePage": "https://directory.bbmri-eric.eu/", "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The BBMRI-ERIC Directory is a tool that collects and makes available information about biobanks throughout Europe that are willing to share their data and/or samples, and to collaborate with other research groups.", @@ -71,8 +71,8 @@ "specsURL": "", "logo": "https://www.bbmri-eric.eu/wp-content/themes/bbmri-eric/img/BBMRI-ERIC-gateway-for-health.svg", "resourceContentType": "", - "queryable": true, - "queryType": ["BEACON_CATALOG"], + "queryable": false, + "queryType": [], "theme": [] }, { From feeb7501a223aff847d18fca8cc82bd78b35ff40 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:56:19 +0100 Subject: [PATCH 48/49] change email in resourcelist --- src/main/resources/static/resources.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index b23a941..4c2ff96 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -384,7 +384,7 @@ "resourceName": "Duchenne Parent Project", "resourceAddress": "", "resourceHomePage": "https://dpp.worldduchenne.org/", - "email": "info@fairdata.systems", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "https://dpp.worldduchenne.org/", "resourceType": [ "PATIENT_REGISTRY" @@ -403,7 +403,7 @@ "resourceName": "Duchenne Parent Project Beacon", "resourceAddress": "http://fairdata.services:10002/individuals", "resourceHomePage": "https://dpp.worldduchenne.org/", - "email": "info@fairdata.systems", + "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The Beacon2 Individuals endpoint for Duchenne Parent Project data and the EJP Virtual Platform", "resourceType": [ "PATIENT_REGISTRY" From bf395c3ba64e52fe5ee33223ace8eda978b36c87 Mon Sep 17 00:00:00 2001 From: Abishaa Vengadeswaran <38211976+vabishaa@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:14:07 +0100 Subject: [PATCH 49/49] update resou - add L2 connection info for BBMRI --- src/main/resources/static/resources.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/resources.txt b/src/main/resources/static/resources.txt index 4c2ff96..3144f58 100644 --- a/src/main/resources/static/resources.txt +++ b/src/main/resources/static/resources.txt @@ -58,7 +58,7 @@ }, { "resourceName": "BBMRI-ERIC Directory", - "resourceAddress": "", + "resourceAddress": "https://collection-discovery.bbmri-eric.eu:5050/api/catalogs", "resourceHomePage": "https://directory.bbmri-eric.eu/", "email": "abishaa.vengadeswaran@ejprd-project.eu", "resourceDescription": "The BBMRI-ERIC Directory is a tool that collects and makes available information about biobanks throughout Europe that are willing to share their data and/or samples, and to collaborate with other research groups.", @@ -71,8 +71,8 @@ "specsURL": "", "logo": "https://www.bbmri-eric.eu/wp-content/themes/bbmri-eric/img/BBMRI-ERIC-gateway-for-health.svg", "resourceContentType": "", - "queryable": false, - "queryType": [], + "queryable": true, + "queryType": ["BEACON_CATALOG"], "theme": [] }, {