From 3cfd1f59fc7327c69016c1b8ee45c0d36272589a Mon Sep 17 00:00:00 2001 From: rob-ouser-bi Date: Thu, 12 Sep 2024 15:55:39 +0000 Subject: [PATCH 1/8] [autocommit] bumping build number --- src/main/resources/version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index daad3eac6..802a73a7c 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -14,5 +14,5 @@ # limitations under the License. # -version=v0.10.0+811 -versionInfo=https://github.com/Breeding-Insight/bi-api/commit/7e4becad3dd603f7ac2e92bf1052a10c909aebc5 +version=v0.10.0+815 +versionInfo=https://github.com/Breeding-Insight/bi-api/commit/2606f2a1911510a0d9d1cd956bb578057b0a2553 From e0f22d256342d8ebf4ab9b2d5771d99e7baf377d Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:46:43 -0400 Subject: [PATCH 2/8] Updates to germplasm search endpoints to support Field Book integration --- .../brapi/v2/BrAPIGermplasmController.java | 83 ++++++++++++++++++- .../breedinginsight/utilities/Utilities.java | 15 +++- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java index f78664f72..33ec62fd7 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java @@ -1,5 +1,6 @@ package org.breedinginsight.brapi.v2; +import io.micronaut.context.annotation.Property; import io.micronaut.http.HttpHeaders; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; @@ -18,6 +19,7 @@ import org.brapi.v2.model.BrAPIIndexPagination; import org.brapi.v2.model.BrAPIMetadata; import org.brapi.v2.model.BrAPIStatus; +import org.brapi.v2.model.core.BrAPITrial; import org.brapi.v2.model.germ.*; import org.brapi.v2.model.germ.request.BrAPIGermplasmSearchRequest; import org.brapi.v2.model.germ.response.*; @@ -31,6 +33,7 @@ import org.breedinginsight.brapi.v2.constants.BrAPIAdditionalInfoFields; import org.breedinginsight.brapi.v2.dao.BrAPIGermplasmDAO; import org.breedinginsight.brapi.v2.model.request.query.GermplasmQuery; +import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; import org.breedinginsight.model.Program; import org.breedinginsight.services.ProgramService; import org.breedinginsight.utilities.Utilities; @@ -49,11 +52,13 @@ import javax.inject.Inject; import javax.validation.Valid; import java.util.*; +import java.util.stream.Collectors; @Slf4j @Controller("/${micronaut.bi.api.version}") @Secured(SecurityRule.IS_AUTHENTICATED) public class BrAPIGermplasmController { + private final String referenceSource; private final BrAPIGermplasmService germplasmService; private final GermplasmQueryMapper germplasmQueryMapper; @@ -67,13 +72,15 @@ public class BrAPIGermplasmController { @Inject - public BrAPIGermplasmController(BrAPIGermplasmService germplasmService, + public BrAPIGermplasmController(@Property(name = "brapi.server.reference-source") String referenceSource, + BrAPIGermplasmService germplasmService, GermplasmQueryMapper germplasmQueryMapper, ProgramDAO programDAO, BrAPIGermplasmDAO germplasmDAO, GenotypeService genoService, BrAPIEndpointProvider brAPIEndpointProvider, ProgramService programService) { + this.referenceSource = referenceSource; this.germplasmService = germplasmService; this.germplasmQueryMapper = germplasmQueryMapper; this.programDAO = programDAO; @@ -84,12 +91,13 @@ public BrAPIGermplasmController(BrAPIGermplasmService germplasmService, } // NOTE: bypasses cache and makes api request directly to brapi service + // Needs to convert DeltaBreed UUIDs to BrAPI Service DbIds and back @Post("/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/search/germplasm") @Produces(MediaType.APPLICATION_JSON) @ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES}) public HttpResponse searchGermplasm( @PathVariable("programId") UUID programId, - @Body BrAPIGermplasmSearchRequest body) throws ApiException { + @Body BrAPIGermplasmSearchRequest body) throws ApiException, DoesNotExistException { log.debug("searchGermplasm: fetching germplasm by filters"); @@ -105,19 +113,88 @@ public HttpResponse searchGermplasm( String extRefId = program.get().getId().toString(); body.externalReferenceIds(List.of(extRefId)); + // convert request filter dbIds from DeltaBreed UUID to BrAPI service dbIds for now + // TODO: all dbIds, just germplasmDbIds for now since that's what Field Book needs + // Could be more performant by doing batch lookup but at least just going to cache + List convertedDbIds = new ArrayList<>(); + for (String germplasmDbId : body.getGermplasmDbIds()) { + BrAPIGermplasm germplasm = germplasmService.getGermplasmByUUID(program.get().getId(), germplasmDbId); + convertedDbIds.add(germplasm.getGermplasmDbId()); + } + body.setGermplasmDbIds(convertedDbIds); + ApiResponse, Optional>> brapiGermplasm; brapiGermplasm = brAPIEndpointProvider .get(programDAO.getCoreClient(program.get().getId()), GermplasmApi.class) .searchGermplasmPost(body); + return getObjectHttpResponse(brapiGermplasm, program.get().getKey()); + } + + // NOTE: bypasses cache and makes api request directly to brapi service + // Needs to convert BrAPIService dbIds to DeltaBreed UUIDs + @Get("/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/search/germplasm/{searchResultId}{?queryParams*}") + @Produces(MediaType.APPLICATION_JSON) + @ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES}) + public HttpResponse getSearchResult( + @PathVariable("programId") UUID programId, + @PathVariable("searchResultId") UUID searchResultId, + @QueryValue @QueryValid(using = GermplasmQueryMapper.class) @Valid GermplasmQuery queryParams) throws ApiException { + + log.debug("getGermplasmResult: getting results"); + + Optional program = programService.getById(programId); + if(program.isEmpty()) { + log.warn("Program id: " + programId + " not found"); + return HttpResponse.notFound(); + } + + ApiResponse, Optional>> brapiGermplasm; + brapiGermplasm = brAPIEndpointProvider + .get(programDAO.getCoreClient(program.get().getId()), GermplasmApi.class) + .searchGermplasmSearchResultsDbIdGet(searchResultId.toString(), queryParams.getPage(), queryParams.getPageSize()); + + return getObjectHttpResponse(brapiGermplasm, program.get().getKey()); + } + + private HttpResponse getObjectHttpResponse(ApiResponse, Optional>> brapiGermplasm, + String programKey) throws ApiException { if (brapiGermplasm.getBody().getLeft().isPresent()) { - return HttpResponse.ok(brapiGermplasm.getBody().getLeft().get()); + // convert dbIds to DeltaBreed UUID + BrAPIGermplasmListResponse response = brapiGermplasm.getBody().getLeft().get(); + List germplasm = response.getResult().getData(); + germplasm.forEach(g -> setDbIdsAndStripProgramKeys(g, programKey)); + return HttpResponse.ok(response); } else if (brapiGermplasm.getBody().getRight().isPresent()) { return HttpResponse.ok(brapiGermplasm.getBody().getRight().get()); } else { throw new ApiException("Expected search response"); } + } + + /** + * Keep dbIds in DeltaBreed UUID context and strip program keys from synonyms and pedigree string for Field Book display + * @param germplasm + * @param programKey + */ + private void setDbIdsAndStripProgramKeys(BrAPIGermplasm germplasm, String programKey) { + String extRef = Utilities.getExternalReference(germplasm.getExternalReferences(), "breedinginsight.org") + .orElseThrow(() -> new IllegalStateException("No BI external reference found")) + .getReferenceId(); + + germplasm.germplasmDbId(extRef); + + // Remove program keys from synonyms + if (germplasm.getSynonyms() != null && !germplasm.getSynonyms().isEmpty()) { + for (BrAPIGermplasmSynonyms synonym: germplasm.getSynonyms()) { + String newSynonym = Utilities.removeProgramKey(synonym.getSynonym(), programKey, germplasm.getAccessionNumber()); + synonym.setSynonym(newSynonym); + } + } + // Remove program keys from pedigree string + String strippedPedigree = Utilities.removeProgramKeyAndUnknownAdditionalData(germplasm.getPedigree(), programKey); + germplasm.setPedigree(strippedPedigree); } @Get("/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/germplasm{?queryParams*}") diff --git a/src/main/java/org/breedinginsight/utilities/Utilities.java b/src/main/java/org/breedinginsight/utilities/Utilities.java index 3d9d6d04c..cb51c1ecc 100644 --- a/src/main/java/org/breedinginsight/utilities/Utilities.java +++ b/src/main/java/org/breedinginsight/utilities/Utilities.java @@ -162,8 +162,21 @@ public static Object formatBrapiObjForDisplay(Object brapiInstance, Class brapiC return brapiInstance; } + /** + * \s*: Matches zero or more whitespace characters before the opening bracket. + * \[: Matches the opening square bracket [. The backslash is used to escape the special meaning of [ in regex. + * .*?: Matches any character (except newline) zero or more times, non-greedily. + * . matches any character except newline. + * * means "zero or more times". + * ? makes the matching non-greedy, so it stops at the first closing bracket. + * \]: Matches the closing square bracket ]. Again, the backslash is used to escape it. + * \s*: Matches zero or more whitespace characters after the closing bracket. + * @param original + * @param programKey + * @return + */ public static String removeProgramKeyAndUnknownAdditionalData(String original, String programKey) { - String keyValueRegEx = String.format(" \\[%s\\-.*\\]", programKey); + String keyValueRegEx = String.format("\\s*\\[%s-.*?\\]\\s*", programKey); String stripped = original.replaceAll(keyValueRegEx, ""); return stripped; } From 004179ed244f74f4716bf2ede1757f76de6dc24b Mon Sep 17 00:00:00 2001 From: dmeidlin <14339308+dmeidlin@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:09:07 -0400 Subject: [PATCH 3/8] fix service method for fetching program user collaborators to allow for system admins --- .../brapi/v2/BrAPIStudiesController.java | 3 --- .../brapi/v2/BrAPITrialsController.java | 18 ++++++++---------- .../services/ProgramUserService.java | 17 +++++++---------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java index a08e01764..e49e1560f 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java @@ -128,9 +128,6 @@ public HttpResponse>>> getStudies( } catch (IllegalArgumentException e) { log.info(e.getMessage(), e); return HttpResponse.status(HttpStatus.UNPROCESSABLE_ENTITY, "Error parsing requested date format"); - } catch (DoesNotExistException e) { - log.info(e.getMessage(), e); - return HttpResponse.status(HttpStatus.NOT_FOUND, e.getMessage()); } } diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java index f63515b77..1ad489d91 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java @@ -95,23 +95,21 @@ public HttpResponse>>> getExperiments( @PathVariable("programId") UUID programId, @QueryValue @QueryValid(using = ExperimentQueryMapper.class) @Valid ExperimentQuery queryParams) { try { - List experiments = new ArrayList<>(); + Optional program = programService.getById(programId); + if (program.isEmpty()) { return HttpResponse.notFound(); } + + SearchRequest searchRequest = queryParams.constructSearchRequest(); log.debug("fetching trials for program: " + programId); + // If the program user is an experimental collaborator, filter results for only authorized experiments. Optional experimentalCollaborator = programUserService.getIfExperimentalCollaborator(programId, securityService.getUser().getId()); - // If the program user is an experimental collaborator, filter results. if (experimentalCollaborator.isPresent()) { - Optional program = programService.getById(programId); - if (program.isEmpty()) { - return HttpResponse.notFound(); - } List experimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); - experiments = experimentService.getTrialsByExperimentIds(program.get(), experimentIds).stream().peek(this::setDbIds).collect(Collectors.toList()); - } else { - experiments = experimentService.getExperiments(programId).stream().peek(this::setDbIds).collect(Collectors.toList()); + List authorizedExperiments = experimentService.getTrialsByExperimentIds(program.get(), experimentIds).stream().peek(this::setDbIds).collect(Collectors.toList()); + return ResponseUtils.getBrapiQueryResponse(authorizedExperiments, experimentQueryMapper, queryParams, searchRequest); } - SearchRequest searchRequest = queryParams.constructSearchRequest(); + List experiments = experimentService.getExperiments(programId).stream().peek(this::setDbIds).collect(Collectors.toList()); return ResponseUtils.getBrapiQueryResponse(experiments, experimentQueryMapper, queryParams, searchRequest); } catch (ApiException e) { log.info(e.getMessage(), e); diff --git a/src/main/java/org/breedinginsight/services/ProgramUserService.java b/src/main/java/org/breedinginsight/services/ProgramUserService.java index a07bd441c..2ecd751e7 100644 --- a/src/main/java/org/breedinginsight/services/ProgramUserService.java +++ b/src/main/java/org/breedinginsight/services/ProgramUserService.java @@ -281,16 +281,13 @@ public boolean existsAndActive(UUID programId, UUID userId) { * @param userId the user ID. * @return an Optional that unwraps to a program user if it is an Experimental Collaborator, Optional.empty() otherwise. */ - public Optional getIfExperimentalCollaborator(UUID programId, UUID userId) throws DoesNotExistException { - Optional programUser = getProgramUserbyId(programId, userId); - if (programUser.isEmpty()) { - throw new DoesNotExistException("Program User does not exist"); - } - boolean isExperimentalCollaborator = programUser.get().getRoles().stream().anyMatch(x -> ProgramSecuredRole.getEnum(x.getDomain()).equals(ProgramSecuredRole.EXPERIMENTAL_COLLABORATOR)); - if (isExperimentalCollaborator) { - return programUser; - } - return Optional.empty(); + public Optional getIfExperimentalCollaborator(UUID programId, UUID userId) { + return getProgramUserbyId(programId, userId) + .flatMap(user -> user.getRoles().stream() + .anyMatch(role -> ProgramSecuredRole.getEnum(role.getDomain()).equals(ProgramSecuredRole.EXPERIMENTAL_COLLABORATOR)) + ? Optional.of(user) + : Optional.empty() + ); } public List getProgramUsersByRole(UUID programId, UUID roleId) throws DoesNotExistException { From 899576c55380758544ef126eab27d6c2dc24093a Mon Sep 17 00:00:00 2001 From: dmeidlin <14339308+dmeidlin@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:19:25 -0400 Subject: [PATCH 4/8] refactor for clarity --- .../brapi/v2/BrAPIStudiesController.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java index e49e1560f..daadea133 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java @@ -95,32 +95,29 @@ public HttpResponse>>> getStudies( @PathVariable("programId") UUID programId, @QueryValue @QueryValid(using = StudyQueryMapper.class) @Valid StudyQuery queryParams) { try { + Optional program = programService.getById(programId); + if (program.isEmpty()) { return HttpResponse.notFound(); } + + queryParams.setSortField(studyQueryMapper.getDefaultSortField()); + queryParams.setSortOrder(studyQueryMapper.getDefaultSortOrder()); + SearchRequest searchRequest = queryParams.constructSearchRequest(); log.debug("fetching studies for program: " + programId); - List studies; + // If the program user is an experimental collaborator, filter results for only authorized studies. Optional experimentalCollaborator = programUserService.getIfExperimentalCollaborator(programId, securityService.getUser().getId()); - // If the program user is an experimental collaborator, filter results. if (experimentalCollaborator.isPresent()) { - Optional program = programService.getById(programId); - if (program.isEmpty()) { - return HttpResponse.notFound(); - } - - List experimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); - studies = studyService.getStudiesByExperimentIds(program.get(), experimentIds) + List authorizedExperimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); + List authorizedStudies = studyService.getStudiesByExperimentIds(program.get(), authorizedExperimentIds) .stream() .peek(this::setDbIds) .collect(Collectors.toList()); - } else { - studies = studyService.getStudies(programId) + return ResponseUtils.getBrapiQueryResponse(authorizedStudies, studyQueryMapper, queryParams, searchRequest); + } + + List studies = studyService.getStudies(programId) .stream() .peek(this::setDbIds) .collect(Collectors.toList()); - } - - queryParams.setSortField(studyQueryMapper.getDefaultSortField()); - queryParams.setSortOrder(studyQueryMapper.getDefaultSortOrder()); - SearchRequest searchRequest = queryParams.constructSearchRequest(); return ResponseUtils.getBrapiQueryResponse(studies, studyQueryMapper, queryParams, searchRequest); } catch (ApiException e) { log.info(e.getMessage(), e); From 655188781ecf347415d9a311ea1f4c7c426e395d Mon Sep 17 00:00:00 2001 From: rob-ouser-bi Date: Thu, 19 Sep 2024 15:28:05 +0000 Subject: [PATCH 5/8] [autocommit] bumping build number --- src/main/resources/version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index 802a73a7c..f293902d3 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -14,5 +14,5 @@ # limitations under the License. # -version=v0.10.0+815 -versionInfo=https://github.com/Breeding-Insight/bi-api/commit/2606f2a1911510a0d9d1cd956bb578057b0a2553 +version=v0.10.0+819 +versionInfo=https://github.com/Breeding-Insight/bi-api/commit/74654778ed3bbff92dfde4d86b9a2f52200dd6ad From 402926b74c04a7ac0b949eb4c03ffa378b50ed20 Mon Sep 17 00:00:00 2001 From: rob-ouser-bi Date: Fri, 20 Sep 2024 18:58:48 +0000 Subject: [PATCH 6/8] [autocommit] bumping build number --- src/main/resources/version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index f293902d3..a4d6b9e84 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -14,5 +14,5 @@ # limitations under the License. # -version=v0.10.0+819 -versionInfo=https://github.com/Breeding-Insight/bi-api/commit/74654778ed3bbff92dfde4d86b9a2f52200dd6ad +version=v0.10.0+823 +versionInfo=https://github.com/Breeding-Insight/bi-api/commit/68609b93fef11c2c0fa5434d979cc93d1f8920ec From ad824550ed0aae8d18c6f1a41c2fec6fe045b106 Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:10:57 -0400 Subject: [PATCH 7/8] Convert germplasm ids in batch --- .../brapi/v2/BrAPIGermplasmController.java | 10 ++-------- .../brapi/v2/dao/BrAPIGermplasmDAO.java | 16 ++++++++++++++++ .../brapi/v2/services/BrAPIGermplasmService.java | 8 ++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java index 33ec62fd7..5280aeea1 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java @@ -113,14 +113,8 @@ public HttpResponse searchGermplasm( String extRefId = program.get().getId().toString(); body.externalReferenceIds(List.of(extRefId)); - // convert request filter dbIds from DeltaBreed UUID to BrAPI service dbIds for now - // TODO: all dbIds, just germplasmDbIds for now since that's what Field Book needs - // Could be more performant by doing batch lookup but at least just going to cache - List convertedDbIds = new ArrayList<>(); - for (String germplasmDbId : body.getGermplasmDbIds()) { - BrAPIGermplasm germplasm = germplasmService.getGermplasmByUUID(program.get().getId(), germplasmDbId); - convertedDbIds.add(germplasm.getGermplasmDbId()); - } + // convert request filter dbIds from DeltaBreed UUID to BrAPI service dbIds + List convertedDbIds = germplasmService.getGermplasmDbIdsForUUIDs(program.get().getId(), body.getGermplasmDbIds()); body.setGermplasmDbIds(convertedDbIds); ApiResponse, Optional>> brapiGermplasm; diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java index c4dd54233..2e9371be4 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java @@ -345,6 +345,22 @@ public BrAPIGermplasm getGermplasmByUUID(String germplasmId, UUID programId) thr return germplasm; } + public List getGermplasmDbIdsForUUIDs(List germplasmUUIDs, UUID programId) throws ApiException, DoesNotExistException { + Map cache = programGermplasmCache.get(programId); + List germplasmList = new ArrayList<>(); + if (cache != null) { + // not using streams because want to throw checked exception + for (String germplasmUUID : germplasmUUIDs) { + BrAPIGermplasm germplasm = cache.get(germplasmUUID); + if (germplasm == null) { + throw new DoesNotExistException("UUID for this germplasm does not exist: " + germplasmUUID); + } + germplasmList.add(germplasm.getGermplasmDbId()); + } + } + return germplasmList; + } + public Optional getGermplasmByDBID(String germplasmDbId, UUID programId) throws ApiException { Map cache = programGermplasmCache.get(programId); //key is UUID, want to filter by DBID diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPIGermplasmService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPIGermplasmService.java index 468a6b5b3..eafde7e1e 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPIGermplasmService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPIGermplasmService.java @@ -68,6 +68,14 @@ public BrAPIGermplasm getGermplasmByUUID(UUID programId, String germplasmId) thr } } + public List getGermplasmDbIdsForUUIDs(UUID programId, List germplasmUUIDs) throws DoesNotExistException { + try { + return germplasmDAO.getGermplasmDbIdsForUUIDs(germplasmUUIDs, programId); + } catch (ApiException e) { + throw new InternalServerException(e.getMessage(), e); + } + } + public Optional getGermplasmByDBID(UUID programId, String germplasmId) throws ApiException { return germplasmDAO.getGermplasmByDBID(germplasmId, programId); } From 49b365cf56403cd1b436befa236235fba2d486ad Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:44:19 -0400 Subject: [PATCH 8/8] Code review changes --- .../brapi/v2/BrAPIGermplasmController.java | 41 ++++++++++--------- .../breedinginsight/utilities/Utilities.java | 5 +++ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java index 5280aeea1..948e68c20 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIGermplasmController.java @@ -52,6 +52,7 @@ import javax.inject.Inject; import javax.validation.Valid; import java.util.*; +import java.util.regex.Pattern; import java.util.stream.Collectors; @Slf4j @@ -157,7 +158,8 @@ private HttpResponse getObjectHttpResponse(ApiResponse germplasm = response.getResult().getData(); - germplasm.forEach(g -> setDbIdsAndStripProgramKeys(g, programKey)); + //germplasm.forEach(g -> setDbIdsAndStripProgramKeys(g, programKey)); + batchProcessGermplasm(germplasm, programKey); return HttpResponse.ok(response); } else if (brapiGermplasm.getBody().getRight().isPresent()) { return HttpResponse.ok(brapiGermplasm.getBody().getRight().get()); @@ -168,27 +170,28 @@ private HttpResponse getObjectHttpResponse(ApiResponse new IllegalStateException("No BI external reference found")) - .getReferenceId(); - - germplasm.germplasmDbId(extRef); - - // Remove program keys from synonyms - if (germplasm.getSynonyms() != null && !germplasm.getSynonyms().isEmpty()) { - for (BrAPIGermplasmSynonyms synonym: germplasm.getSynonyms()) { - String newSynonym = Utilities.removeProgramKey(synonym.getSynonym(), programKey, germplasm.getAccessionNumber()); - synonym.setSynonym(newSynonym); + private void batchProcessGermplasm(List germplasmList, String programKey) throws IllegalStateException { + // Prepare a regex pattern for program key removal + Pattern programKeyPattern = Utilities.getRegexPatternMatchAllProgramKeysAnyAccession(programKey); + germplasmList.parallelStream().forEach(germplasm -> { + // Set dbId + germplasm.germplasmDbId(Utilities.getExternalReference(germplasm.getExternalReferences(), "breedinginsight.org") + .orElseThrow(() -> new IllegalStateException("No BI external reference found")) + .getReferenceId()); + // Process synonyms + if (germplasm.getSynonyms() != null) { + germplasm.getSynonyms().forEach(synonym -> { + synonym.setSynonym(Utilities.removeProgramKey(synonym.getSynonym(), programKey, germplasm.getAccessionNumber())); + }); } - } - - // Remove program keys from pedigree string - String strippedPedigree = Utilities.removeProgramKeyAndUnknownAdditionalData(germplasm.getPedigree(), programKey); - germplasm.setPedigree(strippedPedigree); + // Process pedigree + if (germplasm.getPedigree() != null) { + germplasm.setPedigree(programKeyPattern.matcher(germplasm.getPedigree()).replaceAll("")); + } + }); } @Get("/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/germplasm{?queryParams*}") diff --git a/src/main/java/org/breedinginsight/utilities/Utilities.java b/src/main/java/org/breedinginsight/utilities/Utilities.java index cb51c1ecc..92b46623e 100644 --- a/src/main/java/org/breedinginsight/utilities/Utilities.java +++ b/src/main/java/org/breedinginsight/utilities/Utilities.java @@ -32,6 +32,7 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Function; +import java.util.regex.Pattern; public class Utilities { @@ -97,6 +98,10 @@ public static String removeProgramKeyAnyAccession(String str, String programKey) return str.replaceAll("\\[" + programKey + "-.*\\]", "").trim(); } + public static Pattern getRegexPatternMatchAllProgramKeysAnyAccession(String programKey) { + return Pattern.compile(String.format("\\s*\\[%s-.*?\\]\\s*", programKey)); + } + /** * Remove program key from a string. Returns a new value instead of altering original string. *