From 939a2df82351638a94433a43ee6bdd35f1293a2e Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 18 Apr 2025 13:56:08 -0400 Subject: [PATCH 01/34] Utilize pagination fixes for observations and OUnits --- .../repository/BrAPIRepository.java | 3 +- .../repository/BrAPIRepositoryImpl.java | 11 ++++--- .../service/pheno/ObservationService.java | 17 +++++----- .../service/pheno/ObservationUnitService.java | 32 +++++++++---------- 4 files changed, 33 insertions(+), 30 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 3a796a07..8092235d 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.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; @@ -30,7 +31,7 @@ public interface BrAPIRepository void refresh(S entity); - public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException; + public void fetchXrefs(List page, Page pagedEntities, Class searchClass) throws InvalidPagingException; List findByIdIn(List ids); } \ 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 70ff40b1..b14978ab 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java @@ -14,6 +14,7 @@ import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.model.entity.ExternalReferenceEntity; +import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.SecurityUtils; @@ -141,17 +142,17 @@ public void refresh(S entity) { this.entityManager.refresh(entity); } - public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException { - SearchQueryBuilder searchQuery = new SearchQueryBuilder(searchClass); + public void fetchXrefs(List ids, Page pagedEntities, Class searchClass) { + SearchQueryBuilder searchQuery = new SearchQueryBuilder<>(searchClass); searchQuery.leftJoinFetch("externalReferences", "externalReferences") - .appendList(page.stream().map(p -> p.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page xrefs = findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List xrefs = findAllBySearch(searchQuery); Map> xrefByEntity = new HashMap<>(); xrefs.forEach(entity -> xrefByEntity.put(entity.getId(), entity.getExternalReferences())); - page.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); + pagedEntities.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); } private void applyUserId(SearchQueryBuilder searchQuery) { 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 62033fe8..22105845 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 @@ -6,8 +6,10 @@ import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; +import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; @@ -194,10 +196,7 @@ public Page findObservationEntities(@Valid ObservationSearchR .leftJoinFetch("*observationUnit.germplasm", "ouGermplasm") .leftJoinFetch("*ouGermplasm.pedigree", "pedigree") .leftJoinFetch("*observationUnit.study", "ouStudy") - .leftJoinFetch("study", "study") - .leftJoinFetch("*study.experimentalDesign", "experimentalDesign") - .leftJoinFetch("*study.growthFacility", "growthFacility") - .leftJoinFetch("*study.lastUpdate", "lastUpdate"); + .leftJoinFetch("study", "study"); if (request.getObservationLevels() != null) { searchQuery = searchQuery .appendEnumList( @@ -246,13 +245,15 @@ public Page findObservationEntities(@Valid ObservationSearchR .appendList(request.getTrialDbIds(), "trial.id").appendList(request.getTrialNames(), "trial.trialName"); log.debug("starting search"); - Page page = observationRepository.findAllBySearchAndPaginate(searchQuery, pageReq); + Page observations = observationRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); + + List ids = observations.map(BrAPIBaseEntity::getId).toList(); log.debug("search complete"); - if(!page.isEmpty()) { - observationRepository.fetchXrefs(page, ObservationEntity.class); + if(!observations.isEmpty()) { + observationRepository.fetchXrefs(ids, observations, ObservationEntity.class); } - return page; + return observations; } public Observation getObservation(String observationDbId) throws BrAPIServerException { 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 d6356d57..75e3faf7 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 @@ -217,7 +217,7 @@ public Page findObservationUnitEntities(@Valid Observatio .leftJoinFetch("program", "program"); if (request.getObservationVariableDbIds() != null || request.getObservationVariableNames() != null) { - searchQuery = searchQuery.join("observations", "observation") + searchQuery = searchQuery.join("observationsUnits", "observation") .appendList(request.getObservationVariableDbIds(), "*observation.variable.id") .appendList(request.getObservationVariableNames(), "*observation.variable.name"); } @@ -265,41 +265,41 @@ public Page findObservationUnitEntities(@Valid Observatio .appendList(request.getTrialNames(), "trial.trailName"); log.debug("Starting search"); - Page page = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, pageReq); + Page observationsUnits = observationUnitRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); + + List ids = observationsUnits.map(BrAPIBaseEntity::getId).toList(); log.debug("Search complete"); - if(!page.isEmpty()) { - observationUnitRepository.fetchXrefs(page, ObservationUnitEntity.class); - fetchTreatments(page); - fetchObsUnitLevelRelationships(page); + if(!observationsUnits.isEmpty()) { + observationUnitRepository.fetchXrefs(ids, observationsUnits, ObservationUnitEntity.class); + fetchTreatments(ids, observationsUnits); + fetchObsUnitLevelRelationships(ids, observationsUnits); } - return page; + return observationsUnits; } - private void fetchTreatments(Page page) - throws BrAPIServerException { + private void fetchTreatments(List ids, Page pagedOUs) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("treatments", "treatments") - .appendList(page.stream().map(oue -> oue.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page treatments = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List treatments = observationUnitRepository.findAllBySearch(searchQuery); Map> treatmentsByOu = new HashMap<>(); treatments.forEach(ou -> treatmentsByOu.put(ou.getId().toString(), ou.getTreatments())); - page.forEach(ou -> ou.setTreatments(treatmentsByOu.get(ou.getId().toString()))); + pagedOUs.forEach(ou -> ou.setTreatments(treatmentsByOu.get(ou.getId().toString()))); } - private void fetchObsUnitLevelRelationships(Page page) - throws BrAPIServerException { + private void fetchObsUnitLevelRelationships(List ids, Page page) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("position", "position") .leftJoinFetch("*position.observationLevelRelationships", "observationLevelRelationships") - .appendList(page.stream().map(oue -> oue.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page positions = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List positions = observationUnitRepository.findAllBySearch(searchQuery); Map positionByOu = new HashMap<>(); positions.forEach(ou -> positionByOu.put(ou.getId().toString(), ou.getPosition())); From a1f895cfd05fe314ab80aae3aa776e399f1c04af Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 23 Apr 2025 12:27:35 -0400 Subject: [PATCH 02/34] Use @SecondaryTables on studies to fix hibernate n+1 query issues --- .../entity/core/ExperimentalDesignEntity.java | 19 ++++------------- .../entity/core/GrowthFacilityEntity.java | 19 ++++------------- .../model/entity/core/StudyEntity.java | 11 +++++++--- .../entity/core/StudyLastUpdateEntity.java | 19 ++++------------- .../service/core/StudyService.java | 15 ++++++------- .../U001.1__add_ids_to_study_join_tables.sql | 21 +++++++++++++++++++ .../migration/V001.1__drop_study_join_ids.sql | 11 ++++++++++ 7 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql create mode 100644 src/main/resources/db/migration/V001.1__drop_study_join_ids.sql diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java index c9282ee5..ded46dde 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java @@ -3,23 +3,12 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; -@Entity -@Table(name = "study_experimental_design") -public class ExperimentalDesignEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class ExperimentalDesignEntity { + @Column(name = "pui", table = "study_experimental_design") private String PUI; - @Column + @Column(name = "description", table = "study_experimental_design") private String description; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public String getPUI() { return PUI; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java index 4ed2900f..35cf3052 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java @@ -3,23 +3,12 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; -@Entity -@Table(name = "study_growth_facility") -public class GrowthFacilityEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class GrowthFacilityEntity { + @Column(name = "pui", table = "study_growth_facility") private String PUI; - @Column + @Column(name = "description", table = "study_growth_facility") private String description; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public String getPUI() { return PUI; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java index 107978b6..560d7ac1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java @@ -12,6 +12,11 @@ @Entity @Table(name = "study") +@SecondaryTables({ + @SecondaryTable(name = "study_experimental_design", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")), + @SecondaryTable(name = "study_growth_facility", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")), + @SecondaryTable(name = "study_last_update", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")) +}) @Where(clause = "soft_deleted = false") public class StudyEntity extends BrAPIPrimaryEntity { @@ -32,11 +37,11 @@ public class StudyEntity extends BrAPIPrimaryEntity { private Date endDate; @OneToMany(mappedBy = "study") private List environmentParameters; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private ExperimentalDesignEntity experimentalDesign; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private GrowthFacilityEntity growthFacility; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private StudyLastUpdateEntity lastUpdate; @Column private String license; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java index e7b5baa4..9dd109b6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java @@ -5,23 +5,12 @@ import java.util.Date; -@Entity -@Table(name = "study_last_update") -public class StudyLastUpdateEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class StudyLastUpdateEntity { + @Column(name = "timestamp", table = "study_last_update") private Date timestamp; - @Column + @Column(name = "version", table = "study_last_update") private String version; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public Date getTimestamp() { return timestamp; 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 9ad8f0b9..d4fda0e0 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 @@ -245,11 +245,11 @@ private void updateEntity(StudyEntity entity, StudyNewRequest body) throws BrAPI body.getEnvironmentParameters().stream().map(this::convertToEntity).collect(Collectors.toList())); } if (body.getExperimentalDesign() != null) - entity.setExperimentalDesign(convertToEntity(body.getExperimentalDesign(), entity)); + entity.setExperimentalDesign(convertToEntity(body.getExperimentalDesign())); if (body.getGrowthFacility() != null) - entity.setGrowthFacility(convertToEntity(body.getGrowthFacility(), entity)); + entity.setGrowthFacility(convertToEntity(body.getGrowthFacility())); if (body.getLastUpdate() != null) - entity.setLastUpdate(convertToEntity(body.getLastUpdate(), entity)); + entity.setLastUpdate(convertToEntity(body.getLastUpdate())); if (body.getLicense() != null) entity.setLicense(body.getLicense()); if (body.getLocationDbId() != null) { @@ -412,13 +412,12 @@ private StudyLastUpdate convertFromEntity(StudyLastUpdateEntity entity) { return update; } - private StudyLastUpdateEntity convertToEntity(StudyLastUpdate update, StudyEntity study) { + private StudyLastUpdateEntity convertToEntity(StudyLastUpdate update) { StudyLastUpdateEntity entity = null; if (update != null) { entity = new StudyLastUpdateEntity(); entity.setTimestamp(DateUtility.toDate(update.getTimestamp())); entity.setVersion(update.getVersion()); - entity.setStudy(study); } return entity; } @@ -433,13 +432,12 @@ private StudyGrowthFacility convertFromEntity(GrowthFacilityEntity entity) { return gf; } - private GrowthFacilityEntity convertToEntity(StudyGrowthFacility facility, StudyEntity study) { + private GrowthFacilityEntity convertToEntity(StudyGrowthFacility facility) { GrowthFacilityEntity entity = null; if (facility != null) { entity = new GrowthFacilityEntity(); entity.setDescription(facility.getDescription()); entity.setPUI(facility.getPUI()); - entity.setStudy(study); } return entity; } @@ -454,13 +452,12 @@ private StudyExperimentalDesign convertFromEntity(ExperimentalDesignEntity entit return ed; } - private ExperimentalDesignEntity convertToEntity(StudyExperimentalDesign design, StudyEntity study) { + private ExperimentalDesignEntity convertToEntity(StudyExperimentalDesign design) { ExperimentalDesignEntity entity = null; if (design != null) { entity = new ExperimentalDesignEntity(); entity.setDescription(design.getDescription()); entity.setPUI(design.getPUI()); - entity.setStudy(study); } return entity; } diff --git a/src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql b/src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql new file mode 100644 index 00000000..c2470af6 --- /dev/null +++ b/src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql @@ -0,0 +1,21 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +ALTER TABLE study_growth_facility DROP CONSTRAINT study_growth_facility_pkey; +ALTER TABLE study_growth_facility ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_growth_facility ADD PRIMARY KEY (id); +ALTER TABLE study_growth_facility ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_growth_facility ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_growth_facility ALTER COLUMN id DROP DEFAULT; + +ALTER TABLE study_experimental_design DROP CONSTRAINT study_experimental_design_pkey; +ALTER TABLE study_experimental_design ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_experimental_design ADD PRIMARY KEY (id); +ALTER TABLE study_experimental_design ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_experimental_design ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_experimental_design ALTER COLUMN id DROP DEFAULT; + +ALTER TABLE study_last_update DROP CONSTRAINT study_last_update_pkey; +ALTER TABLE study_last_update ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_last_update ADD PRIMARY KEY (id); +ALTER TABLE study_last_update ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_last_update ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_last_update ALTER COLUMN id DROP DEFAULT; \ No newline at end of file diff --git a/src/main/resources/db/migration/V001.1__drop_study_join_ids.sql b/src/main/resources/db/migration/V001.1__drop_study_join_ids.sql new file mode 100644 index 00000000..f8cdea93 --- /dev/null +++ b/src/main/resources/db/migration/V001.1__drop_study_join_ids.sql @@ -0,0 +1,11 @@ +alter table study_growth_facility drop constraint study_growth_facility_pkey; +alter table study_growth_facility drop column id; +alter table study_growth_facility add primary key (study_id); + +alter table study_experimental_design drop constraint study_experimental_design_pkey; +alter table study_experimental_design drop column id; +alter table study_experimental_design add primary key (study_id); + +alter table study_last_update drop constraint study_last_update_pkey; +alter table study_last_update drop column id; +alter table study_last_update add primary key (study_id); \ No newline at end of file From 7dc567bbb366d9d85bbf093d40fbd8919ce5152e Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 23 Apr 2025 15:50:09 -0400 Subject: [PATCH 03/34] Create entities in batch for OU post call --- .../service/core/ProgramService.java | 10 ++ .../service/core/StudyService.java | 10 ++ .../service/core/TrialService.java | 10 ++ .../service/germ/CrossService.java | 10 ++ .../service/germ/SeedLotService.java | 10 ++ .../service/pheno/ObservationUnitService.java | 120 ++++++++++++++++-- 6 files changed, 162 insertions(+), 8 deletions(-) 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 a2fe65b2..cbc516c3 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 @@ -76,6 +76,16 @@ public List findPrograms(ProgramSearchRequest request, Metadata metadat return programs; } + public List findByIds(List programDbIds) { + var result = new ArrayList(); + + if (programDbIds.isEmpty()) { + return result; + } + + return programRepository.findByIdIn(programDbIds.stream().map(UUID::fromString).toList()); + } + public Program getProgram(String programDbId) throws BrAPIServerException { return convertFromEntity(getProgramEntity(programDbId, HttpStatus.NOT_FOUND)); } 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 d4fda0e0..70189455 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 @@ -113,6 +113,16 @@ public List findStudies(String commonCropName, String studyType, String p return findStudies(request, metadata); } + public List findByIds(List studyDbIds) { + var result = new ArrayList(); + + if (studyDbIds.isEmpty()) { + return result; + } + + return studyRepository.findByIdIn(studyDbIds.stream().map(UUID::fromString).toList()); + } + public List findStudies(StudySearchRequest request, Metadata metaData) throws BrAPIServerException { 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 8657ad11..a3a83018 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 @@ -135,6 +135,16 @@ public List findTrials(@Valid TrialSearchRequest request, Metadata metada return trials; } + public List findByIds(List trialDbIds) { + var result = new ArrayList(); + + if (trialDbIds.isEmpty()) { + return result; + } + + return trialRepository.findByIdIn(trialDbIds.stream().map(UUID::fromString).toList()); + } + public Trial getTrial(String trialDbId) throws BrAPIServerException { return convertFromEntity(getTrialEntity(trialDbId, HttpStatus.NOT_FOUND)); } 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 6d3e4849..6aa405cd 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 @@ -63,6 +63,16 @@ public List findPlannedCrosses(String crossingProjectDbId, String return crosses; } + public List findByIds(List crossDbIds) { + var result = new ArrayList(); + + if (crossDbIds.isEmpty()) { + return result; + } + + return crossRepository.findByIdIn(crossDbIds.stream().map(UUID::fromString).toList()); + } + 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) 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 886ece3b..433b2e0a 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 @@ -143,6 +143,16 @@ public List findSeedLotTransactions(String seedLotDbId, Stri return null; } + public List findByIds(List seedLotsIds) { + var result = new ArrayList(); + + if (seedLotsIds.isEmpty()) { + return result; + } + + return seedLotRepository.findByIdIn(seedLotsIds.stream().map(UUID::fromString).toList()); + } + 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, 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 75e3faf7..07b30fb8 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 @@ -29,7 +29,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; @@ -338,14 +337,9 @@ public ObservationUnitEntity getObservationUnitEntity(String observationUnitDbId public List saveObservationUnits(@Valid List requests) throws BrAPIServerException { - List toSave = new ArrayList<>(); - for (ObservationUnitNewRequest request : requests) { - ObservationUnitEntity entity = new ObservationUnitEntity(); - updateEntity(entity, request); // TODO: does updateEntity need to hit the database? - toSave.add(entity); - } + var toSave = createEntitiesInBatch(requests); - return observationUnitRepository.saveAllAndFlush(toSave) + return observationUnitRepository.saveAll(toSave) .stream() .map(this::convertFromEntity) .collect(Collectors.toList()); @@ -628,6 +622,116 @@ private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitP } + private List createEntitiesInBatch(List obsUnits) + throws BrAPIServerException { + // Gather all IDs we want to look up in a bulk lookup. + var germplasmIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getGermplasmDbId) + .filter(Objects::nonNull) + .toList(); + + var crossIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getCrossDbId) + .filter(Objects::nonNull) + .toList(); + + var seedLotIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getSeedLotDbId) + .filter(Objects::nonNull) + .toList(); + + var studyIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .toList(); + + var trialIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getTrialDbId) + .filter(Objects::nonNull) + .toList(); + + var programIds = obsUnits.stream() + .map(ObservationUnitNewRequest::getProgramDbId) + .filter(Objects::nonNull) + .toList(); + + // Now lookup all the IDs in bulk, creating a Map of the ID to the entity so the entities are easily + // retrievable by IDs in the bulk creating of entities later. + var foundGermsById = germplasmService.findByIds(germplasmIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundCrossesById = crossService.findByIds(crossIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundSeedLotsById = seedLotService.findByIds(seedLotIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundTrialsById = trialService.findByIds(trialIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundProgramsById = programService.findByIds(programIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + List result = new ArrayList<>(); + + for (ObservationUnitNewRequest obsUnit : obsUnits) { + var entity = new ObservationUnitEntity(); + + UpdateUtility.updateEntity(obsUnit, entity); + + if (obsUnit.getGermplasmDbId() != null) { + entity.setGermplasm(foundGermsById.get(UUID.fromString(obsUnit.getGermplasmDbId()))); + } + if (obsUnit.getCrossDbId() != null) { + entity.setCross(foundCrossesById.get(UUID.fromString(obsUnit.getCrossDbId()))); + } + if (obsUnit.getObservationUnitName() != null) + entity.setObservationUnitName(obsUnit.getObservationUnitName()); + if (obsUnit.getObservationUnitPUI() != null) + entity.setObservationUnitPUI(obsUnit.getObservationUnitPUI()); + if (obsUnit.getObservationUnitPosition() != null) { + if (entity.getPosition() == null) + entity.setPosition(new ObservationUnitPositionEntity()); + ObservationUnitPositionEntity position = entity.getPosition(); + updateEntity(position, obsUnit.getObservationUnitPosition()); + position.setObservationUnit(entity); + entity.setPosition(position); + } + if (obsUnit.getSeedLotDbId() != null) { + entity.setSeedLot(foundSeedLotsById.get(UUID.fromString(obsUnit.getSeedLotDbId()))); + } + if (obsUnit.getTreatments() != null) + entity.setTreatments(obsUnit.getTreatments().stream().map(t -> { + TreatmentEntity e = new TreatmentEntity(); + e.setFactor(t.getFactor()); + e.setModality(t.getModality()); + e.setObservationUnit(entity); + return e; + }).collect(Collectors.toList())); + + if (obsUnit.getStudyDbId() != null) { + entity.setStudy(foundStudiesById.get(UUID.fromString(obsUnit.getStudyDbId()))); + } else if (obsUnit.getTrialDbId() != null) { + entity.setTrial(foundTrialsById.get(UUID.fromString(obsUnit.getTrialDbId()))); + } else if (obsUnit.getProgramDbId() != null) { + entity.setProgram(foundProgramsById.get(UUID.fromString(obsUnit.getProgramDbId()))); + } + + result.add(entity); + } + + return result; + } + private List> buildDataMatrix(Page observationUnits, List variables) { List> data = new ArrayList<>(); From 413942c0deb091bf61eb7af8636cc5f79c83b007 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 23 Apr 2025 16:02:17 -0400 Subject: [PATCH 04/34] Rename migration to avoid collision --- ...join_tables.sql => U001.002__add_ids_to_study_join_tables.sql} | 0 ..._drop_study_join_ids.sql => V001.002__drop_study_join_ids.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{U001.1__add_ids_to_study_join_tables.sql => U001.002__add_ids_to_study_join_tables.sql} (100%) rename src/main/resources/db/migration/{V001.1__drop_study_join_ids.sql => V001.002__drop_study_join_ids.sql} (100%) diff --git a/src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql b/src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql similarity index 100% rename from src/main/resources/db/migration/U001.1__add_ids_to_study_join_tables.sql rename to src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql diff --git a/src/main/resources/db/migration/V001.1__drop_study_join_ids.sql b/src/main/resources/db/migration/V001.002__drop_study_join_ids.sql similarity index 100% rename from src/main/resources/db/migration/V001.1__drop_study_join_ids.sql rename to src/main/resources/db/migration/V001.002__drop_study_join_ids.sql From 8eba82779cabf0a77258fe57a3677ea276936038 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 30 Apr 2025 16:57:14 -0400 Subject: [PATCH 05/34] Finish Observation and ObservationUnit Import optimizations --- .../pheno/ObservationsApiController.java | 2 +- .../dto/ObservationUnitGermplasmData.java | 30 +++ .../entity/pheno/ObservationUnitEntity.java | 3 + .../pheno/ObservationUnitRepository.java | 15 ++ .../service/core/SeasonService.java | 10 + .../service/germ/GermplasmService.java | 2 +- .../service/pheno/ObservationService.java | 178 +++++++++++++++--- .../service/pheno/ObservationUnitService.java | 39 +++- .../pheno/ObservationVariableService.java | 10 + 9 files changed, 256 insertions(+), 33 deletions(-) create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java index 81828e1f..ceda2df3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java @@ -121,7 +121,7 @@ public ResponseEntity observationsObservationDbIdPut( log.debug("Request: " + request.getRequestURI()); validateSecurityContext(request, "ROLE_USER"); validateAcceptHeader(request); - Observation data = observationService.updateObservation(observationDbId, body); + Observation data = observationService.updateObservationAndConvert(observationDbId, body); return responseOK(new ObservationSingleResponse(), data); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java b/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java new file mode 100644 index 00000000..fd090214 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java @@ -0,0 +1,30 @@ +package org.brapi.test.BrAPITestServer.model.dto; + +import java.util.UUID; + +public class ObservationUnitGermplasmData { + private String germplasmDbId; + private String germplasmName; + + public ObservationUnitGermplasmData(String germplasmDbId, + String germplasmName) { + this.germplasmDbId = germplasmDbId; + this.germplasmName = germplasmName; + } + + public String getGermplasmDbId() { + return germplasmDbId; + } + + public void setGermplasmDbId(String germplasmDbId) { + this.germplasmDbId = germplasmDbId; + } + + public String getGermplasmName() { + return germplasmName; + } + + public void setGermplasmName(String germplasmName) { + this.germplasmName = germplasmName; + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java index c64512fe..8f205ba3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java @@ -9,6 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; +import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Where; import java.util.List; @@ -27,6 +28,7 @@ public class ObservationUnitEntity extends BrAPIPrimaryEntity { private String observationUnitPUI; @ManyToOne(fetch = FetchType.LAZY) private SeedLotEntity seedLot; + @BatchSize(size = 50) @OneToMany(mappedBy="observationUnit", cascade=CascadeType.ALL) private List treatments; @OneToOne(mappedBy="observationUnit", cascade=CascadeType.ALL, fetch = FetchType.LAZY) @@ -39,6 +41,7 @@ public class ObservationUnitEntity extends BrAPIPrimaryEntity { private TrialEntity trial; @ManyToOne(fetch = FetchType.LAZY) private StudyEntity study; + @BatchSize(size = 50) @OneToMany(mappedBy="observationUnit", cascade=CascadeType.ALL, fetch = FetchType.LAZY) private List observations; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java index c1572e6f..9f01082a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java @@ -2,9 +2,24 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.springframework.data.jpa.repository.NativeQuery; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import java.util.List; import java.util.UUID; public interface ObservationUnitRepository extends BrAPIRepository { + @Query("SELECT ou from ObservationUnitEntity ou " + + "LEFT JOIN FETCH ou.position " + + "WHERE ou.id IN :ids") + List findByIds(@Param("ids") List ids); + @NativeQuery( + "SELECT ou.id, g.id, g.germplasm_name " + + "FROM observation_unit ou " + + "JOIN germplasm g ON g.id = ou.germplasm_id " + + "WHERE ou.id IN :ouIds" + ) + List fetchGermplasmDataForOUs(@Param("ouIds") List ouIds); } 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 2041f141..bf464b25 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 @@ -109,6 +109,16 @@ public Season convertFromEntity(SeasonEntity entity) { return season; } + public List findByIds(List seasonIds) { + var result = new ArrayList(); + + if (!seasonIds.isEmpty()) { + return seasonRepository.findByIdIn(seasonIds.stream().map(UUID::fromString).toList()); + } + + return result; + } + private void updateEntity(SeasonEntity entity, Season request) { if (request.getSeasonName() != null) entity.setSeason(request.getSeasonName()); 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 bdd62bda..3c283c67 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 @@ -790,7 +790,7 @@ public List findByIds(List germplasmDbIds) return result; } - List germIdsAsUUIDs = germplasmDbIds.stream().map(UUID::fromString).toList(); + List germIdsAsUUIDs = germplasmDbIds.stream().distinct().map(UUID::fromString).toList(); List germsFoundInDb = germplasmRepository.findByIdIn(germIdsAsUUIDs); Set germIdsFoundInDB = germsFoundInDb.stream() 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 22105845..a97fd31c 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 @@ -1,15 +1,14 @@ package org.brapi.test.BrAPITestServer.service.pheno; import io.swagger.model.Metadata; -import io.swagger.model.Pagination; import io.swagger.model.pheno.*; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.dto.ObservationUnitGermplasmData; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; -import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; @@ -17,6 +16,7 @@ import org.brapi.test.BrAPITestServer.service.*; import org.brapi.test.BrAPITestServer.service.core.SeasonService; import org.brapi.test.BrAPITestServer.service.core.StudyService; +import org.brapi.test.BrAPITestServer.service.germ.GermplasmService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; @@ -39,15 +39,17 @@ public class ObservationService { private final ObservationUnitService observationUnitService; private final StudyService studyService; private final ObservationVariableService observationVariableService; + private final GermplasmService germplasmService; public ObservationService(ObservationRepository observationRepository, SeasonService seasonService, - @Lazy ObservationUnitService observationUnitService, StudyService studyService, - ObservationVariableService observationVariableService) { + @Lazy ObservationUnitService observationUnitService, StudyService studyService, + ObservationVariableService observationVariableService, GermplasmService germplasmService) { this.observationRepository = observationRepository; this.seasonService = seasonService; this.observationUnitService = observationUnitService; this.studyService = studyService; this.observationVariableService = observationVariableService; + this.germplasmService = germplasmService; } public List findObservations(String observationDbId, String observationUnitDbId, String germplasmDbId, @@ -169,7 +171,7 @@ public List findObservations(@Valid ObservationSearchRequest reques throws BrAPIServerException { Page page = findObservationEntities(request, metadata); log.debug("converting "+page.getSize()+" entities"); - List observations = page.map(this::convertFromEntity).getContent(); + List observations = convertFromEntitiesInBatch(page.getContent()); log.debug("done converting entities"); PagingUtility.calculateMetaData(metadata, page); return observations; @@ -276,29 +278,24 @@ public ObservationEntity getObservationEntity(String observationDbId, HttpStatus return observation; } - public List saveObservations(@Valid List requests) throws BrAPIServerException { - List toSave = new ArrayList<>(); - for (ObservationNewRequest request : requests) { - ObservationEntity entity = new ObservationEntity(); - updateEntity(entity, request); // TODO: does updateEntity need to hit the database? - toSave.add(entity); - } - return observationRepository.saveAllAndFlush(toSave) - .stream() - .map(this::convertFromEntity) - .collect(Collectors.toList()); + public List saveObservations(@Valid List requests) { + List toSave = createEntitiesInBatch(requests); + + var savedEntities = observationRepository.saveAll(toSave); + + return convertFromEntitiesInBatch(savedEntities); } public List updateObservations(@Valid Map requests) throws BrAPIServerException { - List savedObservations = new ArrayList<>(); + List savedObservationEntities = new ArrayList<>(); for (Entry entry : requests.entrySet()) { - Observation saved = updateObservation(entry.getKey(), entry.getValue()); - savedObservations.add(saved); + ObservationEntity saved = updateObservation(entry.getKey(), entry.getValue()); + savedObservationEntities.add(saved); } - return savedObservations; + return convertFromEntitiesInBatch(savedObservationEntities); } public List deleteObservations(ObservationSearchRequest body, Metadata metadata) @@ -314,19 +311,51 @@ public List deleteObservations(ObservationSearchRequest body, Metadata m return deletedObservationDbIds; } - public Observation updateObservation(String observationDbId, ObservationNewRequest request) + public ObservationEntity updateObservation(String observationDbId, ObservationNewRequest request) throws BrAPIServerException { ObservationEntity entity = getObservationEntity(observationDbId, HttpStatus.NOT_FOUND); updateEntity(entity, request); - ObservationEntity savedEntity = observationRepository.save(entity); + return observationRepository.save(entity); + } - return convertFromEntity(savedEntity); + public Observation updateObservationAndConvert(String observationDbId, ObservationNewRequest request) + throws BrAPIServerException { + ObservationEntity updatedEntity = updateObservation(observationDbId, request); + + return convertFromEntity(updatedEntity); } + // For single entity conversion use case public Observation convertFromEntity(ObservationEntity entity) { - log.trace("converting obs: " + entity.getId().toString()); - Observation observation = new Observation(); - if (entity != null) { + return convertFromEntitiesInBatch(List.of(entity)).getFirst(); + } + + public List convertFromEntitiesInBatch(List entities) { + return convertFromEntitiesInBatch(entities, null); + } + + public List convertFromEntitiesInBatch(List entities, + Map germplasmDataByOUId) { + var result = new ArrayList(); + + if (entities.isEmpty()) { + return result; + } + + if (germplasmDataByOUId == null) { + germplasmDataByOUId + = observationUnitService.fetchObservationUnitGermplasmData( + entities.stream() + .filter(obs -> obs.getObservationUnit() != null) + .map(obs -> obs.getObservationUnit().getId()) + .distinct() + .toList() + ); + } + + for (ObservationEntity entity : entities) { + log.trace("converting obs: " + entity.getId().toString()); + Observation observation = new Observation(); UpdateUtility.convertFromEntity(entity, observation); observation.setCollector(entity.getCollector()); @@ -345,11 +374,15 @@ public Observation convertFromEntity(ObservationEntity entity) { observation.setValue(entity.getValue()); if (entity.getObservationUnit() != null) { + observation.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); observation.setObservationUnitName(entity.getObservationUnit().getObservationUnitName()); - if (entity.getObservationUnit().getGermplasm() != null) { - observation.setGermplasmDbId(entity.getObservationUnit().getGermplasm().getId().toString()); - observation.setGermplasmName(entity.getObservationUnit().getGermplasm().getGermplasmName()); + + var germplasmData = germplasmDataByOUId.get(entity.getObservationUnit().getId()); + + if (germplasmData != null) { + observation.setGermplasmDbId(germplasmData.getGermplasmDbId()); + observation.setGermplasmName(germplasmData.getGermplasmName()); } if (entity.getObservationUnit().getStudy() != null) { observation.setStudyDbId(entity.getObservationUnit().getStudy().getId().toString()); @@ -358,9 +391,10 @@ public Observation convertFromEntity(ObservationEntity entity) { observation.setStudyDbId(entity.getStudy().getId().toString()); } + result.add(observation); } - return observation; + return result; } private void updateEntity(ObservationEntity entity, ObservationNewRequest observation) throws BrAPIServerException { @@ -396,6 +430,90 @@ private void updateEntity(ObservationEntity entity, ObservationNewRequest observ } } + private List createEntitiesInBatch(List observations) { + + var observationVarIds = observations.stream() + .map(ObservationNewRequest::getObservationVariableDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var seasonIds = observations.stream() + .map(obs -> { + if (obs.getSeason() != null && obs.getSeason().getSeasonDbId() != null) { + return obs.getSeason().getSeasonDbId(); + } + + return null; + }) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var observationUnitIds = observations.stream() + .map(ObservationNewRequest::getObservationUnitDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var studyIds = observations.stream() + .map(ObservationNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var foundObsVarsById = observationVariableService.findByIds(observationVarIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundSeasonsById = seasonService.findByIds(seasonIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundObsUnitsById = observationUnitService.findByIds(observationUnitIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var result = new ArrayList(); + + for (ObservationNewRequest observation : observations) { + var entity = new ObservationEntity(); + + UpdateUtility.updateEntity(observation, entity); + + if (observation.getCollector() != null) + entity.setCollector(observation.getCollector()); + if (observation.getGeoCoordinates() != null) + entity.setGeoCoordinates(GeoJSONUtility.convertToEntity(observation.getGeoCoordinates())); + if (observation.getObservationTimeStamp() != null) + entity.setObservationTimeStamp(DateUtility.toDate(observation.getObservationTimeStamp())); + if (observation.getObservationVariableDbId() != null) { + entity.setObservationVariable(foundObsVarsById.get(UUID.fromString(observation.getObservationVariableDbId()))); + } + if (observation.getSeason() != null && observation.getSeason().getSeasonDbId() != null) { + entity.setSeason(foundSeasonsById.get(UUID.fromString(observation.getSeason().getSeasonDbId()))); + } + if (observation.getUploadedBy() != null) + entity.setUploadedBy(observation.getUploadedBy()); + if (observation.getValue() != null) + entity.setValue(observation.getValue()); + + if (observation.getObservationUnitDbId() != null) { + entity.setObservationUnit(foundObsUnitsById.get(UUID.fromString(observation.getObservationUnitDbId()))); + } else if (observation.getStudyDbId() != null) { + entity.setStudy(foundStudiesById.get(UUID.fromString(observation.getStudyDbId()))); + } + + result.add(entity); + } + + return result; + } + private List> buildDataMatrix(Page observations, List variables) { List> data = new ArrayList<>(); 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 07b30fb8..201b4f60 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 @@ -2,10 +2,12 @@ import io.swagger.model.IndexPagination; import io.swagger.model.Metadata; +import io.swagger.model.germ.GermplasmSearchRequest; import io.swagger.model.pheno.*; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.dto.ObservationUnitGermplasmData; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; @@ -192,6 +194,16 @@ public List findObservationUnits(@Valid ObservationUnitSearchRe return observationUnits; } + public List findByIds(List observationUnitIds) { + var result = new ArrayList(); + + if (!observationUnitIds.isEmpty()) { + return observationUnitRepository.findByIds(observationUnitIds); + } + + return result; + } + public Page findObservationUnitEntities(@Valid ObservationUnitSearchRequest request, Metadata metadata) throws BrAPIServerException { @@ -628,36 +640,46 @@ private List createEntitiesInBatch(List e)); @@ -732,6 +754,21 @@ private List createEntitiesInBatch(List fetchObservationUnitGermplasmData(List ouIds) { + + if (ouIds.isEmpty()) { + return new HashMap<>(); + } + + var databaseResults = observationUnitRepository.fetchGermplasmDataForOUs(ouIds); + + return databaseResults.stream() + .collect((Collectors.toMap( + rs -> (UUID) rs[0], + rs -> new ObservationUnitGermplasmData(rs[1].toString(), rs[2].toString())) + )); + } + private List> buildDataMatrix(Page observationUnits, List variables) { List> data = new ArrayList<>(); 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 d953390a..c96e4d1f 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 @@ -226,6 +226,16 @@ public void convertFromBaseEntity(VariableBaseEntity entity, VariableBaseClass v var.setTrait(traitService.convertFromEntity(entity.getTrait())); } + public List findByIds(List obsVarIds) { + var result = new ArrayList(); + + if (!obsVarIds.isEmpty()) { + return observationVariableRepository.findByIdIn(obsVarIds.stream().map(UUID::fromString).toList()); + } + + return result; + } + private void updateEntity(ObservationVariableEntity entity, ObservationVariableNewRequest request) throws BrAPIServerException { updateBaseEntity(entity, request); From 05f51b4a83393f7f600d951498628ffe1458323b Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Thu, 1 May 2025 16:29:28 -0400 Subject: [PATCH 06/34] Use unpaginated search query in favor of findByIdIn --- .../BrAPITestServer/service/germ/GermplasmService.java | 8 +++++--- .../service/pheno/ObservationUnitService.java | 6 +----- 2 files changed, 6 insertions(+), 8 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 3c283c67..2bb9358b 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 @@ -790,14 +790,16 @@ public List findByIds(List germplasmDbIds) return result; } - List germIdsAsUUIDs = germplasmDbIds.stream().distinct().map(UUID::fromString).toList(); - List germsFoundInDb = germplasmRepository.findByIdIn(germIdsAsUUIDs); + var searchRq = new GermplasmSearchRequest(); + searchRq.setGermplasmDbIds(germplasmDbIds); + + List germsFoundInDb = findGermplasmEntitiesWithoutPaging(searchRq); Set germIdsFoundInDB = germsFoundInDb.stream() .map(BrAPIBaseEntity::getId) .collect(Collectors.toSet()); - if (!germIdsFoundInDB.containsAll(germIdsAsUUIDs)) { + if (!germIdsFoundInDB.containsAll(germplasmDbIds.stream().map(UUID::fromString).toList())) { throw new BrAPIServerDbIdNotFoundException("Germplasm Ids passed to findByIds were not found in the DB", HttpStatus.BAD_REQUEST); } 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 201b4f60..13df53ce 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 @@ -675,11 +675,7 @@ private List createEntitiesInBatch(List e)); From 0f0dce13a4a1af74a427c49512a9cda77c51b22d Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 6 May 2025 15:18:15 -0400 Subject: [PATCH 07/34] Add migration scripts --- .../U001.003__drop_observation_level_name.sql | 16 + ...001.003__create_observation_level_name.sql | 543 ++++++++++++++++++ 2 files changed, 559 insertions(+) create mode 100644 src/main/resources/db/migration/U001.003__drop_observation_level_name.sql create mode 100644 src/main/resources/db/migration/V001.003__create_observation_level_name.sql diff --git a/src/main/resources/db/migration/U001.003__drop_observation_level_name.sql b/src/main/resources/db/migration/U001.003__drop_observation_level_name.sql new file mode 100644 index 00000000..d307bfb5 --- /dev/null +++ b/src/main/resources/db/migration/U001.003__drop_observation_level_name.sql @@ -0,0 +1,16 @@ +ALTER TABLE observation_unit_level + DROP COLUMN level_name, + ADD COLUMN level_name INTEGER, + ADD COLUMN level_order INTEGER; + +ALTER TABLE observation_unit_position + DROP COLUMN level_name, + ADD COLUMN level_name INTEGER, + ADD COLUMN level_order INTEGER; + +ALTER TABLE study_observation_level + DROP COLUMN level_name, + ADD COLUMN level_name TEXT, + ADD COLUMN level_order INTEGER; + +DROP TABLE observation_unit_level_name;; \ No newline at end of file diff --git a/src/main/resources/db/migration/V001.003__create_observation_level_name.sql b/src/main/resources/db/migration/V001.003__create_observation_level_name.sql new file mode 100644 index 00000000..2947524d --- /dev/null +++ b/src/main/resources/db/migration/V001.003__create_observation_level_name.sql @@ -0,0 +1,543 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +CREATE TABLE observation_unit_level_name ( + id UUID DEFAULT uuid_generate_v4(), + CONSTRAINT observation_unit_level_name_pk PRIMARY KEY(id), + level_name VARCHAR(64) NOT NULL, + level_order INTEGER, + program_id UUID, + CONSTRAINT observation_unit_level_name_program_fk FOREIGN KEY(program_id) REFERENCES program(id) +); + +-- Set legacy level names +INSERT INTO observation_unit_level_name (level_name, level_order) + VALUES + ('study', 0), + ('field', 1), + ('entry', 2), + ('rep', 3), + ('block', 4), + ('sub-block', 5), + ('plot', 6), + ('sub-plot', 7), + ('plant', 8), + ('pot', 9), + ('sample', 10); + +ALTER TABLE observation_unit_level + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT observation_unit_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + observation_unit_level.level_name = 0; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + observation_unit_level.level_name = 1; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + observation_unit_level.level_name = 2; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + observation_unit_level.level_name = 3; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + observation_unit_level.level_name = 4; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + observation_unit_level.level_name = 5; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + observation_unit_level.level_name = 6; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + observation_unit_level.level_name = 7; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + observation_unit_level.level_name = 8; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + observation_unit_level.level_name = 9; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + observation_unit_level.level_name = 10; + +ALTER TABLE observation_unit_position + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT observation_unit_position_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + observation_unit_position.level_name = 0; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + observation_unit_position.level_name = 1; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + observation_unit_position.level_name = 2; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + observation_unit_position.level_name = 3; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + observation_unit_position.level_name = 4; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + observation_unit_position.level_name = 5; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + observation_unit_position.level_name = 6; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + observation_unit_position.level_name = 7; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + observation_unit_position.level_name = 8; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + observation_unit_position.level_name = 9; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + observation_unit_position.level_name = 10; + +ALTER TABLE study_observation_level + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT study_observation_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + study_observation_level.level_name = 'study'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + study_observation_level.level_name = 'field'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + study_observation_level.level_name = 'entry'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + study_observation_level.level_name = 'rep'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + study_observation_level.level_name = 'block'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + study_observation_level.level_name = 'sub-block'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + study_observation_level.level_name = 'plot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + study_observation_level.level_name = 'sub-plot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + study_observation_level.level_name = 'plant'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + study_observation_level.level_name = 'pot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + study_observation_level.level_name = 'sample'; + +-- TODO: Uncomment once the app has been tested +--ALTER TABLE observation_unit_position DROP COLUMN level_name, DROP COLUMN level_order, RENAME COLUMN level_name_new level_name +--ALTER TABLE observation_unit_level DROP COLUMN level_name, DROP COLUMN level_order, RENAME COLUMN level_name_new level_name +--ALTER TABLE study_observation_level DROP COLUMN level_name, DROP COLUMN level_order, RENAME COLUMN level_name_new level_name \ No newline at end of file From fab5f0528ef5a00d8be0404b291bcf93e1a1cecc Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 21 May 2025 12:03:38 -0400 Subject: [PATCH 08/34] Resolve compilation issues after migration --- .../swagger/model/core/StudyNewRequest.java | 11 ++ .../pheno/ObservationUnitHierarchyLevel.java | 11 +- .../entity/core/ObservationLevelEntity.java | 19 +-- .../pheno/ObservationUnitLevelNameEntity.java | 44 +++++ ...bservationUnitLevelRelationshipEntity.java | 18 +-- .../pheno/ObservationUnitPositionEntity.java | 93 +++-------- .../ObservationUnitLevelNameRepository.java | 21 +++ .../service/core/StudyService.java | 33 ++-- .../service/pheno/ObservationService.java | 29 +--- .../ObservationUnitLevelNameService.java | 91 +++++++++++ .../service/pheno/ObservationUnitService.java | 152 ++++++++++-------- 11 files changed, 317 insertions(+), 205 deletions(-) create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java diff --git a/src/main/java/io/swagger/model/core/StudyNewRequest.java b/src/main/java/io/swagger/model/core/StudyNewRequest.java index 15a61bf9..36bc86c4 100644 --- a/src/main/java/io/swagger/model/core/StudyNewRequest.java +++ b/src/main/java/io/swagger/model/core/StudyNewRequest.java @@ -84,6 +84,9 @@ public class StudyNewRequest extends BrAPIDataModel{ @JsonProperty("trialDbId") private String trialDbId = null; + @JsonProperty("programDbId") + private String programDbId = null; + @JsonProperty("trialName") private String trialName = null; @@ -463,6 +466,14 @@ public void setTrialDbId(String trialDbId) { this.trialDbId = trialDbId; } + public String getProgramDbId() { + return programDbId; + } + + public void setProgramDbId(String programDbId) { + this.programDbId = programDbId; + } + public StudyNewRequest trialName(String trialName) { this.trialName = trialName; return this; diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index bbe589d4..00a98464 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -7,21 +7,18 @@ public class ObservationUnitHierarchyLevel { @JsonProperty("levelName") - private ObservationUnitHierarchyLevelEnum levelName = null; + private String levelName = null; @JsonProperty("levelOrder") private Integer levelOrder = null; - public ObservationUnitHierarchyLevel levelName(ObservationUnitHierarchyLevelEnum levelName) { - this.levelName = levelName; - return this; - } + // TODO: Put programId on this? Makes it more obvious it is required for level name lookups. - public ObservationUnitHierarchyLevelEnum getLevelName() { + public String getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(String levelName) { this.levelName = levelName; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java index 53a354bf..22134a97 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java @@ -2,27 +2,22 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; @Entity @Table(name = "study_observation_level") public class ObservationLevelEntity extends BrAPIBaseEntity { - @Column - private String levelName; - @Column - private Integer levelOrder; + + @ManyToOne + @JoinColumn(name = "level_name_new") + private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private StudyEntity study; - public String getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(String levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; - } - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; - } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java new file mode 100644 index 00000000..743b4638 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java @@ -0,0 +1,44 @@ +package org.brapi.test.BrAPITestServer.model.entity.pheno; + + +import jakarta.persistence.*; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; + +@Entity +@Table(name = "observation_unit_level_name") +public class ObservationUnitLevelNameEntity extends BrAPIBaseEntity { + @Column(name = "level_name") + private String levelName; + + @Column(name = "level_order") + private Integer levelOrder; + + @ManyToOne + @JoinColumn(name = "program_id") + private ProgramEntity program; + + public String getLevelName() { + return levelName; + } + + public void setLevelName(String value) { + this.levelName = value; + } + + public ProgramEntity getProgram() { + return program; + } + + public void setProgram(ProgramEntity program) { + this.program = program; + } + + public Integer getLevelOrder() { + return levelOrder; + } + + public void setLevelOrder(Integer value) { + this.levelOrder = value; + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java index 5a080d4d..9712148f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java @@ -1,6 +1,5 @@ package org.brapi.test.BrAPITestServer.model.entity.pheno; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; @@ -9,10 +8,9 @@ public class ObservationUnitLevelRelationshipEntity extends BrAPIBaseEntity { @Column private String levelCode; - @Column - private ObservationUnitHierarchyLevelEnum levelName; - @Column - private Integer levelOrder; + @ManyToOne + @JoinColumn(name = "level_name_new") + private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private ObservationUnitEntity observationUnit; @ManyToOne(fetch = FetchType.LAZY) @@ -30,18 +28,12 @@ public String getLevelCode() { public void setLevelCode(String levelCode) { this.levelCode = levelCode; } - public ObservationUnitHierarchyLevelEnum getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; - } - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; - } public ObservationUnitPositionEntity getPosition() { return position; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java index 38851b24..878dc34b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java @@ -1,7 +1,6 @@ package org.brapi.test.BrAPITestServer.model.entity.pheno; import io.swagger.model.pheno.EntryTypeEnum; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; import io.swagger.model.pheno.PositionCoordinateTypeEnum; import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; @@ -12,28 +11,27 @@ @Entity @Table(name = "observation_unit_position") public class ObservationUnitPositionEntity extends BrAPIBaseEntity { - @Column - private EntryTypeEnum entryType; - @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private GeoJSONEntity geoCoordinates; - @Column - private String levelCode; - @Column - private ObservationUnitHierarchyLevelEnum levelName; - @Column - private Integer levelOrder; - @OneToMany(mappedBy = "position", cascade = CascadeType.ALL) - private List observationLevelRelationships; - @Column - private String positionCoordinateX; - @Column - private PositionCoordinateTypeEnum positionCoordinateXType; - @Column - private String positionCoordinateY; - @Column - private PositionCoordinateTypeEnum positionCoordinateYType; - @OneToOne(fetch = FetchType.LAZY) - private ObservationUnitEntity observationUnit; + @Column + private EntryTypeEnum entryType; + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private GeoJSONEntity geoCoordinates; + @Column + private String levelCode; + @ManyToOne + @JoinColumn(name = "level_name_new") + private ObservationUnitLevelNameEntity levelName; + @OneToMany(mappedBy = "position", cascade = CascadeType.ALL) + private List observationLevelRelationships; + @Column + private String positionCoordinateX; + @Column + private PositionCoordinateTypeEnum positionCoordinateXType; + @Column + private String positionCoordinateY; + @Column + private PositionCoordinateTypeEnum positionCoordinateYType; + @OneToOne(fetch = FetchType.LAZY) + private ObservationUnitEntity observationUnit; public ObservationUnitEntity getObservationUnit() { return observationUnit; @@ -67,22 +65,14 @@ public void setLevelCode(String levelCode) { this.levelCode = levelCode; } - public ObservationUnitHierarchyLevelEnum getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; - } - - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; - } - public List getObservationLevelRelationships() { return observationLevelRelationships; } @@ -123,41 +113,4 @@ public PositionCoordinateTypeEnum getPositionCoordinateYType() { public void setPositionCoordinateYType(PositionCoordinateTypeEnum positionCoordinateYType) { this.positionCoordinateYType = positionCoordinateYType; } - - public String getFieldCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.FIELD); - } - - public String getBlockCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.BLOCK); - } - - public String getEntryCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.ENTRY); - } - - public String getRepCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.REP); - } - - public String getPlotCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.PLOT); - } - - public String getPlantCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.PLANT); - } - - private String getRelationshipCode(ObservationUnitHierarchyLevelEnum level) { - if (getLevelName() == level) { - return getLevelCode(); - } else { - for (ObservationUnitLevelRelationshipEntity rel : getObservationLevelRelationships()) { - if (rel.getLevelName() == level) { - return rel.getLevelCode(); - } - } - } - return null; - } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java new file mode 100644 index 00000000..52576096 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java @@ -0,0 +1,21 @@ +package org.brapi.test.BrAPITestServer.repository.pheno; + +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.UUID; + +public interface ObservationUnitLevelNameRepository extends JpaRepository { + + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + + "WHERE ouln.program IN :levelName") + List findObservationUnitLevelNamesByProgram(@Param("programIds") List programDbIds); + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + + "WHERE ouln.program = NULL") + List findDefaultObservationUnitLevelNames(); +} 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 70189455..2429b249 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 @@ -24,6 +24,7 @@ import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; import org.brapi.test.BrAPITestServer.service.pheno.ObservationVariableService; +import org.brapi.test.BrAPITestServer.service.pheno.ObservationUnitLevelNameService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -43,7 +44,6 @@ import io.swagger.model.core.StudyLastUpdate; import io.swagger.model.core.StudySearchRequest; import io.swagger.model.pheno.ObservationUnitHierarchyLevel; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; @Service public class StudyService { @@ -55,11 +55,12 @@ public class StudyService { private final PeopleService peopleService; private final SeasonService seasonService; private final ObservationVariableService variableService; + private final ObservationUnitLevelNameService observationUnitLevelNameService; @Autowired public StudyService(StudyRepository studyRepository, TrialService trialService, CropService cropService, LocationService locationService, PeopleService peopleService, SeasonService seasonService, - ObservationVariableService variableService) { + ObservationVariableService variableService, ObservationUnitLevelNameService observationUnitLevelNameService) { this.studyRepository = studyRepository; this.locationService = locationService; @@ -68,6 +69,7 @@ public StudyService(StudyRepository studyRepository, TrialService trialService, this.trialService = trialService; this.cropService = cropService; this.variableService = variableService; + this.observationUnitLevelNameService = observationUnitLevelNameService; } public List findStudies(String commonCropName, String studyType, String programDbId, String locationDbId, @@ -267,8 +269,7 @@ private void updateEntity(StudyEntity entity, StudyNewRequest body) throws BrAPI entity.setLocation(location); } if (body.getObservationLevels() != null) { - entity.setObservationLevels( - body.getObservationLevels().stream().map(this::convertToEntity).collect(Collectors.toList())); + entity.setObservationLevels(convertToEntity(body.getObservationLevels(), body.getProgramDbId())); } if (body.getObservationUnitsDescription() != null) entity.setObservationUnitsDescription(body.getObservationUnitsDescription()); @@ -396,20 +397,26 @@ private ObservationUnitHierarchyLevel convertFromEntity(ObservationLevelEntity e ObservationUnitHierarchyLevel level = null; if (entity != null) { level = new ObservationUnitHierarchyLevel(); - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(entity.getLevelName())); - level.setLevelOrder(entity.getLevelOrder()); + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); } return level; } - private ObservationLevelEntity convertToEntity(ObservationUnitHierarchyLevel level) { - ObservationLevelEntity entity = null; - if (level != null) { - entity = new ObservationLevelEntity(); - entity.setLevelName(level.getLevelName().toString()); - entity.setLevelOrder(level.getLevelOrder()); + private List convertToEntity(List levels, String programDbId) + throws BrAPIServerException { + List entities = new ArrayList<>(); + + var submittedLevelNames = levels.stream().map(ObservationUnitHierarchyLevel::getLevelName).toList(); + var foundLevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + + for (ObservationUnitHierarchyLevel level : levels) { + var entity = new ObservationLevelEntity(); + + entity.setLevelName(foundLevelNames.get(level.getLevelName())); + entities.add(entity); } - return entity; + return entities; } private StudyLastUpdate convertFromEntity(StudyLastUpdateEntity entity) { 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 a97fd31c..c805c616 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 @@ -103,7 +103,7 @@ private ObservationSearchRequest buildObservationsSearchRequest(String observati if (observationUnitLevelName != null || observationUnitLevelOrder != null || observationUnitLevelCode != null) { ObservationUnitLevel level = new ObservationUnitLevel(); if (observationUnitLevelName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelName)); + level.setLevelName(observationUnitLevelName); if (observationUnitLevelOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelOrder)); if (observationUnitLevelCode != null) @@ -114,7 +114,7 @@ private ObservationSearchRequest buildObservationsSearchRequest(String observati || observationUnitLevelRelationshipCode != null) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); if (observationUnitLevelRelationshipName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelRelationshipName)); + level.setLevelName(observationUnitLevelRelationshipName); if (observationUnitLevelRelationshipOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelRelationshipOrder)); if (observationUnitLevelRelationshipCode != null) @@ -159,6 +159,7 @@ public ObservationTable findObservationsTable(ObservationSearchRequest obsReques .filter(Objects::nonNull).distinct().collect(Collectors.toList()); ObservationTable table = new ObservationTable(); + // TODO: Add support for dynamic observation unit level names for ouPosition in both buildDataMatrix() and buildHeaderRow(), using rq as input table.setData(buildDataMatrix(page, variables)); table.setHeaderRow(buildHeaderRow()); table.setObservationVariables(variables.stream().map(this::convertVariables).collect(Collectors.toList())); @@ -201,7 +202,8 @@ public Page findObservationEntities(@Valid ObservationSearchR .leftJoinFetch("study", "study"); if (request.getObservationLevels() != null) { searchQuery = searchQuery - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "observationUnit.position.level.levelName") @@ -216,7 +218,8 @@ public Page findObservationEntities(@Valid ObservationSearchR } if (request.getObservationLevelRelationships() != null) { searchQuery = searchQuery.join("observationUnit.position.levelRelationships", "levelRelationship") - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "levelRelationship.levelName") @@ -563,21 +566,9 @@ private List> buildDataMatrix(Page observations, if (obsUnit.getPosition() != null) { row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateX())); // POSITIONCOORDINATEX row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateY())); // POSITIONCOORDINATEY - row.add(printIfNotNull(obsUnit.getPosition().getFieldCode())); // FIELD - row.add(printIfNotNull(obsUnit.getPosition().getBlockCode())); // BLOCK - row.add(printIfNotNull(obsUnit.getPosition().getEntryCode())); // ENTRY - row.add(printIfNotNull(obsUnit.getPosition().getRepCode())); // REP - row.add(printIfNotNull(obsUnit.getPosition().getPlotCode())); // PLOT - row.add(printIfNotNull(obsUnit.getPosition().getPlantCode())); // PLANT } else { row.add(""); // POSITIONCOORDINATEX row.add(""); // POSITIONCOORDINATEY - row.add(""); // FIELD - row.add(""); // BLOCK - row.add(""); // ENTRY - row.add(""); // REP - row.add(""); // PLOT - row.add(""); // PLANT } } else { @@ -618,12 +609,6 @@ private List buildHeaderRow() { headers.add(ObservationTableHeaderRowEnum.OBSERVATIONUNITNAME); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEX); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEY); - headers.add(ObservationTableHeaderRowEnum.FIELD); - headers.add(ObservationTableHeaderRowEnum.BLOCK); - headers.add(ObservationTableHeaderRowEnum.ENTRY); - headers.add(ObservationTableHeaderRowEnum.REP); - headers.add(ObservationTableHeaderRowEnum.PLOT); - headers.add(ObservationTableHeaderRowEnum.PLANT); headers.add(ObservationTableHeaderRowEnum.OBSERVATIONTIMESTAMP); return headers; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java new file mode 100644 index 00000000..43aab76d --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -0,0 +1,91 @@ +package org.brapi.test.BrAPITestServer.service.pheno; + +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; +import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitLevelNameRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class ObservationUnitLevelNameService { + private final ObservationUnitLevelNameRepository observationUnitLevelNameRepository; + + @Autowired + public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository) { + this.observationUnitLevelNameRepository = observationUnitLevelNameRepository; + } + + public Map retrieveAndVerifyObservationUnitLevelNames(String programDbId, + List submittedLevelNames) + { + return retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + } + + public Map retrieveAndVerifyObservationUnitLevelNames(List programDbIds, + List submittedLevelNames) + throws BrAPIServerException { + + List foundOULevelNames = findObservationUnitLevelNames(programDbIds); + + var levelNameEntitiesByName = foundOULevelNames.stream() + .collect(Collectors.toMap(ObservationUnitLevelNameEntity::getLevelName, e -> e)); + + // Now that we have found all the available level names, verify that all submitted level names are valid level names + // in the DB. If they aren't throw an error indicating the client must fix this. + for (String submittedLevelName : submittedLevelNames) { + if (!levelNameEntitiesByName.containsKey(submittedLevelName)) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, + String.format("Submitted observation unit level name [%s] does not exist " + + "globally or for the following submitted programs [%s]. This can be fixed " + + "by adding the level name using the POST endpoint brapi/[version-number]/observationunitlevelnames, " + + "or by using a level name already in the system.", + submittedLevelName, + programDbIds.toString())); + } + } + + // Now that every submitted level name has been verified, return a map of the retrieved submitted levels. + return submittedLevelNames.stream() + .collect(Collectors.toMap(ln -> ln, levelNameEntitiesByName::get)); + + // If there were no global names available, + } + + + // Single Program use case + public List findObservationUnitLevelNames(String programDbId) + throws BrAPIServerException { + return findObservationUnitLevelNames(List.of(programDbId)); + } + + // Finds observation unit level names by programDbIds, or if not available, globally (no associated program) + private List findObservationUnitLevelNames(List programDbIds) + throws BrAPIServerException { + List foundOULevelNames = new ArrayList<>(); + + if (programDbIds != null && !programDbIds.isEmpty()) { + // First look up all level names related to submitted programs if available + foundOULevelNames = observationUnitLevelNameRepository.findObservationUnitLevelNamesByProgram(programDbIds); + } + + if (foundOULevelNames.isEmpty()) { + // None were found. Now try to see if there are globally available level names. + foundOULevelNames = observationUnitLevelNameRepository.findDefaultObservationUnitLevelNames(); + } + + if (foundOULevelNames.isEmpty()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, + "No observation level names were found for the programDbId provided, nor are any global level" + + " names available. Please add via endpoint to attach level names to a program or define " + + "without a program to make them globally accessible."); + } + + return foundOULevelNames; + } +} 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 13df53ce..35aca08c 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 @@ -2,7 +2,6 @@ import io.swagger.model.IndexPagination; import io.swagger.model.Metadata; -import io.swagger.model.germ.GermplasmSearchRequest; import io.swagger.model.pheno.*; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; @@ -52,12 +51,13 @@ public class ObservationUnitService { private final ProgramService programService; private final SeedLotService seedLotService; private final ObservationVariableService observationVariableService; + private final ObservationUnitLevelNameService observationUnitLevelNameService; @Autowired public ObservationUnitService(ObservationUnitRepository observationUnitRepository, StudyService studyService, TrialService trialService, ProgramService programService, ObservationService observationService, GermplasmService germplasmService, SeedLotService seedLotService, CrossService crossService, - ObservationVariableService observationVariableService) { + ObservationVariableService observationVariableService, ObservationUnitLevelNameService observationUnitLevelNameService) { this.observationUnitRepository = observationUnitRepository; this.studyService = studyService; @@ -68,6 +68,7 @@ public ObservationUnitService(ObservationUnitRepository observationUnitRepositor this.observationService = observationService; this.seedLotService = seedLotService; this.observationVariableService = observationVariableService; + this.observationUnitLevelNameService = observationUnitLevelNameService; } public List findObservationUnits(String observationUnitDbId, String observationUnitName, @@ -117,7 +118,7 @@ private ObservationUnitSearchRequest buildObservationUnitsSearchRequest(String o if (observationUnitLevelName != null || observationUnitLevelOrder != null || observationUnitLevelCode != null) { ObservationUnitLevel level = new ObservationUnitLevel(); if (observationUnitLevelName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelName)); + level.setLevelName(observationUnitLevelName); if (observationUnitLevelOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelOrder)); if (observationUnitLevelCode != null) @@ -128,7 +129,7 @@ private ObservationUnitSearchRequest buildObservationUnitsSearchRequest(String o || observationUnitLevelRelationshipCode != null) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); if (observationUnitLevelRelationshipName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelRelationshipName)); + level.setLevelName(observationUnitLevelRelationshipName); if (observationUnitLevelRelationshipOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelRelationshipOrder)); if (observationUnitLevelRelationshipCode != null) @@ -166,6 +167,7 @@ public ObservationUnitTable findObservationUnitsTable(String observationUnitDbId List variables = observationVariableService.findObservationVariables(varRequest, null); ObservationUnitTable table = new ObservationUnitTable(); + // TODO: Add support for dynamic observation unit level names for ouPosition in both buildDataMatrix() and buildHeaderRow(), using rq as input table.setData(buildDataMatrix(observationUnits, variables)); table.setHeaderRow(buildHeaderRow()); table.setObservationVariables(variables.stream().map(this::convertVariables).collect(Collectors.toList())); @@ -237,18 +239,22 @@ public Page findObservationUnitEntities(@Valid Observatio "*season.id"); } + if (request.getObservationLevels() != null) { + searchQuery = searchQuery - .appendEnumList(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "position.levelName") .appendList(request.getObservationLevels().stream().filter(r -> r.getLevelCode() != null) - .map(r -> r.getLevelCode()).collect(Collectors.toList()), "position.levelCode") + .map(ObservationUnitLevel::getLevelCode).collect(Collectors.toList()), "position.levelCode") .appendIntList(request.getObservationLevels().stream().filter(r -> r.getLevelOrder() != null) - .map(r -> r.getLevelOrder()).collect(Collectors.toList()), "position.levelOrder"); + .map(ObservationUnitHierarchyLevel::getLevelOrder).collect(Collectors.toList()), "position.levelOrder"); } if (request.getObservationLevelRelationships() != null) { searchQuery = searchQuery.join("position.observationLevelRelationships", "levelRelationship") - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "*levelRelationship.levelName") @@ -382,10 +388,12 @@ public List findObservationLevels(String studyDbI String programDbId, Metadata metadata) throws BrAPIServerException { - List allLevels = Arrays.asList(ObservationUnitHierarchyLevelEnum.values()).stream() + List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId); + + List levelNames = foundObsLevelNameEntities.stream() .map(levelEnum -> { ObservationUnitLevel rel = new ObservationUnitLevel(); - rel.setLevelName(levelEnum); + rel.setLevelName(levelEnum.getLevelName()); return rel; }).collect(Collectors.toList()); @@ -393,13 +401,13 @@ public List findObservationLevels(String studyDbI null, trialDbId, programDbId, null, null, null, null, null, null, null, null, null, false, null, null, null); - levelsSearch.setObservationLevels(allLevels); + levelsSearch.setObservationLevels(levelNames); List units = new ArrayList<>(); List someunits = findObservationUnits(levelsSearch, new Metadata().pagination(new IndexPagination())); units.addAll(someunits); - levelsSearch.setObservationLevelRelationships(allLevels.stream().map(lvl -> { + levelsSearch.setObservationLevelRelationships(levelNames.stream().map(lvl -> { ObservationUnitLevelRelationship rel = new ObservationUnitLevelRelationship(); rel.setLevelCode(lvl.getLevelCode()); rel.setLevelName(lvl.getLevelName()); @@ -424,11 +432,13 @@ public List findObservationLevels(String studyDbI } list.add(unit.getObservationUnitPosition().getObservationLevel()); return list; - }).flatMap(list -> list.stream()).map(level -> level.getLevelName()).distinct().sorted() - .map(levelName -> { + }).flatMap(Collection::stream) + .distinct() + .sorted() + .map(obsUnitLevel -> { ObservationUnitHierarchyLevel level = new ObservationUnitHierarchyLevel(); - level.setLevelName(levelName); - level.setLevelOrder(levelName.ordinal()); + level.setLevelName(obsUnitLevel.getLevelName()); + level.setLevelOrder(obsUnitLevel.getLevelOrder()); return level; }).collect(Collectors.toList()); @@ -509,8 +519,8 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity position.setGeoCoordinates(GeoJSONUtility.convertFromEntity(entity.getGeoCoordinates())); ObservationUnitLevel level = new ObservationUnitLevel(); level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName()); - level.setLevelOrder(entity.getLevelOrder()); + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); position.setObservationLevel(level); if (entity.getObservationLevelRelationships() != null) { position.setObservationLevelRelationships(entity.getObservationLevelRelationships().stream() @@ -534,8 +544,8 @@ private ObservationTreatment convertFromEntity(TreatmentEntity entity) { private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity, String ouDbId) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName()); - level.setLevelOrder(entity.getLevelOrder()); + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); if (ouDbId != null) level.setObservationUnitDbId(ouDbId); return level; @@ -561,7 +571,7 @@ private ObservationUnitEntity updateEntity(ObservationUnitEntity entity, Observa if (entity.getPosition() == null) entity.setPosition(new ObservationUnitPositionEntity()); ObservationUnitPositionEntity position = entity.getPosition(); - updateEntity(position, unit.getObservationUnitPosition()); + updateEntity(position, unit.getObservationUnitPosition(), entity); position.setObservationUnit(entity); entity.setPosition(position); } @@ -592,7 +602,9 @@ private ObservationUnitEntity updateEntity(ObservationUnitEntity entity, Observa return entity; } - private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitPosition position) { + private void updateEntity(ObservationUnitPositionEntity entity, + ObservationUnitPosition position, + ObservationUnitEntity ouEntity) throws BrAPIServerException { if (position.getEntryType() != null) entity.setEntryType(position.getEntryType()); @@ -601,28 +613,16 @@ private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitP if (position.getObservationLevel() != null) { if (position.getObservationLevel().getLevelCode() != null) entity.setLevelCode(position.getObservationLevel().getLevelCode()); - if (position.getObservationLevel().getLevelName() != null) - entity.setLevelName(position.getObservationLevel().getLevelName()); - if (position.getObservationLevel().getLevelOrder() != null) - entity.setLevelOrder(position.getObservationLevel().getLevelOrder()); + if (position.getObservationLevel().getLevelName() != null) { + var programDbId = Optional.ofNullable(ouEntity.getProgram()) + .map(p -> p.getId().toString()) + .orElse(null); + var foundLevelName = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, List.of(position.getObservationLevel().getLevelName())); + entity.setLevelName(foundLevelName.get(position.getObservationLevel().getLevelName())); + } } if (position.getObservationLevelRelationships() != null) - entity.setObservationLevelRelationships(position.getObservationLevelRelationships().stream().map(level -> { - ObservationUnitLevelRelationshipEntity relationshipEntity = new ObservationUnitLevelRelationshipEntity(); - try { - relationshipEntity.setLevelCode(level.getLevelCode()); - relationshipEntity.setLevelName(level.getLevelName()); - relationshipEntity.setLevelOrder(level.getLevelOrder()); - if (level.getObservationUnitDbId() != null) { - ObservationUnitEntity parentEntity = getObservationUnitEntity(level.getObservationUnitDbId()); - relationshipEntity.setObservationUnit(parentEntity); - } - relationshipEntity.setPosition(entity); - } catch (BrAPIServerException e) { - e.printStackTrace(); - } - return relationshipEntity; - }).collect(Collectors.toList())); + updateOULevelRelationships(ouEntity, entity, position); if (position.getPositionCoordinateX() != null) entity.setPositionCoordinateX(position.getPositionCoordinateX()); if (position.getPositionCoordinateXType() != null) @@ -634,6 +634,38 @@ private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitP } + private void updateOULevelRelationships(ObservationUnitEntity ouEntity, + ObservationUnitPositionEntity pEntity, + ObservationUnitPosition position) + throws BrAPIServerException { + + var submittedLevelNames = position.getObservationLevelRelationships().stream() + .map(ObservationUnitHierarchyLevel::getLevelName) + .toList(); + + var programDbId = Optional.ofNullable(ouEntity.getProgram()) + .map(p -> p.getId().toString()) + .orElse(null); + + var foundOULevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + + var relationshipEntities = new ArrayList(); + + for (ObservationUnitLevelRelationship level : position.getObservationLevelRelationships()) { + ObservationUnitLevelRelationshipEntity relationshipEntity = new ObservationUnitLevelRelationshipEntity(); + relationshipEntity.setLevelCode(level.getLevelCode()); + relationshipEntity.setLevelName(foundOULevelNames.get(level.getLevelName())); + if (level.getObservationUnitDbId() != null) { + ObservationUnitEntity parentEntity = getObservationUnitEntity(level.getObservationUnitDbId()); + relationshipEntity.setObservationUnit(parentEntity); + } + relationshipEntity.setPosition(pEntity); + relationshipEntities.add(relationshipEntity); + } + + pEntity.setObservationLevelRelationships(relationshipEntities); + } + private List createEntitiesInBatch(List obsUnits) throws BrAPIServerException { // Gather all IDs we want to look up in a bulk lookup. @@ -716,14 +748,6 @@ private List createEntitiesInBatch(List createEntitiesInBatch(List> buildDataMatrix(Page observati if (obsUnit.getPosition() != null) { row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateX())); // POSITIONCOORDINATEX row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateY())); // POSITIONCOORDINATEY - row.add(printIfNotNull(obsUnit.getPosition().getFieldCode())); // FIELD - row.add(printIfNotNull(obsUnit.getPosition().getBlockCode())); // BLOCK - row.add(printIfNotNull(obsUnit.getPosition().getEntryCode())); // ENTRY - row.add(printIfNotNull(obsUnit.getPosition().getRepCode())); // REP - row.add(printIfNotNull(obsUnit.getPosition().getPlotCode())); // PLOT - row.add(printIfNotNull(obsUnit.getPosition().getPlantCode())); // PLANT } else { row.add(""); // POSITIONCOORDINATEX row.add(""); // POSITIONCOORDINATEY - row.add(""); // FIELD - row.add(""); // BLOCK - row.add(""); // ENTRY - row.add(""); // REP - row.add(""); // PLOT - row.add(""); // PLANT } for (ObservationVariable var : variables) { @@ -864,12 +886,6 @@ private List buildHeaderRow() { headers.add(ObservationTableHeaderRowEnum.OBSERVATIONUNITNAME); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEX); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEY); - headers.add(ObservationTableHeaderRowEnum.FIELD); - headers.add(ObservationTableHeaderRowEnum.BLOCK); - headers.add(ObservationTableHeaderRowEnum.ENTRY); - headers.add(ObservationTableHeaderRowEnum.REP); - headers.add(ObservationTableHeaderRowEnum.PLOT); - headers.add(ObservationTableHeaderRowEnum.PLANT); return headers; } From 7aa2e93694b3a8aae85db4ce3290ffa973034921 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 27 May 2025 17:25:51 -0400 Subject: [PATCH 09/34] Add endpoints, create first base entity repository --- .../api/pheno/ObservationLevelNamesApi.java | 66 ++++++++ .../pheno/ObservationLevelNewRequest.java | 13 ++ .../pheno/ObservationLevelSingleResponse.java | 127 +++++++++++++++ .../pheno/ObservationUnitHierarchyLevel.java | 35 +++- .../BrapiTestServerConfig.java | 12 +- .../BrAPITestServer/NonBaseRepoConfig.java | 14 ++ .../ObservationLevelNamesApiController.java | 99 ++++++++++++ .../nonBaseRepos/BaseEntityRepository.java | 4 + .../ObservationUnitLevelNameRepository.java | 16 +- .../service/core/ServerInfoService.java | 1 + .../ObservationUnitLevelNameService.java | 153 ++++++++++++++++-- 11 files changed, 522 insertions(+), 18 deletions(-) create mode 100644 src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java create mode 100644 src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java create mode 100644 src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java rename src/main/java/org/brapi/test/BrAPITestServer/repository/{pheno => nonBaseRepos}/ObservationUnitLevelNameRepository.java (58%) diff --git a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java new file mode 100644 index 00000000..f0a2d733 --- /dev/null +++ b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java @@ -0,0 +1,66 @@ +package io.swagger.api.pheno; + +import io.swagger.annotations.*; +import io.swagger.model.pheno.*; +import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2024-05-21T16:32:22.556Z[GMT]") +@Api(value = "observationlevelnames", description = "the observationlevelnames API") +public interface ObservationLevelNamesApi { + @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to retrieve the list of supported observation level names. Observation levels indicate the granularity level at which the measurements are taken. `levelName` defines the level, `levelOrder` defines where that level exists in the hierarchy of levels. `levelOrder`s lower numbers are at the top of the hierarchy (ie field > 0) and higher numbers are at the bottom of the hierarchy (ie plant > 6). The values are used to supply the `observationLevel` parameter in the observation unit details call.", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames", produces = { "application/json" }, method = RequestMethod.GET) + ResponseEntity observationlevelnamesGet( + @ApiParam(value = "programDbId") @Valid @RequestParam(value = "programDbId", required = false) String programDbId, + @ApiParam(value = "all") @Valid @RequestParam(value = "all", required = false) Boolean all, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames", produces = { "application/json" }, method = RequestMethod.POST) + ResponseEntity observationlevelnamesPost( + @ApiParam(value = "") @Valid @RequestBody List body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames/{observationlevelnameDbId}", produces = { "application/json" }, method = RequestMethod.DELETE) + ResponseEntity observationlevelnamesDelete( + @ApiParam(value = "The unique ID of this generic list", required = true) @PathVariable("observationlevelnameDbId") String observationLevelNameDbId, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Update an existing Observation Level Name", nickname = "observationlevelnamesDbIdPut", notes = "Update an existing Observation Level Name", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation Units", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationUnitHierarchyLevel.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames/{observationlevelnameDbId}", produces = { "application/json" }, consumes = { + "application/json" }, method = RequestMethod.PUT) + ResponseEntity observationlevelnamesDbIdPut( + @ApiParam(value = "The unique ID of the specific Observation Level Name", required = true) @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @ApiParam(value = "") @Valid @RequestBody ObservationLevelNewRequest body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; +} + diff --git a/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java b/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java new file mode 100644 index 00000000..ba3df50d --- /dev/null +++ b/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java @@ -0,0 +1,13 @@ +package io.swagger.model.pheno; + +public class ObservationLevelNewRequest extends ObservationUnitHierarchyLevel { + private Boolean global = null; + + public Boolean getGlobal() { + return global; + } + + public void setGlobal(Boolean value) { + this.global = value; + } +} diff --git a/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java b/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java new file mode 100644 index 00000000..5a4e9394 --- /dev/null +++ b/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java @@ -0,0 +1,127 @@ +package io.swagger.model.pheno; + +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; + + +import io.swagger.annotations.ApiModelProperty; +import io.swagger.model.BrAPIResponse; +import io.swagger.model.Context; +import io.swagger.model.Metadata; + +import io.swagger.model.pheno.ObservationLevelListResponseResult; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * ObservationLevelListResponse + */ +@Validated +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2020-03-20T16:32:22.556Z[GMT]") +public class ObservationLevelSingleResponse implements BrAPIResponse { + @JsonProperty("@context") + private Context _atContext = null; + + @JsonProperty("metadata") + private Metadata metadata = null; + + @JsonProperty("result") + private ObservationUnitHierarchyLevel result = null; + + public ObservationLevelSingleResponse _atContext(Context _atContext) { + this._atContext = _atContext; + return this; + } + + + + public void set_atContext(Context _atContext) { + this._atContext = _atContext; + } + + public ObservationLevelSingleResponse metadata(Metadata metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @ApiModelProperty(required = true, value = "") + + + @Valid + public Metadata getMetadata() { + return metadata; + } + + public void setMetadata(Metadata metadata) { + this.metadata = metadata; + } + + public ObservationLevelSingleResponse result(ObservationUnitHierarchyLevel result) { + this.result = result; + return this; + } + + /** + * Get result + * @return result + **/ + @ApiModelProperty(required = true, value = "") + + + @Valid + public ObservationUnitHierarchyLevel getResult() { + return result; + } + + public void setResult(ObservationUnitHierarchyLevel result) { + this.result = result; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ObservationLevelSingleResponse observationLevelSingleResponse = (ObservationLevelSingleResponse) o; + return Objects.equals(this._atContext, observationLevelSingleResponse._atContext) && + Objects.equals(this.metadata, observationLevelSingleResponse.metadata) && + Objects.equals(this.result, observationLevelSingleResponse.result); + } + + @Override + public int hashCode() { + return Objects.hash(_atContext, metadata, result); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ObservationLevelListResponse {\n"); + + sb.append(" _atContext: ").append(toIndentedString(_atContext)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" result: ").append(toIndentedString(result)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index 00a98464..c97ebfb6 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -2,17 +2,34 @@ import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; public class ObservationUnitHierarchyLevel { + @JsonProperty("levelNameDbId") + private String levelNameDbId = null; + @JsonProperty("levelName") private String levelName = null; @JsonProperty("levelOrder") private Integer levelOrder = null; - // TODO: Put programId on this? Makes it more obvious it is required for level name lookups. + @JsonProperty("programDbId") + private String programDbId = null; + + // NOTE: This property is NOT used for lookups, only responses. + @JsonProperty("programName") + private String programName = null; + + public String getLevelNameDbId() { + return levelNameDbId; + } + + public void setLevelNameDbId(String value) { + this.levelNameDbId = value; + } public String getLevelName() { return levelName; @@ -35,6 +52,22 @@ public void setLevelOrder(Integer levelOrder) { this.levelOrder = levelOrder; } + public String getProgramDbId() { + return programDbId; + } + + public void setProgramDbId(String value) { + this.programDbId = value; + } + + public String getProgramName() { + return programName; + } + + public void setProgramName(String value) { + this.programName = value; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java index 2c9fa0a0..4422ac1e 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java @@ -8,9 +8,7 @@ import org.brapi.test.BrAPITestServer.serializer.CustomStringToEnumConverter; import org.brapi.test.BrAPITestServer.serializer.CustomTimeStampSerializer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.*; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -22,7 +20,13 @@ import java.time.OffsetDateTime; @Configuration -@EnableJpaRepositories(basePackages = "org.brapi.test.BrAPITestServer.repository", repositoryBaseClass = BrAPIRepositoryImpl.class) +@EnableJpaRepositories( + basePackages = "org.brapi.test.BrAPITestServer.repository", + excludeFilters = @ComponentScan.Filter( + type = FilterType.REGEX, + pattern = "org\\.brapi\\.test\\.BrAPITestServer\\.repository\\.nonBaseRepos\\..*" + ), + repositoryBaseClass = BrAPIRepositoryImpl.class) @PropertySource(value = "classpath:properties/application.properties") public class BrapiTestServerConfig { @Bean diff --git a/src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java new file mode 100644 index 00000000..213a32aa --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java @@ -0,0 +1,14 @@ +package org.brapi.test.BrAPITestServer; + +import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableJpaRepositories( + basePackages = "org.brapi.test.BrAPITestServer.repository.nonBaseRepos", + excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BrAPIPrimaryEntity.class)) +public class NonBaseRepoConfig { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java new file mode 100644 index 00000000..3a330c0b --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java @@ -0,0 +1,99 @@ +package org.brapi.test.BrAPITestServer.controller.pheno; + + +import io.swagger.annotations.ApiParam; +import io.swagger.api.pheno.ObservationLevelNamesApi; +import io.swagger.model.pheno.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.controller.core.BrAPIController; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.service.pheno.ObservationUnitLevelNameService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2025-05-21T16:32:22.556Z[GMT]") +@Controller +public class ObservationLevelNamesApiController extends BrAPIController + implements ObservationLevelNamesApi { + + private static final Logger log = LoggerFactory.getLogger(ObservationLevelNamesApiController.class); + private final HttpServletRequest request; + private final ObservationUnitLevelNameService observationUnitLevelNameService; + + @Autowired + public ObservationLevelNamesApiController(ObservationUnitLevelNameService observationUnitLevelNameService, + HttpServletRequest request) { + this.observationUnitLevelNameService = observationUnitLevelNameService; + this.request = request; + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesGet( + // If supplied, grabs all Observation Level Names for the given programDbId. + // If not supplied, grabs all global Observation Level Names. + @RequestParam(value = "programDbId", required = false) String programDbId, + // Used to grab all the Observation Level Names in the system, both global, and all level names for all params + @RequestParam(value = "all", required = false) Boolean all, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); + validateAcceptHeader(request); + var foundLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, all); + var data = observationUnitLevelNameService.convertFromEntitiesInBatch(foundLevelNames); + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, null); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesPost( + @RequestBody List body, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); + validateAcceptHeader(request); + var data = observationUnitLevelNameService.save(body); + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, null); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesDelete( + @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_USER"); + validateAcceptHeader(request); + + observationUnitLevelNameService.deleteObservationLevelName(observationlevelnameDbId); + return responseNoContent(); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesDbIdPut( + @ApiParam(value = "The unique ID of the specific Observation Level name", required = true) @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @ApiParam(value = "") @Valid @RequestBody ObservationLevelNewRequest body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_USER"); + validateAcceptHeader(request); + + var data = observationUnitLevelNameService.update(observationlevelnameDbId, body); + return responseOK(new ObservationLevelSingleResponse(), data); + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java new file mode 100644 index 00000000..97c89350 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java @@ -0,0 +1,4 @@ +package org.brapi.test.BrAPITestServer.repository.nonBaseRepos; + +public class BaseEntityRepository { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java index 52576096..26ba4d4a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitLevelNameRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java @@ -1,7 +1,8 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.nonBaseRepos; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -16,6 +17,17 @@ public interface ObservationUnitLevelNameRepository extends JpaRepository findObservationUnitLevelNamesByProgram(@Param("programIds") List programDbIds); @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + - "WHERE ouln.program = NULL") + "WHERE ouln.program IS NULL") List findDefaultObservationUnitLevelNames(); + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln") + List findAllObservationUnitLevelNames(); +// +// @Modifying +// @Query("DELETE FROM ObservationUnitLevelNameEntity WHERE id = :levelNameDbId") +// void deleteObservationUnitLevelNameById(@Param("levelNameDbId") String levelNameDbId); +// +// @Modifying +// @Query("INSERT INTO ObservationUnitLevelNameEntity ") + } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java index 62730ce7..682ffb58 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java @@ -51,6 +51,7 @@ public static List buildServices(){ .setBase("observationunits").GET().POST().PUT().addPath("{observationUnitDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observations").GET().POST().PUT().addPath("{observationDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observationlevels").GET().build() + .setBase("observationlevelnames").GET().POST().addPath("{observationlevelnameDbId}").build() //GENOTYPING .setBase("calls").GET().withSearch() .setBase("callsets").GET().addPath("{callSetDbId}").GET().addPath("calls").GET().withSearch() diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 43aab76d..c994771e 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -1,30 +1,39 @@ package org.brapi.test.BrAPITestServer.service.pheno; +import io.swagger.model.pheno.ObservationLevelNewRequest; +import io.swagger.model.pheno.ObservationUnitHierarchyLevel; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitLevelNameRepository; +import org.brapi.test.BrAPITestServer.repository.nonBaseRepos.ObservationUnitLevelNameRepository; +import org.brapi.test.BrAPITestServer.service.core.ProgramService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Service public class ObservationUnitLevelNameService { private final ObservationUnitLevelNameRepository observationUnitLevelNameRepository; + private final ProgramService programService; + + private final static String GLOBAL_NOT_SET_MSG = "No observation level names were found for the programDbId provided, nor are any global level" + + " names available. Please add via endpoint to attach level names to a program or define " + + "without a program to make them globally accessible."; @Autowired - public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository) { + public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository, + ProgramService programService) { this.observationUnitLevelNameRepository = observationUnitLevelNameRepository; + this.programService = programService; } public Map retrieveAndVerifyObservationUnitLevelNames(String programDbId, List submittedLevelNames) - { - return retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + throws BrAPIServerException { + return retrieveAndVerifyObservationUnitLevelNames(List.of(programDbId), submittedLevelNames); } public Map retrieveAndVerifyObservationUnitLevelNames(List programDbIds, @@ -53,22 +62,144 @@ public Map retrieveAndVerifyObservationU // Now that every submitted level name has been verified, return a map of the retrieved submitted levels. return submittedLevelNames.stream() .collect(Collectors.toMap(ln -> ln, levelNameEntitiesByName::get)); + } + + public List convertFromEntitiesInBatch(List entities) { + List result = new ArrayList<>(); + + for (ObservationUnitLevelNameEntity entity : entities) { + var level = new ObservationUnitHierarchyLevel(); + + level.setLevelNameDbId(entity.getId().toString()); + level.setLevelName(entity.getLevelName()); + level.setLevelOrder(entity.getLevelOrder()); - // If there were no global names available, + if (entity.getProgram() != null) { + level.setProgramDbId(entity.getProgram().getId().toString()); + level.setProgramName(entity.getProgram().getName()); + } + + result.add(level); + } + return result; } + public List convertToEntitiesInBatch(List levels) + throws BrAPIServerException { + List result = new ArrayList<>(); + + var programDbIds = levels.stream() + .map(ObservationUnitHierarchyLevel::getProgramDbId) + .filter(Objects::nonNull) + .toList(); + + var programEntitiesById = programService.findByIds(programDbIds).stream() + .collect(Collectors.toMap(p -> p.getId().toString(), p -> p)); + + for (ObservationLevelNewRequest level : levels) { + var entity = new ObservationUnitLevelNameEntity(); + + entity.setLevelName(level.getLevelName()); + entity.setLevelOrder(level.getLevelOrder()); + + if (level.getProgramDbId() != null) { + var foundProgram = programEntitiesById.get(level.getProgramDbId()); + if (foundProgram != null) { + entity.setProgram(foundProgram); + } else { + throw new BrAPIServerDbIdNotFoundException("program", level.getProgramDbId(), HttpStatus.BAD_REQUEST); + } + } else if (level.getGlobal() == null || !level.getGlobal()){ + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_NOT_SET_MSG); + } + + result.add(entity); + } + + return result; + } + + public ObservationUnitHierarchyLevel update(String observationLevelNameDbId, + ObservationLevelNewRequest level) + throws BrAPIServerException { + var entityOpt = observationUnitLevelNameRepository.findById(UUID.fromString(observationLevelNameDbId)); + + if (entityOpt.isEmpty()) { + throw new BrAPIServerDbIdNotFoundException("ObservationUnitLevelName", observationLevelNameDbId, HttpStatus.BAD_REQUEST); + } + + var entity = entityOpt.get(); + + if (level.getLevelName() != null) { + entity.setLevelName(level.getLevelName()); + } + + if (level.getLevelOrder() != null) { + entity.setLevelOrder(level.getLevelOrder()); + } + + if (level.getProgramDbId() != null) { + var program = programService.getProgramEntity(level.getProgramDbId()); + entity.setProgram(program); + } else if (level.getGlobal() == null || !level.getGlobal()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_NOT_SET_MSG); + } else { + // The user sent in a request to make this observation level name global for the system. + // In the DB impl, this simply means it doesn't belong to any program. + entity.setProgram(null); + } + + var savedEntity = observationUnitLevelNameRepository.save(entity); + + return convertFromEntitiesInBatch(List.of(savedEntity)).getFirst(); + } + + public List save(List request) + throws BrAPIServerException { + var entities = convertToEntitiesInBatch(request); + var savedEntities = observationUnitLevelNameRepository.saveAll(entities); + return convertFromEntitiesInBatch(savedEntities); + } + + public void deleteObservationLevelName(String observationLevelNameDbId) { + observationUnitLevelNameRepository.deleteById(UUID.fromString(observationLevelNameDbId)); + } // Single Program use case public List findObservationUnitLevelNames(String programDbId) throws BrAPIServerException { - return findObservationUnitLevelNames(List.of(programDbId)); + return findObservationUnitLevelNames(List.of(programDbId), null); } - // Finds observation unit level names by programDbIds, or if not available, globally (no associated program) - private List findObservationUnitLevelNames(List programDbIds) + public List findObservationUnitLevelNames(String programDbId, + Boolean all) + throws BrAPIServerException { + + if (programDbId == null) { + return findObservationUnitLevelNames(Collections.emptyList(), + all); + } else { + return findObservationUnitLevelNames(List.of(programDbId), + all); + } + } + + public List findObservationUnitLevelNames(List programDbIds) + throws BrAPIServerException { + return findObservationUnitLevelNames(programDbIds, null); + } + + // Finds observation unit level names by programDbIds, or if not available, globally (no associated program). + // If all is true, find every observation unit level name in the system. + private List findObservationUnitLevelNames(List programDbIds, + Boolean all) throws BrAPIServerException { List foundOULevelNames = new ArrayList<>(); + if (all != null && all) { + return observationUnitLevelNameRepository.findAllObservationUnitLevelNames(); + } + if (programDbIds != null && !programDbIds.isEmpty()) { // First look up all level names related to submitted programs if available foundOULevelNames = observationUnitLevelNameRepository.findObservationUnitLevelNamesByProgram(programDbIds); From 0c6878ac2bf4771d1644347cdc8eaa5489a0529a Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 27 May 2025 18:20:55 -0400 Subject: [PATCH 10/34] Refactor Repo configuration and structure to allow for two base repos --- .../BrapiTestServerAuthConfig.java | 3 ++- .../{ => config}/BrapiTestServerConfig.java | 11 +-------- .../repos/BaseEntitiesConfig.java} | 10 +++++--- .../config/repos/PrimaryEntitiesConfig.java | 23 +++++++++++++++++++ .../baseEntities/BaseEntityRepository.java | 10 ++++++++ .../ObservationUnitLevelNameRepository.java | 12 ++-------- .../nonBaseRepos/BaseEntityRepository.java | 4 ---- .../BrAPIRepository.java | 3 +-- .../BrAPIRepositoryImpl.java | 4 +--- .../SearchRepository.java | 2 +- .../core/BatchDeleteRepository.java | 4 ++-- .../core/CropRepository.java | 4 ++-- .../core/ListRepository.java | 4 ++-- .../core/LocationRepository.java | 4 ++-- .../core/PeopleRepository.java | 4 ++-- .../core/ProgramRepository.java | 4 ++-- .../core/SeasonRepository.java | 4 ++-- .../core/StudyRepository.java | 4 ++-- .../core/TraitRepository.java | 4 ++-- .../core/TrialRepository.java | 4 ++-- .../geno/CallRepository.java | 4 ++-- .../geno/CallSetRepository.java | 4 ++-- .../geno/GenomeMapRepository.java | 4 ++-- .../geno/LinkageGroupRepository.java | 4 ++-- .../geno/MarkerPositionRepository.java | 4 ++-- .../geno/PlateRepository.java | 4 ++-- .../geno/ReferenceBaseRepository.java | 4 ++-- .../geno/ReferenceRepository.java | 4 ++-- .../geno/ReferenceSetRepository.java | 4 ++-- .../geno/SampleRepository.java | 4 ++-- .../geno/VariantRepository.java | 4 ++-- .../geno/VariantSetRepository.java | 4 ++-- .../geno/VendorOrderRepository.java | 4 ++-- .../geno/VendorPlateRepository.java | 4 ++-- .../geno/VendorSpecRepository.java | 4 ++-- .../germ/BreedingMethodRepository.java | 4 ++-- .../germ/CrossRepository.java | 4 ++-- .../germ/CrossingProjectRepository.java | 4 ++-- ...ermplasmAttributeDefinitionRepository.java | 4 ++-- .../GermplasmAttributeValueRepository.java | 4 ++-- .../germ/GermplasmDonorRepository.java | 4 ++-- .../germ/GermplasmRepository.java | 4 ++-- .../germ/GermplasmRepositoryImpl.java | 2 +- .../germ/PedigreeEdgeRepository.java | 4 ++-- .../germ/PedigreeRepository.java | 4 ++-- .../germ/PedigreeRepositoryCustom.java | 2 +- .../germ/PedigreeRepositoryCustomImpl.java | 2 +- .../germ/SeedLotRepository.java | 4 ++-- .../germ/SeedLotTransactionRepository.java | 4 ++-- .../pheno/EventRepository.java | 4 ++-- .../pheno/ImageRepository.java | 4 ++-- .../pheno/MethodRepository.java | 4 ++-- .../pheno/ObservationRepository.java | 4 ++-- .../pheno/ObservationUnitRepository.java | 4 ++-- .../pheno/ObservationVariableRepository.java | 4 ++-- .../pheno/OntologyRepository.java | 4 ++-- .../pheno/ScaleRepository.java | 4 ++-- .../service/SearchService.java | 2 +- .../service/core/BatchService.java | 2 +- .../service/core/CropService.java | 2 +- .../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 | 4 ++-- .../service/geno/ReferenceSetService.java | 2 +- .../service/geno/SampleService.java | 2 +- .../service/geno/VariantService.java | 2 +- .../service/geno/VariantSetService.java | 2 +- .../service/geno/VendorSampleService.java | 8 +++---- .../service/germ/BreedingMethodService.java | 2 +- .../service/germ/CrossParentService.java | 4 ++-- .../service/germ/CrossService.java | 2 +- .../service/germ/CrossingProjectService.java | 3 +-- .../germ/GermplasmAttributeService.java | 2 +- .../germ/GermplasmAttributeValueService.java | 2 +- .../service/germ/GermplasmService.java | 4 ++-- .../service/germ/PedigreeService.java | 4 ++-- .../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 +- .../ObservationUnitLevelNameService.java | 2 +- .../service/pheno/ObservationUnitService.java | 2 +- .../pheno/ObservationVariableService.java | 8 +++---- .../service/pheno/OntologyService.java | 2 +- .../service/pheno/ScaleService.java | 2 +- .../service/pheno/TraitService.java | 2 +- 97 files changed, 190 insertions(+), 179 deletions(-) rename src/main/java/org/brapi/test/BrAPITestServer/{auth => config}/BrapiTestServerAuthConfig.java (94%) rename src/main/java/org/brapi/test/BrAPITestServer/{ => config}/BrapiTestServerConfig.java (81%) rename src/main/java/org/brapi/test/BrAPITestServer/{NonBaseRepoConfig.java => config/repos/BaseEntitiesConfig.java} (68%) create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java rename src/main/java/org/brapi/test/BrAPITestServer/repository/{nonBaseRepos => baseEntities}/ObservationUnitLevelNameRepository.java (63%) delete mode 100644 src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/BrAPIRepository.java (92%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/BrAPIRepositoryImpl.java (98%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/SearchRepository.java (73%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/BatchDeleteRepository.java (55%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/CropRepository.java (73%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/ListRepository.java (85%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/LocationRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/PeopleRepository.java (84%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/ProgramRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/SeasonRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/StudyRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/TraitRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/core/TrialRepository.java (91%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/CallRepository.java (52%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/CallSetRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/GenomeMapRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/LinkageGroupRepository.java (55%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/MarkerPositionRepository.java (56%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/PlateRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/ReferenceBaseRepository.java (73%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/ReferenceRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/ReferenceSetRepository.java (56%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/SampleRepository.java (85%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/VariantRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/VariantSetRepository.java (55%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/VendorOrderRepository.java (71%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/VendorPlateRepository.java (58%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/geno/VendorSpecRepository.java (56%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/BreedingMethodRepository.java (56%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/CrossRepository.java (61%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/CrossingProjectRepository.java (57%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/GermplasmAttributeDefinitionRepository.java (61%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/GermplasmAttributeValueRepository.java (59%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/GermplasmDonorRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/GermplasmRepository.java (87%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/GermplasmRepositoryImpl.java (97%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/PedigreeEdgeRepository.java (56%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/PedigreeRepository.java (72%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/PedigreeRepositoryCustom.java (76%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/PedigreeRepositoryCustomImpl.java (93%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/SeedLotRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/germ/SeedLotTransactionRepository.java (58%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/EventRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/ImageRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/MethodRepository.java (53%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/ObservationRepository.java (78%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/ObservationUnitRepository.java (85%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/ObservationVariableRepository.java (58%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/OntologyRepository.java (54%) rename src/main/java/org/brapi/test/BrAPITestServer/repository/{ => primaryEntities}/pheno/ScaleRepository.java (53%) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java similarity index 94% rename from src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java rename to src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java index 1370f964..0584309b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java @@ -1,5 +1,6 @@ -package org.brapi.test.BrAPITestServer.auth; +package org.brapi.test.BrAPITestServer.config; +import org.brapi.test.BrAPITestServer.auth.BrapiTestServerJWTAuthFilter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java similarity index 81% rename from src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java rename to src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java index 4422ac1e..15019662 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java @@ -1,6 +1,5 @@ -package org.brapi.test.BrAPITestServer; +package org.brapi.test.BrAPITestServer.config; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepositoryImpl; import org.brapi.test.BrAPITestServer.serializer.CustomDateSerializer; import org.brapi.test.BrAPITestServer.serializer.CustomGeoJSONDeserializer; import org.brapi.test.BrAPITestServer.serializer.CustomGermplasmStorageTypesDeserializer; @@ -9,7 +8,6 @@ import org.brapi.test.BrAPITestServer.serializer.CustomTimeStampSerializer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.*; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -20,13 +18,6 @@ import java.time.OffsetDateTime; @Configuration -@EnableJpaRepositories( - basePackages = "org.brapi.test.BrAPITestServer.repository", - excludeFilters = @ComponentScan.Filter( - type = FilterType.REGEX, - pattern = "org\\.brapi\\.test\\.BrAPITestServer\\.repository\\.nonBaseRepos\\..*" - ), - repositoryBaseClass = BrAPIRepositoryImpl.class) @PropertySource(value = "classpath:properties/application.properties") public class BrapiTestServerConfig { @Bean diff --git a/src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java similarity index 68% rename from src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java rename to src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java index 213a32aa..604e5ded 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/NonBaseRepoConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer; +package org.brapi.test.BrAPITestServer.config.repos; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.springframework.context.annotation.ComponentScan; @@ -6,9 +6,13 @@ import org.springframework.context.annotation.FilterType; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +/** + * Configures the repos of entities derived directly from BrAPIBaseEntity so + * basic JPA repos can be implemented to save and delete them. + */ @Configuration @EnableJpaRepositories( - basePackages = "org.brapi.test.BrAPITestServer.repository.nonBaseRepos", + basePackages = "org.brapi.test.BrAPITestServer.repository.baseEntities", excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BrAPIPrimaryEntity.class)) -public class NonBaseRepoConfig { +public class BaseEntitiesConfig { } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java new file mode 100644 index 00000000..a5511e8b --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java @@ -0,0 +1,23 @@ +package org.brapi.test.BrAPITestServer.config.repos; + +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepositoryImpl; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +/** + * Configures the repos of entities derived directly from BrAPIPrimaryEntity so + * the custom repository implementation can be used to save entities, additional info, and external references + * the right way. + */ +@Configuration +@EnableJpaRepositories( + basePackages = "org.brapi.test.BrAPITestServer.repository.primaryEntities", + excludeFilters = @ComponentScan.Filter( + type = FilterType.REGEX, + pattern = "org\\.brapi\\.test\\.BrAPITestServer\\.repository\\.baseEntities\\..*" + ), + repositoryBaseClass = BrAPIRepositoryImpl.class) +public class PrimaryEntitiesConfig { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java new file mode 100644 index 00000000..1a5c327d --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java @@ -0,0 +1,10 @@ +package org.brapi.test.BrAPITestServer.repository.baseEntities; + +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.io.Serializable; + +public interface BaseEntityRepository + extends JpaRepository { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java similarity index 63% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java index 26ba4d4a..6a46ea90 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/ObservationUnitLevelNameRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java @@ -1,15 +1,14 @@ -package org.brapi.test.BrAPITestServer.repository.nonBaseRepos; +package org.brapi.test.BrAPITestServer.repository.baseEntities; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; import java.util.UUID; -public interface ObservationUnitLevelNameRepository extends JpaRepository { +public interface ObservationUnitLevelNameRepository extends BaseEntityRepository { @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + @@ -22,12 +21,5 @@ public interface ObservationUnitLevelNameRepository extends JpaRepository findAllObservationUnitLevelNames(); -// -// @Modifying -// @Query("DELETE FROM ObservationUnitLevelNameEntity WHERE id = :levelNameDbId") -// void deleteObservationUnitLevelNameById(@Param("levelNameDbId") String levelNameDbId); -// -// @Modifying -// @Query("INSERT INTO ObservationUnitLevelNameEntity ") } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java deleted file mode 100644 index 97c89350..00000000 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/nonBaseRepos/BaseEntityRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.brapi.test.BrAPITestServer.repository.nonBaseRepos; - -public class BaseEntityRepository { -} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java similarity index 92% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java index 8092235d..dd76d8f4 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import java.io.Serializable; import java.util.List; @@ -11,7 +11,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.NoRepositoryBean; @NoRepositoryBean diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java similarity index 98% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java index b14978ab..583a28cf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import java.io.Serializable; import java.util.ArrayList; @@ -14,13 +14,11 @@ import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; import org.brapi.test.BrAPITestServer.model.entity.ExternalReferenceEntity; -import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.SecurityUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java index 25245f8a..691ea18d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java index 65ab887e..99acb4a5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java index 445cfed4..0096bbb5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java index a51d9372..be896659 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.ListEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java index 0413a18b..b73263c3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.LocationEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java similarity index 84% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java index 80f27e63..a5d7a2a0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java @@ -1,10 +1,10 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.repository.query.Param; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java index 9f6eafb8..7dbb78ff 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java index e2705d48..87d1bb25 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java index 5baf625d..b11c113a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java index 602b0cef..f5c923f1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.pheno.TraitEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java similarity index 91% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java index 6a88539b..ed71c194 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java @@ -1,11 +1,11 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java similarity index 52% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java index 8a073a21..1f6e3f96 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.CallEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java index 8536ba44..0b29f7c2 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.CallSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java index 09ee6379..1bd8e0fc 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.GenomeMapEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java index 93c7c799..457b9568 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.LinkageGroupEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java index 80524003..8bb9123a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.MarkerPositionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java index 85f54803..3a26c250 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java index 0e496234..5e0a1699 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceBasesPageEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java index 4ec3032a..90d6fc30 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java index 0ca5ed0e..22e74738 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java index d689a6a3..8907b4f6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.SampleEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java index 0a6d6ec5..f77030f3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java index c60a73ee..1520ecd6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java similarity index 71% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java index a3aee996..06804e49 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java @@ -1,9 +1,9 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorOrderEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java index 18d6fb6b..165b3586 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorPlateSubmissionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java index d9955b73..8c1f295c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorSpecEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java index 0d47cd1f..4ec11058 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.BreedingMethodEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java similarity index 61% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java index b853184d..23372b7f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java similarity index 57% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java index 1d623e6d..582c05f3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java similarity index 61% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java index c2c40ffe..b8e68ccd 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeDefinitionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java similarity index 59% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java index 5ee8a483..90ebd251 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeValueEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java index 6d2c6083..8717d0a6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.DonorEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java similarity index 87% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java index bdb8dc69..d5720e8b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java similarity index 97% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java index d0b9475e..fa426f22 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java index e5199ddd..c716a2ed 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeEdgeEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java similarity index 72% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java index b9dd8e41..0dc5da86 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java @@ -1,10 +1,10 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; import java.util.UUID; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeNodeEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; public interface PedigreeRepository extends BrAPIRepository, PedigreeRepositoryCustom { public List findByGermplasm_Id(UUID germplasmDbId); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java similarity index 76% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java index 43ae5569..a53c81b7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java similarity index 93% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java index afef6d21..d67f41a5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java index a153d3b8..ae5e7f6a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java index 68396c56..755a1ad7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotTransactionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java index 0b4972f4..5025a405 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.EventEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java index bb25b47e..96838ff8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ImageEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java index 03ea81fd..d9048265 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.MethodEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java similarity index 78% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java index 2c33e4f9..1b19ac67 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import java.util.List; import java.util.UUID; @@ -6,7 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; public interface ObservationRepository extends BrAPIRepository { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java index 9f01082a..839b628c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.NativeQuery; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java index 62476ddb..07fe0483 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java index bf8c73d6..0dacc5de 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java index 38f2dbc8..a30d8dff 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java index 88d87843..fb44a723 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity.SearchRequestTypes; -import org.brapi.test.BrAPITestServer.repository.SearchRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.SearchRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java index 3b4464b0..1df37d48 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteEntity; import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteItemEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.BatchDeleteRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.BatchDeleteRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java index 3932e698..3fb535a7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java @@ -6,7 +6,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; -import org.brapi.test.BrAPITestServer.repository.core.CropRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.CropRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; 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 eed8459e..dab83121 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 @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.ListEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ListItemEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.ListRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.ListRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 a856f055..d6f28e18 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.LocationEntity; -import org.brapi.test.BrAPITestServer.repository.core.LocationRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.LocationRepository; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 762705c0..642b25c8 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 @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.PeopleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.PeopleRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; 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 cbc516c3..720f731b 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; -import org.brapi.test.BrAPITestServer.repository.core.ProgramRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.ProgramRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 bf464b25..cc0d0b7a 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; -import org.brapi.test.BrAPITestServer.repository.core.SeasonRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.SeasonRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.beans.factory.annotation.Autowired; 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 2429b249..ea001dfe 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 @@ -18,7 +18,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyLastUpdateEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.core.StudyRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.StudyRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 a3a83018..97c904a2 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 @@ -15,7 +15,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PublicationEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; -import org.brapi.test.BrAPITestServer.repository.core.TrialRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TrialRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 3ca47af3..cc973ec8 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 @@ -10,7 +10,7 @@ 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.repository.geno.CallRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.CallRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; 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 4049bf43..c259db52 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 @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.CallSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.CallSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.CallSetRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 f9a872df..14ffd3bc 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 @@ -8,8 +8,8 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.GenomeMapEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.LinkageGroupEntity; -import org.brapi.test.BrAPITestServer.repository.geno.GenomeMapRepository; -import org.brapi.test.BrAPITestServer.repository.geno.LinkageGroupRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.GenomeMapRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.LinkageGroupRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 508715f1..ce4d3187 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 @@ -4,7 +4,7 @@ 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.repository.primaryEntities.geno.MarkerPositionRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; 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 f83c8236..83bc9dcf 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 @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; -import org.brapi.test.BrAPITestServer.repository.geno.PlateRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.PlateRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 73586995..d1384e54 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 @@ -13,8 +13,8 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceBasesPageEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceBaseRepository; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceBaseRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 f6b9e55e..a4d37c41 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 @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceSetRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 8afbb551..2910b5cc 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 @@ -16,7 +16,7 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.SampleEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.geno.SampleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.SampleRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 aabd107d..55fdd89a 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 @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VariantRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VariantRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 869bc55b..8c7b1d89 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 @@ -11,7 +11,7 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetAnalysisEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetAvailableFormatEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VariantSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VariantSetRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java index b85c02bd..3d6c9e1c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java @@ -4,7 +4,6 @@ import java.util.*; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import jakarta.validation.Valid; @@ -15,9 +14,9 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorOrderEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorPlateSubmissionEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorSpecEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VendorOrderRepository; -import org.brapi.test.BrAPITestServer.repository.geno.VendorPlateRepository; -import org.brapi.test.BrAPITestServer.repository.geno.VendorSpecRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorOrderRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorPlateRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorSpecRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -26,7 +25,6 @@ import org.springframework.stereotype.Service; import io.swagger.model.Metadata; -import io.swagger.model.OntologyReference; import io.swagger.model.geno.Measurement; import io.swagger.model.geno.VendorContact; import io.swagger.model.geno.VendorOrder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java index 509efe59..190eafca 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.BreedingMethodEntity; -import org.brapi.test.BrAPITestServer.repository.germ.BreedingMethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.BreedingMethodRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java index e09df763..6df6e7a6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java @@ -11,8 +11,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationUnitRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; 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 6aa405cd..cffa532a 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossPollinationEventEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.germ.CrossRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.CrossRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 e647ab30..6aecfce6 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 @@ -2,14 +2,13 @@ import java.util.*; -import io.swagger.model.IndexPagination; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.germ.CrossingProjectRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.CrossingProjectRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 174b8c8b..f96b8e50 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 @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeDefinitionEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmAttributeDefinitionRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmAttributeDefinitionRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.pheno.ObservationVariableService; 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 7b1da280..d3824689 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeValueEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmAttributeValueRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmAttributeValueRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 2bb9358b..b742543b 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 @@ -15,8 +15,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.*; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmInstituteEntity.InstituteTypeEnum; import org.brapi.test.BrAPITestServer.model.entity.pheno.TaxonEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmDonorRepository; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmDonorRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; 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 011087ae..5bdd847c 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 @@ -14,8 +14,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeEdgeEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeNodeEntity; -import org.brapi.test.BrAPITestServer.repository.germ.PedigreeEdgeRepository; -import org.brapi.test.BrAPITestServer.repository.germ.PedigreeRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.PedigreeEdgeRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.PedigreeRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 433b2e0a..eee19d98 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 @@ -14,8 +14,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotContentMixtureEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotTransactionEntity; -import org.brapi.test.BrAPITestServer.repository.germ.SeedLotRepository; -import org.brapi.test.BrAPITestServer.repository.germ.SeedLotTransactionRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.SeedLotRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.SeedLotTransactionRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 167d2b3a..a22024a7 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 @@ -6,7 +6,7 @@ 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.repository.primaryEntities.pheno.EventRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 b13e34d0..38d42b0e 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 @@ -13,7 +13,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ImageEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ImageRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ImageRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; 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 ba43ea1f..453d7cdb 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 @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.MethodEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.MethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.MethodRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 c805c616..e5d9f301 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 @@ -12,7 +12,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationRepository; import org.brapi.test.BrAPITestServer.service.*; import org.brapi.test.BrAPITestServer.service.core.SeasonService; import org.brapi.test.BrAPITestServer.service.core.StudyService; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index c994771e..44c56016 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -5,7 +5,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; -import org.brapi.test.BrAPITestServer.repository.nonBaseRepos.ObservationUnitLevelNameRepository; +import org.brapi.test.BrAPITestServer.repository.baseEntities.ObservationUnitLevelNameRepository; import org.brapi.test.BrAPITestServer.service.core.ProgramService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; 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 35aca08c..5dc86d8a 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 @@ -15,7 +15,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.*; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationUnitRepository; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; 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 c96e4d1f..42944b47 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 @@ -8,10 +8,10 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.*; -import org.brapi.test.BrAPITestServer.repository.core.TraitRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.MethodRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationVariableRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ScaleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TraitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.MethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationVariableRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ScaleRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java index a6746129..c9a1e193 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyReferenceEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyReferenceHolder; -import org.brapi.test.BrAPITestServer.repository.pheno.OntologyRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.OntologyRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.UpdateUtility; import org.springframework.beans.factory.annotation.Autowired; 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 84d92d37..34448bc3 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 @@ -11,7 +11,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleValidValueCategoryEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ScaleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ScaleRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; 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 9b8d101d..49bb92a3 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 @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.TraitEntity; -import org.brapi.test.BrAPITestServer.repository.core.TraitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TraitRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; From 47f5521926d04f99ab2a2c31799b06e1e793acc6 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 2 Jul 2025 16:43:10 -0400 Subject: [PATCH 11/34] Fix bug in PUT method, correct server info for obslvlnames --- .../service/core/ServerInfoService.java | 2 +- .../service/core/ServiceBuilder.java | 5 +++++ .../pheno/ObservationUnitLevelNameService.java | 13 ++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java index 682ffb58..d6ea6614 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java @@ -51,7 +51,7 @@ public static List buildServices(){ .setBase("observationunits").GET().POST().PUT().addPath("{observationUnitDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observations").GET().POST().PUT().addPath("{observationDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observationlevels").GET().build() - .setBase("observationlevelnames").GET().POST().addPath("{observationlevelnameDbId}").build() + .setBase("observationlevelnames").GET().POST().addPath("{observationlevelnameDbId}").PUT().DELETE().build() //GENOTYPING .setBase("calls").GET().withSearch() .setBase("callsets").GET().addPath("{callSetDbId}").GET().addPath("calls").GET().withSearch() diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java index 8a5cddd7..398006d3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java @@ -53,6 +53,11 @@ public ServiceBuilder GET() { return this; } + public ServiceBuilder DELETE() { + methods.add(MethodsEnum.DELETE); + return this; + } + public ServiceBuilder versions(VersionsEnum ... versions) { this.versions = Arrays.asList(versions); return this; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 44c56016..7e67d5bd 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -23,6 +23,9 @@ public class ObservationUnitLevelNameService { " names available. Please add via endpoint to attach level names to a program or define " + "without a program to make them globally accessible."; + private final static String GLOBAL_AND_PROGRAMMATIC_SET_MSG = "Both programDbId and global=true attributes are set. " + + "A level name cannot be both related to a program and be globally accessible. Choose one."; + @Autowired public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository, ProgramService programService) { @@ -138,12 +141,16 @@ public ObservationUnitHierarchyLevel update(String observationLevelNameDbId, entity.setLevelOrder(level.getLevelOrder()); } + if (level.getProgramDbId() != null && level.getGlobal() != null && level.getGlobal()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_AND_PROGRAMMATIC_SET_MSG); + } + if (level.getProgramDbId() != null) { var program = programService.getProgramEntity(level.getProgramDbId()); entity.setProgram(program); - } else if (level.getGlobal() == null || !level.getGlobal()) { - throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_NOT_SET_MSG); - } else { + } + + if (level.getGlobal() != null && level.getGlobal()) { // The user sent in a request to make this observation level name global for the system. // In the DB impl, this simply means it doesn't belong to any program. entity.setProgram(null); From 0ce831e170bc6633b3a28ed5393d045693a523eb Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 11 Jul 2025 12:23:17 -0400 Subject: [PATCH 12/34] Add unique index for level_name, program_id --- .../db/migration/V001.003__create_observation_level_name.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/db/migration/V001.003__create_observation_level_name.sql b/src/main/resources/db/migration/V001.003__create_observation_level_name.sql index 2947524d..2adff8e9 100644 --- a/src/main/resources/db/migration/V001.003__create_observation_level_name.sql +++ b/src/main/resources/db/migration/V001.003__create_observation_level_name.sql @@ -9,6 +9,8 @@ CREATE TABLE observation_unit_level_name ( CONSTRAINT observation_unit_level_name_program_fk FOREIGN KEY(program_id) REFERENCES program(id) ); +CREATE UNIQUE INDEX lvl_name_program_id_idx ON observation_unit_level_name (level_name, program_id); + -- Set legacy level names INSERT INTO observation_unit_level_name (level_name, level_order) VALUES From c12dc37d6c7c089ee09d55786a64ca84154fbcf7 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Mon, 21 Jul 2025 12:08:54 -0400 Subject: [PATCH 13/34] Ensure batch optimizations for obs and obs units is intact --- .../pheno/ObservationUnitHierarchyLevel.java | 4 +- .../ObservationUnitLevelNameRepository.java | 2 +- .../service/core/StudyService.java | 9 +- .../ObservationUnitLevelNameService.java | 167 +++++++- .../service/pheno/ObservationUnitService.java | 384 +++++++++++++----- 5 files changed, 452 insertions(+), 114 deletions(-) diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index c97ebfb6..12639a5b 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -93,7 +93,9 @@ public String toString() { sb.append(" levelName: ").append(toIndentedString(levelName)).append("\n"); sb.append(" levelOrder: ").append(toIndentedString(levelOrder)).append("\n"); - sb.append("}"); + sb.append(" levelNameDbId: ").append(toIndentedString(levelNameDbId)).append("\n"); + sb.append(" programDbId: ").append(toIndentedString(programDbId)).append("\n"); + sb.append(" programName: ").append(toIndentedString(programName)).append("\n"); return sb.toString(); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java index 6a46ea90..2aaa200f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java @@ -12,7 +12,7 @@ public interface ObservationUnitLevelNameRepository extends BaseEntityRepository @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + - "WHERE ouln.program IN :levelName") + "WHERE ouln.program.id IN :programIds") List findObservationUnitLevelNamesByProgram(@Param("programIds") List programDbIds); @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + 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 ea001dfe..a16a4c07 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 @@ -399,6 +399,12 @@ private ObservationUnitHierarchyLevel convertFromEntity(ObservationLevelEntity e level = new ObservationUnitHierarchyLevel(); level.setLevelName(entity.getLevelName().getLevelName()); level.setLevelOrder(entity.getLevelName().getLevelOrder()); + level.setLevelNameDbId(entity.getLevelName().getId().toString()); + + if (entity.getLevelName().getProgram() != null) { + level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); + level.setProgramName(entity.getLevelName().getProgram().getName()); + } } return level; } @@ -407,8 +413,7 @@ private List convertToEntity(List entities = new ArrayList<>(); - var submittedLevelNames = levels.stream().map(ObservationUnitHierarchyLevel::getLevelName).toList(); - var foundLevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + var foundLevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, levels); for (ObservationUnitHierarchyLevel level : levels) { var entity = new ObservationLevelEntity(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 7e67d5bd..47603bc8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -2,6 +2,7 @@ import io.swagger.model.pheno.ObservationLevelNewRequest; import io.swagger.model.pheno.ObservationUnitHierarchyLevel; +import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; @@ -26,6 +27,8 @@ public class ObservationUnitLevelNameService { private final static String GLOBAL_AND_PROGRAMMATIC_SET_MSG = "Both programDbId and global=true attributes are set. " + "A level name cannot be both related to a program and be globally accessible. Choose one."; + private final static String GLOBAL_KEY_FOR_FOUND_ENTITIES = "global"; + @Autowired public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository, ProgramService programService) { @@ -33,37 +36,145 @@ public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observ this.programService = programService; } - public Map retrieveAndVerifyObservationUnitLevelNames(String programDbId, - List submittedLevelNames) - throws BrAPIServerException { - return retrieveAndVerifyObservationUnitLevelNames(List.of(programDbId), submittedLevelNames); + /** + * Returns the verified level name entity. Should only be used with a list of size 1. + */ + public ObservationUnitLevelNameEntity verifyObservationUnitLevelName(String parentProgramDbId, + List submittedLevelName, + Map foundLevelEntitiesByDbId, + Map> foundLevelEntitiesGroupedByProgramId) + throws BrAPIServerException { + + return verifyObservationUnitLevelNames(parentProgramDbId, submittedLevelName, + foundLevelEntitiesByDbId, + foundLevelEntitiesGroupedByProgramId).get(submittedLevelName.getFirst().getLevelName()); + } + + public Map verifyObservationUnitLevelNames(String parentProgramDbId, + List submittedLevelNames, + Map foundLevelEntitiesByDbId, + Map> foundLevelEntitiesGroupedByProgramId) + throws BrAPIServerException { + + Map verifiedEntitiesByLevelName = new HashMap<>(); + List levelNamesNotFound = new ArrayList<>(); + + submittedLevelNames.forEach(sln -> { + + var verifiedLevelNamesCurrentSize = verifiedEntitiesByLevelName.size(); + + if (StringUtils.isNotBlank(sln.getLevelNameDbId()) && foundLevelEntitiesByDbId.containsKey(sln.getLevelNameDbId())) { + var entity = foundLevelEntitiesByDbId.get(sln.getLevelNameDbId()); + verifiedEntitiesByLevelName.put(entity.getLevelName(), entity); + } else if (StringUtils.isNotBlank(parentProgramDbId) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { + var entities = foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId); + + entities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } else if (StringUtils.isNotBlank(sln.getProgramDbId()) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { + var entities = foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()); + + entities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } + + if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size()) { + // All other ways of detecting the level name have failed so far, try the global ones as a last-ditch effort + var globalEntities = foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES); + + globalEntities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } + + if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size()) { + // This level name was not found. Add it to the list to notify user which level names are invalid. + levelNamesNotFound.add(sln); + } + }); + + if (!levelNamesNotFound.isEmpty()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("The following submitted level names were not found: [%s]. " + + " Please check that these level names exist in the DB by using the /observationlevelnames endpoints. If they do not exist, they can be added there.", + levelNamesNotFound)); + } + + return verifiedEntitiesByLevelName; + } + + /** + * This allows for all found level names to be successfully grouped by programId, because in the case of global level names, + * no programId is allowed. This placeholder returned in this function can be used for global level names. Useful for batching operations. + * + * Example usage: + * + * var foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + * .collect(Collectors.groupingBy(ouln -> + * Optional.ofNullable(ouln.getProgram()) + * .map(p -> p.getId().toString()) + * .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + */ + public String getGlobalKeyForFoundEntities() { + return GLOBAL_KEY_FOR_FOUND_ENTITIES; } - public Map retrieveAndVerifyObservationUnitLevelNames(List programDbIds, - List submittedLevelNames) + public Map retrieveAndVerifyObservationUnitLevelNames(String programDbIdOverride, + List submittedLevelNames) throws BrAPIServerException { - List foundOULevelNames = findObservationUnitLevelNames(programDbIds); + List programDbIds = new ArrayList<>(); + + if (programDbIdOverride != null && !programDbIdOverride.isBlank()) { + // If an programDbIdOverride was given, that means that the caller wants all submitted level names to be + // searched by a single programDbId. This programDbId is usually associated with a parent entity the level names + // belong to, like StudyEntity, ObservationUnitEntity, etc. + programDbIds.add(programDbIdOverride); + } else { + // If the override doesn't exist, use programDbIds from submitted level name object, if they are + // available at all. + programDbIds.addAll(submittedLevelNames.stream() + .map(ObservationUnitHierarchyLevel::getProgramDbId) + .filter(Objects::nonNull) + .toList()); + } + + List levelNameDbIds = submittedLevelNames.stream() + .map(ObservationUnitHierarchyLevel::getLevelNameDbId) + .filter(Objects::nonNull) + .toList(); + + if (levelNameDbIds.size() != submittedLevelNames.size()) { + // Only lookup by levelNameDbIds if every submitted level name has one. + levelNameDbIds = new ArrayList<>(); + } + + List foundOULevelNames = findObservationUnitLevelNames(programDbIds, levelNameDbIds); var levelNameEntitiesByName = foundOULevelNames.stream() - .collect(Collectors.toMap(ObservationUnitLevelNameEntity::getLevelName, e -> e)); + .collect(Collectors.toMap(ouln -> ouln.getLevelName().toLowerCase(), e -> e)); + var submittedNames = submittedLevelNames.stream().map(ouhl -> ouhl.getLevelName().toLowerCase()).toList(); // Now that we have found all the available level names, verify that all submitted level names are valid level names - // in the DB. If they aren't throw an error indicating the client must fix this. - for (String submittedLevelName : submittedLevelNames) { - if (!levelNameEntitiesByName.containsKey(submittedLevelName)) { + // in the DB. + for (String submittedLevelName : submittedNames) { + if (!levelNameEntitiesByName.containsKey(submittedLevelName.toLowerCase())) { throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Submitted observation unit level name [%s] does not exist " + "globally or for the following submitted programs [%s]. This can be fixed " + "by adding the level name using the POST endpoint brapi/[version-number]/observationunitlevelnames, " + "or by using a level name already in the system.", submittedLevelName, - programDbIds.toString())); + programDbIds)); } } // Now that every submitted level name has been verified, return a map of the retrieved submitted levels. - return submittedLevelNames.stream() + return submittedNames.stream() .collect(Collectors.toMap(ln -> ln, levelNameEntitiesByName::get)); } @@ -184,21 +295,25 @@ public List findObservationUnitLevelNames(String if (programDbId == null) { return findObservationUnitLevelNames(Collections.emptyList(), + Collections.emptyList(), all); } else { return findObservationUnitLevelNames(List.of(programDbId), + Collections.emptyList(), all); } } - public List findObservationUnitLevelNames(List programDbIds) + public List findObservationUnitLevelNames(List programDbIds, + List levelNameDbIds) throws BrAPIServerException { - return findObservationUnitLevelNames(programDbIds, null); + return findObservationUnitLevelNames(programDbIds, levelNameDbIds, null); } // Finds observation unit level names by programDbIds, or if not available, globally (no associated program). // If all is true, find every observation unit level name in the system. private List findObservationUnitLevelNames(List programDbIds, + List levelNameDbIds, Boolean all) throws BrAPIServerException { List foundOULevelNames = new ArrayList<>(); @@ -207,6 +322,28 @@ private List findObservationUnitLevelNames(List< return observationUnitLevelNameRepository.findAllObservationUnitLevelNames(); } + if (levelNameDbIds != null && !levelNameDbIds.isEmpty()) { + + var result = observationUnitLevelNameRepository.findAllById(levelNameDbIds.stream().map(UUID::fromString).toList()); + + if (result.size() != levelNameDbIds.size()) { + + var foundDbIds = result.stream() + .map(ouln -> ouln.getId().toString()) + .toList(); + var levelNameDbIdsNotFound = levelNameDbIds.stream() + .filter(lnId -> !foundDbIds.contains(lnId)) + .toList(); + + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, + String.format("Level name DB Ids supplied [%s] were not found in the database. " + + "Utilize the /observationlevelnames GET method to find the level name DB Ids you would like to search, " + + "or forgo supplying level name dbIds and try looking up on a programDbId.", levelNameDbIdsNotFound)); + } + + return result; + } + if (programDbIds != null && !programDbIds.isEmpty()) { // First look up all level names related to submitted programs if available foundOULevelNames = observationUnitLevelNameRepository.findObservationUnitLevelNamesByProgram(programDbIds); 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 5dc86d8a..aee19950 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 @@ -12,7 +12,6 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; -import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.*; import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationUnitRepository; @@ -33,6 +32,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.*; import java.util.Map.Entry; @@ -353,6 +353,46 @@ public ObservationUnitEntity getObservationUnitEntity(String observationUnitDbId return observationUnit; } + public Map getObservationUnitEntities(Map oURequestByDbId, HttpStatus errorStatus) + throws BrAPIServerException { + + if (CollectionUtils.isEmpty(oURequestByDbId)) { + throw new BrAPIServerDbIdNotFoundException("observationUnit", "null", errorStatus); + } + + var submittedDbIds = oURequestByDbId.keySet().stream().toList(); + + var searchRq = new ObservationUnitSearchRequest(); + searchRq.observationUnitDbIds(submittedDbIds); + + var metadata = new Metadata(); + var pagination = new IndexPagination(); + + pagination.setPageSize(submittedDbIds.size()); + metadata.setPagination(pagination); + + var foundEntities = findObservationUnitEntities(searchRq, metadata); + + var foundEntitiesByDbId = foundEntities.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var submittedIdsNotFound = new HashSet<>(submittedDbIds); + + submittedIdsNotFound.removeAll(foundEntitiesByDbId.keySet()); + + if (!submittedIdsNotFound.isEmpty()) { + throw new BrAPIServerDbIdNotFoundException(String.format("The following submitted observation unit db ids were not found: [%s]", submittedIdsNotFound), errorStatus); + } + + var result = new HashMap(); + + for (String dbId : foundEntitiesByDbId.keySet()) { + result.put(foundEntitiesByDbId.get(dbId), oURequestByDbId.get(dbId)); + } + + return result; + } + public List saveObservationUnits(@Valid List requests) throws BrAPIServerException { var toSave = createEntitiesInBatch(requests); @@ -365,21 +405,23 @@ public List saveObservationUnits(@Valid List updateObservationUnits(@Valid Map requests) throws BrAPIServerException { - List savedObservationUnits = new ArrayList<>(); - for (Entry entry : requests.entrySet()) { - ObservationUnit saved = updateObservationUnit(entry.getKey(), entry.getValue()); - savedObservationUnits.add(saved); - } + var foundOUEntities = getObservationUnitEntities(requests, HttpStatus.BAD_REQUEST); + + List toSave = updateEntitiesInBatch(foundOUEntities); - return savedObservationUnits; + List saved = observationUnitRepository.saveAll(toSave); + + return saved.stream() + .map(this::convertFromEntity) + .toList(); } public ObservationUnit updateObservationUnit(String observationUnitDbId, @Valid ObservationUnitNewRequest request) throws BrAPIServerException { - ObservationUnitEntity entity = getObservationUnitEntity(observationUnitDbId, HttpStatus.NOT_FOUND); - updateEntity(entity, request); - ObservationUnitEntity savedEntity = observationUnitRepository.save(entity); + ObservationUnitEntity entityToUpdate = getObservationUnitEntity(observationUnitDbId, HttpStatus.NOT_FOUND); + updateEntity(entityToUpdate, request); + ObservationUnitEntity savedEntity = observationUnitRepository.save(entityToUpdate); return convertFromEntity(savedEntity); } @@ -517,12 +559,9 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity position = new ObservationUnitPosition(); position.setEntryType(entity.getEntryType()); position.setGeoCoordinates(GeoJSONUtility.convertFromEntity(entity.getGeoCoordinates())); - ObservationUnitLevel level = new ObservationUnitLevel(); - level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName().getLevelName()); - level.setLevelOrder(entity.getLevelName().getLevelOrder()); - position.setObservationLevel(level); + position.setObservationLevel(convertFromEntity(entity.getLevelName(), entity.getLevelCode())); if (entity.getObservationLevelRelationships() != null) { + position.setObservationLevelRelationships(entity.getObservationLevelRelationships().stream() .map(rel -> this.convertFromEntity(rel, ouDbId)).collect(Collectors.toList())); } @@ -534,6 +573,25 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity return position; } + private ObservationUnitLevel convertFromEntity(ObservationUnitLevelNameEntity entity, String levelCode) { + ObservationUnitLevel level = null; + + if (entity.getLevelName() != null) { + level = new ObservationUnitLevel(); + level.setLevelCode(levelCode); + level.setLevelName(entity.getLevelName()); + level.setLevelOrder(entity.getLevelOrder()); + level.setLevelNameDbId(entity.getId().toString()); + // If the program is null, then this is a globally scoped level name. + if (entity.getProgram() != null) { + level.setProgramDbId(entity.getProgram().getId().toString()); + level.setProgramName(entity.getProgram().getName()); + } + } + + return level; + } + private ObservationTreatment convertFromEntity(TreatmentEntity entity) { ObservationTreatment treatment = new ObservationTreatment(); treatment.setFactor(entity.getFactor()); @@ -546,108 +604,231 @@ private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelR level.setLevelCode(entity.getLevelCode()); level.setLevelName(entity.getLevelName().getLevelName()); level.setLevelOrder(entity.getLevelName().getLevelOrder()); - if (ouDbId != null) + level.setLevelNameDbId(entity.getLevelName().getId().toString()); + + if (ouDbId != null) { level.setObservationUnitDbId(ouDbId); + } + + // If the program is null, this level name is global. + if (entity.getLevelName().getProgram() != null) { + level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); + level.setProgramName(entity.getLevelName().getProgram().getName()); + } + + return level; } private ObservationUnitEntity updateEntity(ObservationUnitEntity entity, ObservationUnitNewRequest unit) + throws BrAPIServerException { + return updateEntitiesInBatch(Map.of(entity, unit)).getFirst(); + } + + private List updateEntitiesInBatch(Map entitiesByRq) throws BrAPIServerException { - UpdateUtility.updateEntity(unit, entity); - - if (unit.getGermplasmDbId() != null) { - GermplasmEntity germplasm = germplasmService.getGermplasmEntity(unit.getGermplasmDbId()); - entity.setGermplasm(germplasm); - } - if (unit.getCrossDbId() != null) { - CrossEntity cross = crossService.getCrossEntity(unit.getCrossDbId(), false); - entity.setCross(cross); - } - if (unit.getObservationUnitName() != null) - entity.setObservationUnitName(unit.getObservationUnitName()); - if (unit.getObservationUnitPUI() != null) - entity.setObservationUnitPUI(unit.getObservationUnitPUI()); - if (unit.getObservationUnitPosition() != null) { - if (entity.getPosition() == null) - entity.setPosition(new ObservationUnitPositionEntity()); - ObservationUnitPositionEntity position = entity.getPosition(); - updateEntity(position, unit.getObservationUnitPosition(), entity); - position.setObservationUnit(entity); - entity.setPosition(position); - } - if (unit.getSeedLotDbId() != null) { - SeedLotEntity seedLot = seedLotService.getSeedLotEntity(unit.getSeedLotDbId()); - entity.setSeedLot(seedLot); - } - if (unit.getTreatments() != null) - entity.setTreatments(unit.getTreatments().stream().map(t -> { - TreatmentEntity e = new TreatmentEntity(); - e.setFactor(t.getFactor()); - e.setModality(t.getModality()); - e.setObservationUnit(entity); - return e; - }).collect(Collectors.toList())); - - if (unit.getStudyDbId() != null) { - StudyEntity study = studyService.getStudyEntity(unit.getStudyDbId()); - entity.setStudy(study); - } else if (unit.getTrialDbId() != null) { - TrialEntity trial = trialService.getTrialEntity(unit.getTrialDbId()); - entity.setTrial(trial); - } else if (unit.getProgramDbId() != null) { - ProgramEntity program = programService.getProgramEntity(unit.getProgramDbId()); - entity.setProgram(program); - } - - return entity; - } - - private void updateEntity(ObservationUnitPositionEntity entity, - ObservationUnitPosition position, - ObservationUnitEntity ouEntity) throws BrAPIServerException { + + var oURqs = entitiesByRq.values(); + + // Gather all IDs we want to look up in a bulk lookup. + var germplasmIds = oURqs.stream() + .map(ObservationUnitNewRequest::getGermplasmDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var crossIds = oURqs.stream() + .map(ObservationUnitNewRequest::getCrossDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var seedLotIds = oURqs.stream() + .map(ObservationUnitNewRequest::getSeedLotDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var studyIds = oURqs.stream() + .map(ObservationUnitNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var trialIds = oURqs.stream() + .map(ObservationUnitNewRequest::getTrialDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + var programIds = oURqs.stream() + .map(ObservationUnitNewRequest::getProgramDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + // Now lookup all the IDs in bulk, creating a Map of the ID to the entity so the entities are easily + // retrievable by IDs in the bulk creating of entities later. + var foundGermsById = germplasmService.findByIds(germplasmIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundCrossesById = crossService.findByIds(crossIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundSeedLotsById = seedLotService.findByIds(seedLotIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundTrialsById = trialService.findByIds(trialIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var foundProgramsById = programService.findByIds(programIds) + .stream() + .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + + var observationUnitLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(null, true); + + var foundLevelNamesByDbId = observationUnitLevelNames.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + .collect(Collectors.groupingBy(ouln -> + Optional.ofNullable(ouln.getProgram()) + .map(p -> p.getId().toString()) + .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + + List result = new ArrayList<>(); + + for (Entry entry : entitiesByRq.entrySet()) { + + var entity = entry.getKey(); + var oU = entry.getValue(); + + UpdateUtility.updateEntity(entry.getValue(), entry.getKey()); + + if (oU.getGermplasmDbId() != null) { + entity.setGermplasm(foundGermsById.get(UUID.fromString(oU.getGermplasmDbId()))); + } + if (oU.getCrossDbId() != null) { + CrossEntity cross = foundCrossesById.get(UUID.fromString(oU.getCrossDbId())); + + if (!cross.getPlanned()) { + entity.setCross(cross); + } + } + + if (oU.getObservationUnitName() != null) + entity.setObservationUnitName(oU.getObservationUnitName()); + if (oU.getObservationUnitPUI() != null) + entity.setObservationUnitPUI(oU.getObservationUnitPUI()); + if (oU.getSeedLotDbId() != null) { + SeedLotEntity seedLot = foundSeedLotsById.get(UUID.fromString(oU.getSeedLotDbId())); + entity.setSeedLot(seedLot); + } + if (oU.getTreatments() != null) + entity.setTreatments(oU.getTreatments().stream().map(t -> { + TreatmentEntity e = new TreatmentEntity(); + e.setFactor(t.getFactor()); + e.setModality(t.getModality()); + e.setObservationUnit(entity); + return e; + }).collect(Collectors.toList())); + + if (oU.getStudyDbId() != null) { + StudyEntity study = foundStudiesById.get(UUID.fromString(oU.getStudyDbId())); + entity.setStudy(study); + } else if (oU.getTrialDbId() != null) { + TrialEntity trial = foundTrialsById.get(UUID.fromString(oU.getTrialDbId())); + entity.setTrial(trial); + } else if (oU.getProgramDbId() != null) { + ProgramEntity program = foundProgramsById.get(UUID.fromString(oU.getProgramDbId())); + entity.setProgram(program); + } + + if (oU.getObservationUnitPosition() != null) { + if (entity.getPosition() == null) + entity.setPosition(new ObservationUnitPositionEntity()); + ObservationUnitPositionEntity position = entity.getPosition(); + updateOUPosition(oU.getObservationUnitPosition(), + entity, + foundLevelNamesByDbId, + foundLevelNamesGroupedByProgramDbId); + position.setObservationUnit(entity); + entity.setPosition(position); + } + + result.add(entity); + } + + return result; + } + + private void updateOUPosition(ObservationUnitPosition position, + ObservationUnitEntity ouEntity, + Map foundLevelNameEntitiesByDbId, + Map> foundLevelNamesGroupedByProgramId) throws BrAPIServerException { + var pEntity = ouEntity.getPosition(); if (position.getEntryType() != null) - entity.setEntryType(position.getEntryType()); + pEntity.setEntryType(position.getEntryType()); if (position.getGeoCoordinates() != null) - entity.setGeoCoordinates(GeoJSONUtility.convertToEntity(position.getGeoCoordinates())); + pEntity.setGeoCoordinates(GeoJSONUtility.convertToEntity(position.getGeoCoordinates())); if (position.getObservationLevel() != null) { if (position.getObservationLevel().getLevelCode() != null) - entity.setLevelCode(position.getObservationLevel().getLevelCode()); + pEntity.setLevelCode(position.getObservationLevel().getLevelCode()); if (position.getObservationLevel().getLevelName() != null) { - var programDbId = Optional.ofNullable(ouEntity.getProgram()) + var parentProgramDbId = Optional.ofNullable(ouEntity.getProgram()) .map(p -> p.getId().toString()) .orElse(null); - var foundLevelName = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, List.of(position.getObservationLevel().getLevelName())); - entity.setLevelName(foundLevelName.get(position.getObservationLevel().getLevelName())); + + var foundLevelName = observationUnitLevelNameService.verifyObservationUnitLevelName( + parentProgramDbId, + List.of(position.getObservationLevel()), + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId + ); + pEntity.setLevelName(foundLevelName); } } if (position.getObservationLevelRelationships() != null) - updateOULevelRelationships(ouEntity, entity, position); + updateOULevelRelationships(ouEntity, + position, + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId); if (position.getPositionCoordinateX() != null) - entity.setPositionCoordinateX(position.getPositionCoordinateX()); + pEntity.setPositionCoordinateX(position.getPositionCoordinateX()); if (position.getPositionCoordinateXType() != null) - entity.setPositionCoordinateXType(position.getPositionCoordinateXType()); + pEntity.setPositionCoordinateXType(position.getPositionCoordinateXType()); if (position.getPositionCoordinateY() != null) - entity.setPositionCoordinateY(position.getPositionCoordinateY()); + pEntity.setPositionCoordinateY(position.getPositionCoordinateY()); if (position.getPositionCoordinateYType() != null) - entity.setPositionCoordinateYType(position.getPositionCoordinateYType()); + pEntity.setPositionCoordinateYType(position.getPositionCoordinateYType()); } private void updateOULevelRelationships(ObservationUnitEntity ouEntity, - ObservationUnitPositionEntity pEntity, - ObservationUnitPosition position) + ObservationUnitPosition position, + Map foundLevelNameEntitiesByDbId, + Map> foundLevelNamesGroupedByProgramId) throws BrAPIServerException { - var submittedLevelNames = position.getObservationLevelRelationships().stream() - .map(ObservationUnitHierarchyLevel::getLevelName) - .toList(); + var pEntity = ouEntity.getPosition(); var programDbId = Optional.ofNullable(ouEntity.getProgram()) .map(p -> p.getId().toString()) .orElse(null); - var foundOULevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, submittedLevelNames); + var foundOULevelNames = observationUnitLevelNameService.verifyObservationUnitLevelNames(programDbId, + position.getObservationLevelRelationships(), + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId); var relationshipEntities = new ArrayList(); @@ -666,40 +847,40 @@ private void updateOULevelRelationships(ObservationUnitEntity ouEntity, pEntity.setObservationLevelRelationships(relationshipEntities); } - private List createEntitiesInBatch(List obsUnits) + private List createEntitiesInBatch(List oURqs) throws BrAPIServerException { // Gather all IDs we want to look up in a bulk lookup. - var germplasmIds = obsUnits.stream() + var germplasmIds = oURqs.stream() .map(ObservationUnitNewRequest::getGermplasmDbId) .filter(Objects::nonNull) .distinct() .toList(); - var crossIds = obsUnits.stream() + var crossIds = oURqs.stream() .map(ObservationUnitNewRequest::getCrossDbId) .filter(Objects::nonNull) .distinct() .toList(); - var seedLotIds = obsUnits.stream() + var seedLotIds = oURqs.stream() .map(ObservationUnitNewRequest::getSeedLotDbId) .filter(Objects::nonNull) .distinct() .toList(); - var studyIds = obsUnits.stream() + var studyIds = oURqs.stream() .map(ObservationUnitNewRequest::getStudyDbId) .filter(Objects::nonNull) .distinct() .toList(); - var trialIds = obsUnits.stream() + var trialIds = oURqs.stream() .map(ObservationUnitNewRequest::getTrialDbId) .filter(Objects::nonNull) .distinct() .toList(); - var programIds = obsUnits.stream() + var programIds = oURqs.stream() .map(ObservationUnitNewRequest::getProgramDbId) .filter(Objects::nonNull) .distinct() @@ -731,9 +912,20 @@ private List createEntitiesInBatch(List e)); + var observationUnitLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(null, true); + + var foundLevelNamesByDbId = observationUnitLevelNames.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + .collect(Collectors.groupingBy(ouln -> + Optional.ofNullable(ouln.getProgram()) + .map(p -> p.getId().toString()) + .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + List result = new ArrayList<>(); - for (ObservationUnitNewRequest obsUnit : obsUnits) { + for (ObservationUnitNewRequest obsUnit : oURqs) { var entity = new ObservationUnitEntity(); UpdateUtility.updateEntity(obsUnit, entity); @@ -768,12 +960,14 @@ private List createEntitiesInBatch(List Date: Mon, 21 Jul 2025 15:39:56 -0400 Subject: [PATCH 14/34] Address review comments --- .../service/pheno/ObservationUnitService.java | 54 +++++++++---------- .../V001.002__drop_study_join_ids.sql | 18 +++---- 2 files changed, 36 insertions(+), 36 deletions(-) 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 13df53ce..d29048bb 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 @@ -228,9 +228,9 @@ public Page findObservationUnitEntities(@Valid Observatio .leftJoinFetch("program", "program"); if (request.getObservationVariableDbIds() != null || request.getObservationVariableNames() != null) { - searchQuery = searchQuery.join("observationsUnits", "observation") - .appendList(request.getObservationVariableDbIds(), "*observation.variable.id") - .appendList(request.getObservationVariableNames(), "*observation.variable.name"); + searchQuery = searchQuery.join("observations", "observation") + .appendList(request.getObservationVariableDbIds(), "*observation.observationVariable.id") + .appendList(request.getObservationVariableNames(), "*observation.observationVariable.name"); } if (request.getSeasonDbIds() != null) { searchQuery = searchQuery.join("study.seasons", "season").appendList(request.getSeasonDbIds(), @@ -637,37 +637,37 @@ private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitP private List createEntitiesInBatch(List obsUnits) throws BrAPIServerException { // Gather all IDs we want to look up in a bulk lookup. - var germplasmIds = obsUnits.stream() + List germplasmIds = obsUnits.stream() .map(ObservationUnitNewRequest::getGermplasmDbId) .filter(Objects::nonNull) .distinct() .toList(); - var crossIds = obsUnits.stream() + List crossIds = obsUnits.stream() .map(ObservationUnitNewRequest::getCrossDbId) .filter(Objects::nonNull) .distinct() .toList(); - var seedLotIds = obsUnits.stream() + List seedLotIds = obsUnits.stream() .map(ObservationUnitNewRequest::getSeedLotDbId) .filter(Objects::nonNull) .distinct() .toList(); - var studyIds = obsUnits.stream() + List studyIds = obsUnits.stream() .map(ObservationUnitNewRequest::getStudyDbId) .filter(Objects::nonNull) .distinct() .toList(); - var trialIds = obsUnits.stream() + List trialIds = obsUnits.stream() .map(ObservationUnitNewRequest::getTrialDbId) .filter(Objects::nonNull) .distinct() .toList(); - var programIds = obsUnits.stream() + List programIds = obsUnits.stream() .map(ObservationUnitNewRequest::getProgramDbId) .filter(Objects::nonNull) .distinct() @@ -675,29 +675,29 @@ private List createEntitiesInBatch(List foundGermsById = germplasmService.findByIds(germplasmIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundCrossesById = crossService.findByIds(crossIds) + Map foundCrossesById = crossService.findByIds(crossIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundSeedLotsById = seedLotService.findByIds(seedLotIds) + Map foundSeedLotsById = seedLotService.findByIds(seedLotIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundStudiesById = studyService.findByIds(studyIds) + Map foundStudiesById = studyService.findByIds(studyIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundTrialsById = trialService.findByIds(trialIds) + Map foundTrialsById = trialService.findByIds(trialIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundProgramsById = programService.findByIds(programIds) + Map foundProgramsById = programService.findByIds(programIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); List result = new ArrayList<>(); @@ -707,10 +707,10 @@ private List createEntitiesInBatch(List createEntitiesInBatch(List { @@ -737,11 +737,11 @@ private List createEntitiesInBatch(List Date: Mon, 21 Jul 2025 16:33:31 -0400 Subject: [PATCH 15/34] Utilize static typing for observation service comment --- .../service/pheno/ObservationService.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) 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 5c5da3ae..83abce07 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 @@ -432,13 +432,13 @@ private void updateEntity(ObservationEntity entity, ObservationNewRequest observ private List createEntitiesInBatch(List observations) { - var observationVarIds = observations.stream() + List observationVarIds = observations.stream() .map(ObservationNewRequest::getObservationVariableDbId) .filter(Objects::nonNull) .distinct() .toList(); - var seasonIds = observations.stream() + List seasonIds = observations.stream() .map(obs -> { if (obs.getSeason() != null && obs.getSeason().getSeasonDbId() != null) { return obs.getSeason().getSeasonDbId(); @@ -450,33 +450,33 @@ private List createEntitiesInBatch(List observationUnitIds = observations.stream() .map(ObservationNewRequest::getObservationUnitDbId) .filter(Objects::nonNull) .distinct() .toList(); - var studyIds = observations.stream() + List studyIds = observations.stream() .map(ObservationNewRequest::getStudyDbId) .filter(Objects::nonNull) .distinct() .toList(); - var foundObsVarsById = observationVariableService.findByIds(observationVarIds) + Map foundObsVarsById = observationVariableService.findByIds(observationVarIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundSeasonsById = seasonService.findByIds(seasonIds) + Map foundSeasonsById = seasonService.findByIds(seasonIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundObsUnitsById = observationUnitService.findByIds(observationUnitIds) + Map foundObsUnitsById = observationUnitService.findByIds(observationUnitIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var foundStudiesById = studyService.findByIds(studyIds) + Map foundStudiesById = studyService.findByIds(studyIds) .stream() - .collect(Collectors.toMap(BrAPIBaseEntity::getId, e -> e)); + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); var result = new ArrayList(); @@ -492,10 +492,10 @@ private List createEntitiesInBatch(List createEntitiesInBatch(List Date: Tue, 5 Aug 2025 14:46:52 -0400 Subject: [PATCH 16/34] Rename migrations for ordering --- ...udy_join_tables.sql => U004__add_ids_to_study_join_tables.sql} | 0 ...002__drop_study_join_ids.sql => V004__drop_study_join_ids.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{U001.002__add_ids_to_study_join_tables.sql => U004__add_ids_to_study_join_tables.sql} (100%) rename src/main/resources/db/migration/{V001.002__drop_study_join_ids.sql => V004__drop_study_join_ids.sql} (100%) diff --git a/src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql b/src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql similarity index 100% rename from src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql rename to src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql diff --git a/src/main/resources/db/migration/V001.002__drop_study_join_ids.sql b/src/main/resources/db/migration/V004__drop_study_join_ids.sql similarity index 100% rename from src/main/resources/db/migration/V001.002__drop_study_join_ids.sql rename to src/main/resources/db/migration/V004__drop_study_join_ids.sql From 70801067ab5a39a9b73f1182cfa54c9429f2e1bd Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:46:52 -0400 Subject: [PATCH 17/34] Rename migrations for ordering --- ...udy_join_tables.sql => U004__add_ids_to_study_join_tables.sql} | 0 ...002__drop_study_join_ids.sql => V004__drop_study_join_ids.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{U001.002__add_ids_to_study_join_tables.sql => U004__add_ids_to_study_join_tables.sql} (100%) rename src/main/resources/db/migration/{V001.002__drop_study_join_ids.sql => V004__drop_study_join_ids.sql} (100%) diff --git a/src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql b/src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql similarity index 100% rename from src/main/resources/db/migration/U001.002__add_ids_to_study_join_tables.sql rename to src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql diff --git a/src/main/resources/db/migration/V001.002__drop_study_join_ids.sql b/src/main/resources/db/migration/V004__drop_study_join_ids.sql similarity index 100% rename from src/main/resources/db/migration/V001.002__drop_study_join_ids.sql rename to src/main/resources/db/migration/V004__drop_study_join_ids.sql From 6f63b008407e9d2eb9bf83c4329fd9332d17e7ad Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Wed, 6 Aug 2025 11:50:59 -0400 Subject: [PATCH 18/34] Checkout correct branch --- .github/workflows/docker-build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index c5aaddcf..e8d35577 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -26,7 +26,6 @@ jobs: - name: Checkout develop branch uses: actions/checkout@v4 with: - ref: develop # Default to develop, will be overridden by push events to other branches fetch-depth: 0 # Fetch all history to ensure common ancestor is found - name: Conditionally Fetch and Merge Upstream PR @@ -149,4 +148,4 @@ jobs: for tag in "${TAG_ARRAY[@]}"; do FORMATTED_TAGS="$FORMATTED_TAGS --tag $tag" done - docker buildx build . --file Dockerfile $FORMATTED_TAGS --push --platform=linux/arm64,linux/amd64 \ No newline at end of file + docker buildx build . --file Dockerfile $FORMATTED_TAGS --push --platform=linux/arm64,linux/amd64 From a997f436deaa8a62c3ef577f00d9f45359f7a3ef Mon Sep 17 00:00:00 2001 From: Nick <53413353+nickpalladino@users.noreply.github.com> Date: Wed, 6 Aug 2025 11:52:50 -0400 Subject: [PATCH 19/34] Rename step to be more accurate --- .github/workflows/docker-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index e8d35577..286bde7d 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout develop branch + - name: Checkout branch uses: actions/checkout@v4 with: fetch-depth: 0 # Fetch all history to ensure common ancestor is found From 539962856d453084cf3ea30f764e19899d80ffd2 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 6 Aug 2025 16:31:58 -0400 Subject: [PATCH 20/34] Make old /observationlevels endpoint usable --- .../pheno/ObservationUnitHierarchyLevel.java | 5 ++--- .../model/pheno/ObservationUnitLevel.java | 4 ++-- .../pheno/ObservationUnitLevelNameService.java | 6 ------ .../service/pheno/ObservationUnitService.java | 17 ++++++++++------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index 12639a5b..8a5a1c51 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -77,13 +77,12 @@ public boolean equals(java.lang.Object o) { return false; } ObservationUnitHierarchyLevel observationUnitHierarchyLevel = (ObservationUnitHierarchyLevel) o; - return Objects.equals(this.levelName, observationUnitHierarchyLevel.levelName) - && Objects.equals(this.levelOrder, observationUnitHierarchyLevel.levelOrder); + return Objects.equals(this.levelNameDbId, observationUnitHierarchyLevel.levelNameDbId); } @Override public int hashCode() { - return Objects.hash(levelName, levelOrder); + return Objects.hash(levelNameDbId); } @Override diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java index a9dc0b7b..b39a960f 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java @@ -24,14 +24,14 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ObservationUnitLevel other = (ObservationUnitLevel) obj; - return Objects.equals(levelCode, other.levelCode); + return Objects.equals(getLevelNameDbId(), other.getLevelNameDbId()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + Objects.hash(levelCode); + result = prime * result + Objects.hash(getLevelNameDbId()); return result; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 47603bc8..8a138b1b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -283,12 +283,6 @@ public void deleteObservationLevelName(String observationLevelNameDbId) { observationUnitLevelNameRepository.deleteById(UUID.fromString(observationLevelNameDbId)); } - // Single Program use case - public List findObservationUnitLevelNames(String programDbId) - throws BrAPIServerException { - return findObservationUnitLevelNames(List.of(programDbId), null); - } - public List findObservationUnitLevelNames(String programDbId, Boolean all) throws BrAPIServerException { 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 6965be97..505464c7 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 @@ -245,8 +245,8 @@ public Page findObservationUnitEntities(@Valid Observatio searchQuery = searchQuery // TODO: This will likely need to be updated so the search works by program and with globally available level names - .appendList(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) - .map(r -> r.getLevelName()).collect(Collectors.toList()), "position.levelName") + .appendIds(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) + .map(ouhl -> UUID.fromString(ouhl.getLevelNameDbId())).toList(), "position.levelName.id") .appendList(request.getObservationLevels().stream().filter(r -> r.getLevelCode() != null) .map(ObservationUnitLevel::getLevelCode).collect(Collectors.toList()), "position.levelCode") .appendIntList(request.getObservationLevels().stream().filter(r -> r.getLevelOrder() != null) @@ -257,8 +257,8 @@ public Page findObservationUnitEntities(@Valid Observatio // TODO: This will likely need to be updated so the search works by program and with globally available level names .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelName() != null) - .map(r -> r.getLevelName()).collect(Collectors.toList()), - "*levelRelationship.levelName") + .map(ObservationUnitHierarchyLevel::getLevelNameDbId).collect(Collectors.toList()), + "*levelRelationship.levelName.id") .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelCode() != null) .map(r -> r.getLevelCode()).collect(Collectors.toList()), @@ -431,12 +431,13 @@ public List findObservationLevels(String studyDbI String programDbId, Metadata metadata) throws BrAPIServerException { - List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId); + List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, false); List levelNames = foundObsLevelNameEntities.stream() .map(levelEnum -> { ObservationUnitLevel rel = new ObservationUnitLevel(); rel.setLevelName(levelEnum.getLevelName()); + rel.setLevelNameDbId(levelEnum.getId().toString()); return rel; }).collect(Collectors.toList()); @@ -454,7 +455,7 @@ public List findObservationLevels(String studyDbI ObservationUnitLevelRelationship rel = new ObservationUnitLevelRelationship(); rel.setLevelCode(lvl.getLevelCode()); rel.setLevelName(lvl.getLevelName()); - rel.setLevelOrder(lvl.getLevelOrder()); + rel.setLevelNameDbId(lvl.getLevelNameDbId()); return rel; }).collect(Collectors.toList())); levelsSearch.setObservationLevels(null); @@ -477,11 +478,13 @@ public List findObservationLevels(String studyDbI return list; }).flatMap(Collection::stream) .distinct() - .sorted() .map(obsUnitLevel -> { ObservationUnitHierarchyLevel level = new ObservationUnitHierarchyLevel(); + level.setLevelNameDbId(obsUnitLevel.getLevelNameDbId()); level.setLevelName(obsUnitLevel.getLevelName()); level.setLevelOrder(obsUnitLevel.getLevelOrder()); + level.setProgramDbId(obsUnitLevel.getProgramDbId()); + level.setProgramName(obsUnitLevel.getProgramName()); return level; }).collect(Collectors.toList()); From d05da7429444cd51d7a82ab67d2772b277c52649 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Wed, 6 Aug 2025 16:55:34 -0400 Subject: [PATCH 21/34] Add DISTINCT to select id only query --- .../brapi/test/BrAPITestServer/service/SearchQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 314af1e1..80bf5bc5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchQueryBuilder.java @@ -21,7 +21,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.selectOnlyIds = "SELECT distinct entity.id FROM " + clazz.getSimpleName() + " entity "; this.whereClause = "WHERE 1=1 "; this.defaultSort = " ORDER BY entity.id ASC "; this.sortClause = ""; From 6afd444ce1c20227696d7739d1f17e616785fffe Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Fri, 8 Aug 2025 16:05:01 -0400 Subject: [PATCH 22/34] Optimize /observationlevels GET endpoint for use with dynamic obs lvls --- .../pheno/ObservationTableHeaderRowEnum.java | 10 +- .../pheno/ObservationUnitRepository.java | 22 +++ .../service/pheno/ObservationUnitService.java | 138 ++++++++++-------- ... => U005__drop_observation_level_name.sql} | 0 ...> V005__create_observation_level_name.sql} | 0 5 files changed, 101 insertions(+), 69 deletions(-) rename src/main/resources/db/migration/{U001.003__drop_observation_level_name.sql => U005__drop_observation_level_name.sql} (100%) rename src/main/resources/db/migration/{V001.003__create_observation_level_name.sql => V005__create_observation_level_name.sql} (100%) diff --git a/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java b/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java index 1cd1a92c..ccd7561d 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java +++ b/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java @@ -15,15 +15,7 @@ public enum ObservationTableHeaderRowEnum { GERMPLASMNAME("germplasmName"), POSITIONCOORDINATEX("positionCoordinateX"), POSITIONCOORDINATEY("positionCoordinateY"), - YEAR("year"), - FIELD("field"), - PLOT("plot"), - SUB_PLOT("sub-plot"), - PLANT("plant"), - POT("pot"), - BLOCK("block"), - ENTRY("entry"), - REP("rep"); + YEAR("year"); private String value; ObservationTableHeaderRowEnum(String value) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java index 839b628c..cb77c8ee 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java @@ -22,4 +22,26 @@ public interface ObservationUnitRepository extends BrAPIRepository fetchGermplasmDataForOUs(@Param("ouIds") List ouIds); + + @NativeQuery( + "SELECT EXISTS(" + + "SELECT ou.id " + + "FROM observation_unit ou " + + "JOIN observation_unit_position oup ON ou.id = oup.observation_unit_id " + + "JOIN observation_unit_level_name ouln ON oup.level_name_new = ouln.id " + + "WHERE oup.level_name_new = :levelNameDbId AND ou.program_id = :programDbId " + + // The IS NULL checks allow for some moderate custom query generation based off of input params. + "AND (:trialDbId ::uuid IS NULL OR ou.trial_id = :trialDbId) AND (:studyDbId ::uuid IS NULL OR ou.study_id = :studyDbId) " + + ") OR EXISTS ( " + + "SELECT ou.id " + + "FROM observation_unit ou " + + "JOIN observation_unit_position oup ON oup.observation_unit_id = ou.id " + + "JOIN observation_unit_level oul ON oul.position_id = oup.id " + + "WHERE oul.level_name_new = :levelNameDbId AND ou.program_id = :programDbId " + + "AND (:trialDbId ::uuid IS NULL OR ou.trial_id = :trialDbId) AND (:studyDbId ::uuid IS NULL OR ou.study_id = :studyDbId))" + ) + Boolean existsOUsWithLevelNameAndProgramAndTrialAndStudy(@Param("levelNameDbId") String levelNameDbId, + @Param("programDbId") String programDbId, + @Param("trialDbId") String trialDbId, + @Param("studyDbId") String studyDbId); } 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 505464c7..f930ec24 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 @@ -4,6 +4,7 @@ import io.swagger.model.Metadata; import io.swagger.model.pheno.*; import jakarta.validation.Valid; +import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.dto.ObservationUnitGermplasmData; @@ -427,66 +428,83 @@ public ObservationUnit updateObservationUnit(String observationUnitDbId, @Valid return convertFromEntity(savedEntity); } + // Grabs the programDbId from an associated trial or study + private String getProgramDbId(String trialDbId, + String studyDbId) throws BrAPIServerException { + TrialEntity trial = null; + StudyEntity study = null; + + if (!StringUtils.isEmpty(trialDbId)) { + trial = trialService.getTrialEntity(trialDbId); + } + + if (trial != null) { + return trial.getProgram().getId().toString(); + } + + if (!StringUtils.isEmpty(studyDbId)) { + study = studyService.getStudyEntity(studyDbId); + } + + if (study != null) { + return study.getProgram().getId().toString(); + } + + return null; + } + public List findObservationLevels(String studyDbId, String trialDbId, String programDbId, Metadata metadata) throws BrAPIServerException { - List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, false); - - List levelNames = foundObsLevelNameEntities.stream() - .map(levelEnum -> { - ObservationUnitLevel rel = new ObservationUnitLevel(); - rel.setLevelName(levelEnum.getLevelName()); - rel.setLevelNameDbId(levelEnum.getId().toString()); - return rel; - }).collect(Collectors.toList()); - - ObservationUnitSearchRequest levelsSearch = buildObservationUnitsSearchRequest(null, null, null, studyDbId, - null, trialDbId, programDbId, null, null, null, null, null, null, null, null, null, false, null, null, - null); - - levelsSearch.setObservationLevels(levelNames); - List units = new ArrayList<>(); - List someunits = findObservationUnits(levelsSearch, - new Metadata().pagination(new IndexPagination())); - units.addAll(someunits); - - levelsSearch.setObservationLevelRelationships(levelNames.stream().map(lvl -> { - ObservationUnitLevelRelationship rel = new ObservationUnitLevelRelationship(); - rel.setLevelCode(lvl.getLevelCode()); - rel.setLevelName(lvl.getLevelName()); - rel.setLevelNameDbId(lvl.getLevelNameDbId()); - return rel; - }).collect(Collectors.toList())); - levelsSearch.setObservationLevels(null); - List moreUnits = findObservationUnits(levelsSearch, - new Metadata().pagination(new IndexPagination())); - units.addAll(moreUnits); - - List levels = units.stream() - .filter(unit -> unit.getObservationUnitPosition() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevelRelationships() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevel() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevel().getLevelName() != null) - .map(unit -> { - List list = new ArrayList<>(); - for (ObservationUnitLevel level : unit.getObservationUnitPosition() - .getObservationLevelRelationships()) { - list.add(level); - } - list.add(unit.getObservationUnitPosition().getObservationLevel()); - return list; - }).flatMap(Collection::stream) - .distinct() - .map(obsUnitLevel -> { + if (StringUtils.isEmpty(studyDbId) && StringUtils.isEmpty(trialDbId) && StringUtils.isEmpty(programDbId)) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "No trialDbId, studyDbId, or programDbId was detected. " + + "Please provide at least one of these to find observation units related to level names."); + } + + // First, if there is no programDbId available, try to grab it from a study or trial + if (StringUtils.isEmpty(programDbId)) { + programDbId = getProgramDbId(trialDbId, studyDbId); + } + + // First, grab all global level names that are not tied to any programs + List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(null, false); + + if (!StringUtils.isEmpty(programDbId)) { + // If programDbId is present, try to grab the level names related to the program submitted. + var levelNamesFoundByProgram = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, false); + + if (!foundObsLevelNameEntities.containsAll(levelNamesFoundByProgram)) { + foundObsLevelNameEntities.addAll(levelNamesFoundByProgram); + } + } + + List levelNamesRelatedToOUs = new ArrayList<>(); + + for (ObservationUnitLevelNameEntity lnEntity : foundObsLevelNameEntities) { + if (observationUnitRepository.existsOUsWithLevelNameAndProgramAndTrialAndStudy(lnEntity.getId().toString(), + programDbId, + trialDbId, + studyDbId)) { + levelNamesRelatedToOUs.add(lnEntity); + } + } + + List levels = levelNamesRelatedToOUs.stream() + .map(lne -> { ObservationUnitHierarchyLevel level = new ObservationUnitHierarchyLevel(); - level.setLevelNameDbId(obsUnitLevel.getLevelNameDbId()); - level.setLevelName(obsUnitLevel.getLevelName()); - level.setLevelOrder(obsUnitLevel.getLevelOrder()); - level.setProgramDbId(obsUnitLevel.getProgramDbId()); - level.setProgramName(obsUnitLevel.getProgramName()); + level.setLevelNameDbId(lne.getId().toString()); + level.setLevelName(lne.getLevelName()); + level.setLevelOrder(lne.getLevelOrder()); + + if (lne.getProgram() != null) { + level.setProgramDbId(lne.getProgram().getId().toString()); + level.setProgramName(lne.getProgram().getName()); + } + return level; - }).collect(Collectors.toList()); + }) + .toList(); return PagingUtility.paginateSimpleList(levels, metadata); } @@ -514,7 +532,7 @@ private ObservationUnit convertFromEntity(ObservationUnitEntity entity, boolean } unit.setObservationUnitDbId(entity.getId().toString()); unit.setObservationUnitName(entity.getObservationUnitName()); - unit.setObservationUnitPosition(convertFromEntity(entity.getPosition(), entity.getId().toString())); + unit.setObservationUnitPosition(convertFromEntity(entity.getPosition())); unit.setObservationUnitPUI(entity.getObservationUnitPUI()); if (entity.getSeedLot() != null) { unit.setSeedLotDbId(entity.getSeedLot().getId().toString()); @@ -557,7 +575,7 @@ private ObservationUnit convertFromEntity(ObservationUnitEntity entity, boolean } - private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity entity, String ouDbId) { + private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity entity) { ObservationUnitPosition position = null; if (entity != null) { position = new ObservationUnitPosition(); @@ -567,7 +585,7 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity if (entity.getObservationLevelRelationships() != null) { position.setObservationLevelRelationships(entity.getObservationLevelRelationships().stream() - .map(rel -> this.convertFromEntity(rel, ouDbId)).collect(Collectors.toList())); + .map(rel -> this.convertFromEntity(rel)).collect(Collectors.toList())); } position.setPositionCoordinateX(entity.getPositionCoordinateX()); position.setPositionCoordinateXType(entity.getPositionCoordinateXType()); @@ -603,15 +621,15 @@ private ObservationTreatment convertFromEntity(TreatmentEntity entity) { return treatment; } - private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity, String ouDbId) { + private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); level.setLevelCode(entity.getLevelCode()); level.setLevelName(entity.getLevelName().getLevelName()); level.setLevelOrder(entity.getLevelName().getLevelOrder()); level.setLevelNameDbId(entity.getLevelName().getId().toString()); - if (ouDbId != null) { - level.setObservationUnitDbId(ouDbId); + if (entity.getObservationUnit() != null) { + level.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); } // If the program is null, this level name is global. diff --git a/src/main/resources/db/migration/U001.003__drop_observation_level_name.sql b/src/main/resources/db/migration/U005__drop_observation_level_name.sql similarity index 100% rename from src/main/resources/db/migration/U001.003__drop_observation_level_name.sql rename to src/main/resources/db/migration/U005__drop_observation_level_name.sql diff --git a/src/main/resources/db/migration/V001.003__create_observation_level_name.sql b/src/main/resources/db/migration/V005__create_observation_level_name.sql similarity index 100% rename from src/main/resources/db/migration/V001.003__create_observation_level_name.sql rename to src/main/resources/db/migration/V005__create_observation_level_name.sql From 8b7414c2a1d9be083000b0b4bc265314086f08f5 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 12 Aug 2025 15:50:18 -0400 Subject: [PATCH 23/34] Fix issues with study posts including obs lvls, fix ou search --- .../entity/core/ObservationLevelEntity.java | 8 +++ .../model/entity/core/StudyEntity.java | 3 +- .../service/core/StudyService.java | 28 ++++++++-- .../ObservationUnitLevelNameService.java | 55 ------------------- .../service/pheno/ObservationUnitService.java | 26 +++++---- 5 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java index 22134a97..e41fbac6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java @@ -20,4 +20,12 @@ public ObservationUnitLevelNameEntity getLevelName() { public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } + + public StudyEntity getStudy() { + return study; + } + + public void setStudy(StudyEntity study) { + this.study = study; + } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java index 560d7ac1..2197b3b0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java @@ -47,7 +47,8 @@ public class StudyEntity extends BrAPIPrimaryEntity { private String license; @OneToOne(fetch = FetchType.LAZY) private LocationEntity location; - @OneToMany(mappedBy = "study") + + @OneToMany(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true) private List observationLevels; @Column private String observationUnitsDescription; 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 a16a4c07..1b6526ea 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 @@ -3,8 +3,10 @@ import java.util.*; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.core.DataLinkEntity; import org.brapi.test.BrAPITestServer.model.entity.core.EnvironmentParametersEntity; @@ -17,6 +19,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyLastUpdateEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.StudyRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; @@ -269,7 +272,14 @@ private void updateEntity(StudyEntity entity, StudyNewRequest body) throws BrAPI entity.setLocation(location); } if (body.getObservationLevels() != null) { - entity.setObservationLevels(convertToEntity(body.getObservationLevels(), body.getProgramDbId())); + + List lvlEntities = convertToEntity(body.getObservationLevels(), body.getProgramDbId()); + + for(ObservationLevelEntity lvlEntity : lvlEntities) { + lvlEntity.setStudy(entity); + } + + entity.setObservationLevels(lvlEntities); } if (body.getObservationUnitsDescription() != null) entity.setObservationUnitsDescription(body.getObservationUnitsDescription()); @@ -413,12 +423,22 @@ private List convertToEntity(List entities = new ArrayList<>(); - var foundLevelNames = observationUnitLevelNameService.retrieveAndVerifyObservationUnitLevelNames(programDbId, levels); + List submittedLevelNameDbIds = levels.stream() + .map(ObservationUnitHierarchyLevel::getLevelNameDbId) + .toList(); + + if (submittedLevelNameDbIds.isEmpty() && StringUtils.isEmpty(programDbId)) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "No levelNameDbIds or programDbId available in request. levelNameDbIds can be found using /observationlevelnames GET."); + } + + Map foundLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(Arrays.asList(programDbId), submittedLevelNameDbIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - for (ObservationUnitHierarchyLevel level : levels) { + for (String lnDbId : submittedLevelNameDbIds) { var entity = new ObservationLevelEntity(); - entity.setLevelName(foundLevelNames.get(level.getLevelName())); + entity.setLevelName(foundLevelNames.get(lnDbId)); entities.add(entity); } return entities; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 8a138b1b..fcfe0f6e 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -123,61 +123,6 @@ public String getGlobalKeyForFoundEntities() { return GLOBAL_KEY_FOR_FOUND_ENTITIES; } - public Map retrieveAndVerifyObservationUnitLevelNames(String programDbIdOverride, - List submittedLevelNames) - throws BrAPIServerException { - - List programDbIds = new ArrayList<>(); - - if (programDbIdOverride != null && !programDbIdOverride.isBlank()) { - // If an programDbIdOverride was given, that means that the caller wants all submitted level names to be - // searched by a single programDbId. This programDbId is usually associated with a parent entity the level names - // belong to, like StudyEntity, ObservationUnitEntity, etc. - programDbIds.add(programDbIdOverride); - } else { - // If the override doesn't exist, use programDbIds from submitted level name object, if they are - // available at all. - programDbIds.addAll(submittedLevelNames.stream() - .map(ObservationUnitHierarchyLevel::getProgramDbId) - .filter(Objects::nonNull) - .toList()); - } - - List levelNameDbIds = submittedLevelNames.stream() - .map(ObservationUnitHierarchyLevel::getLevelNameDbId) - .filter(Objects::nonNull) - .toList(); - - if (levelNameDbIds.size() != submittedLevelNames.size()) { - // Only lookup by levelNameDbIds if every submitted level name has one. - levelNameDbIds = new ArrayList<>(); - } - - List foundOULevelNames = findObservationUnitLevelNames(programDbIds, levelNameDbIds); - - var levelNameEntitiesByName = foundOULevelNames.stream() - .collect(Collectors.toMap(ouln -> ouln.getLevelName().toLowerCase(), e -> e)); - - var submittedNames = submittedLevelNames.stream().map(ouhl -> ouhl.getLevelName().toLowerCase()).toList(); - // Now that we have found all the available level names, verify that all submitted level names are valid level names - // in the DB. - for (String submittedLevelName : submittedNames) { - if (!levelNameEntitiesByName.containsKey(submittedLevelName.toLowerCase())) { - throw new BrAPIServerException(HttpStatus.BAD_REQUEST, - String.format("Submitted observation unit level name [%s] does not exist " + - "globally or for the following submitted programs [%s]. This can be fixed " + - "by adding the level name using the POST endpoint brapi/[version-number]/observationunitlevelnames, " + - "or by using a level name already in the system.", - submittedLevelName, - programDbIds)); - } - } - - // Now that every submitted level name has been verified, return a map of the retrieved submitted levels. - return submittedNames.stream() - .collect(Collectors.toMap(ln -> ln, levelNameEntitiesByName::get)); - } - public List convertFromEntitiesInBatch(List entities) { List result = new ArrayList<>(); 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 f930ec24..add276f0 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 @@ -581,7 +581,10 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity position = new ObservationUnitPosition(); position.setEntryType(entity.getEntryType()); position.setGeoCoordinates(GeoJSONUtility.convertFromEntity(entity.getGeoCoordinates())); - position.setObservationLevel(convertFromEntity(entity.getLevelName(), entity.getLevelCode())); + + if (entity.getLevelName() != null) { + position.setObservationLevel(convertFromEntity(entity.getLevelName(), entity.getLevelCode())); + } if (entity.getObservationLevelRelationships() != null) { position.setObservationLevelRelationships(entity.getObservationLevelRelationships().stream() @@ -624,18 +627,21 @@ private ObservationTreatment convertFromEntity(TreatmentEntity entity) { private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName().getLevelName()); - level.setLevelOrder(entity.getLevelName().getLevelOrder()); - level.setLevelNameDbId(entity.getLevelName().getId().toString()); - if (entity.getObservationUnit() != null) { - level.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); + if (entity.getLevelName() != null) { + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); + level.setLevelNameDbId(entity.getLevelName().getId().toString()); + + // If the program is null, this level name is global. + if (entity.getLevelName().getProgram() != null) { + level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); + level.setProgramName(entity.getLevelName().getProgram().getName()); + } } - // If the program is null, this level name is global. - if (entity.getLevelName().getProgram() != null) { - level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); - level.setProgramName(entity.getLevelName().getProgram().getName()); + if (entity.getObservationUnit() != null) { + level.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); } From 601169981c9fb4286d38aeba5c3c7b89c2b8da33 Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 12 Aug 2025 18:48:19 -0400 Subject: [PATCH 24/34] Improve var usage, add comments --- .../ObservationUnitLevelNameService.java | 31 ++++++++++--------- .../service/pheno/ObservationUnitService.java | 19 ++++++++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index fcfe0f6e..3499bf7a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -5,6 +5,7 @@ import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.brapi.test.BrAPITestServer.repository.baseEntities.ObservationUnitLevelNameRepository; import org.brapi.test.BrAPITestServer.service.core.ProgramService; @@ -64,17 +65,17 @@ public Map verifyObservationUnitLevelNam var verifiedLevelNamesCurrentSize = verifiedEntitiesByLevelName.size(); if (StringUtils.isNotBlank(sln.getLevelNameDbId()) && foundLevelEntitiesByDbId.containsKey(sln.getLevelNameDbId())) { - var entity = foundLevelEntitiesByDbId.get(sln.getLevelNameDbId()); + ObservationUnitLevelNameEntity entity = foundLevelEntitiesByDbId.get(sln.getLevelNameDbId()); verifiedEntitiesByLevelName.put(entity.getLevelName(), entity); } else if (StringUtils.isNotBlank(parentProgramDbId) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { - var entities = foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId); + List entities = foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId); entities.stream() .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) .findFirst() .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); } else if (StringUtils.isNotBlank(sln.getProgramDbId()) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { - var entities = foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()); + List entities = foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()); entities.stream() .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) @@ -84,7 +85,7 @@ public Map verifyObservationUnitLevelNam if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size()) { // All other ways of detecting the level name have failed so far, try the global ones as a last-ditch effort - var globalEntities = foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES); + List globalEntities = foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES); globalEntities.stream() .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) @@ -147,12 +148,12 @@ public List convertToEntitiesInBatch(List result = new ArrayList<>(); - var programDbIds = levels.stream() + List programDbIds = levels.stream() .map(ObservationUnitHierarchyLevel::getProgramDbId) .filter(Objects::nonNull) .toList(); - var programEntitiesById = programService.findByIds(programDbIds).stream() + Map programEntitiesById = programService.findByIds(programDbIds).stream() .collect(Collectors.toMap(p -> p.getId().toString(), p -> p)); for (ObservationLevelNewRequest level : levels) { @@ -162,7 +163,7 @@ public List convertToEntitiesInBatch(List convertToEntitiesInBatch(List entityOpt = observationUnitLevelNameRepository.findById(UUID.fromString(observationLevelNameDbId)); if (entityOpt.isEmpty()) { throw new BrAPIServerDbIdNotFoundException("ObservationUnitLevelName", observationLevelNameDbId, HttpStatus.BAD_REQUEST); } - var entity = entityOpt.get(); + ObservationUnitLevelNameEntity entity = entityOpt.get(); if (level.getLevelName() != null) { entity.setLevelName(level.getLevelName()); @@ -212,15 +213,15 @@ public ObservationUnitHierarchyLevel update(String observationLevelNameDbId, entity.setProgram(null); } - var savedEntity = observationUnitLevelNameRepository.save(entity); + ObservationUnitLevelNameEntity savedEntity = observationUnitLevelNameRepository.save(entity); return convertFromEntitiesInBatch(List.of(savedEntity)).getFirst(); } public List save(List request) throws BrAPIServerException { - var entities = convertToEntitiesInBatch(request); - var savedEntities = observationUnitLevelNameRepository.saveAll(entities); + List entities = convertToEntitiesInBatch(request); + List savedEntities = observationUnitLevelNameRepository.saveAll(entities); return convertFromEntitiesInBatch(savedEntities); } @@ -263,14 +264,14 @@ private List findObservationUnitLevelNames(List< if (levelNameDbIds != null && !levelNameDbIds.isEmpty()) { - var result = observationUnitLevelNameRepository.findAllById(levelNameDbIds.stream().map(UUID::fromString).toList()); + List result = observationUnitLevelNameRepository.findAllById(levelNameDbIds.stream().map(UUID::fromString).toList()); if (result.size() != levelNameDbIds.size()) { - var foundDbIds = result.stream() + List foundDbIds = result.stream() .map(ouln -> ouln.getId().toString()) .toList(); - var levelNameDbIdsNotFound = levelNameDbIds.stream() + List levelNameDbIdsNotFound = levelNameDbIds.stream() .filter(lnId -> !foundDbIds.contains(lnId)) .toList(); 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 add276f0..5a7ba02d 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 @@ -355,6 +355,12 @@ public ObservationUnitEntity getObservationUnitEntity(String observationUnitDbId return observationUnit; } + /** + * Retrieves all submitted observation units in bulk by their dbId, + * returning a map of each found entity to its original request for fastest access speed in batch updating. + * + * Throws an error if there are any requests not found. + */ public Map getObservationUnitEntities(Map oURequestByDbId, HttpStatus errorStatus) throws BrAPIServerException { @@ -362,7 +368,7 @@ public Map getObservationUnitE throw new BrAPIServerDbIdNotFoundException("observationUnit", "null", errorStatus); } - var submittedDbIds = oURequestByDbId.keySet().stream().toList(); + List submittedDbIds = oURequestByDbId.keySet().stream().toList(); var searchRq = new ObservationUnitSearchRequest(); searchRq.observationUnitDbIds(submittedDbIds); @@ -373,12 +379,13 @@ public Map getObservationUnitE pagination.setPageSize(submittedDbIds.size()); metadata.setPagination(pagination); - var foundEntities = findObservationUnitEntities(searchRq, metadata); + Page foundEntities = findObservationUnitEntities(searchRq, metadata); - var foundEntitiesByDbId = foundEntities.stream() + Map foundEntitiesByDbId = foundEntities.stream() .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); - var submittedIdsNotFound = new HashSet<>(submittedDbIds); + // Use a set here to improve performance of .removeAll() + Set submittedIdsNotFound = new HashSet<>(submittedDbIds); submittedIdsNotFound.removeAll(foundEntitiesByDbId.keySet()); @@ -397,7 +404,7 @@ public Map getObservationUnitE public List saveObservationUnits(@Valid List requests) throws BrAPIServerException { - var toSave = createEntitiesInBatch(requests); + List toSave = createEntitiesInBatch(requests); return observationUnitRepository.saveAll(toSave) .stream() @@ -408,7 +415,7 @@ public List saveObservationUnits(@Valid List updateObservationUnits(@Valid Map requests) throws BrAPIServerException { - var foundOUEntities = getObservationUnitEntities(requests, HttpStatus.BAD_REQUEST); + Map foundOUEntities = getObservationUnitEntities(requests, HttpStatus.BAD_REQUEST); List toSave = updateEntitiesInBatch(foundOUEntities); From a08dc2af947ef1a6371ba80d97fbda83af3b2aaf Mon Sep 17 00:00:00 2001 From: jloux-brapi Date: Tue, 12 Aug 2025 22:02:53 -0400 Subject: [PATCH 25/34] Support for removing level_name_new and utilizing new column ref --- .../model/entity/core/ObservationLevelEntity.java | 2 +- .../ObservationUnitLevelRelationshipEntity.java | 2 +- .../entity/pheno/ObservationUnitPositionEntity.java | 2 +- .../pheno/ObservationUnitRepository.java | 6 +++--- .../migration/U005__drop_observation_level_name.sql | 2 +- .../V005__create_observation_level_name.sql | 12 ++++++++---- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java index e41fbac6..c92b0f68 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java @@ -9,7 +9,7 @@ public class ObservationLevelEntity extends BrAPIBaseEntity { @ManyToOne - @JoinColumn(name = "level_name_new") + @JoinColumn(name = "level_name") private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private StudyEntity study; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java index 9712148f..3ad859a1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java @@ -9,7 +9,7 @@ public class ObservationUnitLevelRelationshipEntity extends BrAPIBaseEntity { @Column private String levelCode; @ManyToOne - @JoinColumn(name = "level_name_new") + @JoinColumn(name = "level_name") private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private ObservationUnitEntity observationUnit; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java index 878dc34b..8fe5f373 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java @@ -18,7 +18,7 @@ public class ObservationUnitPositionEntity extends BrAPIBaseEntity { @Column private String levelCode; @ManyToOne - @JoinColumn(name = "level_name_new") + @JoinColumn(name = "level_name") private ObservationUnitLevelNameEntity levelName; @OneToMany(mappedBy = "position", cascade = CascadeType.ALL) private List observationLevelRelationships; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java index cb77c8ee..7f062079 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java @@ -28,8 +28,8 @@ public interface ObservationUnitRepository extends BrAPIRepository Date: Tue, 27 Jan 2026 18:01:27 -0500 Subject: [PATCH 26/34] [BI-2219] Obfuscate unused new level name fields Additionally update Api notes --- .../java/io/swagger/api/pheno/ObservationLevelNamesApi.java | 6 +++--- .../swagger/model/pheno/ObservationUnitHierarchyLevel.java | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java index f0a2d733..5b4ffad5 100644 --- a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java +++ b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java @@ -12,7 +12,7 @@ @javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2024-05-21T16:32:22.556Z[GMT]") @Api(value = "observationlevelnames", description = "the observationlevelnames API") public interface ObservationLevelNamesApi { - @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to retrieve the list of supported observation level names. Observation levels indicate the granularity level at which the measurements are taken. `levelName` defines the level, `levelOrder` defines where that level exists in the hierarchy of levels. `levelOrder`s lower numbers are at the top of the hierarchy (ie field > 0) and higher numbers are at the bottom of the hierarchy (ie plant > 6). The values are used to supply the `observationLevel` parameter in the observation unit details call.", response = ObservationLevelListResponse.class, authorizations = { + @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to retrieve the list of supported observation level names", response = ObservationLevelListResponse.class, authorizations = { @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), @ApiResponse(code = 400, message = "Bad Request", response = String.class), @@ -25,7 +25,7 @@ ResponseEntity observationlevelnamesGet( @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException; - @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @ApiOperation(value = "Create Observation Level Names", nickname = "observationlevelnamesPost", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), @ApiResponse(code = 400, message = "Bad Request", response = String.class), @@ -37,7 +37,7 @@ ResponseEntity observationlevelnamesPost( @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException; - @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @ApiOperation(value = "Delete Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to delete a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), @ApiResponse(code = 400, message = "Bad Request", response = String.class), diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index 8a5a1c51..4434e70b 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -2,7 +2,7 @@ import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; public class ObservationUnitHierarchyLevel { @@ -17,10 +17,12 @@ public class ObservationUnitHierarchyLevel { private Integer levelOrder = null; @JsonProperty("programDbId") + @JsonInclude(JsonInclude.Include.NON_NULL) private String programDbId = null; // NOTE: This property is NOT used for lookups, only responses. @JsonProperty("programName") + @JsonInclude(JsonInclude.Include.NON_NULL) private String programName = null; public String getLevelNameDbId() { From fde4e1509d1515a638a5b8babbf67b2d6362128a Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Thu, 29 Jan 2026 13:13:29 -0500 Subject: [PATCH 27/34] Return 409 with offending duplicate message Additional exception handling utilities added for future conflict concerns --- .../exceptions/ExceptionUtils.java | 47 +++++++++++++++++++ .../ObservationUnitLevelNameRepository.java | 4 ++ .../ObservationUnitLevelNameService.java | 16 ++++++- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java diff --git a/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java new file mode 100644 index 00000000..f249936a --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java @@ -0,0 +1,47 @@ +package org.brapi.test.BrAPITestServer.exceptions; + +import org.postgresql.util.PSQLException; +import org.postgresql.util.ServerErrorMessage; +import org.springframework.http.HttpStatus; + +import java.util.Optional; + +public class ExceptionUtils { + private static final String SQL_CONFLICT_ERROR_CODE = "23505"; + + public static T findCause( + Throwable throwable, + Class targetType + ) { + Throwable t = throwable; + while (t != null) { + if (targetType.isInstance(t)) { + return targetType.cast(t); + } + t = t.getCause(); + } + return null; + } + + /** + * Throws a BrAPIServerException with status 409 (CONFLICT) if a duplicate is detected in the database. + * The offending table and key that failed will also be sent in the response. + */ + public static void checkForPSQLConflict(Throwable possibleConflict) throws BrAPIServerException { + PSQLException possibleConflictException = findCause(possibleConflict, PSQLException.class); + + String sqlState = Optional.ofNullable(possibleConflictException) + .map(PSQLException::getServerErrorMessage) + .map(ServerErrorMessage::getSQLState) + .orElse(null); + + if (sqlState != null && sqlState.equals(SQL_CONFLICT_ERROR_CODE)) { + String conflictDetailMessage = possibleConflictException.getServerErrorMessage().getDetail(); + String offendingTable = possibleConflictException.getServerErrorMessage().getTable(); + + String errorResponse = String.format("A duplicate of an existing record is trying be submitted on table %s.\n\n %s", offendingTable, conflictDetailMessage); + + throw new BrAPIServerException(HttpStatus.CONFLICT, errorResponse); + } + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java index 2aaa200f..9e452525 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java @@ -2,6 +2,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.NativeQuery; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -19,6 +20,9 @@ public interface ObservationUnitLevelNameRepository extends BaseEntityRepository "WHERE ouln.program IS NULL") List findDefaultObservationUnitLevelNames(); + @NativeQuery("select * from a_table") + List botchedQuery(); + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln") List findAllObservationUnitLevelNames(); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 3499bf7a..fe4d7070 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -5,11 +5,14 @@ import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.exceptions.ExceptionUtils; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.brapi.test.BrAPITestServer.repository.baseEntities.ObservationUnitLevelNameRepository; import org.brapi.test.BrAPITestServer.service.core.ProgramService; +import org.postgresql.util.PSQLException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -221,7 +224,18 @@ public ObservationUnitHierarchyLevel update(String observationLevelNameDbId, public List save(List request) throws BrAPIServerException { List entities = convertToEntitiesInBatch(request); - List savedEntities = observationUnitLevelNameRepository.saveAll(entities); + + List savedEntities = null; + + try { + savedEntities = observationUnitLevelNameRepository.saveAll(entities); + } catch (DataIntegrityViolationException e) { + ExceptionUtils.checkForPSQLConflict(e.getMostSpecificCause()); + + // If a conflict didn't occur, something else happened on the DB server. Throw a 500 and attach the root cause to the message. + throw new BrAPIServerException(HttpStatus.INTERNAL_SERVER_ERROR, String.format("An DB error occurred while processing level names %s\n\n%s", request, e.getMostSpecificCause())); + } + return convertFromEntitiesInBatch(savedEntities); } From d76fc89cdec90fe674e3df63da833220938609c7 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Thu, 29 Jan 2026 15:31:45 -0500 Subject: [PATCH 28/34] Update migration file to add partial index for global level names --- .../db/migration/V005__create_observation_level_name.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/db/migration/V005__create_observation_level_name.sql b/src/main/resources/db/migration/V005__create_observation_level_name.sql index 372831de..bba997b3 100644 --- a/src/main/resources/db/migration/V005__create_observation_level_name.sql +++ b/src/main/resources/db/migration/V005__create_observation_level_name.sql @@ -9,6 +9,10 @@ CREATE TABLE observation_unit_level_name ( CONSTRAINT observation_unit_level_name_program_fk FOREIGN KEY(program_id) REFERENCES program(id) ); +CREATE UNIQUE INDEX lvl_name_global_unique_idx + ON observation_unit_level_name (level_name) + WHERE program_id IS NULL; + CREATE UNIQUE INDEX lvl_name_program_id_idx ON observation_unit_level_name (level_name, program_id); -- Set legacy level names From 47ab537b11f0513ca2d0cadead74cbad2eb1c576 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Mon, 2 Feb 2026 18:23:21 -0500 Subject: [PATCH 29/34] Add page and pageCount to get method. POST returns empty metadata --- .../api/pheno/ObservationLevelNamesApi.java | 2 ++ .../pheno/ObservationLevelNamesApiController.java | 14 ++++++++++++-- .../pheno/ObservationUnitLevelNameService.java | 1 - 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java index 5b4ffad5..0e79ab86 100644 --- a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java +++ b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java @@ -22,6 +22,8 @@ public interface ObservationLevelNamesApi { ResponseEntity observationlevelnamesGet( @ApiParam(value = "programDbId") @Valid @RequestParam(value = "programDbId", required = false) String programDbId, @ApiParam(value = "all") @Valid @RequestParam(value = "all", required = false) Boolean all, + @ApiParam(value = "page") @Valid @RequestParam(value = "page", required = false) Integer page, + @ApiParam(value = "pageSize") @Valid @RequestParam(value = "pageSize", required = false) Integer pageSize, @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java index 3a330c0b..ef872d03 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java @@ -3,11 +3,13 @@ import io.swagger.annotations.ApiParam; import io.swagger.api.pheno.ObservationLevelNamesApi; +import io.swagger.model.Metadata; import io.swagger.model.pheno.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.controller.core.BrAPIController; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.pheno.ObservationUnitLevelNameService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,15 +44,23 @@ public ResponseEntity observationlevelnamesGet( @RequestParam(value = "programDbId", required = false) String programDbId, // Used to grab all the Observation Level Names in the system, both global, and all level names for all params @RequestParam(value = "all", required = false) Boolean all, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "pageSize", required = false) Integer pageSize, @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException { log.debug("Request: " + request.getRequestURI()); validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); + + Metadata metadata = generateMetaDataTemplate(page, pageSize); + var foundLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, all); var data = observationUnitLevelNameService.convertFromEntitiesInBatch(foundLevelNames); - return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, null); + + data = PagingUtility.paginateSimpleList(data, metadata); + + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, metadata); } @CrossOrigin @@ -64,7 +74,7 @@ public ResponseEntity observationlevelnamesPost( validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); validateAcceptHeader(request); var data = observationUnitLevelNameService.save(body); - return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, null); + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, generateEmptyMetadata()); } @CrossOrigin diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index fe4d7070..70c183f9 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -10,7 +10,6 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.brapi.test.BrAPITestServer.repository.baseEntities.ObservationUnitLevelNameRepository; import org.brapi.test.BrAPITestServer.service.core.ProgramService; -import org.postgresql.util.PSQLException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; From b7385d73414b1cd12961a877749ec36982d9af20 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Fri, 13 Feb 2026 18:24:12 -0500 Subject: [PATCH 30/34] Migration to remove treatments out of ou additionalInfo --- ...U006__add_treatments_back_to_ou_addinfo.sql | 18 ++++++++++++++++++ ...V006__remove_treatments_from_ou_addinfo.sql | 1 + 2 files changed, 19 insertions(+) create mode 100644 src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql create mode 100644 src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql diff --git a/src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql b/src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql new file mode 100644 index 00000000..af79b9d2 --- /dev/null +++ b/src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql @@ -0,0 +1,18 @@ +WITH treatment_json AS (SELECT + observation_unit_id, + jsonb_agg( + jsonb_build_object('factor', factor) + ) AS treatments + FROM observation_unit_treatment + GROUP BY observation_unit_id) + +UPDATE observation_unit ou +SET additional_info = + jsonb_set( + COALESCE(ou.additional_info, '{}'::jsonb), + '{treatments}', + tj.treatments, + true + ) + FROM treatment_json tj +WHERE ou.id = tj.observation_unit_id; \ No newline at end of file diff --git a/src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql b/src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql new file mode 100644 index 00000000..f2ad3294 --- /dev/null +++ b/src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql @@ -0,0 +1 @@ +UPDATE observation_unit SET additional_info = additional_info - 'treatments'; \ No newline at end of file From 9968f3f8cec10236adb16a1f31a2a44f0b985dea Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Tue, 17 Feb 2026 08:48:39 -0500 Subject: [PATCH 31/34] Change migration version --- ...ddinfo.sql => U005.001__add_treatments_back_to_ou_addinfo.sql} | 0 ...ddinfo.sql => V005.001__remove_treatments_from_ou_addinfo.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{U006__add_treatments_back_to_ou_addinfo.sql => U005.001__add_treatments_back_to_ou_addinfo.sql} (100%) rename src/main/resources/db/migration/{V006__remove_treatments_from_ou_addinfo.sql => V005.001__remove_treatments_from_ou_addinfo.sql} (100%) diff --git a/src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql b/src/main/resources/db/migration/U005.001__add_treatments_back_to_ou_addinfo.sql similarity index 100% rename from src/main/resources/db/migration/U006__add_treatments_back_to_ou_addinfo.sql rename to src/main/resources/db/migration/U005.001__add_treatments_back_to_ou_addinfo.sql diff --git a/src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql b/src/main/resources/db/migration/V005.001__remove_treatments_from_ou_addinfo.sql similarity index 100% rename from src/main/resources/db/migration/V006__remove_treatments_from_ou_addinfo.sql rename to src/main/resources/db/migration/V005.001__remove_treatments_from_ou_addinfo.sql From 9cba318f2fc47afa850ba72d885bc13001d1d3eb Mon Sep 17 00:00:00 2001 From: sb2597 <62260853+sb2597@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:47:02 -0500 Subject: [PATCH 32/34] Create pull_request_template.md Added PR template --- .github/pull_request_template.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..81bf9989 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# Description +**Story:** _Please include a link to the story in Jira_ + +_Please include a summary of the change that was made._ + + + +# Dependencies +_Please include any dependencies to other code branches, testing configurations, scripts to be run, etc._ + +# Testing +_Please include any details needed for reviewers to test this code_ + + +# Checklist: + +- [ ] I have performed a self-review of my own code +- [ ] I have tested my code and ensured it meets the acceptance criteria of the story +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have either updated the source of truth or arranged for update with product owner if needed https://breedinginsight.atlassian.net/wiki/spaces/BI/pages/1559953409/Source+of+Truth From 0ff5b1113230b9c01b9bd667aec6215d15c9e214 Mon Sep 17 00:00:00 2001 From: nickpalladino Date: Mon, 16 Mar 2026 10:10:28 -0400 Subject: [PATCH 33/34] Added observation levels migration --- .../V005.002__migrate_observation_levels.sql | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/main/resources/db/migration/V005.002__migrate_observation_levels.sql diff --git a/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql b/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql new file mode 100644 index 00000000..47346b7e --- /dev/null +++ b/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql @@ -0,0 +1,116 @@ +-- Create new observation level names for each unique observationLevel in +-- the additional_info column of the observation_unit table +-- +-- Assumption: all observation_unit.program_id have ids which is true for our +-- usage. Database allows NULLs but we don't have to handle that +-- +-- * The level order will be 0 for all of these indicating Exp Unit +-- * All level names should be converted to lower case and combined +-- in the case of different cases to reference the same level +-- * Level names should be created for the program the observation unit is in, not globally +INSERT INTO observation_unit_level_name (level_name, level_order, program_id) +SELECT DISTINCT + lower(btrim(ou.additional_info ->> 'observationLevel')) AS level_name, + 0 AS level_order, + ou.program_id +FROM observation_unit ou +WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ou.program_id IS NOT NULL + ON CONFLICT (level_name, program_id) DO NOTHING; +-- on conflict only relevant for test servers, won't have conflicts on prod because +-- no additional observationlevelnames have been created other than global defaults from migration + +-- Update global level references to newly created program scoped levels +-- For prod, these will be: +-- * plot +-- * plant +-- * fish +-- * bine +-- * tree +-- There will be multiple instances as some levels are reused in different programs +-- +-- Need to handle observation_unit_position, but can skip & observation_unit_level and +-- study_observation_level. bi-api has never written study_observation_level and no records exist +-- in prod. observation_unit_level only has rep and block global references and those were already +-- updated in a previous migration. + +-- Updates observation_unit_position.level_name to point to the program-scoped +-- observation_unit_level_name record that matches the observation unit's +-- additional_info.observationLevel value. +-- +-- Only updates rows where: +-- * additional_info.observationLevel is present and not blank +-- * observation_unit.program_id is present +-- * the current linked level is null or does not already match the target +-- * some data like tree will point to plot due to how old data was written and will be fixed by this +-- * some data has null levels due to how it was written and will be fixed by this +WITH rows_to_update AS ( + SELECT + oup.id AS observation_unit_position_id, + target.id AS target_level_id + FROM observation_unit_position oup + JOIN observation_unit ou + ON ou.id = oup.observation_unit_id + JOIN observation_unit_level_name target + ON target.program_id = ou.program_id + AND target.level_name = lower(btrim(ou.additional_info ->> 'observationLevel')) + WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ou.program_id IS NOT NULL + AND oup.level_name IS DISTINCT FROM target.id + ) +UPDATE observation_unit_position oup +SET level_name = rows_to_update.target_level_id + FROM rows_to_update +WHERE oup.id = rows_to_update.observation_unit_position_id; + +-- Assertion to assure we don't remove additional_info.observationLevel where +-- references can't be updated. For our prod data, shouldn't be any. +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM observation_unit ou + WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ( + ou.program_id IS NULL + OR NOT EXISTS ( + SELECT 1 + FROM observation_unit_level_name ouln + WHERE ouln.program_id = ou.program_id + AND ouln.level_name = lower(btrim(ou.additional_info ->> 'observationLevel')) + ) + ) + ) THEN + RAISE EXCEPTION + 'V005.002 cannot remove observationLevel from observation_unit.additional_info because some rows could not be + mapped'; +END IF; +END $$; + +-- Remove observationLevel from additional_info in observation_unit table as it is no longer needed +UPDATE observation_unit +SET additional_info = additional_info - 'observationLevel'; + +-- Remove unused global level names (will exclude rep & block). On prod, these will be removed: +-- * entry +-- * field +-- * pot +-- * sample +-- * study +-- * sub-block +-- * sub-plot +-- Level is unused if not referenced in tables: +-- * observation_unit_position +-- * observation_unit_level +-- * study_observation_level has no existing data in prod but included +DELETE FROM observation_unit_level_name ouln +WHERE ouln.program_id IS NULL + AND NOT EXISTS ( + SELECT 1 FROM observation_unit_position oup WHERE oup.level_name = ouln.id + ) + AND NOT EXISTS ( + SELECT 1 FROM observation_unit_level oul WHERE oul.level_name = ouln.id + ) + AND NOT EXISTS ( + SELECT 1 FROM study_observation_level sol WHERE sol.level_name = ouln.id + ); From a9ef48501682c0f6088aa8fd8898dec2f2422a61 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Fri, 20 Mar 2026 17:44:13 -0400 Subject: [PATCH 34/34] Fix NPE use cases --- .../service/pheno/ObservationUnitLevelNameService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java index 70c183f9..1d918e1a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -76,7 +76,7 @@ public Map verifyObservationUnitLevelNam .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) .findFirst() .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); - } else if (StringUtils.isNotBlank(sln.getProgramDbId()) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { + } else if (StringUtils.isNotBlank(sln.getProgramDbId()) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()) != null) { List entities = foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()); entities.stream() @@ -85,7 +85,7 @@ public Map verifyObservationUnitLevelNam .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); } - if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size()) { + if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size() && foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES) != null) { // All other ways of detecting the level name have failed so far, try the global ones as a last-ditch effort List globalEntities = foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES);