From 3b2b0477f389f59a0430bd6fc3a60baf7934ad53 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 6 May 2026 16:46:07 -0400 Subject: [PATCH 01/10] Remove unused imports, comments, refactor some function names in BrAPITrialDAOImpl --- .../brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 30 +++---------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java index 29b01ed44..fbbf119b2 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java @@ -17,7 +17,6 @@ package org.breedinginsight.brapi.v2.dao.impl; import io.micronaut.context.annotation.Context; -import io.micronaut.context.annotation.Property; import io.micronaut.http.server.exceptions.InternalServerException; import lombok.extern.slf4j.Slf4j; import okhttp3.HttpUrl; @@ -33,10 +32,8 @@ import org.breedinginsight.brapi.v2.dao.BrAPITrialDAO; import org.breedinginsight.brapps.importer.daos.ImportDAO; import org.breedinginsight.brapps.importer.model.ImportUpload; -import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; import org.breedinginsight.daos.ProgramDAO; import org.breedinginsight.model.Program; -import org.breedinginsight.services.ProgramService; import org.breedinginsight.services.brapi.BrAPIEndpointProvider; import org.breedinginsight.services.exceptions.DoesNotExistException; import org.breedinginsight.utilities.BrAPIDAOUtil; @@ -54,33 +51,24 @@ public class BrAPITrialDAOImpl implements BrAPITrialDAO { private final ProgramDAO programDAO; private final ImportDAO importDAO; private final BrAPIDAOUtil brAPIDAOUtil; - private final ProgramService programService; private final BrAPIEndpointProvider brAPIEndpointProvider; - private final String referenceSource; - private final boolean runScheduledTasks; @Inject public BrAPITrialDAOImpl(ProgramDAO programDAO, ImportDAO importDAO, BrAPIDAOUtil brAPIDAOUtil, - ProgramService programService, - @Property(name = "brapi.server.reference-source") String referenceSource, - BrAPIEndpointProvider brAPIEndpointProvider, - @Property(name = "micronaut.bi.api.run-scheduled-tasks") boolean runScheduledTasks) { + BrAPIEndpointProvider brAPIEndpointProvider) { this.programDAO = programDAO; this.importDAO = importDAO; this.brAPIDAOUtil = brAPIDAOUtil; - this.programService = programService; - this.referenceSource = referenceSource; this.brAPIEndpointProvider = brAPIEndpointProvider; - this.runScheduledTasks = runScheduledTasks; } /** * This method requires a BI-API program. If the BrAPIProgram inside this data model is not set, * this method will retrieve it. */ - private List getBrAPITrialsUsingBrAPIProgram(Program program) throws ApiException { + private List getBrAPITrialsUsingBrAPIProgramId(Program program) throws ApiException { if (program == null || program.getId() == null) { throw new InternalServerException("BI-API Program or Program ID is null"); @@ -128,17 +116,9 @@ private List getTrialsFromBrAPI(Program program, TrialQueryParams tr return processExperimentsForDisplay(trialsFromResponse, program.getKey()); } - private Map experimentById(List trials) { - Map experimentById = new HashMap<>(); - for (BrAPITrial experiment: trials) { - experimentById.put(experiment.getTrialDbId(), experiment); - } - return experimentById; - } - @Override public List getTrialsByName(List trialNames, Program program) throws ApiException { - List allTrialsForProgram = getBrAPITrialsUsingBrAPIProgram(program); + List allTrialsForProgram = getBrAPITrialsUsingBrAPIProgramId(program); List trials = new ArrayList<>(); if (allTrialsForProgram != null) { @@ -151,7 +131,6 @@ public List getTrialsByName(List trialNames, Program program return trials; } - // TODO: Fix by using only code of inner callback and returning result @Override public List createBrAPITrials(List brAPITrialList, UUID programId, ImportUpload upload) { TrialsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), TrialsApi.class); @@ -177,7 +156,7 @@ public List getTrials(UUID programId) throws ApiException { Program program = programDAO.get(programId).get(0); program.setBrapiProgram(programDAO.getProgramBrAPI(program)); - return getBrAPITrialsUsingBrAPIProgram(program); + return getBrAPITrialsUsingBrAPIProgramId(program); } //Removes program key from trial name @@ -213,7 +192,6 @@ public List getTrialsByDbIds(Collection trialDbIds, Program return getTrialsByExperimentIds(trialDbUUIDs, program); } - // TODO: ExperimentIds will = trialDbIds once cache is updated. Update this method to get trials on dbId directly from brapi. @Override public List getTrialsByExperimentIds(Collection experimentIds, Program program) throws ApiException { if(experimentIds.isEmpty()) { From 3b081b8c5a127fd851e6a39ebefa69af6b4334dc Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 6 May 2026 16:59:23 -0400 Subject: [PATCH 02/10] Rename BrAPIStudyDAO method to reflect lookup on BrAPI Trial ExRef --- .../brapi/v2/dao/BrAPIStudyDAO.java | 6 +++--- .../brapi/v2/services/BrAPITrialService.java | 2 +- ...ulateExistingPendingImportObjectsStep.java | 2 +- .../services/BrAPITrialServiceUnitTest.java | 2 +- .../importer/ExperimentFileImportTest.java | 20 +++++++++---------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java index 7bc893f10..08298a130 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java @@ -136,11 +136,11 @@ public List getStudiesByName(List studyNames, Program progra ); } - public List getStudiesByExperimentID(@NotNull UUID experimentId, Program program) throws ApiException { - // TODO: This should look up on trialDbId, and the trialDbId should be passed thru + public List getStudiesByBrAPITrialExRefId(@NotNull UUID brapiTrialExRefId, Program program) throws ApiException { + // TODO: If external references are removed for trial for studies, this method should look up on trialDbId, and the trialDbId should be passed through. BrAPIStudySearchRequest studySearch = new BrAPIStudySearchRequest(); studySearch.programDbIds(List.of(program.getBrapiProgram().getProgramDbId())); - studySearch.addExternalReferenceIdsItem(experimentId.toString()); + studySearch.addExternalReferenceIdsItem(brapiTrialExRefId.toString()); studySearch.addExternalReferenceSourcesItem(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.TRIALS)); StudiesApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), StudiesApi.class); return brAPIDAOUtil.search( diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java index 34312233b..c1c4a44dd 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java @@ -196,7 +196,7 @@ public DownloadFile exportObservations( // get requested environments for the experiment log.debug(logHash + ": fetching environments for export"); - List expStudies = studyDAO.getStudiesByExperimentID(UUID.fromString(expExRefId), program); + List expStudies = studyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(expExRefId), program); if (!requestedEnvIds.isEmpty()) { expStudies = expStudies .stream() diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/create/workflow/steps/PopulateExistingPendingImportObjectsStep.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/create/workflow/steps/PopulateExistingPendingImportObjectsStep.java index 06c7c14c9..e4d6d93cc 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/create/workflow/steps/PopulateExistingPendingImportObjectsStep.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/create/workflow/steps/PopulateExistingPendingImportObjectsStep.java @@ -213,7 +213,7 @@ private Map> initializeStudyByNameNoScop try { // the 'trial' variable will never be "null". UUID experimentId = UUID.fromString(expExRefId); - existingStudies = brAPIStudyDAO.getStudiesByExperimentID(experimentId, program); + existingStudies = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(experimentId, program); for (BrAPIStudy existingStudy : existingStudies) { experimentStudyService.processAndCacheStudy(existingStudy, program, BrAPIStudy::getStudyName, studyByName); } diff --git a/src/test/java/org/breedinginsight/brapi/v2/services/BrAPITrialServiceUnitTest.java b/src/test/java/org/breedinginsight/brapi/v2/services/BrAPITrialServiceUnitTest.java index 866866195..c10778b35 100644 --- a/src/test/java/org/breedinginsight/brapi/v2/services/BrAPITrialServiceUnitTest.java +++ b/src/test/java/org/breedinginsight/brapi/v2/services/BrAPITrialServiceUnitTest.java @@ -171,7 +171,7 @@ void exportObservationsFetchesSeasonOncePerDistinctSeasonAndWritesEnvYears() thr when(trialDAO.getTrialsByExperimentIds(eq(List.of(UUID.fromString("11111111-1111-1111-1111-111111111111"))), eq(program))) .thenReturn(List.of(experiment)); - when(studyDAO.getStudiesByExperimentID(eq(UUID.fromString("11111111-1111-1111-1111-111111111111")), eq(program))) + when(studyDAO.getStudiesByBrAPITrialExRefId(eq(UUID.fromString("11111111-1111-1111-1111-111111111111")), eq(program))) .thenReturn(List.of(study, secondStudy)); when(seasonDAO.getSeasonById("season-1", program.getId())).thenReturn(season); when(seasonDAO.getSeasonById("season-2", program.getId())).thenReturn(secondSeason); diff --git a/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java b/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java index abd55e9b0..07f5f583c 100644 --- a/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java +++ b/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java @@ -926,7 +926,7 @@ public void importNewObsVarExistingOu() { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -992,7 +992,7 @@ public void importNewObsVarByObsUnitId() { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1046,7 +1046,7 @@ public void importNewObservationDataByObsUnitId(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1123,7 +1123,7 @@ public void verifyBlankObsInOverwriteIsNoOp(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); assertTrue(ouIdXref.isPresent()); @@ -1192,7 +1192,7 @@ public void importNewObsExistingOu(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1260,7 +1260,7 @@ public void verifyFailureImportNewObsExistingOuWithExistingObs(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1389,7 +1389,7 @@ public void importNewObsAfterFirstExpWithObs(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1466,7 +1466,7 @@ public void importNewObsAfterFirstExpWithObsAndTimestamps() { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1542,7 +1542,7 @@ public void importNewObsAfterFirstExpWithObs_blank(boolean commit) { BrAPITrial brAPITrial = brAPITrialDAO.getTrialsByName(List.of((String)newExp.get(Columns.EXP_TITLE)), program).get(0); Optional trialIdXref = Utilities.getExternalReference(brAPITrial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); + BrAPIStudy brAPIStudy = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program).get(0); BrAPIObservationUnit ou = ouDAO.getObservationUnitsForStudyDbId(brAPIStudy.getStudyDbId(), program).get(0); Optional ouIdXref = Utilities.getExternalReference(ou.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.OBSERVATION_UNITS.getName())); @@ -1639,7 +1639,7 @@ private Map assertRowSaved(Map expected, Program Optional trialIdXref = Utilities.getExternalReference(trial.getExternalReferences(), String.format("%s/%s", BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS.getName())); assertTrue(trialIdXref.isPresent()); - List studies = brAPIStudyDAO.getStudiesByExperimentID(UUID.fromString(trialIdXref.get().getReferenceId()), program); + List studies = brAPIStudyDAO.getStudiesByBrAPITrialExRefId(UUID.fromString(trialIdXref.get().getReferenceId()), program); assertFalse(studies.isEmpty()); BrAPIStudy study = null; for(BrAPIStudy s : studies) { From 092c25b60cf3ed86b269a07bb574345501f3bbc3 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 6 May 2026 17:04:03 -0400 Subject: [PATCH 03/10] Add comment on PendingImportObject id --- .../brapps/importer/model/response/PendingImportObject.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java b/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java index 9b0027e27..1cc24b9a3 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java +++ b/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java @@ -33,6 +33,7 @@ public class PendingImportObject { public PendingImportObject(ImportObjectState state, T brAPIObject, UUID id) { this.state = state; this.brAPIObject = brAPIObject; + // TODO: With 1.5 work, this id is the BI-API generated ID that is set for external references in BrAPI. It is different than the BrAPI DB ID of an entity. We may want to consider changing this at some point this.id = id; } public PendingImportObject(ImportObjectState state, T brAPIObject) { From 7425a6ead64199ca890ed0a4da44afda672f2ec5 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 27 May 2026 12:18:38 -0400 Subject: [PATCH 04/10] Update brapi java client version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 674e7ffea..009602e45 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 31.0.1-jre 4.9.3 4.3.1 - 2.2-SNAPSHOT + 2.2.1-SNAPSHOT 2.11.0 2.2.1 From da3eeb23acd2f833d844232266a1f5c77cfaa503 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Fri, 29 May 2026 11:36:26 -0400 Subject: [PATCH 05/10] Update TrialsController to support brapi side filter/sort/pagination Additionally, create utilities for developers to reuse --- .../v1/controller/ExperimentController.java | 4 +- .../brapi/v2/BrAPITrialsController.java | 16 ++-- .../brapi/v2/dao/BrAPITrialDAO.java | 5 ++ .../brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 88 ++++++++++++++++++- .../brapi/v2/services/BrAPITrialService.java | 10 ++- .../v2/utilities/BrAPISortFilterMapper.java | 28 ++++++ .../brapi/v2/utilities/BrAPITrialsMapper.java | 16 ++++ .../utilities/BrAPIDAOUtil.java | 83 ++++++++++++++++- .../utilities/response/ResponseUtils.java | 15 ++++ .../ExperimentControllerIntegrationTest.java | 7 +- .../brapi/v2/BrAPITestUtils.java | 3 +- ...tionVariableControllerIntegrationTest.java | 3 +- .../SubEntityDatasetLockIntegrationTest.java | 5 +- .../SampleSubmissionFileImportTest.java | 4 +- 14 files changed, 260 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPISortFilterMapper.java create mode 100644 src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPITrialsMapper.java diff --git a/src/main/java/org/breedinginsight/api/v1/controller/ExperimentController.java b/src/main/java/org/breedinginsight/api/v1/controller/ExperimentController.java index c846fb17d..41a167ed1 100644 --- a/src/main/java/org/breedinginsight/api/v1/controller/ExperimentController.java +++ b/src/main/java/org/breedinginsight/api/v1/controller/ExperimentController.java @@ -46,7 +46,6 @@ @Secured(SecurityRule.IS_AUTHENTICATED) public class ExperimentController { private final BrAPITrialService experimentService; - private final ExperimentQueryMapper experimentQueryMapper; private final ProgramService programService; private final ExperimentalCollaboratorService experimentalCollaboratorService; private final SecurityService securityService; @@ -54,9 +53,8 @@ public class ExperimentController { private final RoleService roleService; @Inject - public ExperimentController(BrAPITrialService experimentService, ExperimentQueryMapper experimentQueryMapper, ProgramService programService, ExperimentalCollaboratorService experimentalCollaboratorService, SecurityService securityService, ProgramUserService programUserService, RoleService roleService) { + public ExperimentController(BrAPITrialService experimentService, ProgramService programService, ExperimentalCollaboratorService experimentalCollaboratorService, SecurityService securityService, ProgramUserService programUserService, RoleService roleService) { this.experimentService = experimentService; - this.experimentQueryMapper = experimentQueryMapper; this.programService = programService; this.experimentalCollaboratorService = experimentalCollaboratorService; this.securityService = securityService; diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java index 195270184..8cf726e9e 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java @@ -26,8 +26,8 @@ import io.micronaut.security.rules.SecurityRule; import lombok.extern.slf4j.Slf4j; import org.brapi.client.v2.model.exceptions.ApiException; -import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.core.BrAPITrial; +import org.brapi.v2.model.core.response.BrAPITrialListResponse; import org.brapi.v2.model.core.response.BrAPITrialSingleResponse; import org.breedinginsight.api.auth.*; import org.breedinginsight.api.model.v1.request.query.SearchRequest; @@ -43,8 +43,6 @@ import org.breedinginsight.services.ExperimentalCollaboratorService; import org.breedinginsight.services.ProgramService; import org.breedinginsight.services.ProgramUserService; -import org.breedinginsight.model.ProgramUser; -import org.breedinginsight.model.Role; import org.breedinginsight.services.exceptions.DoesNotExistException; import org.breedinginsight.utilities.Utilities; import org.breedinginsight.utilities.response.ResponseUtils; @@ -52,7 +50,6 @@ import javax.inject.Inject; import javax.validation.Valid; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -65,6 +62,7 @@ public class BrAPITrialsController { private final String referenceSource; private final BrAPITrialService experimentService; + // TODO: See if it's feasible to remove this mapper entirely private final ExperimentQueryMapper experimentQueryMapper; private final SecurityService securityService; private final ProgramUserService programUserService; @@ -92,7 +90,7 @@ public BrAPITrialsController(BrAPITrialService experimentService, @Produces(MediaType.APPLICATION_JSON) @ProgramSecured(roles = {ProgramSecuredRole.SYSTEM_ADMIN, ProgramSecuredRole.READ_ONLY, ProgramSecuredRole.PROGRAM_ADMIN ,ProgramSecuredRole.EXPERIMENTAL_COLLABORATOR }) - public HttpResponse>>> getExperiments( + public HttpResponse>> getExperiments( @PathVariable("programId") UUID programId, @QueryValue @QueryValid(using = ExperimentQueryMapper.class) @Valid ExperimentQuery queryParams) { try { @@ -105,13 +103,17 @@ public HttpResponse>>> getExperiments( // If the program user is an experimental collaborator, filter results for only authorized experiments. Optional experimentalCollaborator = programUserService.getIfExperimentalCollaborator(programId, securityService.getUser().getId()); if (experimentalCollaborator.isPresent()) { + // TODO: Modify this code to use brapi side filter, pagination and sort List experimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); List authorizedExperiments = experimentService.getTrialsByExperimentIds(program.get(), experimentIds).stream().peek(this::setDbIds).collect(Collectors.toList()); return ResponseUtils.getBrapiQueryResponse(authorizedExperiments, experimentQueryMapper, queryParams, searchRequest); } - List experiments = experimentService.getExperiments(programId).stream().peek(this::setDbIds).collect(Collectors.toList()); - return ResponseUtils.getBrapiQueryResponse(experiments, experimentQueryMapper, queryParams, searchRequest); + BrAPITrialListResponse brapiResponse = experimentService.searchTrials(program.get(), queryParams); + + List foundTrials = brapiResponse.getResult().getData(); + foundTrials.forEach(this::setDbIds); + return ResponseUtils.getBrapiQueryResponse(foundTrials, brapiResponse, queryParams); } catch (ApiException e) { log.info(e.getMessage(), e); return HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR, "Error retrieving experiments"); diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java index bbc3ceb56..ebe6bf3b9 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java @@ -19,6 +19,9 @@ import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.v2.model.core.BrAPITrial; +import org.brapi.v2.model.core.request.BrAPITrialSearchRequest; +import org.brapi.v2.model.core.response.BrAPITrialListResponse; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapps.importer.model.ImportUpload; import org.breedinginsight.model.Program; import org.breedinginsight.services.exceptions.DoesNotExistException; @@ -45,4 +48,6 @@ List createBrAPITrials(List brAPITrialList, UUID program List getTrialsByExperimentIds(Collection experimentIds, Program program) throws ApiException; void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) throws ApiException; + + BrAPITrialListResponse brapiTrialSearch(Program program, ExperimentQuery experimentQuery) throws ApiException; } diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java index fbbf119b2..db5dc969c 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java @@ -21,15 +21,21 @@ import lombok.extern.slf4j.Slf4j; import okhttp3.HttpUrl; import okhttp3.Request; +import org.apache.commons.lang3.StringUtils; import org.brapi.client.v2.ApiResponse; import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.client.v2.model.queryParams.core.TrialQueryParams; import org.brapi.client.v2.modules.core.TrialsApi; +import org.brapi.v2.model.BrAPIFilterBy; +import org.brapi.v2.model.BrAPIResponse; +import org.brapi.v2.model.BrAPISortBy; import org.brapi.v2.model.core.BrAPIProgram; import org.brapi.v2.model.core.BrAPITrial; import org.brapi.v2.model.core.request.BrAPITrialSearchRequest; import org.brapi.v2.model.core.response.BrAPITrialListResponse; import org.breedinginsight.brapi.v2.dao.BrAPITrialDAO; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; +import org.breedinginsight.brapi.v2.utilities.BrAPITrialsMapper; import org.breedinginsight.brapps.importer.daos.ImportDAO; import org.breedinginsight.brapps.importer.model.ImportUpload; import org.breedinginsight.daos.ProgramDAO; @@ -52,16 +58,25 @@ public class BrAPITrialDAOImpl implements BrAPITrialDAO { private final ImportDAO importDAO; private final BrAPIDAOUtil brAPIDAOUtil; private final BrAPIEndpointProvider brAPIEndpointProvider; + private final BrAPITrialsMapper brAPITrialsMapper; + + + private static final String BI_FILTER_COLUMN_NAME = "name"; + private static final String BI_FILTER_COLUMN_ACTIVE = "active"; + private static final String BI_FILTER_COLUMN_CREATED_DATE = "createdDate"; + private static final String BI_FILTER_COLUMN_CREATED_BY = "createdBy"; @Inject public BrAPITrialDAOImpl(ProgramDAO programDAO, ImportDAO importDAO, BrAPIDAOUtil brAPIDAOUtil, - BrAPIEndpointProvider brAPIEndpointProvider) { + BrAPIEndpointProvider brAPIEndpointProvider, + BrAPITrialsMapper brAPITrialsMapper) { this.programDAO = programDAO; this.importDAO = importDAO; this.brAPIDAOUtil = brAPIDAOUtil; this.brAPIEndpointProvider = brAPIEndpointProvider; + this.brAPITrialsMapper = brAPITrialsMapper; } /** @@ -211,6 +226,27 @@ public List getTrialsByExperimentIds(Collection experimentIds, ), program.getKey()); } + @Override + public BrAPITrialListResponse brapiTrialSearch(Program program, + ExperimentQuery experimentQuery) throws ApiException { + TrialsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), TrialsApi.class); + + BrAPITrialSearchRequest brAPITrialSearchRequest = buildSearchRequest(program, experimentQuery); + + BrAPITrialListResponse brAPIResponse = + brAPIDAOUtil.simpleSearch( + api::searchTrialsPost, + brAPITrialSearchRequest + ); + + List processedTrials = + processExperimentsForDisplay(brAPIDAOUtil.getListResult(brAPIResponse), program.getKey()); + + brAPIResponse.getResult().setData(processedTrials); + + return brAPIResponse; + } + @Override public void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) throws ApiException { // TODO: Switch to using the TrialsApi from the BrAPI client library once the delete endpoints are merged into it. @@ -225,4 +261,54 @@ public void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) th brAPIDAOUtil.makeCall(brapiRequest); } + + + private BrAPITrialSearchRequest buildSearchRequest(Program program, ExperimentQuery experimentQuery) { + BrAPIProgram brAPIProgram = programDAO.getProgramBrAPI(program); + + if (brAPIProgram == null || brAPIProgram.getProgramDbId() == null) { + throw new InternalServerException(String.format("BI program with id [%s] not found in BrAPI db", program.getId())); + } + + BrAPITrialSearchRequest searchRequest = new BrAPITrialSearchRequest(); + + searchRequest.programDbIds(List.of(brAPIProgram.getProgramDbId())); + + // Set FilterBy + List brAPIFilterBy = new ArrayList<>(); + + if (StringUtils.isNotBlank(experimentQuery.getName())) { + brAPIFilterBy.add(brAPIDAOUtil.constructFilterBy(brAPITrialsMapper.getBrAPIName(BI_FILTER_COLUMN_NAME), experimentQuery.getName())); + } + if (StringUtils.isNotBlank(experimentQuery.getActive())) { + brAPIFilterBy.add(brAPIDAOUtil.constructFilterBy(brAPITrialsMapper.getBrAPIName(BI_FILTER_COLUMN_ACTIVE), experimentQuery.getActive())); + } + if (StringUtils.isNotBlank(experimentQuery.getCreatedBy())) { + brAPIFilterBy.add(brAPIDAOUtil.constructFilterBy(brAPITrialsMapper.getBrAPIName(BI_FILTER_COLUMN_CREATED_BY), experimentQuery.getCreatedBy())); + } + if (StringUtils.isNotBlank(experimentQuery.getCreatedDate())) { + brAPIFilterBy.add(brAPIDAOUtil.constructFilterBy(brAPITrialsMapper.getBrAPIName(BI_FILTER_COLUMN_CREATED_DATE), experimentQuery.getCreatedDate())); + } + + if (!brAPIFilterBy.isEmpty()) { + searchRequest.setFilterBy(brAPIFilterBy); + } + + // Set SortBy + List brAPISortBy = new ArrayList<>(); + + if (StringUtils.isNotBlank(experimentQuery.getSortField()) && brAPITrialsMapper.exists(experimentQuery.getSortField())) { + brAPISortBy.add(brAPIDAOUtil.constructSortBy(brAPITrialsMapper.getBrAPIName(experimentQuery.getSortField()), experimentQuery.getSortOrder().toString())); + } + + if (!brAPISortBy.isEmpty()) { + searchRequest.setSortBy(brAPISortBy); + } + + searchRequest.setPage(experimentQuery.getPage()); + searchRequest.setPageSize(experimentQuery.getPageSize()); + + return searchRequest; + + } } diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java index c1c4a44dd..a6c739047 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java @@ -15,6 +15,7 @@ import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.core.*; import org.brapi.v2.model.core.response.BrAPIListsSingleResponse; +import org.brapi.v2.model.core.response.BrAPITrialListResponse; import org.brapi.v2.model.germ.BrAPIGermplasm; import org.brapi.v2.model.pheno.*; @@ -22,6 +23,7 @@ import org.breedinginsight.brapi.v2.constants.BrAPIAdditionalInfoFields; import org.breedinginsight.brapi.v2.dao.*; import org.breedinginsight.brapi.v2.model.request.query.ExperimentExportQuery; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapps.importer.model.exports.FileType; import org.breedinginsight.brapps.importer.model.imports.experimentObservation.ExperimentObservation; import org.breedinginsight.brapps.importer.model.imports.experimentObservation.ExperimentObservation.Columns; @@ -120,8 +122,12 @@ public BrAPITrialService(@Property(name = "brapi.server.reference-source") Strin this.observationLevelService = observationLevelService; } - public List getExperiments(UUID programId) throws ApiException, DoesNotExistException { - // TODO: Edit this to filter/paginate trials + public BrAPITrialListResponse searchTrials(Program program, + ExperimentQuery experimentQuery) throws ApiException, DoesNotExistException { + return trialDAO.brapiTrialSearch(program, experimentQuery); + } + + public List getTrialsByProgramId(UUID programId) throws ApiException { return trialDAO.getTrials(programId); } diff --git a/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPISortFilterMapper.java b/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPISortFilterMapper.java new file mode 100644 index 000000000..388a481cd --- /dev/null +++ b/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPISortFilterMapper.java @@ -0,0 +1,28 @@ +package org.breedinginsight.brapi.v2.utilities; + +import java.util.Map; + +public abstract class BrAPISortFilterMapper { + + private final Map fields; + + protected BrAPISortFilterMapper(Map fields) { + this.fields = Map.copyOf(fields); + } + + public boolean exists(String fieldName) { + return fields.containsKey(fieldName); + } + + public String getBrAPIName(String biFieldName) throws NullPointerException { + String value = fields.get(biFieldName); + + if (value == null) { + throw new IllegalArgumentException( + "No BrAPI mapping exists for field: " + biFieldName + ); + } + + return value; + } +} diff --git a/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPITrialsMapper.java b/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPITrialsMapper.java new file mode 100644 index 000000000..0107efe86 --- /dev/null +++ b/src/main/java/org/breedinginsight/brapi/v2/utilities/BrAPITrialsMapper.java @@ -0,0 +1,16 @@ +package org.breedinginsight.brapi.v2.utilities; + +import javax.inject.Singleton; +import java.util.Map; + +@Singleton +public class BrAPITrialsMapper extends BrAPISortFilterMapper { + public BrAPITrialsMapper() { + super(Map.of( + "name", "trialName", + "active", "active", + "createdBy", "createdBy", + "createdDate", "createdDate" + )); + } +} diff --git a/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java b/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java index cab44d951..a9049663a 100644 --- a/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java +++ b/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java @@ -44,10 +44,7 @@ import javax.inject.Singleton; import java.io.IOException; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeUnit; import static org.brapi.v2.model.BrAPIWSMIMEDataTypes.APPLICATION_JSON; @@ -78,6 +75,53 @@ public BrAPIDAOUtil(@Property(name = "brapi.search.wait-time") int searchWaitTim this.programService = programService; } + // Performs a POST brapi search on an entity without looping paging logic, utilizing filters and pagination provided in the searchBody. + // Also verifies response paging matches requested paging + public T simpleSearch(Function, Optional>>> searchMethod, + U searchBody) throws ApiException { + List result = new ArrayList<>(); + + + T brapiResponseResult = null; + + try { + // Traverse response with an optional to allow for free null checking with .map() + brapiResponseResult = Optional.ofNullable(searchMethod.apply(searchBody)) + .map(ApiResponse::getBody) + .map(Pair::getLeft) + // Deal with wrapped Optionals + .flatMap(optional -> optional) + .orElseThrow(); + } catch (ApiException e) { + log.warn(Utilities.generateApiExceptionLogMessage(e)); + throw e; + } catch (NoSuchElementException e) { + log.debug("Unable to retrieve BrAPIResponse from POST search request", e); + throw new InternalServerException(e.toString(), e); + } catch (Exception e) { + log.debug("error", e); + throw new InternalServerException(e.toString(), e); + } + + BrAPIPagination responsePagination = Optional.of(brapiResponseResult) + .map(BrAPIResponse::getMetadata) + .map(BrAPIMetadata::getPagination) + .orElse(null); + + if (responsePagination == null) { + throw new InternalServerException("Expected pagination metadata in BrAPI search response not present"); + } + + var requestPageNumber = searchBody.getPage(); + var requestPageSize = searchBody.getPageSize(); + + if (!responsePagination.getCurrentPage().equals(requestPageNumber) || !responsePagination.getPageSize().equals(requestPageSize)) { + throw new InternalServerException("Page number and/or page size do not match between BrAPI search request and response"); + } + + return brapiResponseResult; + } + public List search(Function, Optional>>> searchMethod, Function3, Optional>>> searchGetMethod, U searchBody @@ -302,6 +346,14 @@ private List getListResult(ApiResponse, Optional(); } + public List getListResult(T response) { + return Optional.ofNullable(response) + .map(BrAPIResponse::getResult) + .map(result -> (BrAPIResponseResult) result) + .map(BrAPIResponseResult::getData) + .orElseThrow(); + } + // TODO: write generic put code public List put(List brapiObjects, ImportUpload upload, @@ -455,4 +507,27 @@ public String getProgramBrAPIBaseUrl(UUID programId) { programBrAPIBaseUrl = programBrAPIBaseUrl.endsWith("/") ? programBrAPIBaseUrl.substring(0, programBrAPIBaseUrl.length() - 1) : programBrAPIBaseUrl; return programBrAPIBaseUrl.endsWith(BrapiVersion.BRAPI_V2) ? programBrAPIBaseUrl : programBrAPIBaseUrl + BrapiVersion.BRAPI_V2; } + + public BrAPIFilterBy constructFilterBy(String filterOn, String value) { + var filterBy = new BrAPIFilterBy(); + + filterBy.setFilterOn(filterOn); + filterBy.setValue(value); + return filterBy; + } + + public BrAPISortBy constructSortBy(String sortOn, String sortOrder) { + var sortBy = new BrAPISortBy(); + sortBy.setSortedOn(sortOn); + + BrAPISortOrder sortOrderEnum = BrAPISortOrder.valueOf(sortOrder.toUpperCase()); + + if (sortOrderEnum == null) { + sortOrderEnum = BrAPISortOrder.ASC; + } + + sortBy.setSortOrder(sortOrderEnum); + + return sortBy; + } } diff --git a/src/main/java/org/breedinginsight/utilities/response/ResponseUtils.java b/src/main/java/org/breedinginsight/utilities/response/ResponseUtils.java index cb8791fae..6f6e41614 100644 --- a/src/main/java/org/breedinginsight/utilities/response/ResponseUtils.java +++ b/src/main/java/org/breedinginsight/utilities/response/ResponseUtils.java @@ -24,6 +24,8 @@ import io.micronaut.http.exceptions.HttpStatusException; import io.micronaut.http.server.types.files.StreamedFile; import org.apache.commons.lang3.tuple.Pair; +import org.brapi.client.v2.model.queryParams.core.BrAPIQueryParams; +import org.brapi.v2.model.BrAPIResponse; import org.breedinginsight.api.model.v1.request.query.PaginationParams; import org.breedinginsight.api.model.v1.request.query.QueryParams; import org.breedinginsight.api.model.v1.request.query.SearchRequest; @@ -129,6 +131,19 @@ private static HttpResponse>> processBrapiResponse( return HttpResponse.ok(new Response(metadata, new DataResponse(paginationResult.getLeft()))); } + public static HttpResponse>> getBrapiQueryResponse(List data, + BrAPIResponse brAPIResponse, + BrapiQuery queryParams) { + Pagination pagination = new Pagination(); + pagination.setTotalCount(brAPIResponse.getMetadata().getPagination().getTotalCount()); + pagination.setCurrentPage(queryParams.getPage()); + pagination.setPageSize(queryParams.getPageSize()); + + Metadata metadata = constructMetadata(new Metadata(), pagination); + + return HttpResponse.ok(new Response<>(metadata, new DataResponse<>(data))); + } + private static HttpResponse> processUploadSearchResponse( ProgramUpload upload, SearchRequest searchRequest, QueryParams queryParams, AbstractQueryMapper mapper, Metadata metadata) { diff --git a/src/test/java/org/breedinginsight/api/v1/controller/ExperimentControllerIntegrationTest.java b/src/test/java/org/breedinginsight/api/v1/controller/ExperimentControllerIntegrationTest.java index bf8f6ba52..d95270d27 100644 --- a/src/test/java/org/breedinginsight/api/v1/controller/ExperimentControllerIntegrationTest.java +++ b/src/test/java/org/breedinginsight/api/v1/controller/ExperimentControllerIntegrationTest.java @@ -24,6 +24,7 @@ import org.breedinginsight.api.model.v1.request.ProgramRequest; import org.breedinginsight.api.model.v1.request.SpeciesRequest; import org.breedinginsight.brapi.v2.dao.BrAPIGermplasmDAO; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapi.v2.services.BrAPITrialService; import org.breedinginsight.brapps.importer.ImportTestUtils; import org.breedinginsight.brapps.importer.model.exports.FileType; @@ -204,7 +205,7 @@ void setup() throws Exception { mappingId, newExperimentWorkflowId); - BrAPITrial trial = brAPITrialService.getExperiments(program.getId()).get(0); + BrAPITrial trial = brAPITrialService.getTrialsByProgramId(program.getId()).get(0); experimentId = trial.getTrialDbId(); @@ -244,7 +245,7 @@ private String uploadExperimentWithoutObs(Program targetProgram, String title, S mappingId, newExperimentWorkflowId); - BrAPITrial trial = brAPITrialService.getExperiments(targetProgram.getId()) + BrAPITrial trial = brAPITrialService.getTrialsByProgramId(targetProgram.getId()) .stream() .filter(t -> t.getTrialName().equals(title)) .findFirst() @@ -939,7 +940,7 @@ private String uploadExperimentWithObs(Program targetProgram, String title, List mappingId, newExperimentWorkflowId); - BrAPITrial trial = brAPITrialService.getExperiments(targetProgram.getId()) + BrAPITrial trial = brAPITrialService.getTrialsByProgramId(targetProgram.getId()) .stream() .filter(t -> t.getTrialName().equals(title)) .findFirst() diff --git a/src/test/java/org/breedinginsight/brapi/v2/BrAPITestUtils.java b/src/test/java/org/breedinginsight/brapi/v2/BrAPITestUtils.java index 44caec1fa..6af62c7cf 100644 --- a/src/test/java/org/breedinginsight/brapi/v2/BrAPITestUtils.java +++ b/src/test/java/org/breedinginsight/brapi/v2/BrAPITestUtils.java @@ -38,6 +38,7 @@ import org.breedinginsight.api.model.v1.request.SpeciesRequest; import org.breedinginsight.api.v1.controller.TestTokenValidator; import org.breedinginsight.brapi.v2.dao.BrAPIGermplasmDAO; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapi.v2.services.BrAPITrialService; import org.breedinginsight.brapps.importer.ImportTestUtils; import org.breedinginsight.brapps.importer.model.imports.experimentObservation.ExperimentObservation; @@ -200,7 +201,7 @@ public Tuple2> setupTestProgram(DSLContext brAPIDslContext mappingId, newExperimentWorkflowId); - List trials = brAPITrialService.getExperiments(program.getId()) + List trials = brAPITrialService.getTrialsByProgramId(program.getId()) .stream() // Ensure trial with title xyz is always second .sorted(Comparator.comparing(BrAPITrial::getTrialName)) diff --git a/src/test/java/org/breedinginsight/brapi/v2/BrAPIV2ObservationVariableControllerIntegrationTest.java b/src/test/java/org/breedinginsight/brapi/v2/BrAPIV2ObservationVariableControllerIntegrationTest.java index 17f91ea0c..f8a99ac35 100644 --- a/src/test/java/org/breedinginsight/brapi/v2/BrAPIV2ObservationVariableControllerIntegrationTest.java +++ b/src/test/java/org/breedinginsight/brapi/v2/BrAPIV2ObservationVariableControllerIntegrationTest.java @@ -41,6 +41,7 @@ import org.breedinginsight.api.model.v1.request.SpeciesRequest; import org.breedinginsight.api.v1.controller.TestTokenValidator; import org.breedinginsight.brapi.v2.dao.BrAPIGermplasmDAO; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapi.v2.services.BrAPITrialService; import org.breedinginsight.brapps.importer.ImportTestUtils; import org.breedinginsight.brapps.importer.model.imports.experimentObservation.ExperimentObservation; @@ -200,7 +201,7 @@ void setup() throws Exception { mappingId, newExperimentWorkflowId); - BrAPITrial trial = brAPITrialService.getExperiments(program.getId()) + BrAPITrial trial = brAPITrialService.getTrialsByProgramId(program.getId()) .stream() .findFirst() .orElseThrow(); diff --git a/src/test/java/org/breedinginsight/brapi/v2/SubEntityDatasetLockIntegrationTest.java b/src/test/java/org/breedinginsight/brapi/v2/SubEntityDatasetLockIntegrationTest.java index 1e1f3c110..c0b3dd029 100644 --- a/src/test/java/org/breedinginsight/brapi/v2/SubEntityDatasetLockIntegrationTest.java +++ b/src/test/java/org/breedinginsight/brapi/v2/SubEntityDatasetLockIntegrationTest.java @@ -1,7 +1,6 @@ package org.breedinginsight.brapi.v2; import com.google.gson.*; -import io.micronaut.context.annotation.Property; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; @@ -12,6 +11,7 @@ import io.reactivex.Flowable; import org.brapi.v2.model.core.BrAPITrial; import org.breedinginsight.BrAPITest; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapi.v2.services.BrAPITrialService; import org.breedinginsight.model.Program; import org.junit.jupiter.api.*; @@ -22,7 +22,6 @@ import java.util.Objects; import java.util.UUID; import java.util.concurrent.*; -import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.*; @@ -51,7 +50,7 @@ public class SubEntityDatasetLockIntegrationTest extends BrAPITest { void setup() throws Exception { var setup = brAPITestUtils.setupTestProgram(super.getBrapiDsl(), gson); program = setup.getV1(); - experimentId = brAPIITrialService.getExperiments(program.getId()).stream() + experimentId = brAPIITrialService.getTrialsByProgramId(program.getId()).stream() .map(BrAPITrial::getTrialDbId) .findFirst() .orElseThrow(); diff --git a/src/test/java/org/breedinginsight/brapps/importer/SampleSubmissionFileImportTest.java b/src/test/java/org/breedinginsight/brapps/importer/SampleSubmissionFileImportTest.java index b59c41900..1705360f3 100644 --- a/src/test/java/org/breedinginsight/brapps/importer/SampleSubmissionFileImportTest.java +++ b/src/test/java/org/breedinginsight/brapps/importer/SampleSubmissionFileImportTest.java @@ -45,8 +45,8 @@ import org.breedinginsight.api.model.v1.request.SpeciesRequest; import org.breedinginsight.brapi.v2.constants.BrAPIAdditionalInfoFields; import org.breedinginsight.brapi.v2.dao.*; +import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery; import org.breedinginsight.brapi.v2.services.BrAPITrialService; -import org.breedinginsight.brapps.importer.daos.*; import org.breedinginsight.brapps.importer.model.imports.experimentObservation.ExperimentObservation; import org.breedinginsight.brapps.importer.model.imports.sample.SampleSubmissionImport.Columns; import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; @@ -585,7 +585,7 @@ private String createExperiment(Program program) throws IOException, Interrupted try { // Assumes only one trial/experiment exists - BrAPITrial trial = brAPITrialService.getExperiments(program.getId()) + BrAPITrial trial = brAPITrialService.getTrialsByProgramId(program.getId()) .stream() .findFirst() .orElseThrow(); From 174378a8cd1711b2de6cb9b9ee01a52d2ff2e845 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Fri, 29 May 2026 13:01:45 -0400 Subject: [PATCH 06/10] Add pagination logic to use defaults if not provided - This fixed unit test failures --- .../brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 3 +-- .../utilities/BrAPIDAOUtil.java | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java index db5dc969c..efc444bb7 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java @@ -305,8 +305,7 @@ private BrAPITrialSearchRequest buildSearchRequest(Program program, ExperimentQu searchRequest.setSortBy(brAPISortBy); } - searchRequest.setPage(experimentQuery.getPage()); - searchRequest.setPageSize(experimentQuery.getPageSize()); + brAPIDAOUtil.setPagination(searchRequest, experimentQuery); return searchRequest; diff --git a/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java b/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java index a9049663a..947625656 100644 --- a/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java +++ b/src/main/java/org/breedinginsight/utilities/BrAPIDAOUtil.java @@ -35,6 +35,7 @@ import org.brapi.v2.model.*; import org.breedinginsight.api.model.v1.response.DataResponse; import org.breedinginsight.brapi.v1.controller.BrapiVersion; +import org.breedinginsight.brapi.v1.model.request.query.BrapiQuery; import org.breedinginsight.brapps.importer.model.ImportUpload; import org.breedinginsight.model.ProgramBrAPIEndpoints; import org.breedinginsight.services.ProgramService; @@ -79,10 +80,7 @@ public BrAPIDAOUtil(@Property(name = "brapi.search.wait-time") int searchWaitTim // Also verifies response paging matches requested paging public T simpleSearch(Function, Optional>>> searchMethod, U searchBody) throws ApiException { - List result = new ArrayList<>(); - - - T brapiResponseResult = null; + T brapiResponseResult; try { // Traverse response with an optional to allow for free null checking with .map() @@ -530,4 +528,18 @@ public BrAPISortBy constructSortBy(String sortOn, String sortOrder) { return sortBy; } + + public void setPagination(T brapiSearchRequest, U biSearchQuery) { + if (biSearchQuery.getPage() == null) { + brapiSearchRequest.setPage(biSearchQuery.getDefaultPage()); + } else { + brapiSearchRequest.setPage(biSearchQuery.getPage()); + } + + if (biSearchQuery.getPageSize() == null) { + brapiSearchRequest.setPageSize(biSearchQuery.getDefaultPageSize()); + } else { + brapiSearchRequest.setPageSize(biSearchQuery.getPageSize()); + } + } } From 73218043fc5e5a84b601d0e3f82f6a98f3f50bf5 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Fri, 29 May 2026 15:35:12 -0400 Subject: [PATCH 07/10] Fix Trial collaborator use case --- .../brapi/v2/BrAPITrialsController.java | 11 ++++++++--- .../brapi/v2/dao/BrAPITrialDAO.java | 3 +++ .../brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 16 +++++++++++++--- .../brapi/v2/services/BrAPITrialService.java | 6 ++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java index 8cf726e9e..ff0b3a2c1 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java @@ -104,9 +104,14 @@ public HttpResponse>> getExperiments( Optional experimentalCollaborator = programUserService.getIfExperimentalCollaborator(programId, securityService.getUser().getId()); if (experimentalCollaborator.isPresent()) { // TODO: Modify this code to use brapi side filter, pagination and sort - List experimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); - List authorizedExperiments = experimentService.getTrialsByExperimentIds(program.get(), experimentIds).stream().peek(this::setDbIds).collect(Collectors.toList()); - return ResponseUtils.getBrapiQueryResponse(authorizedExperiments, experimentQueryMapper, queryParams, searchRequest); + List authorizedExperimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); + + BrAPITrialListResponse brapiResponse = experimentService.searchTrials(program.get(), authorizedExperimentIds, queryParams); + + List foundTrials = brapiResponse.getResult().getData(); + foundTrials.forEach(this::setDbIds); + + return ResponseUtils.getBrapiQueryResponse(foundTrials, brapiResponse, queryParams); } BrAPITrialListResponse brapiResponse = experimentService.searchTrials(program.get(), queryParams); diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java index ebe6bf3b9..1a6a4424b 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPITrialDAO.java @@ -50,4 +50,7 @@ List createBrAPITrials(List brAPITrialList, UUID program void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) throws ApiException; BrAPITrialListResponse brapiTrialSearch(Program program, ExperimentQuery experimentQuery) throws ApiException; + + BrAPITrialListResponse brapiTrialSearch(Program program, List brapiTrialIds, ExperimentQuery experimentQuery) throws ApiException; + } diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java index efc444bb7..e93a8e73e 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java @@ -226,12 +226,18 @@ public List getTrialsByExperimentIds(Collection experimentIds, ), program.getKey()); } + @Override + public BrAPITrialListResponse brapiTrialSearch(Program program, ExperimentQuery experimentQuery) throws ApiException { + return brapiTrialSearch(program, Collections.emptyList(), experimentQuery); + } + @Override public BrAPITrialListResponse brapiTrialSearch(Program program, - ExperimentQuery experimentQuery) throws ApiException { + List brapiTrialIds, + ExperimentQuery experimentQuery) throws ApiException { TrialsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), TrialsApi.class); - BrAPITrialSearchRequest brAPITrialSearchRequest = buildSearchRequest(program, experimentQuery); + BrAPITrialSearchRequest brAPITrialSearchRequest = buildSearchRequest(program, brapiTrialIds, experimentQuery); BrAPITrialListResponse brAPIResponse = brAPIDAOUtil.simpleSearch( @@ -263,7 +269,7 @@ public void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) th } - private BrAPITrialSearchRequest buildSearchRequest(Program program, ExperimentQuery experimentQuery) { + private BrAPITrialSearchRequest buildSearchRequest(Program program, List brapiTrialIds, ExperimentQuery experimentQuery) { BrAPIProgram brAPIProgram = programDAO.getProgramBrAPI(program); if (brAPIProgram == null || brAPIProgram.getProgramDbId() == null) { @@ -274,6 +280,10 @@ private BrAPITrialSearchRequest buildSearchRequest(Program program, ExperimentQu searchRequest.programDbIds(List.of(brAPIProgram.getProgramDbId())); + if (brapiTrialIds != null && !brapiTrialIds.isEmpty()) { + searchRequest.setTrialDbIds(brapiTrialIds.stream().map(UUID::toString).collect(Collectors.toList())); + } + // Set FilterBy List brAPIFilterBy = new ArrayList<>(); diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java index a6c739047..8d7ca67ef 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java @@ -127,6 +127,12 @@ public BrAPITrialListResponse searchTrials(Program program, return trialDAO.brapiTrialSearch(program, experimentQuery); } + public BrAPITrialListResponse searchTrials(Program program, + List brapiTrialIds, + ExperimentQuery experimentQuery) throws ApiException, DoesNotExistException { + return trialDAO.brapiTrialSearch(program, brapiTrialIds, experimentQuery); + } + public List getTrialsByProgramId(UUID programId) throws ApiException { return trialDAO.getTrials(programId); } From 4b9d345260c504d67645c2a026ba236a44b1284a Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Mon, 1 Jun 2026 17:40:29 -0400 Subject: [PATCH 08/10] Remove comment --- .../org/breedinginsight/brapi/v2/BrAPITrialsController.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java index ff0b3a2c1..351f66efc 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java @@ -62,8 +62,6 @@ public class BrAPITrialsController { private final String referenceSource; private final BrAPITrialService experimentService; - // TODO: See if it's feasible to remove this mapper entirely - private final ExperimentQueryMapper experimentQueryMapper; private final SecurityService securityService; private final ProgramUserService programUserService; private final ExperimentalCollaboratorService experimentalCollaboratorService; @@ -71,14 +69,12 @@ public class BrAPITrialsController { @Inject public BrAPITrialsController(BrAPITrialService experimentService, - ExperimentQueryMapper experimentQueryMapper, @Property(name = "brapi.server.reference-source") String referenceSource, SecurityService securityService, ProgramUserService programUserService, ExperimentalCollaboratorService experimentalCollaboratorService, ProgramService programService) { this.experimentService = experimentService; - this.experimentQueryMapper = experimentQueryMapper; this.referenceSource = referenceSource; this.securityService = securityService; this.programUserService = programUserService; @@ -103,7 +99,6 @@ public HttpResponse>> getExperiments( // If the program user is an experimental collaborator, filter results for only authorized experiments. Optional experimentalCollaborator = programUserService.getIfExperimentalCollaborator(programId, securityService.getUser().getId()); if (experimentalCollaborator.isPresent()) { - // TODO: Modify this code to use brapi side filter, pagination and sort List authorizedExperimentIds = experimentalCollaboratorService.getAuthorizedExperimentIds(experimentalCollaborator.get().getId()); BrAPITrialListResponse brapiResponse = experimentService.searchTrials(program.get(), authorizedExperimentIds, queryParams); From edd03fd1a427f21536331bce6f6ea4b12df2d2b8 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 10 Jun 2026 12:04:41 -0400 Subject: [PATCH 09/10] Update TODO comments with created tickets/epics --- .../java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java | 2 +- .../breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 4 ++-- .../brapps/importer/model/response/PendingImportObject.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java index 08298a130..ccbe0abfd 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java @@ -137,7 +137,7 @@ public List getStudiesByName(List studyNames, Program progra } public List getStudiesByBrAPITrialExRefId(@NotNull UUID brapiTrialExRefId, Program program) throws ApiException { - // TODO: If external references are removed for trial for studies, this method should look up on trialDbId, and the trialDbId should be passed through. + // TODO: If external references are removed for trial for studies, this method should look up on trialDbId, and the trialDbId should be passed through. [BI-2933] BrAPIStudySearchRequest studySearch = new BrAPIStudySearchRequest(); studySearch.programDbIds(List.of(program.getBrapiProgram().getProgramDbId())); studySearch.addExternalReferenceIdsItem(brapiTrialExRefId.toString()); diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java index e93a8e73e..b5465830d 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/impl/BrAPITrialDAOImpl.java @@ -83,6 +83,7 @@ public BrAPITrialDAOImpl(ProgramDAO programDAO, * This method requires a BI-API program. If the BrAPIProgram inside this data model is not set, * this method will retrieve it. */ + // TODO: Generalize Code for General Get By Program for BrAPI Entities [BI-2932] private List getBrAPITrialsUsingBrAPIProgramId(Program program) throws ApiException { if (program == null || program.getId() == null) { @@ -98,7 +99,7 @@ private List getBrAPITrialsUsingBrAPIProgramId(Program program) thro brapiProgramDbId = programDAO.getProgramBrAPI(program).getProgramDbId(); } - // TODO: Configurable max amount of trials per program, or paginate. + // TODO: Configurable max amount of trials per program, or paginate [BI-2932] TrialQueryParams trialQueryParams = TrialQueryParams.builder() @@ -255,7 +256,6 @@ public BrAPITrialListResponse brapiTrialSearch(Program program, @Override public void deleteBrAPITrial(Program program, BrAPITrial trial, boolean hard) throws ApiException { - // TODO: Switch to using the TrialsApi from the BrAPI client library once the delete endpoints are merged into it. var programBrAPIBaseUrl = brAPIDAOUtil.getProgramBrAPIBaseUrl(program.getId()); var requestUrl = HttpUrl.parse(programBrAPIBaseUrl + "/trials/" + trial.getTrialDbId()).newBuilder(); requestUrl.addQueryParameter("hardDelete", Boolean.toString(hard)); diff --git a/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java b/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java index 1cc24b9a3..934d1a565 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java +++ b/src/main/java/org/breedinginsight/brapps/importer/model/response/PendingImportObject.java @@ -33,7 +33,7 @@ public class PendingImportObject { public PendingImportObject(ImportObjectState state, T brAPIObject, UUID id) { this.state = state; this.brAPIObject = brAPIObject; - // TODO: With 1.5 work, this id is the BI-API generated ID that is set for external references in BrAPI. It is different than the BrAPI DB ID of an entity. We may want to consider changing this at some point + // TODO: With 1.5 work, this id is the BI-API generated ID that is set for external references in BrAPI. It is different than the BrAPI DB ID of an entity. We may want to consider changing this at some point [BI-2933] this.id = id; } public PendingImportObject(ImportObjectState state, T brAPIObject) { From 5be89c65a58b97b3a7c7a6c079fcb12c2684ecd9 Mon Sep 17 00:00:00 2001 From: Jason Loux Date: Wed, 10 Jun 2026 12:20:19 -0400 Subject: [PATCH 10/10] Addtional comment edits to include created tasks/epics --- .../org/breedinginsight/brapi/v2/BrAPIStudiesController.java | 2 +- .../org/breedinginsight/brapi/v2/BrAPITrialsController.java | 2 +- .../breedinginsight/brapi/v2/services/BrAPITrialService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java index f9536ebdd..52027436d 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPIStudiesController.java @@ -114,7 +114,7 @@ public HttpResponse>>> getStudies( return ResponseUtils.getBrapiQueryResponse(authorizedStudies, studyQueryMapper, queryParams, searchRequest); } - // TODO: Instead of getting all studies for a program and filtering, doing the filtering on brapi side + // TODO: Instead of getting all studies for a program and filtering, doing the filtering on brapi side [BI-2922] List studies = studyService.getStudies(programId) .stream() .peek(this::setDbIds) diff --git a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java index 351f66efc..6a2cd579f 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/BrAPITrialsController.java @@ -161,7 +161,7 @@ public HttpResponse trialsTrialDbIdPut(@PathVariable("programId") UUID progra return HttpResponse.notFound(); } - // TODO: Remove for trialDbId once cache is removed for that entity + // TODO: Verify that the programDbId does not need to be reset and that the BrAPI programDbId can be used instead [BI-2931] private void setDbIds(BrAPITrial trial) { trial.programDbId(Utilities.getExternalReference(trial.getExternalReferences(), Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS)) .orElseThrow(() -> new IllegalStateException("No BI external reference found")) diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java index 8d7ca67ef..8e0b4bae6 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java @@ -823,7 +823,7 @@ public int deleteExperiment(Program program, UUID experimentId, boolean hard) th // Make request to delete experiment. trialDAO.deleteBrAPITrial(program, trial, hard); // Get all lists for the trial. - // TODO: Get lists by trialDbId if trials get decoupled from datasets. + // TODO: Get lists by trialDbId if trials get decoupled from datasets. [BI-2993] List lists = listDAO .getListsByTypeAndExternalRef(BrAPIListTypes.OBSERVATIONVARIABLES, program.getId(),