From 83167210a04ef83cd4f4abc82f994a0bcda134d2 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 5 Mar 2025 14:36:13 -0500 Subject: [PATCH 01/13] Prevent pagination from occurring while join fetching on germs --- .../repository/BrAPIRepository.java | 5 + .../repository/BrAPIRepositoryImpl.java | 70 ++++++++-- .../service/SearchQueryBuilder.java | 5 + .../service/germ/GermplasmService.java | 120 +++++++++--------- 4 files changed, 128 insertions(+), 72 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java index 255cd5bd..7b73ee08 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java @@ -3,6 +3,7 @@ import java.io.Serializable; import java.util.List; import java.util.Optional; +import java.util.UUID; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -16,6 +17,10 @@ public interface BrAPIRepository findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageReq); + public Page findAllBySearchIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq); + + public Page findAllBySearchNoPage(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq); + public Optional findById(ID id); public S save(S entity); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java index bbad6ea2..2a1b75c2 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -30,8 +30,9 @@ public BrAPIRepositoryImpl(JpaEntityInformation entityInformation, Entity this.entityManager = entityManager; } + // This is the method that should be used for simple entities with few collections and eager loading requirements. public Page findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageReq) { - searchQuery = applyUserId(searchQuery); + applyUserId(searchQuery); List content = getPagedContent(searchQuery, pageReq); Long totalCount = getTotalCount(searchQuery); @@ -40,6 +41,28 @@ public Page findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageR return page; } + public Page findAllBySearchNoPage(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { + applyUserId(searchQuery); + + var entities = searchEntitiesWithIds(searchQuery, pagedIds); + + return new PageImpl<>(entities, pageReq, pagedIds.getTotalElements()); + } + + + + // For entities that are complex and have lots of Collections and lazy loaded entities, it is more efficient to grab the IDs of the on Page, + // and afterward fetch these collections using the Ids, this time without paging. + public Page findAllBySearchIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { + applyUserId(searchQuery); + List content = getPagedContentIdsOnly(searchQuery, pageReq); + Long totalCount = getTotalCount(searchQuery); + + Page page = new PageImpl<>(content, pageReq, totalCount); + + return page; + } + public Optional findById(ID id) { Optional response = super.findById(id); if (response.isPresent()) { @@ -82,16 +105,7 @@ public void fetchXrefs(Page page, Class searchClass) { page.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); } - private String getCurrentUserId() { - SecurityContext context = SecurityContextHolder.getContext(); - String userId = ""; - if (context.getAuthentication().getPrincipal() != null) { - userId = context.getAuthentication().getPrincipal().toString(); - } - return userId; - } - - private SearchQueryBuilder applyUserId(SearchQueryBuilder searchQuery) { + private void applyUserId(SearchQueryBuilder searchQuery) { SecurityContext context = SecurityContextHolder.getContext(); Set userRolesSet = context.getAuthentication().getAuthorities().stream() @@ -100,14 +114,12 @@ private SearchQueryBuilder applyUserId(SearchQueryBuilder searchQuery) { List userIds = new ArrayList<>(); userIds.add(getCurrentUserId()); if (userRolesSet.contains("ROLE_ADMIN")) { - return searchQuery; + return; } else if (userRolesSet.contains("ROLE_USER")) { userIds.add("anonymousUser"); } searchQuery.appendList(userIds, "authUserId"); - - return searchQuery; } private List getPagedContent(SearchQueryBuilder searchQuery, Pageable pageReq) { @@ -125,6 +137,36 @@ private List getPagedContent(SearchQueryBuilder searchQuery, Pageable page return content; } + private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, Page ids) { + searchQuery.appendList(ids.stream().map(UUID::toString).toList(), "id"); + + TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); + + for (Entry entry : searchQuery.getParams().entrySet()) { + query.setParameter(entry.getKey(), entry.getValue()); + } + + List content = query.getResultList(); + return content; } + + private List getPagedContentIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { + + TypedQuery query = entityManager.createQuery(searchQuery.getIdQuery(), UUID.class); + + for (Entry entry : searchQuery.getParams().entrySet()) { + query.setParameter(entry.getKey(), entry.getValue()); + } + + query.setFirstResult((int) pageReq.getOffset()); + query.setMaxResults(pageReq.getPageSize()); + + List content = query.getResultList(); + return content; + } + + + + private Long getTotalCount(SearchQueryBuilder searchQuery) { String countQueryStr = searchQuery.getQuery() .replaceFirst("(select|Select|SELECT)( distinct)? ([^\\s]*) ", "select count($2 $3) ") diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java index f96023f2..8d1d183d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java @@ -16,6 +16,7 @@ public class SearchQueryBuilder { private String selectClause; + private String selectOnlyIds; private String whereClause; private String sortClause; private Map params; @@ -23,6 +24,7 @@ public class SearchQueryBuilder { public SearchQueryBuilder(Class clazz) { this.selectClause = "SELECT distinct entity FROM " + clazz.getSimpleName() + " entity "; + this.selectOnlyIds = "SELECT entity.id FROM " + clazz.getSimpleName() + " entity "; this.whereClause = "WHERE 1=1 "; this.sortClause = ""; this.params = new HashMap<>(); @@ -33,6 +35,8 @@ public String getQuery() { return selectClause + whereClause + sortClause; } + public String getIdQuery() { return selectOnlyIds + whereClause + sortClause;} + public Map getParams() { return params; } @@ -221,6 +225,7 @@ public SearchQueryBuilder withExRefs(List exRefIds, List exRe public SearchQueryBuilder join(String join, String name) { this.selectClause += "JOIN " + entityPrefix(join) + " " + paramFilter(name) + " "; + this.selectOnlyIds += "JOIN " + entityPrefix(join) + " " + paramFilter(name) + " "; return this; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index 5c36949d..8f88e265 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -137,7 +137,7 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest "*institute.instituteCode"); } - searchQuery.withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) + searchQuery.withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) .appendList(request.getAccessionNumbers(), "accessionNumber") .appendList(request.getCollections(), "collection") .appendList(request.getCommonCropNames(), "crop.cropName").appendList(request.getGermplasmDbIds(), "id") @@ -149,146 +149,150 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest .appendNamesList(request.getBinomialNames(), "genus", "genus", "species") .appendList(request.getFamilyCodes(), "familyCode"); - Page page = germplasmRepository.findAllBySearch(searchQuery, pageReq); + Page page = germplasmRepository.findAllBySearchIdsOnly(searchQuery, pageReq); - if(!page.isEmpty()) { - log.debug("fetching xrefs"); - fetchXrefs(page); + Page germs = germplasmRepository.findAllBySearchNoPage(searchQuery, page, pageReq); + + if (!page.isEmpty()) { + log.debug("Fetching xrefs"); + fetchXrefs(page, germs); log.debug("fetching attributes"); - fetchAttributes(page); + fetchAttributes(page, germs); log.debug("fetching donors"); - fetchDonors(page); + fetchDonors(page, germs); log.debug("fetching origins"); - fetchOrigin(page); + fetchOrigin(page, germs); log.debug("fetching institutes"); - fetchInstitutes(page); + fetchInstitutes(page, germs); log.debug("fetching taxons"); - fetchTaxons(page); + fetchTaxons(page, germs); log.debug("fetching storage codes"); - fetchStorageCodes(page); + fetchStorageCodes(page, germs); log.debug("fetching pedigree edges"); - fetchPedigreeEdges(page); + fetchPedigreeEdges(page, germs); } - - return page; + return germs; } - private void fetchXrefs(Page page) { + private void fetchXrefs(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder(GermplasmEntity.class); - searchQuery.leftJoinFetch("externalReferences", "externalReferences") - .leftJoinFetch("pedigree", "pedigree") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("externalReferences", "externalReferences"); - Page xrefs = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page xrefs = germplasmRepository.findAllBySearchNoPage(searchQuery, page, PageRequest.of(0, page.getSize())); Map> xrefByEntity = new HashMap<>(); xrefs.forEach(entity -> xrefByEntity.put(entity.getId(), entity.getExternalReferences())); - page.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); + germEntities.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId().toString()))); } - private void fetchAttributes(Page page) { + private void fetchAttributes(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("attributes", "attributes") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("attributes", "attributes"); - Page attributes = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page attributes = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> attributesByGerm = new HashMap<>(); attributes.forEach(germ -> attributesByGerm.put(germ.getId(), germ.getAttributes())); - page.forEach(germ -> germ.setAttributes(attributesByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setAttributes(attributesByGerm.get(germ.getId().toString()))); } - private void fetchDonors(Page page) { + private void fetchDonors(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("donors", "donors") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("donors", "donors"); - Page donors = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page donors = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> donorsByGerm = new HashMap<>(); donors.forEach(germ -> donorsByGerm.put(germ.getId(), germ.getDonors())); - page.forEach(germ -> germ.setDonors(donorsByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setDonors(donorsByGerm.get(germ.getId().toString()))); } - private void fetchOrigin(Page page) { + private void fetchOrigin(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("germplasmOrigin", "germplasmOrigin") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("germplasmOrigin", "germplasmOrigin"); - Page origins = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page origins = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> originsByGerm = new HashMap<>(); origins.forEach(germ -> originsByGerm.put(germ.getId(), germ.getGermplasmOrigin())); - page.forEach(germ -> germ.setGermplasmOrigin(originsByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setGermplasmOrigin(originsByGerm.get(germ.getId().toString()))); } - private void fetchInstitutes(Page page) { + private void fetchInstitutes(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("institutes", "institutes") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("institutes", "institutes"); - Page institutes = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page institutes = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> institutesByGerm = new HashMap<>(); institutes.forEach(germ -> institutesByGerm.put(germ.getId(), germ.getInstitutes())); - page.forEach(germ -> germ.setInstitutes(institutesByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setInstitutes(institutesByGerm.get(germ.getId().toString()))); } - private void fetchTaxons(Page page) { + private void fetchTaxons(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("taxonIds", "taxonIds") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("taxonIds", "taxonIds"); - Page taxonIds = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page taxonIds = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> taxonIdsByGerm = new HashMap<>(); taxonIds.forEach(germ -> taxonIdsByGerm.put(germ.getId(), germ.getTaxonIds())); - page.forEach(germ -> germ.setTaxonIds(taxonIdsByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setTaxonIds(taxonIdsByGerm.get(germ.getId().toString()))); } - private void fetchStorageCodes(Page page) { + private void fetchStorageCodes(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("typeOfGermplasmStorageCode", "typeOfGermplasmStorageCode") - .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); + searchQuery.leftJoinFetch("typeOfGermplasmStorageCode", "typeOfGermplasmStorageCode"); - Page storageCodes = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page storageCodes = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map> storageCodesByGerm = new HashMap<>(); storageCodes.forEach(germ -> storageCodesByGerm.put(germ.getId(), germ.getTypeOfGermplasmStorageCode())); - page.forEach(germ -> germ.setTypeOfGermplasmStorageCode(storageCodesByGerm.get(germ.getId()))); + germEntities.forEach(germ -> germ.setTypeOfGermplasmStorageCode(storageCodesByGerm.get(germ.getId().toString()))); } - private void fetchPedigreeEdges(Page page) { + private void fetchPedigreeEdges(Page page, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); searchQuery.leftJoinFetch("pedigree", "pedigree") .leftJoinFetch("*pedigree.crossingProject", "crossingProject") .leftJoinFetch("*pedigree.edges", "pedigreeEdges") - .leftJoinFetch("*pedigreeEdges.connectedNode", "connectedNode") - .appendList(page.stream() - .map(BrAPIBaseEntity::getId) - .collect(Collectors.toList()), "id"); + .leftJoinFetch("*pedigreeEdges.conncetedNode", "connectedNode"); - Page pedigree = germplasmRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page pedigree = germplasmRepository.findAllBySearchNoPage(searchQuery, + page, + PageRequest.of(0, page.getSize())); Map pedigreeByGerm = new HashMap<>(); pedigree.forEach(germ -> pedigreeByGerm.put(germ.getId(), germ.getPedigree())); - page.forEach(germ -> { - germ.setPedigree(pedigreeByGerm.get(germ.getId())); + germEntities.forEach(germ -> { + germ.setPedigree(pedigreeByGerm.get(germ.getId().toString())); }); } From cc5d9c6446fcf0bcf10c1e117c6ddd66e660d744 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 14 Mar 2025 14:50:11 -0400 Subject: [PATCH 02/13] Add SecurityUtils --- .../repository/BrAPIRepositoryImpl.java | 13 +++++++------ .../BrAPITestServer/service/SecurityUtils.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/service/SecurityUtils.java diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java index 2a1b75c2..20f03364 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -4,6 +4,7 @@ import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.model.entity.ExternalReferenceEntity; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; +import org.brapi.test.BrAPITestServer.service.SecurityUtils; import org.hibernate.jpa.QueryHints; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -44,7 +45,7 @@ public Page findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageR public Page findAllBySearchNoPage(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { applyUserId(searchQuery); - var entities = searchEntitiesWithIds(searchQuery, pagedIds); + List entities = searchEntitiesWithIds(searchQuery, pagedIds); return new PageImpl<>(entities, pageReq, pagedIds.getTotalElements()); } @@ -66,7 +67,7 @@ public Page findAllBySearchIdsOnly(SearchQueryBuilder searchQuery, Page public Optional findById(ID id) { Optional response = super.findById(id); if (response.isPresent()) { - String userId = getCurrentUserId(); + String userId = SecurityUtils.getCurrentUserId(); if (!(null == response.get().getAuthUserId() || userId.equals(response.get().getAuthUserId()) || "anonymousUser".equals(response.get().getAuthUserId()))) { @@ -77,13 +78,13 @@ public Optional findById(ID id) { } public S save(S entity) { - entity.setAuthUserId(getCurrentUserId()); + entity.setAuthUserId(SecurityUtils.getCurrentUserId()); return super.save(entity); } public List saveAll(Iterable entities) { for (S entity : entities) { - entity.setAuthUserId(getCurrentUserId()); + entity.setAuthUserId(SecurityUtils.getCurrentUserId()); } return super.saveAll(entities); } @@ -112,7 +113,7 @@ private void applyUserId(SearchQueryBuilder searchQuery) { .map(auth -> auth.getAuthority()).collect(Collectors.toSet()); List userIds = new ArrayList<>(); - userIds.add(getCurrentUserId()); + userIds.add(SecurityUtils.getCurrentUserId()); if (userRolesSet.contains("ROLE_ADMIN")) { return; } else if (userRolesSet.contains("ROLE_USER")) { @@ -138,7 +139,7 @@ private List getPagedContent(SearchQueryBuilder searchQuery, Pageable page } private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, Page ids) { - searchQuery.appendList(ids.stream().map(UUID::toString).toList(), "id"); + searchQuery.appendList(ids.stream().map(UUID::toString).collect(Collectors.toList()), "id"); TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SecurityUtils.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SecurityUtils.java new file mode 100644 index 00000000..6784a6f1 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SecurityUtils.java @@ -0,0 +1,15 @@ +package org.brapi.test.BrAPITestServer.service; + +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +public class SecurityUtils { + public static String getCurrentUserId() { + SecurityContext context = SecurityContextHolder.getContext(); + String userId = ""; + if (context.getAuthentication().getPrincipal() != null) { + userId = context.getAuthentication().getPrincipal().toString(); + } + return userId; + } +} \ No newline at end of file From ec4055a17dad6f3159216a6ff63ff00754df0969 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 11 Mar 2025 11:13:12 -0400 Subject: [PATCH 03/13] Add default sort to all SearchQueryBuilder queries on entity id. If not specified, this sort will be used to keep the endpoints idempotent. --- src/main/java/io/swagger/model/SearchRequest.java | 2 ++ .../service/SearchQueryBuilder.java | 14 +++++++++++++- .../service/germ/GermplasmService.java | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/swagger/model/SearchRequest.java b/src/main/java/io/swagger/model/SearchRequest.java index 8ad217c4..b1329a28 100644 --- a/src/main/java/io/swagger/model/SearchRequest.java +++ b/src/main/java/io/swagger/model/SearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.model.core.SortBy; +import io.swagger.model.core.SortOrder; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java index 8d1d183d..e60b55d0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java @@ -32,10 +32,22 @@ public SearchQueryBuilder(Class clazz) { } public String getQuery() { + if (sortClause.isBlank()) { + // By default, sort on entity id to have query result remain idempotent + sortClause = " ORDER BY entity.id ASC "; + } + return selectClause + whereClause + sortClause; } - public String getIdQuery() { return selectOnlyIds + whereClause + sortClause;} + public String getIdQuery() { + if (sortClause.isBlank()) { + // By default, sort on entity id to have query result remain idempotent + sortClause = " ORDER BY entity.id ASC "; + } + + return selectOnlyIds + whereClause + sortClause; + } public Map getParams() { return params; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index 8f88e265..9d76e84e 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -4,6 +4,7 @@ import java.util.*; import java.util.stream.Collectors; +import io.swagger.model.core.SortOrder; import io.swagger.model.germ.*; import jakarta.validation.Valid; @@ -137,7 +138,7 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest "*institute.instituteCode"); } - searchQuery.withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) + searchQuery.withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) .appendList(request.getAccessionNumbers(), "accessionNumber") .appendList(request.getCollections(), "collection") .appendList(request.getCommonCropNames(), "crop.cropName").appendList(request.getGermplasmDbIds(), "id") From 773b307328aad3f191fa58fc6dac37c850204ed6 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Thu, 13 Mar 2025 19:15:07 -0400 Subject: [PATCH 04/13] SearchQueryBuilder and BrAPIRepositoryImpl overhaul for germ optimization Added utility methods to SearchQueryBuilder and BrAPIRepositoryImpl to allow for proper paginating for hibernate fetch queries that don't suffocate memory. Also added methods to run queries without pagination entirely using the SearchQueryBuilder to prevent the use of pagination when it's not required, an issue that specifically had to be addressed for the BI cache, but one that introduced code that is reusable for other use cases. Modified the GermplasmApiController's searchGermplasmPost endpoint to accomodate two code paths: - One where no page and pageSize are supplied. In this scenario the code will grab all germplasm without the use of pagination. Good for large data grabs, but gets dangerous with excessively large amounts of data. This is entirely to meet BI's current use case, which we have strongly advised they move off of. - When page and/or pageSize are supplied, paginate as requested, default page size of 1000 if not requested. --- .../germ/GermplasmApiController.java | 27 +- .../repository/BrAPIRepository.java | 6 +- .../repository/BrAPIRepositoryImpl.java | 111 ++++--- .../service/SearchQueryBuilder.java | 50 +++- .../service/core/ListService.java | 2 +- .../service/core/LocationService.java | 2 +- .../service/core/PeopleService.java | 2 +- .../service/core/ProgramService.java | 2 +- .../service/core/SeasonService.java | 2 +- .../service/core/StudyService.java | 2 +- .../service/core/TrialService.java | 2 +- .../service/geno/CallService.java | 2 +- .../service/geno/CallSetService.java | 2 +- .../service/geno/GenomeMapService.java | 4 +- .../service/geno/MarkerPositionService.java | 2 +- .../service/geno/PlateService.java | 2 +- .../service/geno/ReferenceService.java | 2 +- .../service/geno/ReferenceSetService.java | 2 +- .../service/geno/SampleService.java | 2 +- .../service/geno/VariantService.java | 2 +- .../service/geno/VariantSetService.java | 2 +- .../service/germ/CrossService.java | 2 +- .../service/germ/CrossingProjectService.java | 23 +- .../germ/GermplasmAttributeService.java | 2 +- .../germ/GermplasmAttributeValueService.java | 2 +- .../service/germ/GermplasmService.java | 272 +++++++++++++----- .../service/germ/PedigreeService.java | 6 +- .../service/germ/SeedLotService.java | 4 +- .../service/pheno/EventService.java | 2 +- .../service/pheno/ImageService.java | 2 +- .../service/pheno/MethodService.java | 2 +- .../service/pheno/ObservationService.java | 2 +- .../service/pheno/ObservationUnitService.java | 6 +- .../pheno/ObservationVariableService.java | 2 +- .../service/pheno/ScaleService.java | 2 +- .../service/pheno/TraitService.java | 2 +- 36 files changed, 410 insertions(+), 151 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/GermplasmApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/GermplasmApiController.java index e13fa9ac..9f1ed1ae 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/GermplasmApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/GermplasmApiController.java @@ -213,12 +213,37 @@ public ResponseEntity searchGermplasmPost(@RequestBody log.debug("Request: " + request.getRequestURI()); validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); - Metadata metadata = generateMetaDataTemplate(body); String searchReqDbId = searchService.saveSearchRequest(body, SearchRequestTypes.GERMPLASM); if (searchReqDbId != null) { return responseAccepted(searchReqDbId); + } + + // WARN: This code was introduced to deal with a specific use case from BI which requires all data associated with + // a particular program to be retreived at once. This method of data retreival is highly unadvised and can come + // with serious performance deficits, such as slow response times and exhausted memory allocation. + // Benchmarking suggests that at around 245-275k germplasm records returned 8GB of allocated memory will fail to + // be enough to return a result. + + // This code is a stop-gap to allow BI to continue to do this improper retreival in a way that will be efficient + // for their specific use case. + + // To get the data in this ill-advised way, forgo sending a page or pageSize attribute in the germplasm search request + // to this endpoint. This will trigger the findGermplasmWithoutPaging code, which will grab all of the data without regard + // to data size. + + // To use the endpoint the right way, ensure one or both of the aforementioned attributes are set and the germplasm + // records will be retrieved and returned paginated to limit resource consumption. This way is much more fine tuned + // and will result in fast retrieval times with minimal memory allocation. + if (body.getPage() == null && body.getPageSize() == null) { + log.debug("Retrieving germs without pagination"); + List data = germplasmService.findGermplasmWithoutPaging(body); + Metadata metadata = generateEmptyMetadata(); + metadata.getPagination().setTotalCount(data.size()); + return responseOK(new GermplasmListResponse(), new GermplasmListResponseResult(), data, metadata); } else { + log.debug("Retrieving germs with pagination"); + Metadata metadata = generateMetaDataTemplate(body); List data = germplasmService.findGermplasm(body, metadata); return responseOK(new GermplasmListResponse(), new GermplasmListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java index 7b73ee08..5d0ebe15 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java @@ -15,11 +15,11 @@ @NoRepositoryBean public interface BrAPIRepository extends JpaRepository { - public Page findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageReq); + public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq); - public Page findAllBySearchIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq); + public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq); - public Page findAllBySearchNoPage(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq); + public List findAllBySearch(SearchQueryBuilder searchQuery); public Optional findById(ID id); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java index 20f03364..4ce23eab 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -1,5 +1,15 @@ package org.brapi.test.BrAPITestServer.repository; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import io.swagger.model.Metadata; +import io.swagger.model.germ.GermplasmSearchRequest; +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; + import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.model.entity.ExternalReferenceEntity; @@ -15,53 +25,70 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; - public class BrAPIRepositoryImpl extends SimpleJpaRepository implements BrAPIRepository { - private EntityManager entityManager; + private final EntityManager entityManager; public BrAPIRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { super(entityInformation, entityManager); this.entityManager = entityManager; } - // This is the method that should be used for simple entities with few collections and eager loading requirements. - public Page findAllBySearch(SearchQueryBuilder searchQuery, Pageable pageReq) { + /** + * Use this method to page simple entities with no lazily loaded collections or attributes. + * WARN: Failure to do so can easily exhaust memory at scale and will cause hibernate warnings. + */ + public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq) { applyUserId(searchQuery); List content = getPagedContent(searchQuery, pageReq); Long totalCount = getTotalCount(searchQuery); - Page page = new PageImpl<>(content, pageReq, totalCount); - - return page; + return new PageImpl<>(content, pageReq, totalCount); } - public Page findAllBySearchNoPage(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { + /** + * This method should be used when there is a need to page entities that are complex and have lots of lazily loaded, + * one-to-many collection attributes. Call this method with the query you've built. + * WARN: To avoid multiple bag fetch hibernate errors, only one collection that is one-many can be fetched at a time. + * Ensure only one of these types of entity members is being fetched at time. + * See {@link org.brapi.test.BrAPITestServer.service.germ.GermplasmService#findGermplasmEntities(GermplasmSearchRequest, Metadata)} for example usage. + * + * Once you fetch the first lazy loaded collection, if there are others you need to fetch for your entity it is + * recommended to utilize the non-paging findAllBySearch() method, creating a searchQuery that inserts all the ids + * of the entities found in the results from this method. Again, follow code path of above example usage to see how this is done. + * + * If the need is to fetch according to an entirely different base criteria, feel free to call this method again. + * + * The results will be paged and ordered based on the submitted searchQuery and pageReq. + */ + public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq) { applyUserId(searchQuery); - List entities = searchEntitiesWithIds(searchQuery, pagedIds); + // First grab all the ids of the entities according to the criteria of the searchQuery, paging as specified in the pageReq. + List content = getPagedContentIdsOnly(searchQuery, pageReq); + Long totalCount = getTotalCount(searchQuery); + + Page pagedIds = new PageImpl<>(content, pageReq, totalCount); - return new PageImpl<>(entities, pageReq, pagedIds.getTotalElements()); + // Now execute another query to fetch all the entities requested in the searchQuery, passing the pagedIds found + // in the previous query. We will fetch them utilizing the ids from the paged query, avoiding the hibernate + // warning of paging while fetching and consuming considerably less memory. + return findAllBySearchUsingIds(searchQuery, pagedIds, pageReq); } + private Page findAllBySearchUsingIds(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { + List entities = searchEntitiesWithIds(searchQuery, pagedIds.toList()); + return new PageImpl<>(entities, pageReq, pagedIds.getSize()); + } - // For entities that are complex and have lots of Collections and lazy loaded entities, it is more efficient to grab the IDs of the on Page, - // and afterward fetch these collections using the Ids, this time without paging. - public Page findAllBySearchIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { + /** + * Use this method to run the searchQuery without pagination. Useful for use cases where calls need to grab + * every result at once, but use sparingly for use cases returning large result sets. + */ + public List findAllBySearch(SearchQueryBuilder searchQuery) { applyUserId(searchQuery); - List content = getPagedContentIdsOnly(searchQuery, pageReq); - Long totalCount = getTotalCount(searchQuery); - - Page page = new PageImpl<>(content, pageReq, totalCount); - - return page; + return searchEntities(searchQuery); } public Optional findById(ID id) { @@ -98,7 +125,7 @@ public void fetchXrefs(Page page, Class searchClass) { searchQuery.leftJoinFetch("externalReferences", "externalReferences") .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); - Page xrefs = findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page xrefs = findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); Map> xrefByEntity = new HashMap<>(); xrefs.forEach(entity -> xrefByEntity.put(entity.getId(), entity.getExternalReferences())); @@ -127,28 +154,37 @@ private List getPagedContent(SearchQueryBuilder searchQuery, Pageable page TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); query.setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false); - for (Entry entry : searchQuery.getParams().entrySet()) { - query.setParameter(entry.getKey(), entry.getValue()); - } + setQueryParams(query, searchQuery); query.setFirstResult((int) pageReq.getOffset()); query.setMaxResults(pageReq.getPageSize()); - List content = query.getResultList(); - return content; + return query.getResultList(); } - private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, Page ids) { - searchQuery.appendList(ids.stream().map(UUID::toString).collect(Collectors.toList()), "id"); + private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, List ids) { + searchQuery.appendList(ids.stream().map(Object::toString).collect(Collectors.toList()), "id"); + + TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); + + setQueryParams(query, searchQuery); + return query.getResultList(); + } + + private List searchEntities(SearchQueryBuilder searchQuery) { TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); + setQueryParams(query, searchQuery); + + return query.getResultList(); + } + + private void setQueryParams(TypedQuery query, SearchQueryBuilder searchQuery) { for (Entry entry : searchQuery.getParams().entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } - - List content = query.getResultList(); - return content; } + } private List getPagedContentIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { @@ -161,8 +197,7 @@ private List getPagedContentIdsOnly(SearchQueryBuilder searchQuery, Pag query.setFirstResult((int) pageReq.getOffset()); query.setMaxResults(pageReq.getPageSize()); - List content = query.getResultList(); - return content; + return query.getResultList(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java index e60b55d0..57d19782 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java @@ -1,11 +1,7 @@ package org.brapi.test.BrAPITestServer.service; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.time.LocalDate; import java.time.OffsetDateTime; @@ -32,7 +28,7 @@ public SearchQueryBuilder(Class clazz) { } public String getQuery() { - if (sortClause.isBlank()) { + if (sortClause.isEmpty()) { // By default, sort on entity id to have query result remain idempotent sortClause = " ORDER BY entity.id ASC "; } @@ -41,7 +37,7 @@ public String getQuery() { } public String getIdQuery() { - if (sortClause.isBlank()) { + if (sortClause.isEmpty()) { // By default, sort on entity id to have query result remain idempotent sortClause = " ORDER BY entity.id ASC "; } @@ -66,6 +62,15 @@ public SearchQueryBuilder appendList(List list, String columnName) { return this; } + public SearchQueryBuilder appendIds(List ids) { + String paramName = paramFilter("id"); + if (ids != null && !ids.isEmpty()) { + this.whereClause += "AND " + entityPrefix("id") + " in :" + paramName + " "; + this.params.put(paramName, ids); + } + return this; + } + public SearchQueryBuilder appendIntList(List list, String columnName) { String paramName = paramFilter(columnName); if (list != null && !list.isEmpty()) { @@ -242,10 +247,39 @@ public SearchQueryBuilder join(String join, String name) { } public SearchQueryBuilder leftJoinFetch(String join, String name) { - this.selectClause += "LEFT JOIN FETCH " + entityPrefix(join) + " " + paramFilter(name) + " "; + this.selectClause += generateLeftJoinFetch(join, name); + return this; + } + + /** + * Use this method to remove left join fetches from specific collection attributes so you can leverage the same query to + * iterate through other lazily loaded collections on an entity you need to fetch. + */ + public SearchQueryBuilder removeAndReplaceLeftJoinFetch(String join, + String name, + String existingJoin, + String existingName) { + + this.selectClause = + this.selectClause.replace(generateLeftJoinFetch(existingJoin, existingName), generateLeftJoinFetch(join, name)); + return this; } + /** + * Use this method to remove left join fetches from specific collection attributes so you can leverage the same + * base query criteria to add another join fetch with leftJoinFetch() + */ + public SearchQueryBuilder removeLeftJoinFetch(String join, String name) { + this.selectClause = + this.selectClause.replace(generateLeftJoinFetch(join, name), ""); + return this; + } + + private String generateLeftJoinFetch(String join, String paramName) { + return "LEFT JOIN FETCH " + entityPrefix(join) + " " + paramFilter(paramName) + " "; + } + private String entityPrefix(String field) { if (field.startsWith("*")) { return field.substring(1); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java index b4ecc4b4..0bddb270 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java @@ -88,7 +88,7 @@ public List findLists(ListSearchRequest request, Metadata metadata) Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = buildQueryString(request); - Page entityPage = listRepository.findAllBySearch(searchQuery, pageReq); + Page entityPage = listRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List data = entityPage.map(this::convertToSummary).getContent(); PagingUtility.calculateMetaData(metadata, entityPage); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java index 71bc8943..505bb0d0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java @@ -83,7 +83,7 @@ public List findLocations(LocationSearchRequest request, Metadata meta .appendList(request.getParentLocationDbIds(), "parentLocation.id") .appendList(request.getParentLocationNames(), "parentLocation.name"); - Page entityPage = locationRepository.findAllBySearch(searchQuery, pageReq); + Page entityPage = locationRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List data = entityPage.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, entityPage); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java index 0a7ec737..60dfe288 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java @@ -62,7 +62,7 @@ public List findPeople(PersonSearchRequest request, Metadata metadata) { .appendList(request.getMiddleNames(), "middleName").appendList(request.getPersonDbIds(), "id") .appendList(request.getPhoneNumbers(), "phoneNumber").appendList(request.getUserIDs(), "userID"); - Page entityPage = peopleRepository.findAllBySearch(searchQuery, pageReq); + Page entityPage = peopleRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List data = entityPage.map(this::convertToPerson).getContent(); PagingUtility.calculateMetaData(metadata, entityPage); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java index e160b190..0ef25c0c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java @@ -69,7 +69,7 @@ public List findPrograms(ProgramSearchRequest request, Metadata metadat .appendList(request.getObjectives(), "objective").appendList(request.getProgramDbIds(), "id") .appendList(request.getProgramNames(), "name").appendEnumList(request.getProgramTypes(), "programType"); - Page page = programRepository.findAllBySearch(searchQuery, pageReq); + Page page = programRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List programs = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return programs; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java index ec8b4f89..5f3973b2 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java @@ -44,7 +44,7 @@ public List findSeasons(String seasonDbId, String season, String seasonN if (year != null) searchQuery = searchQuery.appendSingle(year, "year"); - Page entityPage = seasonRepository.findAllBySearch(searchQuery, pageReq); + Page entityPage = seasonRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List data = entityPage.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, entityPage); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java index 0c6c78bf..403a7d14 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java @@ -149,7 +149,7 @@ public List findStudies(StudySearchRequest request, Metadata metaData) { .appendList(request.getTrialDbIds(), "trial.id").appendList(request.getTrialNames(), "trial.trialName") .withSort(getSortByField(request.getSortBy()), request.getSortOrder()); - Page studiesPage = studyRepository.findAllBySearch(searchQuery, pageReq); + Page studiesPage = studyRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metaData, studiesPage); List studies = studiesPage.map(this::convertFromEntity).getContent(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java index 472d61c8..c5484200 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java @@ -129,7 +129,7 @@ public List findTrials(@Valid TrialSearchRequest request, Metadata metada .appendDateRange(request.getSearchDateRangeStart(), request.getSearchDateRangeEnd(), "startDate") .withSort(getSortByField(request.getSortBy()), request.getSortOrder()); - Page trialsPage = trialRepository.findAllBySearch(searchQuery, pageReq); + Page trialsPage = trialRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, trialsPage); List trials = trialsPage.map(this::convertFromEntity).getContent(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java index 757722f4..c904b36c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java @@ -71,7 +71,7 @@ public List findCallEntities(CallsSearchRequest request, Metadata me .appendList(request.getCallSetDbIds(), "callSet.id").appendList(request.getVariantDbIds(), "variant.id") .appendList(request.getVariantSetDbIds(), "variant.variantSet.id"); - Page page = callRepository.findAllBySearch(searchQuery, pageReq); + Page page = callRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, page); return page.getContent(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java index 1fe253bd..30e78c04 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java @@ -66,7 +66,7 @@ public List findCallSetEntities(CallSetsSearchRequest request, Me .appendList(request.getSampleDbIds(), "sample.id") .appendList(request.getSampleNames(), "sample.sampleName"); - Page page = callSetRepository.findAllBySearch(searchQuery, pageReq); + Page page = callSetRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, page); return page.getContent(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java index 8393a0fb..33e7a850 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java @@ -51,7 +51,7 @@ public List findMaps(String commonCropName, String mapPUI, String sci .appendSingle(studyDbId, "*study.id"); Pageable pageReq = PagingUtility.getPageRequest(metadata); - Page page = genomeMapRepository.findAllBySearch(searchQuery, pageReq); + Page page = genomeMapRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List maps = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return maps; @@ -73,7 +73,7 @@ public List findLinkageGroups(String mapDbId, Metadata metadata) { LinkageGroupEntity.class).appendSingle(mapDbId, "genomeMap.id"); Pageable pageReq = PagingUtility.getPageRequest(metadata); - Page page = linkageGroupRepository.findAllBySearch(searchQuery, pageReq); + Page page = linkageGroupRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List linkageGroups = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return linkageGroups; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java index 09e7f6f2..2f921f51 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java @@ -46,7 +46,7 @@ public List findMarkerPositions(MarkerPositionSearchRequest requ .appendList(request.getMapDbIds(), "linkageGroup.genomeMap.id") .appendNumberRange(request.getMinPosition(), request.getMaxPosition(), "position"); - Page page = markerPositionRepository.findAllBySearch(searchQuery, pageReq); + Page page = markerPositionRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List markerPositions = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return markerPositions; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java index 64f4777b..0803b6d1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java @@ -101,7 +101,7 @@ public List findPlates(PlateSearchRequest request, Metadata metadata) { .appendList(request.getTrialNames(), "trial.trialName").appendList(request.getStudyDbIds(), "study.id") .appendList(request.getStudyNames(), "study.studyName"); - Page page = plateRepository.findAllBySearch(searchQuery, pageReq); + Page page = plateRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List plates = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return plates; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java index f8da61fb..1f093427 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java @@ -83,7 +83,7 @@ public List findReferences(@Valid ReferencesSearchRequest request, Me .appendNumberRange(request.getMinLength(), request.getMaxLength(), "length") .appendSingle(request.isIsDerived(), "referenceSet.isDerived"); - Page page = referenceRepository.findAllBySearch(searchQuery, pageReq); + Page page = referenceRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List references = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return references; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java index 89b889b9..a865a399 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java @@ -65,7 +65,7 @@ public List findReferenceSets(ReferenceSetsSearchRequest request, .appendList(request.getMd5checksums(), "md5checksum") .appendList(request.getReferenceSetDbIds(), "id"); - Page page = referenceSetRepository.findAllBySearch(searchQuery, pageReq); + Page page = referenceSetRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List referenceSets = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return referenceSets; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java index 9b612ebb..02315386 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java @@ -135,7 +135,7 @@ public List findSamples(SampleSearchRequest request, Metadata metadata) .appendList(request.getStudyDbIds(), "plate.study.id") .appendList(request.getStudyNames(), "plate.study.studyName"); - Page page = sampleRepository.findAllBySearch(searchQuery, pageReq); + Page page = sampleRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List samples = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return samples; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java index 6a046e3a..9a9ba0de 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java @@ -63,7 +63,7 @@ public List findVariantEntities(VariantsSearchRequest request, Me searchQuery = searchQuery.appendList(request.getVariantSetDbIds(), "variantSet.id") .appendList(request.getVariantDbIds(), "id"); - Page page = variantRepository.findAllBySearch(searchQuery, pageReq); + Page page = variantRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, page); return page.getContent(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java index 507b1a18..1a309e92 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java @@ -97,7 +97,7 @@ private List findVariantSetEntities(VariantSetsSearchRequest r searchQuery.appendList(request.getStudyDbIds(), "study.id") .appendList(request.getStudyNames(), "study.studyName").appendList(request.getVariantSetDbIds(), "id"); - Page page = variantSetRepository.findAllBySearch(searchQuery, pageReq); + Page page = variantSetRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, page); return page.getContent(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java index 93932f1e..72114956 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java @@ -81,7 +81,7 @@ public Page findCrossEntities(String crossingProjectDbId, String cr if (plannedCross != null) searchQuery = searchQuery.appendSingle(plannedCross, "planned"); - Page page = crossRepository.findAllBySearch(searchQuery, pageReq); + Page page = crossRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, page); return page; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java index b7cabfc5..6869740f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Optional; +import io.swagger.model.IndexPagination; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; @@ -59,7 +60,7 @@ public List findCrossingProjects(String crossingProjectDbId, St searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), Arrays.asList(externalReferenceSource)); - Page page = crossingProjectRepository.findAllBySearch(searchQuery, pageReq); + Page page = crossingProjectRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List crossingProjects = new ArrayList<>(); for (CrossingProjectEntity entity : page) { crossingProjects.add(convertFromEntity(entity, includePotentialParents)); @@ -68,6 +69,26 @@ public List findCrossingProjects(String crossingProjectDbId, St return crossingProjects; } + public List findCrossingProjectsByIds(List crossingProjectIds) { + Metadata metadata = new Metadata().pagination(new IndexPagination()); + Pageable pageReq = PagingUtility.getPageRequest(metadata); + + SearchQueryBuilder searchQuery = new SearchQueryBuilder( + CrossingProjectEntity.class); + + if (crossingProjectIds != null && !crossingProjectIds.isEmpty()) { + searchQuery = searchQuery.appendList(crossingProjectIds, "id"); + } + + Page page = crossingProjectRepository.findAllBySearchAndPaginate(searchQuery, pageReq); + + if (page.hasContent()) { + return page.getContent(); + } + + return null; + } + public CrossingProject getCrossingProject(String crossingProjectDbId) throws BrAPIServerException { return convertFromEntity(getCrossingProjectEntity(crossingProjectDbId, HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java index a22ca6e9..e6e69958 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java @@ -125,7 +125,7 @@ public List findGermplasmAttributes(@Valid GermplasmAttribut .appendList(request.getOntologyDbIds(), "ontology.id") .appendList(request.getCommonCropNames(), "crop.crop_name"); - Page page = attributeRepository.findAllBySearch(searchQuery, pageReq); + Page page = attributeRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List attributes = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return attributes; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java index ca892a77..ae669b02 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java @@ -78,7 +78,7 @@ public List findGermplasmAttributeValues( .appendList(request.getGermplasmDbIds(), "germplasm.id") .appendList(request.getGermplasmNames(), "germplasm.germplasmName"); - Page page = attributeValueRepository.findAllBySearch(searchQuery, pageReq); + Page page = attributeValueRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List attributeValues = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return attributeValues; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index 9d76e84e..61f32f06 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -4,7 +4,6 @@ import java.util.*; import java.util.stream.Collectors; -import io.swagger.model.core.SortOrder; import io.swagger.model.germ.*; import jakarta.validation.Valid; @@ -28,7 +27,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -109,8 +107,57 @@ public List findGermplasm(@Valid GermplasmSearchRequest request, Meta return germplasms; } + public List findGermplasmWithoutPaging(@Valid GermplasmSearchRequest request) { + List entities = findGermplasmEntitiesWithoutPaging(request); + return entities.stream().map(this::convertFromEntity).collect(Collectors.toList()); + } + public Page findGermplasmEntities(@Valid GermplasmSearchRequest request, Metadata metadata) { Pageable pageReq = PagingUtility.getPageRequest(metadata); + + SearchQueryBuilder searchQuery = buildGermplasmSearchQuery(request); + + // First run the query without the fetching all the entities, grabbing the IDs only and paginating and sorting them. + Page germs = germplasmRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); + + // Hopefully this retains insertion order in the page? + List ids = germs.map(BrAPIBaseEntity::getId).toList(); + + if (!germs.isEmpty()) { + // If records were found, iterate through the rest of the lazyily loaded collections of the GermplasmEntity + // and LEFT JOIN FETCH all of them. + log.debug("Fetching xrefs"); + fetchXrefs(ids, germs); + log.debug("fetching attributes"); + fetchAttributes(ids, germs); + log.debug("fetching donors"); + fetchDonors(ids, germs); + log.debug("fetching origins"); + fetchOrigin(ids, germs); + log.debug("fetching institutes"); + fetchInstitutes(ids, germs); + log.debug("fetching taxons"); + fetchTaxons(ids, germs); + log.debug("fetching storage codes"); + fetchStorageCodes(ids, germs); + log.debug("fetching pedigree edges"); + fetchPedigreeEdges(ids, germs); + } + return germs; + } + + public List findGermplasmEntitiesWithoutPaging(@Valid GermplasmSearchRequest request) { + SearchQueryBuilder searchQuery = buildGermplasmSearchQuery(request); + + List germs = germplasmRepository.findAllBySearch(searchQuery); + + if (!germs.isEmpty()) { + fetchRemainingGermCollectionsUsingQuery(searchQuery, germs); + } + return germs; + } + + private SearchQueryBuilder buildGermplasmSearchQuery(GermplasmSearchRequest request) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); searchQuery.leftJoinFetch("synonyms", "synonyms") @@ -149,37 +196,21 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest .appendList(request.getGenus(), "genus").appendList(request.getSpecies(), "species") .appendNamesList(request.getBinomialNames(), "genus", "genus", "species") .appendList(request.getFamilyCodes(), "familyCode"); + return searchQuery; + } - Page page = germplasmRepository.findAllBySearchIdsOnly(searchQuery, pageReq); - - Page germs = germplasmRepository.findAllBySearchNoPage(searchQuery, page, pageReq); + // TODO: These left join fetch methods could be optimized a bit by guaranteeing a search on the same sort, because if the fetched + // TODO: list comes back with the same number of elements as the entities that come in, the two entity lists are in the exact same order. + // TODO: Therefore no need to store a map and can just iterate through both at the same time O(n). - if (!page.isEmpty()) { - log.debug("Fetching xrefs"); - fetchXrefs(page, germs); - log.debug("fetching attributes"); - fetchAttributes(page, germs); - log.debug("fetching donors"); - fetchDonors(page, germs); - log.debug("fetching origins"); - fetchOrigin(page, germs); - log.debug("fetching institutes"); - fetchInstitutes(page, germs); - log.debug("fetching taxons"); - fetchTaxons(page, germs); - log.debug("fetching storage codes"); - fetchStorageCodes(page, germs); - log.debug("fetching pedigree edges"); - fetchPedigreeEdges(page, germs); - } - return germs; - } + // TODO: Revisit when sortBy is added to GermplasmSearchRequest and we can pass through a sortBy value. + private void fetchXrefs(List ids, Page germEntities) { + SearchQueryBuilder searchQuery = new SearchQueryBuilder<>(GermplasmEntity.class); - private void fetchXrefs(Page page, Page germEntities) { - SearchQueryBuilder searchQuery = new SearchQueryBuilder(GermplasmEntity.class); - searchQuery.leftJoinFetch("externalReferences", "externalReferences"); + searchQuery.leftJoinFetch("externalReferences", "externalReferences") + .appendIds(ids); - Page xrefs = germplasmRepository.findAllBySearchNoPage(searchQuery, page, PageRequest.of(0, page.getSize())); + List xrefs = germplasmRepository.findAllBySearch(searchQuery); Map> xrefByEntity = new HashMap<>(); xrefs.forEach(entity -> xrefByEntity.put(entity.getId(), entity.getExternalReferences())); @@ -187,14 +218,13 @@ private void fetchXrefs(Page page, Page germEntities) { germEntities.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId().toString()))); } - private void fetchAttributes(Page page, Page germEntities) { + private void fetchAttributes(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("attributes", "attributes"); + searchQuery.leftJoinFetch("attributes", "attributes") + .appendIds(ids); - Page attributes = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List attributes = germplasmRepository.findAllBySearch(searchQuery); Map> attributesByGerm = new HashMap<>(); attributes.forEach(germ -> attributesByGerm.put(germ.getId(), germ.getAttributes())); @@ -202,14 +232,13 @@ private void fetchAttributes(Page page, Page germEntities germEntities.forEach(germ -> germ.setAttributes(attributesByGerm.get(germ.getId().toString()))); } - private void fetchDonors(Page page, Page germEntities) { + private void fetchDonors(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("donors", "donors"); + searchQuery.leftJoinFetch("donors", "donors") + .appendIds(ids); - Page donors = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List donors = germplasmRepository.findAllBySearch(searchQuery); Map> donorsByGerm = new HashMap<>(); donors.forEach(germ -> donorsByGerm.put(germ.getId(), germ.getDonors())); @@ -217,14 +246,13 @@ private void fetchDonors(Page page, Page germEntities) { germEntities.forEach(germ -> germ.setDonors(donorsByGerm.get(germ.getId().toString()))); } - private void fetchOrigin(Page page, Page germEntities) { + private void fetchOrigin(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("germplasmOrigin", "germplasmOrigin"); + searchQuery.leftJoinFetch("germplasmOrigin", "germplasmOrigin") + .appendIds(ids); - Page origins = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List origins = germplasmRepository.findAllBySearch(searchQuery); Map> originsByGerm = new HashMap<>(); origins.forEach(germ -> originsByGerm.put(germ.getId(), germ.getGermplasmOrigin())); @@ -232,14 +260,13 @@ private void fetchOrigin(Page page, Page germEntities) { germEntities.forEach(germ -> germ.setGermplasmOrigin(originsByGerm.get(germ.getId().toString()))); } - private void fetchInstitutes(Page page, Page germEntities) { + private void fetchInstitutes(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("institutes", "institutes"); + searchQuery.leftJoinFetch("institutes", "institutes") + .appendIds(ids); - Page institutes = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List institutes = germplasmRepository.findAllBySearch(searchQuery); Map> institutesByGerm = new HashMap<>(); institutes.forEach(germ -> institutesByGerm.put(germ.getId(), germ.getInstitutes())); @@ -247,14 +274,13 @@ private void fetchInstitutes(Page page, Page germEntities germEntities.forEach(germ -> germ.setInstitutes(institutesByGerm.get(germ.getId().toString()))); } - private void fetchTaxons(Page page, Page germEntities) { + private void fetchTaxons(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("taxonIds", "taxonIds"); + searchQuery.leftJoinFetch("taxonIds", "taxonIds") + .appendIds(ids); - Page taxonIds = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List taxonIds = germplasmRepository.findAllBySearch(searchQuery); Map> taxonIdsByGerm = new HashMap<>(); taxonIds.forEach(germ -> taxonIdsByGerm.put(germ.getId(), germ.getTaxonIds())); @@ -262,14 +288,13 @@ private void fetchTaxons(Page page, Page germEntities) { germEntities.forEach(germ -> germ.setTaxonIds(taxonIdsByGerm.get(germ.getId().toString()))); } - private void fetchStorageCodes(Page page, Page germEntities) { + private void fetchStorageCodes(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); - searchQuery.leftJoinFetch("typeOfGermplasmStorageCode", "typeOfGermplasmStorageCode"); + searchQuery.leftJoinFetch("typeOfGermplasmStorageCode", "typeOfGermplasmStorageCode") + .appendIds(ids); - Page storageCodes = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List storageCodes = germplasmRepository.findAllBySearch(searchQuery); Map> storageCodesByGerm = new HashMap<>(); storageCodes.forEach(germ -> storageCodesByGerm.put(germ.getId(), germ.getTypeOfGermplasmStorageCode())); @@ -277,17 +302,16 @@ private void fetchStorageCodes(Page page, Page germEntiti germEntities.forEach(germ -> germ.setTypeOfGermplasmStorageCode(storageCodesByGerm.get(germ.getId().toString()))); } - private void fetchPedigreeEdges(Page page, Page germEntities) { + private void fetchPedigreeEdges(List ids, Page germEntities) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmEntity.class); searchQuery.leftJoinFetch("pedigree", "pedigree") .leftJoinFetch("*pedigree.crossingProject", "crossingProject") .leftJoinFetch("*pedigree.edges", "pedigreeEdges") - .leftJoinFetch("*pedigreeEdges.conncetedNode", "connectedNode"); + .leftJoinFetch("*pedigreeEdges.conncetedNode", "connectedNode") + .appendIds(ids); - Page pedigree = germplasmRepository.findAllBySearchNoPage(searchQuery, - page, - PageRequest.of(0, page.getSize())); + List pedigree = germplasmRepository.findAllBySearch(searchQuery); Map pedigreeByGerm = new HashMap<>(); pedigree.forEach(germ -> pedigreeByGerm.put(germ.getId(), germ.getPedigree())); @@ -297,6 +321,126 @@ private void fetchPedigreeEdges(Page page, Page germEntit }); } + private void fetchRemainingGermCollectionsUsingQuery(SearchQueryBuilder searchQuery, List germEntities) { + // Remove unused left join fetches from the base query + searchQuery.removeLeftJoinFetch("synonyms", "synonyms") + .removeLeftJoinFetch("breedingMethod", "breedingMethod") + .removeLeftJoinFetch("crop", "crop") + .removeLeftJoinFetch("pedigree", "pedigree") + .removeLeftJoinFetch("*pedigree.crossingProject", "crossingProject"); + // Fetch xrefs + log.debug("Fetching xrefs"); + searchQuery.leftJoinFetch("externalReferences", + "externalReferences"); + + // TODO: This method doesn't need to utilize a method that returns a page. + List xrefs = germplasmRepository.findAllBySearch(searchQuery); + + Map> xrefByEntity = new HashMap<>(); + xrefs.forEach(entity -> xrefByEntity.put(entity.getId().toString(), entity.getExternalReferences())); + + germEntities.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId().toString()))); + // Fetch attributes + log.debug("fetching attributes"); + searchQuery.removeAndReplaceLeftJoinFetch("attributes", + "attributes", + "externalReferences", + "externalReferences"); + + List attributes = germplasmRepository.findAllBySearch(searchQuery); + + Map> attributesByGerm = new HashMap<>(); + attributes.forEach(germ -> attributesByGerm.put(germ.getId().toString(), germ.getAttributes())); + + germEntities.forEach(germ -> germ.setAttributes(attributesByGerm.get(germ.getId().toString()))); + // Fetch donors + log.debug("fetching donors"); + searchQuery.removeAndReplaceLeftJoinFetch("donors", + "donors", + "attributes", + "attributes"); + + List donors = germplasmRepository.findAllBySearch(searchQuery); + + Map> donorsByGerm = new HashMap<>(); + donors.forEach(germ -> donorsByGerm.put(germ.getId().toString(), germ.getDonors())); + + germEntities.forEach(germ -> germ.setDonors(donorsByGerm.get(germ.getId().toString()))); + // Fetch origins + log.debug("fetching origins"); + searchQuery.removeAndReplaceLeftJoinFetch("germplasmOrigin", + "germplasmOrigin", + "donors", + "donors"); + + + List origins = germplasmRepository.findAllBySearch(searchQuery); + + Map> originsByGerm = new HashMap<>(); + origins.forEach(germ -> originsByGerm.put(germ.getId().toString(), germ.getGermplasmOrigin())); + + germEntities.forEach(germ -> germ.setGermplasmOrigin(originsByGerm.get(germ.getId().toString()))); + + // Fetch institutes + log.debug("fetching institutes"); + searchQuery.removeAndReplaceLeftJoinFetch("institutes", + "institutes", + "germplasmOrigin", + "germplasmOrigin"); + + List institutes = germplasmRepository.findAllBySearch(searchQuery); + + Map> institutesByGerm = new HashMap<>(); + institutes.forEach(germ -> institutesByGerm.put(germ.getId().toString(), germ.getInstitutes())); + + germEntities.forEach(germ -> germ.setInstitutes(institutesByGerm.get(germ.getId().toString()))); + + // Fetch taxons + log.debug("fetching taxons"); + searchQuery.removeAndReplaceLeftJoinFetch("taxonIds", + "taxonIds", + "institutes", + "institutes"); + + List taxonIds = germplasmRepository.findAllBySearch(searchQuery); + + Map> taxonIdsByGerm = new HashMap<>(); + taxonIds.forEach(germ -> taxonIdsByGerm.put(germ.getId().toString(), germ.getTaxonIds())); + + germEntities.forEach(germ -> germ.setTaxonIds(taxonIdsByGerm.get(germ.getId().toString()))); + // Fetch storage codes + log.debug("fetching storage codes"); + searchQuery.removeAndReplaceLeftJoinFetch("typeOfGermplasmStorageCode", + "typeOfGermplasmStorageCode", + "taxonIds", + "taxonIds"); + + List storageCodes = germplasmRepository.findAllBySearch(searchQuery); + + Map> storageCodesByGerm = new HashMap<>(); + storageCodes.forEach(germ -> storageCodesByGerm.put(germ.getId().toString(), germ.getTypeOfGermplasmStorageCode())); + + germEntities.forEach(germ -> germ.setTypeOfGermplasmStorageCode(storageCodesByGerm.get(germ.getId().toString()))); + // Fetch pedigree edges + log.debug("fetching pedigree edges"); + searchQuery.removeAndReplaceLeftJoinFetch("pedigree", + "pedigree", + "typeOfGermplasmStorageCode", + "typeOfGermplasmStorageCode") + .leftJoinFetch("*pedigree.crossingProject", "crossingProject") + .leftJoinFetch("*pedigree.edges", "pedigreeEdges") + .leftJoinFetch("*pedigreeEdges.conncetedNode", "connectedNode"); + + List pedigree = germplasmRepository.findAllBySearch(searchQuery); + + Map pedigreeByGerm = new HashMap<>(); + pedigree.forEach(germ -> pedigreeByGerm.put(germ.getId().toString(), germ.getPedigree())); + + germEntities.forEach(germ -> { + germ.setPedigree(pedigreeByGerm.get(germ.getId().toString())); + }); + }; + public Germplasm getGermplasm(String germplasmDbId) throws BrAPIServerException { return convertFromEntity(getGermplasmEntity(germplasmDbId, HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java index 875ab788..0921f718 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java @@ -153,7 +153,7 @@ public List findPedigreeEntities(PedigreeSearchRequest reque .appendNamesList(request.getBinomialNames(), "germplasm.genus", "germplasm.genus", "germplasm.species") .appendList(request.getFamilyCodes(), "familyCode"); - Page page = pedigreeRepository.findAllBySearch(searchQuery, pageReq); + Page page = pedigreeRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List filteredNodes = filterGenerations(request, page.getContent()); @@ -495,7 +495,7 @@ private void updateEntityWithEdges(PedigreeNodeEntity entity, PedigreeNode node) search.appendSingle(node.getGermplasmDbId(), "connectedNode.germplasm.id"); search.appendEnum(PedigreeEdgeEntity.EdgeType.child, "edgeType"); Pageable defaultPageSize = PagingUtility.getPageRequest(new Metadata().pagination(new IndexPagination().pageSize(10000000))); - Page existingParentEdges = pedigreeEdgeRepository.findAllBySearch(search, defaultPageSize); + Page existingParentEdges = pedigreeEdgeRepository.findAllBySearchAndPaginate(search, defaultPageSize); List edgeIdsToDelete = new ArrayList<>(); edgeIdsToDelete.addAll(entity.getParentEdges().stream().map(e -> e.getId()).collect(Collectors.toList())); @@ -518,7 +518,7 @@ private void updateEntityWithEdges(PedigreeNodeEntity entity, PedigreeNode node) search.appendSingle(node.getGermplasmDbId(), "connectedNode.germplasm.id"); search.appendEnum(PedigreeEdgeEntity.EdgeType.parent, "edgeType"); Pageable defaultPageSize = PagingUtility.getPageRequest(new Metadata().pagination(new IndexPagination().pageSize(10000000))); - Page existingProgenyEdges = pedigreeEdgeRepository.findAllBySearch(search, defaultPageSize); + Page existingProgenyEdges = pedigreeEdgeRepository.findAllBySearchAndPaginate(search, defaultPageSize); List edgeIdsToDelete = new ArrayList<>(); edgeIdsToDelete.addAll(entity.getProgenyEdges().stream().map(e -> e.getId()).collect(Collectors.toList())); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java index 9ab9c104..ac013306 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java @@ -81,7 +81,7 @@ public List findSeedLots(String seedLotDbId, String germplasmDbId, Stri searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), Arrays.asList(externalReferenceSource)); - Page page = seedLotRepository.findAllBySearch(searchQuery, pageReq); + Page page = seedLotRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List seedLots = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return seedLots; @@ -165,7 +165,7 @@ public List findSeedLotTransactions(String transactionDbId, searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), Arrays.asList(externalReferenceSource)); - Page page = seedLotTransactionRepository.findAllBySearch(searchQuery, pageReq); + Page page = seedLotTransactionRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List transactions = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return transactions; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java index 76eeb10a..2dd37ce6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java @@ -45,7 +45,7 @@ public List findEvents(String eventDbId, String studyDbId, String observa "*dateOccured"); } - Page page = eventRepository.findAllBySearch(searchQuery, pageReq); + Page page = eventRepository.findAllBySearchAndPaginate(searchQuery, pageReq); List crossingProjects = page.map(this::convertFromEntity).getContent(); PagingUtility.calculateMetaData(metadata, page); return crossingProjects; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java index 040541de..ce916a6f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java @@ -86,7 +86,7 @@ public List findImageEntities(ImageSearchRequest request, Metadata "timeStamp") .appendGeoJSONArea(request.getImageLocation()); - Page imagePage = imageRepository.findAllBySearch(searchQuery, pageReq); + Page imagePage = imageRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, imagePage); return imagePage.getContent(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java index f7802388..6db5b694 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java @@ -43,7 +43,7 @@ public List findMethods(String methodDbId, String observationVariableDbI } searchQuery = searchQuery.appendSingle(methodDbId, "id").withExRefs(externalReferenceID, externalReferenceSource); - Page methodPage = methodRepository.findAllBySearch(searchQuery, pageReq); + Page methodPage = methodRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, methodPage); List methods = methodPage.map(this::convertFromEntity).getContent(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java index e729306a..b8ed689a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java @@ -243,7 +243,7 @@ public Page findObservationEntities(@Valid ObservationSearchR .appendList(request.getTrialDbIds(), "trial.id").appendList(request.getTrialNames(), "trial.trialName"); log.debug("starting search"); - Page page = observationRepository.findAllBySearch(searchQuery, pageReq); + Page page = observationRepository.findAllBySearchAndPaginate(searchQuery, pageReq); log.debug("search complete"); if(!page.isEmpty()) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java index 7b145f8b..f4da6cd3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java @@ -261,7 +261,7 @@ public Page findObservationUnitEntities(@Valid Observatio .appendList(request.getTrialNames(), "trial.trailName"); log.debug("Starting search"); - Page page = observationUnitRepository.findAllBySearch(searchQuery, pageReq); + Page page = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, pageReq); log.debug("Search complete"); if(!page.isEmpty()) { @@ -278,7 +278,7 @@ private void fetchTreatments(Page page) { searchQuery.leftJoinFetch("treatments", "treatments") .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); - Page treatments = observationUnitRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page treatments = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); Map> treatmentsByOu = new HashMap<>(); treatments.forEach(ou -> treatmentsByOu.put(ou.getId(), ou.getTreatments())); @@ -293,7 +293,7 @@ private void fetchObsUnitLevelRelationships(Page page) { .leftJoinFetch("*position.observationLevelRelationships", "observationLevelRelationships") .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); - Page positions = observationUnitRepository.findAllBySearch(searchQuery, PageRequest.of(0, page.getSize())); + Page positions = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); Map positionByOu = new HashMap<>(); positions.forEach(ou -> positionByOu.put(ou.getId(), ou.getPosition())); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java index 18261b1e..5f8ff598 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java @@ -137,7 +137,7 @@ public List findObservationVariables(ObservationVariableSea .appendEnumList(request.getDataTypes(), "scale.dataType"); log.debug("Starting variable search"); - Page page = observationVariableRepository.findAllBySearch(searchQuery, pageReq); + Page page = observationVariableRepository.findAllBySearchAndPaginate(searchQuery, pageReq); log.debug("Variable search complete"); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java index 501f28fa..796326b3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java @@ -48,7 +48,7 @@ public List findScales(String scaleDbId, String observationVariableDbId, } searchQuery = searchQuery.appendSingle(scaleDbId, "id").withExRefs(externalReferenceID, externalReferenceSource); - Page scalePage = scaleRepository.findAllBySearch(searchQuery, pageReq); + Page scalePage = scaleRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, scalePage); List scales = scalePage.map(this::convertFromEntity).getContent(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java index d9dddc14..3e9411cf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java @@ -44,7 +44,7 @@ public List findTraits(String traitDbId, String observationVariableDbId, } searchQuery = searchQuery.appendSingle(traitDbId, "id").withExRefs(externalReferenceID, externalReferenceSource); - Page traitPage = traitRepository.findAllBySearch(searchQuery, pageReq); + Page traitPage = traitRepository.findAllBySearchAndPaginate(searchQuery, pageReq); PagingUtility.calculateMetaData(metadata, traitPage); List traits = traitPage.map(this::convertFromEntity).getContent(); From 1b06e85e0456dabb1b80ee74727eb05fa924f8e8 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 14 Mar 2025 22:19:00 -0400 Subject: [PATCH 05/13] Fix paging response metadata bug, patch UUID issue --- .../BrAPITestServer/converter/JsonbConverter.java | 5 ++++- .../repository/BrAPIRepositoryImpl.java | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java b/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java index 795a4b2a..0b437bcf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java @@ -17,7 +17,10 @@ public class JsonbConverter implements AttributeConverter { @Override public String convertToDatabaseColumn(Object jsonb) { try { - return mapper.writeValueAsString(jsonb); + if (jsonb != null) { + return mapper.writeValueAsString(jsonb); + } + return null; } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java index 4ce23eab..7f8e9588 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -65,10 +65,10 @@ public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder search applyUserId(searchQuery); // First grab all the ids of the entities according to the criteria of the searchQuery, paging as specified in the pageReq. - List content = getPagedContentIdsOnly(searchQuery, pageReq); + List content = getPagedContentIdsOnly(searchQuery, pageReq); Long totalCount = getTotalCount(searchQuery); - Page pagedIds = new PageImpl<>(content, pageReq, totalCount); + Page pagedIds = new PageImpl<>(content, pageReq, totalCount); // Now execute another query to fetch all the entities requested in the searchQuery, passing the pagedIds found // in the previous query. We will fetch them utilizing the ids from the paged query, avoiding the hibernate @@ -76,10 +76,10 @@ public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder search return findAllBySearchUsingIds(searchQuery, pagedIds, pageReq); } - private Page findAllBySearchUsingIds(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { + private Page findAllBySearchUsingIds(SearchQueryBuilder searchQuery, Page pagedIds, Pageable pageReq) { List entities = searchEntitiesWithIds(searchQuery, pagedIds.toList()); - return new PageImpl<>(entities, pageReq, pagedIds.getSize()); + return new PageImpl<>(entities, pageReq, pagedIds.getTotalElements()); } /** @@ -162,7 +162,7 @@ private List getPagedContent(SearchQueryBuilder searchQuery, Pageable page return query.getResultList(); } - private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, List ids) { + private List searchEntitiesWithIds(SearchQueryBuilder searchQuery, List ids) { searchQuery.appendList(ids.stream().map(Object::toString).collect(Collectors.toList()), "id"); TypedQuery query = entityManager.createQuery(searchQuery.getQuery(), searchQuery.getClazz()); @@ -186,9 +186,9 @@ private void setQueryParams(TypedQuery query, SearchQueryBuilder searchQue } } - private List getPagedContentIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { + private List getPagedContentIdsOnly(SearchQueryBuilder searchQuery, Pageable pageReq) { - TypedQuery query = entityManager.createQuery(searchQuery.getIdQuery(), UUID.class); + TypedQuery query = entityManager.createQuery(searchQuery.getIdQuery(), String.class); for (Entry entry : searchQuery.getParams().entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); From 9ff25a53250b371dec1a280c838b393a0d2cdb3a Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Mon, 17 Mar 2025 13:30:49 -0400 Subject: [PATCH 06/13] Add error handling for bad pagination RQs to avoid giant queries and errors --- .../controller/germ/CrossesApiController.java | 4 +-- .../germ/CrossingProjectsApiController.java | 4 +-- .../germ/PlannedCrossesApiController.java | 4 +-- .../germ/SeedLotsApiController.java | 4 +-- .../exceptions/InvalidPagingException.java | 9 +++++ .../factory/BrAPIComponent.java | 3 +- .../factory/core/ListComponent.java | 4 ++- .../factory/core/TrialComponent.java | 4 ++- .../factory/geno/PlateComponent.java | 4 ++- .../factory/geno/SampleComponent.java | 4 ++- .../factory/germ/GermplasmComponent.java | 4 ++- .../repository/BrAPIRepository.java | 8 ++--- .../repository/BrAPIRepositoryImpl.java | 34 ++++++++++++++++--- .../service/core/ListService.java | 6 ++-- .../service/core/LocationService.java | 6 ++-- .../service/core/PeopleService.java | 6 ++-- .../service/core/SeasonService.java | 3 +- .../service/core/StudyService.java | 5 +-- .../service/core/TrialService.java | 6 ++-- .../service/geno/AlleleMatrixService.java | 16 ++++++--- .../service/geno/CallService.java | 9 +++-- .../service/geno/CallSetService.java | 9 +++-- .../service/geno/GenomeMapService.java | 6 ++-- .../service/geno/MarkerPositionService.java | 7 ++-- .../service/geno/PlateService.java | 6 ++-- .../service/geno/ReferenceService.java | 6 ++-- .../service/geno/ReferenceSetService.java | 6 ++-- .../service/geno/SampleService.java | 6 ++-- .../service/geno/VariantService.java | 9 +++-- .../service/geno/VariantSetService.java | 9 +++-- .../service/germ/CrossService.java | 31 +++++++++-------- .../service/germ/CrossingProjectService.java | 26 ++------------ .../germ/GermplasmAttributeService.java | 5 +-- .../germ/GermplasmAttributeValueService.java | 6 ++-- .../service/germ/GermplasmService.java | 14 +++++--- .../service/germ/PedigreeService.java | 15 +++++--- .../service/germ/SeedLotService.java | 14 ++++---- .../service/pheno/EventService.java | 4 ++- .../service/pheno/ImageService.java | 12 ++++--- .../service/pheno/MethodService.java | 3 +- .../service/pheno/ObservationService.java | 12 ++++--- .../service/pheno/ObservationUnitService.java | 21 ++++++++---- .../pheno/ObservationVariableService.java | 6 ++-- .../service/pheno/ScaleService.java | 5 +-- .../service/pheno/TraitService.java | 3 +- 45 files changed, 245 insertions(+), 143 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java index 0b967588..6761aab6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java @@ -59,8 +59,8 @@ public ResponseEntity crossesGet( validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); - List data = crossService.findCrosses(crossingProjectDbId, crossingProjectName, crossDbId, crossName, - commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, + List data = crossService.findCrosses(crossingProjectDbId, crossDbId, + externalReferenceID, externalReferenceSource, metadata); return responseOK(new CrossesListResponse(), new CrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java index dc26d757..cddbc80f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java @@ -60,8 +60,8 @@ public ResponseEntity crossingProjectsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = crossingProjectService.findCrossingProjects(crossingProjectDbId, - crossingProjectName, includePotentialParents, commonCropName, programDbId, externalReferenceId, - externalReferenceID, externalReferenceSource, metadata); + crossingProjectName, includePotentialParents, commonCropName, programDbId, + externalReferenceID, externalReferenceSource, metadata); return responseOK(new CrossingProjectsListResponse(), new CrossingProjectsListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java index 83bf62c1..cad3aad7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java @@ -60,8 +60,8 @@ public ResponseEntity plannedCrossesGet( validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); - List data = crossService.findPlannedCrosses(crossingProjectDbId, crossingProjectName, - plannedCrossDbId, plannedCrossName, status, commonCropName, programDbId, externalReferenceId, + List data = crossService.findPlannedCrosses(crossingProjectDbId, + plannedCrossDbId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new PlannedCrossesListResponse(), new PlannedCrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java index 9147ca44..9fdad3db 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java @@ -66,7 +66,7 @@ public ResponseEntity seedlotsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = seedLotService.findSeedLots(seedLotDbId, germplasmDbId, germplasmName, crossDbId, - crossName, commonCropName, programDbId, externalReferenceId, externalReferenceID, + crossName, commonCropName, programDbId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new SeedLotListResponse(), new SeedLotListResponseResult(), data, metadata); } @@ -156,7 +156,7 @@ public ResponseEntity seedlotsTransactionsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = seedLotService.findSeedLotTransactions(transactionDbId, seedLotDbId, - germplasmDbId, germplasmName, crossDbId, crossName, commonCropName, programDbId, externalReferenceId, + germplasmDbId, germplasmName, crossDbId, crossName, commonCropName, programDbId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new SeedLotTransactionListResponse(), new SeedLotTransactionListResponseResult(), data, metadata); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/exceptions/InvalidPagingException.java b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/InvalidPagingException.java index cee5b80f..819b23d6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/exceptions/InvalidPagingException.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/InvalidPagingException.java @@ -4,9 +4,18 @@ public class InvalidPagingException extends BrAPIServerException { private static final long serialVersionUID = 6250184179200451757L; + + private static final String pageNumExceedsTotalPages = + "A page was requested which exceeds total amount of data available. Please make a RQ with page < totalPages - 1. " + + "Page numbers start at 0, and you can find out totalPages by making a RQ with \"page\": 0"; public InvalidPagingException(String field) { super(HttpStatus.BAD_REQUEST, "\'" + field + "\' value is invalid"); } + + // This constructor should only be used when the pageNum of the RQ exceeds the total number of pages available. + public InvalidPagingException() { + super(HttpStatus.BAD_REQUEST, pageNumExceedsTotalPages); + } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/BrAPIComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/BrAPIComponent.java index 7744633c..207d5404 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/BrAPIComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/BrAPIComponent.java @@ -4,11 +4,12 @@ import io.swagger.model.SearchRequest; import io.swagger.model.core.BatchDeleteTypes; import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import java.util.List; public interface BrAPIComponent { - List findEntities(@Valid R request, Metadata metadata); + List findEntities(@Valid R request, Metadata metadata) throws BrAPIServerException; BatchDeleteTypes getBatchDeleteType(); List collectDbIds(List entities); void deleteBatchDeleteData(List dbIds); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/core/ListComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/core/ListComponent.java index 25b3a1e9..134e08cd 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/core/ListComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/core/ListComponent.java @@ -5,6 +5,7 @@ import io.swagger.model.core.ListSearchRequest; import io.swagger.model.core.ListSummary; import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.factory.BrAPIComponent; import org.brapi.test.BrAPITestServer.service.core.ListService; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +24,8 @@ public ListComponent(ListService listService) { } @Override - public List findEntities(@Valid ListSearchRequest request, Metadata metadata) { + public List findEntities(@Valid ListSearchRequest request, Metadata metadata) + throws BrAPIServerException { return listService.findLists(request, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/core/TrialComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/core/TrialComponent.java index fc8ccbb9..0efbbaf7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/core/TrialComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/core/TrialComponent.java @@ -4,6 +4,7 @@ import io.swagger.model.core.BatchDeleteTypes; import io.swagger.model.core.Trial; import io.swagger.model.core.TrialSearchRequest; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.factory.BrAPIComponent; import org.brapi.test.BrAPITestServer.service.core.TrialService; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +23,8 @@ public TrialComponent(TrialService trialService) { } @Override - public List findEntities(TrialSearchRequest request, Metadata metadata) { + public List findEntities(TrialSearchRequest request, Metadata metadata) + throws BrAPIServerException { return trialService.findTrials(request, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/PlateComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/PlateComponent.java index 5bfaf1f4..52d7ee50 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/PlateComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/PlateComponent.java @@ -5,6 +5,7 @@ import io.swagger.model.geno.Plate; import io.swagger.model.geno.PlateSearchRequest; import org.apache.commons.lang3.NotImplementedException; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.factory.BrAPIComponent; import org.brapi.test.BrAPITestServer.service.geno.PlateService; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +24,8 @@ public PlateComponent(PlateService plateService) { } @Override - public List findEntities(PlateSearchRequest request, Metadata metadata) { + public List findEntities(PlateSearchRequest request, Metadata metadata) + throws BrAPIServerException { return plateService.findPlates(request, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/SampleComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/SampleComponent.java index 05209351..26679f58 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/SampleComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/geno/SampleComponent.java @@ -4,6 +4,7 @@ import io.swagger.model.core.BatchDeleteTypes; import io.swagger.model.geno.Sample; import io.swagger.model.geno.SampleSearchRequest; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.factory.BrAPIComponent; import org.brapi.test.BrAPITestServer.service.geno.SampleService; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +23,8 @@ public SampleComponent(SampleService sampleService) { } @Override - public List findEntities(SampleSearchRequest request, Metadata metadata) { + public List findEntities(SampleSearchRequest request, Metadata metadata) + throws BrAPIServerException { return sampleService.findSamples(request, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/factory/germ/GermplasmComponent.java b/src/main/java/org/brapi/test/BrAPITestServer/factory/germ/GermplasmComponent.java index 953b4ec4..fea81f5b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/factory/germ/GermplasmComponent.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/factory/germ/GermplasmComponent.java @@ -5,6 +5,7 @@ import io.swagger.model.germ.Germplasm; import io.swagger.model.germ.GermplasmSearchRequest; import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.factory.BrAPIComponent; import org.brapi.test.BrAPITestServer.service.germ.GermplasmService; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +24,8 @@ public GermplasmComponent(GermplasmService germplasmService) { } @Override - public List findEntities(@Valid GermplasmSearchRequest request, Metadata metadata) { + public List findEntities(@Valid GermplasmSearchRequest request, Metadata metadata) + throws BrAPIServerException { return germplasmService.findGermplasm(request, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java index 5d0ebe15..e038360c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java @@ -3,8 +3,8 @@ import java.io.Serializable; import java.util.List; import java.util.Optional; -import java.util.UUID; +import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; @@ -15,9 +15,9 @@ @NoRepositoryBean public interface BrAPIRepository extends JpaRepository { - public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq); + public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq) throws InvalidPagingException; - public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq); + public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq) throws InvalidPagingException; public List findAllBySearch(SearchQueryBuilder searchQuery); @@ -29,5 +29,5 @@ public interface BrAPIRepository void refresh(S entity); - public void fetchXrefs(Page page, Class searchClass); + public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException; } \ No newline at end of file diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java index 7f8e9588..9bfa577c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -10,6 +10,7 @@ import javax.persistence.EntityManager; import javax.persistence.TypedQuery; +import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.model.entity.ExternalReferenceEntity; @@ -38,11 +39,21 @@ public BrAPIRepositoryImpl(JpaEntityInformation entityInformation, Entity * Use this method to page simple entities with no lazily loaded collections or attributes. * WARN: Failure to do so can easily exhaust memory at scale and will cause hibernate warnings. */ - public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq) { + public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pageable pageReq) + throws InvalidPagingException { applyUserId(searchQuery); - List content = getPagedContent(searchQuery, pageReq); + Long totalCount = getTotalCount(searchQuery); + validatePageNumber(pageReq, totalCount); + + if (totalCount == 0) { + // Short-circuit to avoid running possible long-running query + return new PageImpl<>(Collections.emptyList(), pageReq, totalCount); + } + + List content = getPagedContent(searchQuery, pageReq); + return new PageImpl<>(content, pageReq, totalCount); } @@ -61,12 +72,16 @@ public Page findAllBySearchAndPaginate(SearchQueryBuilder searchQuery, Pag * * The results will be paged and ordered based on the submitted searchQuery and pageReq. */ - public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq) { + public Page findAllBySearchPaginatingWithFetches(SearchQueryBuilder searchQuery, Pageable pageReq) + throws InvalidPagingException { applyUserId(searchQuery); + Long totalCount = getTotalCount(searchQuery); + + validatePageNumber(pageReq, totalCount); + // First grab all the ids of the entities according to the criteria of the searchQuery, paging as specified in the pageReq. List content = getPagedContentIdsOnly(searchQuery, pageReq); - Long totalCount = getTotalCount(searchQuery); Page pagedIds = new PageImpl<>(content, pageReq, totalCount); @@ -120,7 +135,7 @@ public void refresh(S entity) { this.entityManager.refresh(entity); } - public void fetchXrefs(Page page, Class searchClass) { + public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException { SearchQueryBuilder searchQuery = new SearchQueryBuilder(searchClass); searchQuery.leftJoinFetch("externalReferences", "externalReferences") .appendList(page.stream().map(BrAPIBaseEntity::getId).collect(Collectors.toList()), "id"); @@ -220,4 +235,13 @@ private Long getTotalCount(SearchQueryBuilder searchQuery) { } return 0L; } + + private void validatePageNumber(Pageable pageReq, Long totalCount) throws InvalidPagingException { + int reqPageNum = pageReq.getPageNumber(); + if (reqPageNum != 0 && reqPageNum > Math.floor(((double) totalCount) / pageReq.getPageSize())) { + // Condition indicates a request was sent where the page requested exceeds the total number of pages. + // Instruct requester to send the correct request. + throw new InvalidPagingException(); + } + } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java index 0bddb270..854559a2 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java @@ -59,7 +59,7 @@ public List findBatchDeleteLists(String batchDeleteDbId, Metadata m public List findLists(ListTypes listType, String listName, String listDbId, String listSource, String programDbId, String commonCropName, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) throws BrAPIServerException { ListSearchRequest request = new ListSearchRequest(); if (listType != null) { request.setListType(listType); @@ -80,11 +80,11 @@ public List findLists(ListTypes listType, String listName, String l request.addCommonCropNamesItem(commonCropName); } request.addExternalReferenceItem(externalReferenceId, externalReferenceID, externalReferenceSource); - + return findLists(request, metadata); } - public List findLists(ListSearchRequest request, Metadata metadata) { + public List findLists(ListSearchRequest request, Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = buildQueryString(request); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java index 505bb0d0..857d5187 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java @@ -37,7 +37,8 @@ public LocationService(LocationRepository locationRepository) { public List findLocations(String locationDbId, String locationType, String locationName, String parentLocationDbId, String parentLocationName, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { LocationSearchRequest request = new LocationSearchRequest(); if (locationDbId != null) request.addLocationDbIdsItem(locationDbId); @@ -59,7 +60,8 @@ public List findLocations(String locationDbId, String locationType, St return findLocations(request, metadata); } - public List findLocations(LocationSearchRequest request, Metadata metadata) { + public List findLocations(LocationSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(LocationEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java index 60dfe288..8fc905fc 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java @@ -32,7 +32,8 @@ public PeopleService(PeopleRepository peopleRepository) { public List findPeople(String firstName, String lastName, String personDbId, String userID, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { PersonSearchRequest request = new PersonSearchRequest(); if (firstName != null) @@ -52,7 +53,8 @@ public List findPeople(String firstName, String lastName, String personD return findPeople(request, metadata); } - public List findPeople(PersonSearchRequest request, Metadata metadata) { + public List findPeople(PersonSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(PersonEntity.class) .withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java index 5f3973b2..eaf9e706 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java @@ -32,7 +32,8 @@ public SeasonService(SeasonRepository seasonRepository) { } public List findSeasons(String seasonDbId, String season, String seasonName, Integer year, - Metadata metadata) { + Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(SeasonEntity.class); if (seasonDbId != null) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java index 403a7d14..b8e995b0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java @@ -78,7 +78,7 @@ public List findStudies(String commonCropName, String studyType, String p String seasonDbId, String trialDbId, String studyDbId, String studyName, String studyCode, String studyPUI, String germplasmDbId, String observationVariableDbId, String externalReferenceId, String externalReferenceID, String externalReferenceSource, Boolean active, String sortBy, String sortOrder, - Metadata metadata) { + Metadata metadata) throws BrAPIServerException { StudySearchRequest request = new StudySearchRequest(); if (commonCropName != null) @@ -117,7 +117,8 @@ public List findStudies(String commonCropName, String studyType, String p return findStudies(request, metadata); } - public List findStudies(StudySearchRequest request, Metadata metaData) { + public List findStudies(StudySearchRequest request, Metadata metaData) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metaData); SearchQueryBuilder searchQuery = new SearchQueryBuilder(StudyEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java index c5484200..776906da 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java @@ -71,7 +71,8 @@ public List findTrials(@Valid String commonCropName, @Valid String contac @Valid String locationDbId, @Valid LocalDate searchDateRangeStart, @Valid LocalDate searchDateRangeEnd, @Valid String studyDbId, @Valid String trialDbId, @Valid String trialName, @Valid String trialPUI, @Valid String externalReferenceId, @Valid String externalReferenceID, @Valid String externalReferenceSource, - @Valid Boolean active, @Valid String sortBy, @Valid String sortOrder, Metadata metadata) { + @Valid Boolean active, @Valid String sortBy, @Valid String sortOrder, Metadata metadata) + throws BrAPIServerException { TrialSearchRequest request = new TrialSearchRequest(); if (active != null) @@ -105,7 +106,8 @@ public List findTrials(@Valid String commonCropName, @Valid String contac return findTrials(request, metadata); } - public List findTrials(@Valid TrialSearchRequest request, Metadata metadata) { + public List findTrials(@Valid TrialSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(TrialEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/AlleleMatrixService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/AlleleMatrixService.java index c0ba0c76..74e3ee14 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/AlleleMatrixService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/AlleleMatrixService.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.math.NumberUtils; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.CallEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.CallSetEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantEntity; @@ -43,7 +44,8 @@ public AlleleMatrix findAlleleMatrix(Integer dimensionVariantPage, Integer dimen Integer dimensionCallSetPage, Integer dimensionCallSetPageSize, Boolean preview, String dataMatrixNames, String dataMatrixAbbreviations, String positionRange, String germplasmDbId, String germplasmName, String germplasmPUI, String callSetDbId, String variantDbId, String variantSetDbId, - Boolean expandHomozygotes, String unknownString, String sepPhased, String sepUnphased, Metadata metadata) { + Boolean expandHomozygotes, String unknownString, String sepPhased, String sepUnphased, Metadata metadata) + throws BrAPIServerException { AlleleMatrixSearchRequestPagination variantPage = new AlleleMatrixSearchRequestPagination() .dimension(DimensionEnum.VARIANTS); @@ -111,7 +113,8 @@ public AlleleMatrix findAlleleMatrix(Integer dimensionVariantPage, Integer dimen return findAlleleMatrix(request, metadata); } - public AlleleMatrix findAlleleMatrix(AlleleMatrixSearchRequest request, Metadata metadata) { + public AlleleMatrix findAlleleMatrix(AlleleMatrixSearchRequest request, Metadata metadata) + throws BrAPIServerException { AlleleMatrix matrixResponse = new AlleleMatrix(); AlleleMatrixPagination variantPage = new AlleleMatrixPagination().dimension(DimensionEnum.VARIANTS); AlleleMatrixPagination callSetPage = new AlleleMatrixPagination().dimension(DimensionEnum.CALLSETS); @@ -221,7 +224,8 @@ private void prepareMatrices(AlleleMatrixSearchRequest request, AlleleMatrix mat } } - private List findCalls(AlleleMatrix matrixResponse, AlleleMatrixSearchRequest request) { + private List findCalls(AlleleMatrix matrixResponse, AlleleMatrixSearchRequest request) + throws BrAPIServerException { CallsSearchRequest callSearchReq = new CallsSearchRequest(); callSearchReq.setCallSetDbIds(matrixResponse.getCallSetDbIds()); callSearchReq.setVariantDbIds(matrixResponse.getVariantDbIds()); @@ -241,7 +245,8 @@ private List findCalls(AlleleMatrix matrixResponse, AlleleMatrixSear return callService.findCallEntities(callSearchReq, metadata); } - private List findVariants(AlleleMatrixSearchRequest request, AlleleMatrixPagination page) { + private List findVariants(AlleleMatrixSearchRequest request, AlleleMatrixPagination page) + throws BrAPIServerException { VariantsSearchRequest variantSearchReq = new VariantsSearchRequest(); variantSearchReq.setCallSetDbIds(request.getCallSetDbIds()); variantSearchReq.setVariantDbIds(request.getVariantDbIds()); @@ -269,7 +274,8 @@ private List findVariants(AlleleMatrixSearchRequest request, Alle return variants; } - private List findCallSets(AlleleMatrixSearchRequest request, AlleleMatrixPagination page) { + private List findCallSets(AlleleMatrixSearchRequest request, AlleleMatrixPagination page) + throws BrAPIServerException { CallSetsSearchRequest callSetSearchReq = new CallSetsSearchRequest(); callSetSearchReq.setCallSetDbIds(request.getCallSetDbIds()); callSetSearchReq.setGermplasmDbIds(request.getGermplasmDbIds()); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java index c904b36c..ab9be78f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java @@ -41,7 +41,8 @@ public CallService(CallRepository callRepository) { } public CallsListResponseResult findCalls(String callSetDbId, String variantDbId, String variantSetDbId, - Boolean expandHomozygotes, String unknownString, String sepPhased, String sepUnphased, Metadata metadata) { + Boolean expandHomozygotes, String unknownString, String sepPhased, String sepUnphased, Metadata metadata) + throws BrAPIServerException { CallsSearchRequest request = new CallsSearchRequest(); if (callSetDbId != null) request.addCallSetDbIdsItem(callSetDbId); @@ -57,7 +58,8 @@ public CallsListResponseResult findCalls(String callSetDbId, String variantDbId, return findCalls(request, metadata); } - public CallsListResponseResult findCalls(CallsSearchRequest request, Metadata metadata) { + public CallsListResponseResult findCalls(CallsSearchRequest request, Metadata metadata) + throws BrAPIServerException { List calls = findCallEntities(request, metadata).stream().map(e -> { return convertFromEntityWithFormatting(e, request); }).collect(Collectors.toList()); @@ -65,7 +67,8 @@ public CallsListResponseResult findCalls(CallsSearchRequest request, Metadata me return result; } - public List findCallEntities(CallsSearchRequest request, Metadata metadata) { + public List findCallEntities(CallsSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(CallEntity.class) .appendList(request.getCallSetDbIds(), "callSet.id").appendList(request.getVariantDbIds(), "variant.id") diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java index 30e78c04..906f19b4 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java @@ -30,7 +30,8 @@ public CallSetService(CallSetRepository callSetRepository) { } public List findCallSets(String callSetDbId, String callSetName, String variantSetDbId, String sampleDbId, - String germplasmDbId, String externalReferenceId, String externalReferenceSource, Metadata metadata) { + String germplasmDbId, String externalReferenceId, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { CallSetsSearchRequest request = new CallSetsSearchRequest(); if (callSetDbId != null) request.addCallSetDbIdsItem(callSetDbId); @@ -47,11 +48,13 @@ public List findCallSets(String callSetDbId, String callSetName, String return findCallSets(request, metadata); } - public List findCallSets(CallSetsSearchRequest request, Metadata metadata) { + public List findCallSets(CallSetsSearchRequest request, Metadata metadata) + throws BrAPIServerException { return findCallSetEntities(request, metadata).stream().map(this::convertFromEntity).collect(Collectors.toList()); } - public List findCallSetEntities(CallSetsSearchRequest request, Metadata metadata) { + public List findCallSetEntities(CallSetsSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(CallSetEntity.class); if(request.getVariantSetDbIds() != null) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java index 33e7a850..654c87c0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java @@ -35,7 +35,8 @@ public GenomeMapService(GenomeMapRepository genomeMapRepository, LinkageGroupRep } public List findMaps(String commonCropName, String mapPUI, String scientificName, String type, - String programDbId, String trialDbId, String studyDbId, Metadata metadata) { + String programDbId, String trialDbId, String studyDbId, Metadata metadata) + throws BrAPIServerException { SearchQueryBuilder searchQuery = new SearchQueryBuilder(GenomeMapEntity.class); if (programDbId != null || trialDbId != null || studyDbId != null) { @@ -68,7 +69,8 @@ public GenomeMap getMap(String mapDbId) throws BrAPIServerException { return map; } - public List findLinkageGroups(String mapDbId, Metadata metadata) { + public List findLinkageGroups(String mapDbId, Metadata metadata) + throws BrAPIServerException { SearchQueryBuilder searchQuery = new SearchQueryBuilder( LinkageGroupEntity.class).appendSingle(mapDbId, "genomeMap.id"); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java index 2f921f51..65c7391f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java @@ -2,6 +2,7 @@ import java.util.List; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.MarkerPositionEntity; import org.brapi.test.BrAPITestServer.repository.geno.MarkerPositionRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; @@ -24,7 +25,8 @@ public MarkerPositionService(MarkerPositionRepository markerPositionRepository) } public List findMarkerPositions(String mapDbId, String linkageGroupName, String variantDbId, - Integer maxPosition, Integer minPosition, Metadata metadata) { + Integer maxPosition, Integer minPosition, Metadata metadata) + throws BrAPIServerException { MarkerPositionSearchRequest request = new MarkerPositionSearchRequest(); if (mapDbId != null) request.addMapDbIdsItem(mapDbId); @@ -38,7 +40,8 @@ public List findMarkerPositions(String mapDbId, String linkageGr return findMarkerPositions(request, metadata); } - public List findMarkerPositions(MarkerPositionSearchRequest request, Metadata metadata) { + public List findMarkerPositions(MarkerPositionSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( MarkerPositionEntity.class).appendList(request.getLinkageGroupNames(), "linkageGroup.linkageGroupName") diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java index 0803b6d1..1509a4d0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java @@ -48,7 +48,8 @@ public PlateService(PlateRepository plateRepository, ProgramService programServi public List findPlates(String sampleDbId, String sampleName, String sampleGroupDbId, String observationUnitDbId, String plateDbId, String plateName, String germplasmDbId, String studyDbId, String trialDbId, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { PlateSearchRequest request = new PlateSearchRequest(); if (sampleDbId != null) request.addSampleDbIdsItem(sampleDbId); @@ -78,7 +79,8 @@ public List findPlates(String sampleDbId, String sampleName, String sampl return findPlates(request, metadata); } - public List findPlates(PlateSearchRequest request, Metadata metadata) { + public List findPlates(PlateSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(PlateEntity.class); if (request.getSampleDbIds() != null || request.getSampleNames() != null diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java index 1f093427..0dd23e3c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java @@ -47,7 +47,8 @@ public ReferenceService(ReferenceRepository referenceRepository, ReferenceBaseRe public List findReferences(String referenceDbId, String referenceSetDbId, String accession, String md5checksum, Boolean isDerived, Integer minLength, Integer maxLength, String trialDbId, String studyDbId, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { ReferencesSearchRequest request = new ReferencesSearchRequest(); if (referenceDbId != null) request.addReferenceDbIdsItem(referenceDbId); @@ -74,7 +75,8 @@ public List findReferences(String referenceDbId, String referenceSetD return findReferences(request, metadata); } - public List findReferences(@Valid ReferencesSearchRequest request, Metadata metadata) { + public List findReferences(@Valid ReferencesSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(ReferenceEntity.class) .appendList(request.getAccessions(), "referenceSet.sourceGermplasm.accessionNumber") diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java index a865a399..1ad58b53 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java @@ -33,7 +33,8 @@ public ReferenceSetService(ReferenceSetRepository referenceSetRepository) { public List findReferenceSets(String referenceSetDbId, String accession, String assemblyPUI, String md5checksum, String trialDbId, String studyDbId, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { ReferenceSetsSearchRequest request = new ReferenceSetsSearchRequest(); if (referenceSetDbId != null) request.addReferenceSetDbIdsItem(referenceSetDbId); @@ -57,7 +58,8 @@ public List findReferenceSets(String referenceSetDbId, String acce return findReferenceSets(request, metadata); } - public List findReferenceSets(ReferenceSetsSearchRequest request, Metadata metadata) { + public List findReferenceSets(ReferenceSetsSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( ReferenceSetEntity.class).appendList(request.getAccessions(), "sourceGermplasm.accessionNumber") diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java index 02315386..4f5b3680 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java @@ -87,7 +87,8 @@ public List findBatchDeleteSamples(String batchDeleteDbId, Metadata meta public List findSamples(String sampleDbId, String sampleName, String sampleGroupDbId, String observationUnitDbId, String plateDbId, String plateName, String germplasmDbId, String studyDbId, String trialDbId, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { SampleSearchRequest request = new SampleSearchRequest(); if (sampleDbId != null) request.addSampleDbIdsItem(sampleDbId); @@ -117,7 +118,8 @@ public List findSamples(String sampleDbId, String sampleName, String sam return findSamples(request, metadata); } - public List findSamples(SampleSearchRequest request, Metadata metadata) { + public List findSamples(SampleSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(SampleEntity.class) .withExRefs(request.getExternalReferenceIDs(), request.getExternalReferenceSources()) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java index 9a9ba0de..c4612fc3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java @@ -31,7 +31,8 @@ public VariantService(VariantRepository variantRepository) { } public List findVariants(String variantDbId, String variantSetDbId, String referenceDbId, - String referenceSetDbId, String externalReferenceId, String externalReferenceSource, Metadata metadata) { + String referenceSetDbId, String externalReferenceId, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException{ VariantsSearchRequest request = new VariantsSearchRequest(); if (variantSetDbId != null) @@ -48,12 +49,14 @@ public List findVariants(String variantDbId, String variantSetDbId, Str return findVariants(request, metadata); } - public List findVariants(VariantsSearchRequest request, Metadata metadata) { + public List findVariants(VariantsSearchRequest request, Metadata metadata) + throws BrAPIServerException { return findVariantEntities(request, metadata).stream().map(this::convertFromEntity) .collect(Collectors.toList()); } - public List findVariantEntities(VariantsSearchRequest request, Metadata metadata) { + public List findVariantEntities(VariantsSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(VariantEntity.class); if (request.getCallSetDbIds() != null && !request.getCallSetDbIds().isEmpty()) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java index 1a309e92..a1572a41 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java @@ -55,7 +55,8 @@ public VariantSetService(VariantSetRepository variantSetRepository, VariantServi public List findVariantSets(String variantSetDbId, String variantDbId, String callSetDbId, String studyDbId, String studyName, String referenceSetDbId, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { VariantSetsSearchRequest request = new VariantSetsSearchRequest(); if (variantSetDbId != null) request.addVariantSetDbIdsItem(variantSetDbId); @@ -78,13 +79,15 @@ public List findVariantSets(String variantSetDbId, String variantDbI return findVariantSets(request, metadata); } - public List findVariantSets(VariantSetsSearchRequest request, Metadata metadata) { + public List findVariantSets(VariantSetsSearchRequest request, Metadata metadata) + throws BrAPIServerException { List variantSets = findVariantSetEntities(request, metadata).stream().map(this::convertFromEntity) .collect(Collectors.toList()); return variantSets; } - private List findVariantSetEntities(VariantSetsSearchRequest request, Metadata metadata) { + private List findVariantSetEntities(VariantSetsSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( VariantSetEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java index 72114956..2ef3a7b8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java @@ -47,27 +47,30 @@ public CrossService(CrossRepository crossRepository, CrossingProjectService cros this.crossParentService = crossParentService; } - public List findCrosses(String crossingProjectDbId, String crossingProjectName, String crossDbId, - String crossName, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { - List crosses = findCrossEntities(crossingProjectDbId, crossingProjectName, crossDbId, crossName, null, - commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, false, + public List findCrosses(String crossingProjectDbId, String crossDbId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { + List crosses = findCrossEntities(crossingProjectDbId, crossDbId, + externalReferenceID, externalReferenceSource, false, metadata).map(this::convertToCross).getContent(); return crosses; } - public List findPlannedCrosses(String crossingProjectDbId, String crossingProjectName, - String crossDbId, String crossName, String status, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) { - List crosses = findCrossEntities(crossingProjectDbId, crossingProjectName, crossDbId, crossName, status, - commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, true, + public List findPlannedCrosses(String crossingProjectDbId, + String crossDbId, + String externalReferenceID, String externalReferenceSource, + Metadata metadata) + throws BrAPIServerException { + List crosses = findCrossEntities(crossingProjectDbId, crossDbId, + externalReferenceID, externalReferenceSource, true, metadata).map(this::convertToPlanned).getContent(); return crosses; } - public Page findCrossEntities(String crossingProjectDbId, String crossingProjectName, String crossDbId, - String crossName, String status, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Boolean plannedCross, Metadata metadata) { + public Page findCrossEntities(String crossingProjectDbId, String crossDbId, + String externalReferenceID, String externalReferenceSource, + Boolean plannedCross, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(CrossEntity.class); @@ -224,7 +227,7 @@ private void updateEntity(CrossEntity entity, CrossNewRequest cross) throws BrAP if (cross.getCrossName() != null) entity.setName(cross.getCrossName()); if (cross.getPlannedCrossDbId() != null) { - List plannedEntity = findCrossEntities(null, null, cross.getPlannedCrossDbId(), null, null, null, null, null, null, null, true, null).getContent(); + List plannedEntity = findCrossEntities(null, cross.getPlannedCrossDbId(), null, null, true, null).getContent(); entity.setPlannedCross(plannedEntity.get(0)); } if (cross.getPollinationEvents() != null) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java index 6869740f..373dc65f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Optional; -import io.swagger.model.IndexPagination; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; @@ -41,8 +40,9 @@ public CrossingProjectService(CrossingProjectRepository crossingProjectRepositor } public List findCrossingProjects(String crossingProjectDbId, String crossingProjectName, - Boolean includePotentialParents, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { + Boolean includePotentialParents, String commonCropName, String programDbId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( @@ -69,26 +69,6 @@ public List findCrossingProjects(String crossingProjectDbId, St return crossingProjects; } - public List findCrossingProjectsByIds(List crossingProjectIds) { - Metadata metadata = new Metadata().pagination(new IndexPagination()); - Pageable pageReq = PagingUtility.getPageRequest(metadata); - - SearchQueryBuilder searchQuery = new SearchQueryBuilder( - CrossingProjectEntity.class); - - if (crossingProjectIds != null && !crossingProjectIds.isEmpty()) { - searchQuery = searchQuery.appendList(crossingProjectIds, "id"); - } - - Page page = crossingProjectRepository.findAllBySearchAndPaginate(searchQuery, pageReq); - - if (page.hasContent()) { - return page.getContent(); - } - - return null; - } - public CrossingProject getCrossingProject(String crossingProjectDbId) throws BrAPIServerException { return convertFromEntity(getCrossingProjectEntity(crossingProjectDbId, HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java index e6e69958..1a912ede 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java @@ -43,7 +43,8 @@ public List findGermplasmAttributes(String attributeCategory String attributeName, String attributePUI, String germplasmDbId, String methodDbId, String methodName, String methodPUI, String scaleDbId, String scaleName, String scalePUI, String traitDbId, String traitName, String traitPUI, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { GermplasmAttributeSearchRequest request = new GermplasmAttributeSearchRequest(); if (attributeCategory != null) @@ -85,7 +86,7 @@ public List findGermplasmAttributes(String attributeCategory } public List findGermplasmAttributes(@Valid GermplasmAttributeSearchRequest request, - Metadata metadata) { + Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmAttributeDefinitionEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java index ae669b02..d74ca453 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java @@ -40,7 +40,8 @@ public GermplasmAttributeValueService(GermplasmAttributeValueRepository attribut public List findGermplasmAttributeValues(String attributeValueDbId, String attributeDbId, String attributeName, String germplasmDbId, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { GermplasmAttributeValueSearchRequest request = new GermplasmAttributeValueSearchRequest(); if (attributeValueDbId != null) @@ -62,7 +63,8 @@ public List findGermplasmAttributeValues(String attribu } public List findGermplasmAttributeValues( - @Valid GermplasmAttributeValueSearchRequest request, Metadata metadata) { + @Valid GermplasmAttributeValueSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( GermplasmAttributeValueEntity.class) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index 61f32f06..a562bf93 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -58,7 +58,8 @@ public List findGermplasm(String germplasmPUI, String germplasmDbId, String accessionNumber, String collection, String binomialName, String genus, String species, String trialDbId, String studyDbId, String synonym, String parentDbId, String progenyDbId, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { GermplasmSearchRequest request = new GermplasmSearchRequest(); if (germplasmPUI != null) @@ -97,7 +98,8 @@ public List findGermplasm(String germplasmPUI, String germplasmDbId, return findGermplasm(request, metadata); } - public List findGermplasm(@Valid GermplasmSearchRequest request, Metadata metadata) { + public List findGermplasm(@Valid GermplasmSearchRequest request, Metadata metadata) + throws BrAPIServerException { log.debug("starting germplasm search"); Page page = findGermplasmEntities(request, metadata); log.debug("germplasm search complete, converting germplasm entities"); @@ -112,7 +114,8 @@ public List findGermplasmWithoutPaging(@Valid GermplasmSearchRequest return entities.stream().map(this::convertFromEntity).collect(Collectors.toList()); } - public Page findGermplasmEntities(@Valid GermplasmSearchRequest request, Metadata metadata) { + public Page findGermplasmEntities(@Valid GermplasmSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = buildGermplasmSearchQuery(request); @@ -124,7 +127,7 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest List ids = germs.map(BrAPIBaseEntity::getId).toList(); if (!germs.isEmpty()) { - // If records were found, iterate through the rest of the lazyily loaded collections of the GermplasmEntity + // If records were found, iterate through the rest of the lazily loaded collections of the GermplasmEntity // and LEFT JOIN FETCH all of them. log.debug("Fetching xrefs"); fetchXrefs(ids, germs); @@ -674,7 +677,8 @@ private void updateSynonymEntities(List synonyms, G } } - public GermplasmEntity findByUnknownIdentity(String germplasmStr) { + public GermplasmEntity findByUnknownIdentity(String germplasmStr) + throws BrAPIServerException { List germplasmList = Arrays.asList(germplasmStr); Metadata metadata = new Metadata().pagination(new IndexPagination()); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java index 0921f718..0921c89d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java @@ -64,7 +64,8 @@ public List findPedigree(String germplasmPUI, String germplasmDbId String trialDbId, String studyDbId, String synonym, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceSource, Boolean includeParents, Boolean includeSiblings, Boolean includeProgeny, Boolean includeFullTree, Integer pedigreeDepth, Integer progenyDepth, - Metadata metadata) { + Metadata metadata) + throws BrAPIServerException { PedigreeSearchRequest request = new PedigreeSearchRequest(); if (germplasmPUI != null) @@ -111,13 +112,15 @@ public List findPedigree(String germplasmPUI, String germplasmDbId return findPedigree(request, metadata); } - public List findPedigree(PedigreeSearchRequest request, Metadata metadata) { + public List findPedigree(PedigreeSearchRequest request, Metadata metadata) + throws BrAPIServerException { List page = findPedigreeEntities(request, metadata); List pedigreeNodes = convertFromEntities(page, request); return pedigreeNodes; } - public List findPedigreeEntities(PedigreeSearchRequest request, Metadata metadata) { + public List findPedigreeEntities(PedigreeSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( PedigreeNodeEntity.class); @@ -304,7 +307,8 @@ public void updateGermplasmPedigree(List data) throws BrAPIServerExce } - private Map getExistingPedigreeNodes(List germplasmDbIds) { + private Map getExistingPedigreeNodes(List germplasmDbIds) + throws BrAPIServerException { Map nodesByGermplasm = new HashMap<>(); if (null != germplasmDbIds && !germplasmDbIds.isEmpty()) { @@ -537,7 +541,8 @@ private void updateEntityWithEdges(PedigreeNodeEntity entity, PedigreeNode node) } } - public PedigreeNode convertFromGermplasmToPedigree(Germplasm germplasm) { + public PedigreeNode convertFromGermplasmToPedigree(Germplasm germplasm) + throws BrAPIServerException { PedigreeNode node = new PedigreeNode(); List pedigreeList = new ArrayList<>(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java index ac013306..81b683f9 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java @@ -59,8 +59,9 @@ public SeedLotService(SeedLotRepository seedLotRepository, } public List findSeedLots(String seedLotDbId, String germplasmDbId, String germplasmName, String crossDbId, - String crossName, String commonCropName, String programDbId, String externalReferenceId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String crossName, String commonCropName, String programDbId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(SeedLotEntity.class); @@ -131,16 +132,17 @@ public List findSeedLotTransactions(String seedLotDbId, Stri String transactionDirection, Metadata metadata) throws BrAPIServerException { SeedLot seedLot = getSeedLot(seedLotDbId); if (seedLot != null) { - return findSeedLotTransactions(transactionDbId, seedLotDbId, null, null, null, null, null, null, null, null, + return findSeedLotTransactions(transactionDbId, seedLotDbId, null, null, null, null, null, null, null, null, metadata); } return null; } public List findSeedLotTransactions(String transactionDbId, String seedLotDbId, - String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, - String programDbId, String externalReferenceId, String externalReferenceID, String externalReferenceSource, - Metadata metadata) { + String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, + String programDbId, String externalReferenceID, String externalReferenceSource, + Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( SeedLotTransactionEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java index 2dd37ce6..318d9fd9 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.stream.Collectors; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.EventEntity; import org.brapi.test.BrAPITestServer.repository.pheno.EventRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; @@ -29,7 +30,8 @@ public EventService(EventRepository eventRepository) { } public List findEvents(String eventDbId, String studyDbId, String observationUnitDbId, String eventType, - OffsetDateTime dateRangeStart, OffsetDateTime dateRangeEnd, Metadata metadata) { + OffsetDateTime dateRangeStart, OffsetDateTime dateRangeEnd, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(EventEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java index ce916a6f..ac24e8d8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java @@ -42,7 +42,8 @@ public ImageService(ImageRepository imageRepository, ObservationService observat public List findImages(String imageDbId, String imageName, String observationUnitDbId, String observationDbId, String descriptiveOntologyTerm, String commonCropName, String programDbId, - String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { ImageSearchRequest request = new ImageSearchRequest(); if (imageDbId != null) request.addImageDbIdsItem(imageDbId); @@ -64,7 +65,8 @@ public List findImages(String imageDbId, String imageName, String observa return findImages(request, metadata); } - public List findImageEntities(ImageSearchRequest request, Metadata metadata) { + public List findImageEntities(ImageSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(ImageEntity.class); if (request.getDescriptiveOntologyTerms() != null) { @@ -91,7 +93,8 @@ public List findImageEntities(ImageSearchRequest request, Metadata return imagePage.getContent(); } - public List findImages(ImageSearchRequest request, Metadata metadata) { + public List findImages(ImageSearchRequest request, Metadata metadata) + throws BrAPIServerException { List imagePage = findImageEntities(request, metadata); List images = imagePage.stream().map(this::convertFromEntity).collect(Collectors.toList()); return images; @@ -170,7 +173,8 @@ public byte[] getImageData(String imageDbId) { return bytes; } - public List deleteImages(ImageSearchRequest body, Metadata metadata) { + public List deleteImages(ImageSearchRequest body, Metadata metadata) + throws BrAPIServerException { List deletedImageDbIds = new ArrayList<>(); if (body.getTotalParameterCount() > 0) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java index 6db5b694..e0b29d07 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java @@ -34,7 +34,8 @@ public MethodService(MethodRepository methodRepository, OntologyService ontology public List findMethods(String methodDbId, String observationVariableDbId, String ontologyDbId, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(MethodEntity.class); if (observationVariableDbId != null) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java index b8ed689a..7e6b0b51 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java @@ -146,7 +146,8 @@ public ObservationTable findObservationsTable(String observationUnitDbId, String return findObservationsTable(obsRequest, metadata); } - public ObservationTable findObservationsTable(ObservationSearchRequest obsRequest, Metadata metadata) { + public ObservationTable findObservationsTable(ObservationSearchRequest obsRequest, Metadata metadata) + throws BrAPIServerException { Page page = findObservationEntities(obsRequest, metadata); log.debug("converting "+page.getSize()+" entities"); @@ -162,7 +163,8 @@ public ObservationTable findObservationsTable(ObservationSearchRequest obsReques return table; } - public List findObservations(@Valid ObservationSearchRequest request, Metadata metadata) { + public List findObservations(@Valid ObservationSearchRequest request, Metadata metadata) + throws BrAPIServerException { Page page = findObservationEntities(request, metadata); log.debug("converting "+page.getSize()+" entities"); List observations = page.map(this::convertFromEntity).getContent(); @@ -171,7 +173,8 @@ public List findObservations(@Valid ObservationSearchRequest reques return observations; } - public Page findObservationEntities(@Valid ObservationSearchRequest request, Metadata metadata) { + public Page findObservationEntities(@Valid ObservationSearchRequest request, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationEntity.class); @@ -297,7 +300,8 @@ public List updateObservations(@Valid Map deleteObservations(ObservationSearchRequest body, Metadata metadata) { + public List deleteObservations(ObservationSearchRequest body, Metadata metadata) + throws BrAPIServerException { List deletedObservationDbIds = new ArrayList<>(); if (body.getTotalParameterCount() > 0) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java index f4da6cd3..d87556d7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java @@ -75,7 +75,8 @@ public List findObservationUnits(String observationUnitDbId, St String observationUnitLevelCode, String observationUnitLevelRelationshipName, String observationUnitLevelRelationshipOrder, String observationUnitLevelRelationshipCode, String observationUnitLevelRelationshipDbId, String commonCropName, Boolean includeObservations, - String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) { + String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { ObservationUnitSearchRequest request = buildObservationUnitsSearchRequest(observationUnitDbId, observationUnitName, germplasmDbId, studyDbId, locationDbId, trialDbId, programDbId, seasonDbId, observationUnitLevelName, observationUnitLevelOrder, observationUnitLevelCode, @@ -148,7 +149,8 @@ public ObservationUnitTable findObservationUnitsTable(String observationUnitDbId String seasonDbId, String observationLevel, String observationUnitLevelName, String observationUnitLevelOrder, String observationUnitLevelCode, String observationUnitLevelRelationshipName, String observationUnitLevelRelationshipOrder, - String observationUnitLevelRelationshipCode, String observationUnitLevelRelationshipDbId) { + String observationUnitLevelRelationshipCode, String observationUnitLevelRelationshipDbId) + throws BrAPIServerException { ObservationUnitSearchRequest ouRequest = buildObservationUnitsSearchRequest(observationUnitDbId, null, germplasmDbId, studyDbId, locationDbId, trialDbId, programDbId, seasonDbId, observationUnitLevelName, @@ -169,7 +171,8 @@ public ObservationUnitTable findObservationUnitsTable(String observationUnitDbId return table; } - public List findObservationUnits(@Valid ObservationUnitSearchRequest request, Metadata metadata) { + public List findObservationUnits(@Valid ObservationUnitSearchRequest request, Metadata metadata) + throws BrAPIServerException { Page page = findObservationUnitEntities(request, metadata); boolean includeObservations = request.isIncludeObservations() != null && request.isIncludeObservations(); @@ -191,7 +194,8 @@ public List findObservationUnits(@Valid ObservationUnitSearchRe } public Page findObservationUnitEntities(@Valid ObservationUnitSearchRequest request, - Metadata metadata) { + Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); @@ -272,7 +276,8 @@ public Page findObservationUnitEntities(@Valid Observatio return page; } - private void fetchTreatments(Page page) { + private void fetchTreatments(Page page) + throws BrAPIServerException { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("treatments", "treatments") @@ -286,7 +291,8 @@ private void fetchTreatments(Page page) { page.forEach(ou -> ou.setTreatments(treatmentsByOu.get(ou.getId()))); } - private void fetchObsUnitLevelRelationships(Page page) { + private void fetchObsUnitLevelRelationships(Page page) + throws BrAPIServerException { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("position", "position") @@ -367,7 +373,8 @@ public ObservationUnit updateObservationUnit(String observationUnitDbId, @Valid } public List findObservationLevels(String studyDbId, String trialDbId, - String programDbId, Metadata metadata) { + String programDbId, Metadata metadata) + throws BrAPIServerException { List allLevels = Arrays.asList(ObservationUnitHierarchyLevelEnum.values()).stream() .map(levelEnum -> { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java index 5f8ff598..8ba0b935 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java @@ -68,7 +68,8 @@ public List findObservationVariables(String observationVari String methodPUI, String scaleDbId, String scaleName, String scalePUI, String traitDbId, String traitName, String traitPUI, String traitClass, String ontologyDbId, String commonCropName, String programDbId, String trialDbId, String studyDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { ObservationVariableSearchRequest request = new ObservationVariableSearchRequest(); @@ -113,7 +114,8 @@ public List findObservationVariables(String observationVari } public List findObservationVariables(ObservationVariableSearchRequest request, - Metadata metadata) { + Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationVariableEntity.class); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java index 796326b3..de8e1a31 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java @@ -39,11 +39,12 @@ public ScaleService(ScaleRepository scaleRepository, OntologyService ontologySer public List findScales(String scaleDbId, String observationVariableDbId, String ontologyDbId, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(ScaleEntity.class); if (observationVariableDbId != null) { - searchQuery = searchQuery.join("variables", "variable").appendSingle(observationVariableDbId, + searchQuery = searchQuery.join("variables", "variabTle").appendSingle(observationVariableDbId, "*variable.id"); } searchQuery = searchQuery.appendSingle(scaleDbId, "id").withExRefs(externalReferenceID, diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java index 3e9411cf..adb0bf7d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java @@ -35,7 +35,8 @@ public TraitService(TraitRepository traitRepository, OntologyService ontologySer public List findTraits(String traitDbId, String observationVariableDbId, String ontologyDbId, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, - String externalReferenceSource, Metadata metadata) { + String externalReferenceSource, Metadata metadata) + throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(TraitEntity.class); if (observationVariableDbId != null) { From 2526b1e1d9d67a5a807c206fba267220d0250264 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Mon, 17 Mar 2025 16:44:53 -0400 Subject: [PATCH 07/13] Add configurable default page size and max allowed page size Additionally make these configurable vars consistent and usable across BrAPIController and PagingUtility, which both utilize them. --- .../controller/core/BrAPIController.java | 33 ++------------- .../service/PagingUtility.java | 40 ++++++++++++++++++- .../resources/application.properties.template | 10 +++++ 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/core/BrAPIController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/core/BrAPIController.java index e7ec4d54..1b4a5ddf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/core/BrAPIController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/core/BrAPIController.java @@ -11,7 +11,7 @@ import io.swagger.model.core.BatchDeletesListResponseResult; import org.brapi.test.BrAPITestServer.auth.AuthDetails; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; -import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; +import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -33,21 +33,6 @@ public class BrAPIController { private static final Logger log = LoggerFactory.getLogger(ServerInfoApiController.class); - - protected Metadata generateMetaDataTemplateForSearch(Integer originalRequestedPage, Integer newRequestedPage, - Integer originalRequestedPageSize, Integer newRequestedPageSize) throws BrAPIServerException { - Integer page = newRequestedPage; - Integer pageSize = newRequestedPageSize; - - if (page == null) { - page = originalRequestedPage; - } - if (pageSize == null) { - pageSize = originalRequestedPageSize; - } - - return generateMetaDataTemplate(page, pageSize); - } protected Metadata generateMetaDataTemplate(SearchRequest request) throws BrAPIServerException { return generateMetaDataTemplate(request.getPage(), request.getPageSize()); @@ -55,7 +40,7 @@ protected Metadata generateMetaDataTemplate(SearchRequest request) throws BrAPIS protected Metadata generateMetaDataTemplate(String pageToken, Integer pageSize) { if (pageSize == null) { - pageSize = 1000; + pageSize = PagingUtility.getDefaultPageSize(); } Metadata metaData = generateEmptyMetadataToken(); @@ -65,14 +50,14 @@ protected Metadata generateMetaDataTemplate(String pageToken, Integer pageSize) } protected Metadata generateMetaDataTemplate(Integer page, Integer pageSize) throws BrAPIServerException { - validatePaging(page, pageSize); + PagingUtility.validatePaging(page, pageSize); // defaults if (page == null) { page = 0; } if (pageSize == null) { - pageSize = 1000; + pageSize = PagingUtility.getDefaultPageSize(); } Metadata metaData = generateEmptyMetadata(); @@ -81,16 +66,6 @@ protected Metadata generateMetaDataTemplate(Integer page, Integer pageSize) thro return metaData; } - private void validatePaging(Integer page, Integer pageSize) throws BrAPIServerException { - boolean pageValid = (page == null) || (page >= 0); - if (!pageValid) - throw new InvalidPagingException("page"); - boolean pageSizeValid = (pageSize == null) || (pageSize >= 1); - if (!pageSizeValid) - throw new InvalidPagingException("pageSize"); - - } - protected Metadata generateEmptyMetadata() { Metadata metaData = new Metadata(); metaData.setDatafiles(new ArrayList<>()); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/PagingUtility.java b/src/main/java/org/brapi/test/BrAPITestServer/service/PagingUtility.java index 57c39c6b..8b2c250c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/PagingUtility.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/PagingUtility.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -10,14 +13,49 @@ import io.swagger.model.IndexPagination; import io.swagger.model.Metadata; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; + +@Component public class PagingUtility { + @Value("${paging.page-size.default:1000}") + private int defaultPageSize; + @Value("${paging.page-size.max-allowed:65000}") + private int maxAllowablePageSize; + + private static int defaultPageSizeStatic; + private static int maxAllowablePageSizeStatic; + + @PostConstruct + private void init() { + // Java made me do this - JL + defaultPageSizeStatic = defaultPageSize; + maxAllowablePageSizeStatic = maxAllowablePageSize; + } + public static void calculateMetaData(Metadata metaData) { int totalCount = metaData.getPagination().getTotalCount(); int pageSize = metaData.getPagination().getPageSize(); metaData.getPagination().setTotalPages((totalCount / pageSize) + Integer.signum( totalCount % pageSize)); } + public static void validatePaging(Integer page, Integer pageSize) throws BrAPIServerException { + boolean pageValid = (page == null) || (page >= 0); + if (!pageValid) + throw new InvalidPagingException("page"); + boolean pageSizeValid = (pageSize == null) || (pageSize >= 1); + if (!pageSizeValid) + throw new InvalidPagingException("pageSize"); + if (pageSize != null && pageSize > maxAllowablePageSizeStatic) { + throw new InvalidPagingException("pageSize [Over maximum allowable page size of [" + maxAllowablePageSizeStatic + "]] "); + } + } + + public static int getDefaultPageSize() { + return defaultPageSizeStatic; + } + public static Pageable getPageRequest(Metadata metaData) { if (metaData == null) { metaData = new Metadata(); @@ -34,7 +72,7 @@ public static Pageable getPageRequest(Metadata metaData, Sort sort) { page = metaData.getPagination().getCurrentPage(); } - int pageSize = 1000; + int pageSize = defaultPageSizeStatic; if (metaData.getPagination().getPageSize() != null && metaData.getPagination().getPageSize() > 0) { pageSize = metaData.getPagination().getPageSize(); } diff --git a/src/main/resources/application.properties.template b/src/main/resources/application.properties.template index 6263bd9c..8baf2928 100644 --- a/src/main/resources/application.properties.template +++ b/src/main/resources/application.properties.template @@ -19,3 +19,13 @@ spring.mvc.dispatch-options-request=true security.oidc_discovery_url=https://example.com/auth/.well-known/openid-configuration security.enabled=true +security.issuer_url=http://example.com/issuerurl + +# This should either be set in accordance with a maximum number of SQL parameters (on JOIN FETCHES of collections, +# if there is more than one collection the IDs of each entity need to be passed through as parameters, and there is a SQL +# maximum of 65535. See GermplasmService.findGermplasmEntities()), +# whatever returns in a reasonable amount of time, +# or if you want to limit for the sake of server efficiency. +paging.page-size.max-allowed=65000 + +paging.page-size.default=1000 From 0f56f7393e8dca79d4a85b792964c720a2e08085 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 19 Mar 2025 12:15:09 -0400 Subject: [PATCH 08/13] Fix bug where pedigree attribute was misspelled --- .../test/BrAPITestServer/service/germ/GermplasmService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index a562bf93..6e4f0e29 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -311,7 +311,7 @@ private void fetchPedigreeEdges(List ids, Page germEnti searchQuery.leftJoinFetch("pedigree", "pedigree") .leftJoinFetch("*pedigree.crossingProject", "crossingProject") .leftJoinFetch("*pedigree.edges", "pedigreeEdges") - .leftJoinFetch("*pedigreeEdges.conncetedNode", "connectedNode") + .leftJoinFetch("*pedigreeEdges.connectedNode", "connectedNode") .appendIds(ids); List pedigree = germplasmRepository.findAllBySearch(searchQuery); @@ -432,7 +432,7 @@ private void fetchRemainingGermCollectionsUsingQuery(SearchQueryBuilder pedigree = germplasmRepository.findAllBySearch(searchQuery); From d148e5d95e9ce36be30e6d71dea19efc16be7018 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 21 Mar 2025 16:09:30 -0400 Subject: [PATCH 09/13] Remove erroneous imports from SearchRequest --- src/main/java/io/swagger/model/SearchRequest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/io/swagger/model/SearchRequest.java b/src/main/java/io/swagger/model/SearchRequest.java index b1329a28..8ad217c4 100644 --- a/src/main/java/io/swagger/model/SearchRequest.java +++ b/src/main/java/io/swagger/model/SearchRequest.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.model.core.SortBy; -import io.swagger.model.core.SortOrder; import java.util.ArrayList; import java.util.List; From 55b184109b0516f84ecadb294bb62f7885b964e9 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 21 Mar 2025 16:19:40 -0400 Subject: [PATCH 10/13] Revert erroneous JsonbConverter change --- .../brapi/test/BrAPITestServer/converter/JsonbConverter.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java b/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java index 0b437bcf..795a4b2a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/converter/JsonbConverter.java @@ -17,10 +17,7 @@ public class JsonbConverter implements AttributeConverter { @Override public String convertToDatabaseColumn(Object jsonb) { try { - if (jsonb != null) { - return mapper.writeValueAsString(jsonb); - } - return null; + return mapper.writeValueAsString(jsonb); } catch (JsonProcessingException e) { throw new RuntimeException(e); } From 407242c5e84bca9ebad513391d2e6c1eb53f0136 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Mon, 24 Mar 2025 11:05:09 -0400 Subject: [PATCH 11/13] Swap ref to externalReferenceID w externalReferenceId --- .../controller/germ/CrossesApiController.java | 2 +- .../germ/PlannedCrossesApiController.java | 2 +- .../controller/germ/SeedLotsApiController.java | 2 +- .../BrAPITestServer/service/germ/CrossService.java | 14 +++++++------- .../service/germ/SeedLotService.java | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java index 6761aab6..613dcc26 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java @@ -60,7 +60,7 @@ public ResponseEntity crossesGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = crossService.findCrosses(crossingProjectDbId, crossDbId, - externalReferenceID, externalReferenceSource, + externalReferenceId, externalReferenceSource, metadata); return responseOK(new CrossesListResponse(), new CrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java index cad3aad7..ff22a0fb 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java @@ -62,7 +62,7 @@ public ResponseEntity plannedCrossesGet( Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = crossService.findPlannedCrosses(crossingProjectDbId, plannedCrossDbId, - externalReferenceID, externalReferenceSource, metadata); + externalReferenceId, externalReferenceSource, metadata); return responseOK(new PlannedCrossesListResponse(), new PlannedCrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java index 9fdad3db..42c33c35 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java @@ -66,7 +66,7 @@ public ResponseEntity seedlotsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = seedLotService.findSeedLots(seedLotDbId, germplasmDbId, germplasmName, crossDbId, - crossName, commonCropName, programDbId, externalReferenceID, + crossName, commonCropName, programDbId, externalReferenceId, externalReferenceSource, metadata); return responseOK(new SeedLotListResponse(), new SeedLotListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java index 2ef3a7b8..02fc5632 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java @@ -48,27 +48,27 @@ public CrossService(CrossRepository crossRepository, CrossingProjectService cros } public List findCrosses(String crossingProjectDbId, String crossDbId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) + String externalReferenceId, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { List crosses = findCrossEntities(crossingProjectDbId, crossDbId, - externalReferenceID, externalReferenceSource, false, + externalReferenceId, externalReferenceSource, false, metadata).map(this::convertToCross).getContent(); return crosses; } public List findPlannedCrosses(String crossingProjectDbId, String crossDbId, - String externalReferenceID, String externalReferenceSource, + String externalReferenceId, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { List crosses = findCrossEntities(crossingProjectDbId, crossDbId, - externalReferenceID, externalReferenceSource, true, + externalReferenceId, externalReferenceSource, true, metadata).map(this::convertToPlanned).getContent(); return crosses; } public Page findCrossEntities(String crossingProjectDbId, String crossDbId, - String externalReferenceID, String externalReferenceSource, + String externalReferenceId, String externalReferenceSource, Boolean plannedCross, Metadata metadata) throws BrAPIServerException { @@ -78,8 +78,8 @@ public Page findCrossEntities(String crossingProjectDbId, String cr searchQuery = searchQuery.appendSingle(crossDbId, "id"); if (crossingProjectDbId != null) searchQuery = searchQuery.appendSingle(crossingProjectDbId, "crossingProject.id"); - if (externalReferenceID != null && externalReferenceSource != null) - searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), + if (externalReferenceId != null && externalReferenceSource != null) + searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceId), Arrays.asList(externalReferenceSource)); if (plannedCross != null) searchQuery = searchQuery.appendSingle(plannedCross, "planned"); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java index 81b683f9..974e81a9 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java @@ -140,7 +140,7 @@ public List findSeedLotTransactions(String seedLotDbId, Stri public List findSeedLotTransactions(String transactionDbId, String seedLotDbId, String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, - String programDbId, String externalReferenceID, String externalReferenceSource, + String programDbId, String externalReferenceId, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); @@ -163,8 +163,8 @@ public List findSeedLotTransactions(String transactionDbId, if (programDbId != null) searchQuery = searchQuery.appendSingle(programDbId, "toSeedLot.program.id"); - if (externalReferenceID != null && externalReferenceSource != null) - searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), + if (externalReferenceId != null && externalReferenceSource != null) + searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceId), Arrays.asList(externalReferenceSource)); Page page = seedLotTransactionRepository.findAllBySearchAndPaginate(searchQuery, pageReq); From b59ec3e7f51fc9490e646263e941da6546b96cbf Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 28 Mar 2025 12:23:35 -0400 Subject: [PATCH 12/13] Revert changes around externalReferenceID and unused params These were simply IntelliJ suggestions I added in bc I was editing the surrounding code. I did not intend or want to change the way the spec or APIs work surrounding, at least not in this body of commits. To keep this work separate from the germ optimization work, I have reverted these changes. Also fixed a typo Matthew caught in ScaleService --- .../controller/germ/CrossesApiController.java | 4 +-- .../germ/CrossingProjectsApiController.java | 4 +-- .../germ/PlannedCrossesApiController.java | 6 ++-- .../germ/SeedLotsApiController.java | 4 +-- .../service/germ/CrossService.java | 32 +++++++++---------- .../service/germ/CrossingProjectService.java | 4 +-- .../service/germ/SeedLotService.java | 16 +++++----- .../service/pheno/ScaleService.java | 2 +- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java index 613dcc26..0b967588 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossesApiController.java @@ -59,8 +59,8 @@ public ResponseEntity crossesGet( validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); - List data = crossService.findCrosses(crossingProjectDbId, crossDbId, - externalReferenceId, externalReferenceSource, + List data = crossService.findCrosses(crossingProjectDbId, crossingProjectName, crossDbId, crossName, + commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new CrossesListResponse(), new CrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java index cddbc80f..dc26d757 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/CrossingProjectsApiController.java @@ -60,8 +60,8 @@ public ResponseEntity crossingProjectsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = crossingProjectService.findCrossingProjects(crossingProjectDbId, - crossingProjectName, includePotentialParents, commonCropName, programDbId, - externalReferenceID, externalReferenceSource, metadata); + crossingProjectName, includePotentialParents, commonCropName, programDbId, externalReferenceId, + externalReferenceID, externalReferenceSource, metadata); return responseOK(new CrossingProjectsListResponse(), new CrossingProjectsListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java index ff22a0fb..83bf62c1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/PlannedCrossesApiController.java @@ -60,9 +60,9 @@ public ResponseEntity plannedCrossesGet( validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); - List data = crossService.findPlannedCrosses(crossingProjectDbId, - plannedCrossDbId, - externalReferenceId, externalReferenceSource, metadata); + List data = crossService.findPlannedCrosses(crossingProjectDbId, crossingProjectName, + plannedCrossDbId, plannedCrossName, status, commonCropName, programDbId, externalReferenceId, + externalReferenceID, externalReferenceSource, metadata); return responseOK(new PlannedCrossesListResponse(), new PlannedCrossesListResponseResult(), data, metadata); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java index 42c33c35..9147ca44 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/germ/SeedLotsApiController.java @@ -66,7 +66,7 @@ public ResponseEntity seedlotsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = seedLotService.findSeedLots(seedLotDbId, germplasmDbId, germplasmName, crossDbId, - crossName, commonCropName, programDbId, externalReferenceId, + crossName, commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new SeedLotListResponse(), new SeedLotListResponseResult(), data, metadata); } @@ -156,7 +156,7 @@ public ResponseEntity seedlotsTransactionsGet( validateAcceptHeader(request); Metadata metadata = generateMetaDataTemplate(page, pageSize); List data = seedLotService.findSeedLotTransactions(transactionDbId, seedLotDbId, - germplasmDbId, germplasmName, crossDbId, crossName, commonCropName, programDbId, + germplasmDbId, germplasmName, crossDbId, crossName, commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, metadata); return responseOK(new SeedLotTransactionListResponse(), new SeedLotTransactionListResponseResult(), data, metadata); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java index 02fc5632..e35d0911 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java @@ -47,29 +47,29 @@ public CrossService(CrossRepository crossRepository, CrossingProjectService cros this.crossParentService = crossParentService; } - public List findCrosses(String crossingProjectDbId, String crossDbId, - String externalReferenceId, String externalReferenceSource, Metadata metadata) + public List findCrosses(String crossingProjectDbId, String crossingProjectName, String crossDbId, + String crossName, String commonCropName, String programDbId, String externalReferenceId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { - List crosses = findCrossEntities(crossingProjectDbId, crossDbId, - externalReferenceId, externalReferenceSource, false, + List crosses = findCrossEntities(crossingProjectDbId, crossingProjectName, crossDbId, crossName, null, + commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, false, metadata).map(this::convertToCross).getContent(); return crosses; } - public List findPlannedCrosses(String crossingProjectDbId, - String crossDbId, - String externalReferenceId, String externalReferenceSource, - Metadata metadata) + public List findPlannedCrosses(String crossingProjectDbId, String crossingProjectName, + String crossDbId, String crossName, String status, String commonCropName, String programDbId, + String externalReferenceId, String externalReferenceID, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { - List crosses = findCrossEntities(crossingProjectDbId, crossDbId, - externalReferenceId, externalReferenceSource, true, + List crosses = findCrossEntities(crossingProjectDbId, crossingProjectName, crossDbId, crossName, status, + commonCropName, programDbId, externalReferenceId, externalReferenceID, externalReferenceSource, true, metadata).map(this::convertToPlanned).getContent(); return crosses; } - public Page findCrossEntities(String crossingProjectDbId, String crossDbId, - String externalReferenceId, String externalReferenceSource, - Boolean plannedCross, Metadata metadata) + public Page findCrossEntities(String crossingProjectDbId, String crossingProjectName, String crossDbId, + String crossName, String status, String commonCropName, String programDbId, String externalReferenceId, + String externalReferenceID, String externalReferenceSource, Boolean plannedCross, Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); @@ -78,8 +78,8 @@ public Page findCrossEntities(String crossingProjectDbId, String cr searchQuery = searchQuery.appendSingle(crossDbId, "id"); if (crossingProjectDbId != null) searchQuery = searchQuery.appendSingle(crossingProjectDbId, "crossingProject.id"); - if (externalReferenceId != null && externalReferenceSource != null) - searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceId), + if (externalReferenceID != null && externalReferenceSource != null) + searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), Arrays.asList(externalReferenceSource)); if (plannedCross != null) searchQuery = searchQuery.appendSingle(plannedCross, "planned"); @@ -227,7 +227,7 @@ private void updateEntity(CrossEntity entity, CrossNewRequest cross) throws BrAP if (cross.getCrossName() != null) entity.setName(cross.getCrossName()); if (cross.getPlannedCrossDbId() != null) { - List plannedEntity = findCrossEntities(null, cross.getPlannedCrossDbId(), null, null, true, null).getContent(); + List plannedEntity = findCrossEntities(null, null, cross.getPlannedCrossDbId(), null, null, null, null, null, null, null, true, null).getContent(); entity.setPlannedCross(plannedEntity.get(0)); } if (cross.getPollinationEvents() != null) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java index 373dc65f..d8edb9ec 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java @@ -40,8 +40,8 @@ public CrossingProjectService(CrossingProjectRepository crossingProjectRepositor } public List findCrossingProjects(String crossingProjectDbId, String crossingProjectName, - Boolean includePotentialParents, String commonCropName, String programDbId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) + Boolean includePotentialParents, String commonCropName, String programDbId, String externalReferenceId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java index 974e81a9..630aa755 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java @@ -59,8 +59,8 @@ public SeedLotService(SeedLotRepository seedLotRepository, } public List findSeedLots(String seedLotDbId, String germplasmDbId, String germplasmName, String crossDbId, - String crossName, String commonCropName, String programDbId, - String externalReferenceID, String externalReferenceSource, Metadata metadata) + String crossName, String commonCropName, String programDbId, String externalReferenceId, + String externalReferenceID, String externalReferenceSource, Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(SeedLotEntity.class); @@ -132,16 +132,16 @@ public List findSeedLotTransactions(String seedLotDbId, Stri String transactionDirection, Metadata metadata) throws BrAPIServerException { SeedLot seedLot = getSeedLot(seedLotDbId); if (seedLot != null) { - return findSeedLotTransactions(transactionDbId, seedLotDbId, null, null, null, null, null, null, null, + return findSeedLotTransactions(transactionDbId, seedLotDbId, null, null, null, null, null, null, null, null, null, metadata); } return null; } public List findSeedLotTransactions(String transactionDbId, String seedLotDbId, - String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, - String programDbId, String externalReferenceId, String externalReferenceSource, - Metadata metadata) + String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, + String programDbId, String externalReferenceId, String externalReferenceID, String externalReferenceSource, + Metadata metadata) throws BrAPIServerException { Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder( @@ -163,8 +163,8 @@ public List findSeedLotTransactions(String transactionDbId, if (programDbId != null) searchQuery = searchQuery.appendSingle(programDbId, "toSeedLot.program.id"); - if (externalReferenceId != null && externalReferenceSource != null) - searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceId), + if (externalReferenceID != null && externalReferenceSource != null) + searchQuery = searchQuery.withExRefs(Arrays.asList(externalReferenceID), Arrays.asList(externalReferenceSource)); Page page = seedLotTransactionRepository.findAllBySearchAndPaginate(searchQuery, pageReq); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java index de8e1a31..a4700d81 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java @@ -44,7 +44,7 @@ public List findScales(String scaleDbId, String observationVariableDbId, Pageable pageReq = PagingUtility.getPageRequest(metadata); SearchQueryBuilder searchQuery = new SearchQueryBuilder(ScaleEntity.class); if (observationVariableDbId != null) { - searchQuery = searchQuery.join("variables", "variabTle").appendSingle(observationVariableDbId, + searchQuery = searchQuery.join("variables", "variable").appendSingle(observationVariableDbId, "*variable.id"); } searchQuery = searchQuery.appendSingle(scaleDbId, "id").withExRefs(externalReferenceID, From 2de845c824e267351d110ed69b917fa5675ab5a4 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 28 Mar 2025 13:02:07 -0400 Subject: [PATCH 13/13] Update comment, move default sort String to constructor --- .../test/BrAPITestServer/service/SearchQueryBuilder.java | 6 ++++-- .../test/BrAPITestServer/service/germ/GermplasmService.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java index 57d19782..45226bdb 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java @@ -14,6 +14,7 @@ public class SearchQueryBuilder { private String selectClause; private String selectOnlyIds; private String whereClause; + private String defaultSort; private String sortClause; private Map params; private Class clazz; @@ -22,6 +23,7 @@ public SearchQueryBuilder(Class clazz) { this.selectClause = "SELECT distinct entity FROM " + clazz.getSimpleName() + " entity "; this.selectOnlyIds = "SELECT entity.id FROM " + clazz.getSimpleName() + " entity "; this.whereClause = "WHERE 1=1 "; + this.defaultSort = " ORDER BY entity.id ASC "; this.sortClause = ""; this.params = new HashMap<>(); this.clazz = clazz; @@ -30,7 +32,7 @@ public SearchQueryBuilder(Class clazz) { public String getQuery() { if (sortClause.isEmpty()) { // By default, sort on entity id to have query result remain idempotent - sortClause = " ORDER BY entity.id ASC "; + sortClause = defaultSort; } return selectClause + whereClause + sortClause; @@ -39,7 +41,7 @@ public String getQuery() { public String getIdQuery() { if (sortClause.isEmpty()) { // By default, sort on entity id to have query result remain idempotent - sortClause = " ORDER BY entity.id ASC "; + sortClause = defaultSort; } return selectOnlyIds + whereClause + sortClause; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index 6e4f0e29..7513d84c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -120,7 +120,8 @@ public Page findGermplasmEntities(@Valid GermplasmSearchRequest SearchQueryBuilder searchQuery = buildGermplasmSearchQuery(request); - // First run the query without the fetching all the entities, grabbing the IDs only and paginating and sorting them. + // Since the built searchQuery contains a lazily loaded collection retrieved with a LEFT JOIN FETCH, + // use findAllBySearchPaginatingWithFetches() Page germs = germplasmRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); // Hopefully this retains insertion order in the page? @@ -336,7 +337,6 @@ private void fetchRemainingGermCollectionsUsingQuery(SearchQueryBuilder xrefs = germplasmRepository.findAllBySearch(searchQuery); Map> xrefByEntity = new HashMap<>();