From 3f26df757ad96def21476d9d7385a65e97b799e8 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:06:29 -0400 Subject: [PATCH 01/18] [BI-2058] - added exception handling IntelliJ was complaining --- src/main/java/org/breedinginsight/utilities/FileUtil.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/breedinginsight/utilities/FileUtil.java b/src/main/java/org/breedinginsight/utilities/FileUtil.java index 87fec8b46..b7b9ea3a2 100644 --- a/src/main/java/org/breedinginsight/utilities/FileUtil.java +++ b/src/main/java/org/breedinginsight/utilities/FileUtil.java @@ -192,12 +192,17 @@ public static Table parseTableFromCsv(InputStream inputStream) throws ParsingExc } public static Table parseTableFromJson(String jsonString) throws ParsingException { + try { return Table.read() .usingOptions( JsonReadOptions .builderFromString(jsonString) .columnTypesToDetect(List.of(ColumnType.STRING)) ); + } catch (IOException e) { + log.debug(e.getMessage()); + throw new ParsingException(ParsingExceptionType.ERROR_READING_FILE); + } } public static Table removeNullRows(Table table) { From e1f27ac07593fa4e47ee4cceef08db2cc6abdccb Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:07:09 -0400 Subject: [PATCH 02/18] [BI-2058] - cached Observations and ObservationUnits on startup --- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 75 ++++++++++++++- .../brapi/v2/dao/impl/BrAPITrialDAOImpl.java | 2 +- .../breedinginsight/daos/ObservationDAO.java | 92 +++++++++++++++++-- 3 files changed, 157 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 40833dc3e..23e4c6fa2 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -23,10 +23,13 @@ import com.google.gson.reflect.TypeToken; import io.micronaut.context.annotation.Property; import io.micronaut.http.server.exceptions.InternalServerException; +import io.micronaut.scheduling.annotation.Scheduled; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.brapi.client.v2.JSON; import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.client.v2.modules.phenotype.ObservationUnitsApi; +import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.germ.BrAPIGermplasm; import org.brapi.v2.model.pheno.BrAPIObservationTreatment; import org.brapi.v2.model.pheno.BrAPIObservationUnit; @@ -38,6 +41,8 @@ import org.breedinginsight.brapps.importer.model.ImportUpload; import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; import org.breedinginsight.daos.ProgramDAO; +import org.breedinginsight.daos.cache.ProgramCache; +import org.breedinginsight.daos.cache.ProgramCacheProvider; import org.breedinginsight.model.Program; import org.breedinginsight.services.ProgramService; import org.breedinginsight.services.brapi.BrAPIEndpointProvider; @@ -53,6 +58,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; +@Slf4j @Singleton public class BrAPIObservationUnitDAO { private final ProgramDAO programDAO; @@ -63,10 +69,13 @@ public class BrAPIObservationUnitDAO { private final BrAPIGermplasmService germplasmService; private final String referenceSource; + private boolean runScheduledTasks; private final Gson gson = new JSON().getGson(); private final Type treatmentlistType = new TypeToken>(){}.getType(); + private final ProgramCache programObservationUnitCache; + @Inject public BrAPIObservationUnitDAO(ProgramDAO programDAO, ImportDAO importDAO, @@ -74,14 +83,78 @@ public BrAPIObservationUnitDAO(ProgramDAO programDAO, BrAPIEndpointProvider brAPIEndpointProvider, BrAPIGermplasmService germplasmService, ProgramService programService, - @Property(name = "brapi.server.reference-source") String referenceSource) { + @Property(name = "brapi.server.reference-source") String referenceSource, + @Property(name = "micronaut.bi.api.run-scheduled-tasks") boolean runScheduledTasks, + ProgramCacheProvider programCacheProvider) { this.programDAO = programDAO; this.importDAO = importDAO; this.brAPIDAOUtil = brAPIDAOUtil; this.brAPIEndpointProvider = brAPIEndpointProvider; this.referenceSource = referenceSource; + this.runScheduledTasks = runScheduledTasks; this.programService = programService; this.germplasmService = germplasmService; + this.programObservationUnitCache = programCacheProvider.getProgramCache(this::fetchProgramObservationUnits, BrAPIObservationUnit.class); + } + + @Scheduled(initialDelay = "2s") + public void setup() { + if(!runScheduledTasks) { + return; + } + // Populate observation unit cache for all programs on startup. + log.debug("populating observation unit cache"); + List programs = programDAO.getActive(); + if(programs != null) { + programObservationUnitCache.populate(programs.stream().map(Program::getId).collect(Collectors.toList())); + } + } + + /** + * Fetch formatted observation units for this program. + * @param programId + * @return Map + * @throws ApiException + */ + private Map fetchProgramObservationUnits(UUID programId) throws ApiException { + ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationUnitsApi.class); + // Get the program key. + List programs = programDAO.get(programId); + if (programs.size() != 1) { + throw new InternalServerException("Program was not found for given key"); + } + Program program = programs.get(0); + + // Set query params and make call. + BrAPIObservationUnitSearchRequest observationUnitSearch = new BrAPIObservationUnitSearchRequest(); + observationUnitSearch.externalReferenceIds(List.of(programId.toString())); + observationUnitSearch.externalReferenceSources(List.of(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS))); + return processObservationUnitsForCache(brAPIDAOUtil.search( + api::searchObservationunitsPost, + api::searchObservationunitsSearchResultsDbIdGet, + observationUnitSearch + ), program.getKey()); + } + + // TODO: use program key, strip from observationUnitName, etc. + /** + * Process a list of observation units for insertion into the cache. + * @param programObservationUnits + * @param programKey + * @return + */ + private Map processObservationUnitsForCache(List programObservationUnits, String programKey) { + // Build map. + Map programObservationUnitsMap = new HashMap<>(); + for (BrAPIObservationUnit observationUnit: programObservationUnits) { + BrAPIExternalReference xref = observationUnit + .getExternalReferences() + .stream() + .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATION_UNITS.getName()).equals(reference.getReferenceSource())) + .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); + programObservationUnitsMap.put(xref.getReferenceID(), observationUnit); + } + return programObservationUnitsMap; } public List getObservationUnitByName(List observationUnitNames, Program program) 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 a60008dcd..a1670bf3c 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 @@ -124,7 +124,7 @@ private Map experimentById(List trials) { BrAPIExternalReference xref = experiment .getExternalReferences() .stream() - .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.TRIALS).equalsIgnoreCase(reference.getReferenceSource())) + .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.TRIALS.getName()).equals(reference.getReferenceSource())) .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); experimentById.put(xref.getReferenceID(), experiment); } diff --git a/src/main/java/org/breedinginsight/daos/ObservationDAO.java b/src/main/java/org/breedinginsight/daos/ObservationDAO.java index 9ecfb0588..33f3935b0 100644 --- a/src/main/java/org/breedinginsight/daos/ObservationDAO.java +++ b/src/main/java/org/breedinginsight/daos/ObservationDAO.java @@ -16,31 +16,31 @@ */ package org.breedinginsight.daos; +import io.micronaut.context.annotation.Property; import io.micronaut.http.server.exceptions.InternalServerException; +import io.micronaut.scheduling.annotation.Scheduled; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; import org.brapi.client.v2.ApiResponse; import org.brapi.client.v2.BrAPIClient; import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.client.v2.model.queryParams.phenotype.ObservationQueryParams; import org.brapi.client.v2.modules.phenotype.ObservationsApi; -import org.brapi.v2.model.BrAPIAcceptedSearchResponse; +import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.pheno.BrAPIObservation; import org.brapi.v2.model.pheno.request.BrAPIObservationSearchRequest; import org.brapi.v2.model.pheno.response.BrAPIObservationListResponse; -import org.breedinginsight.services.brapi.BrAPIClientType; +import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; +import org.breedinginsight.daos.cache.ProgramCache; +import org.breedinginsight.daos.cache.ProgramCacheProvider; +import org.breedinginsight.model.Program; import org.breedinginsight.services.brapi.BrAPIEndpointProvider; -import org.breedinginsight.services.brapi.BrAPIProvider; import org.breedinginsight.utilities.BrAPIDAOUtil; import org.breedinginsight.utilities.Utilities; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import static org.brapi.v2.model.BrAPIWSMIMEDataTypes.APPLICATION_JSON; +import java.util.*; +import java.util.stream.Collectors; @Singleton @@ -49,12 +49,84 @@ public class ObservationDAO { private final BrAPIDAOUtil brAPIDAOUtil; private ProgramDAO programDAO; private final BrAPIEndpointProvider brAPIEndpointProvider; + private final String referenceSource; + private boolean runScheduledTasks; + private final ProgramCache programObservationCache; @Inject - public ObservationDAO(BrAPIDAOUtil brAPIDAOUtil, ProgramDAO programDAO, BrAPIEndpointProvider brAPIEndpointProvider) { + public ObservationDAO(BrAPIDAOUtil brAPIDAOUtil, + ProgramDAO programDAO, + BrAPIEndpointProvider brAPIEndpointProvider, + @Property(name = "brapi.server.reference-source") String referenceSource, + @Property(name = "micronaut.bi.api.run-scheduled-tasks") boolean runScheduledTasks, + ProgramCacheProvider programCacheProvider) { this.brAPIDAOUtil = brAPIDAOUtil; this.programDAO = programDAO; this.brAPIEndpointProvider = brAPIEndpointProvider; + this.referenceSource = referenceSource; + this.runScheduledTasks = runScheduledTasks; + this.programObservationCache = programCacheProvider.getProgramCache(this::fetchProgramObservations, BrAPIObservation.class); + } + + @Scheduled(initialDelay = "2s") + public void setup() { + if(!runScheduledTasks) { + return; + } + // Populate the observation cache for all programs on startup. + log.debug("populating observation cache"); + List programs = programDAO.getActive(); + if (programs != null) { + programObservationCache.populate(programs.stream().map(Program::getId).collect(Collectors.toList())); + } + } + + /** + * Fetch formatted observation for this program. + * @param programId + * @return Map + * @throws ApiException + */ + private Map fetchProgramObservations(UUID programId) throws ApiException { + ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); + // Get the program key. + List programs = programDAO.get(programId); + if (programs.size() != 1) { + throw new InternalServerException("Program was not found for given key"); + } + Program program = programs.get(0); + + // Set query params and make call. + BrAPIObservationSearchRequest observationSearch = new BrAPIObservationSearchRequest(); + observationSearch.externalReferenceIds(List.of(programId.toString())); + observationSearch.externalReferenceSources(List.of(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS))); + return processObservationsForCache(brAPIDAOUtil.search( + api::searchObservationsPost, + api::searchObservationsSearchResultsDbIdGet, + observationSearch + ), program.getKey()); + } + + // TODO: use program key, strip from observationUnitName, etc. + /** + * Process a list of observations for insertion into the cache. + * @param programObservations + * @param programKey + * @return + */ + private Map processObservationsForCache(List programObservations, String programKey) { + // Build map. + Map programObservationsMap = new HashMap<>(); + log.trace("processing observationUnits for cache: " + programObservations); + for (BrAPIObservation observation: programObservations) { + BrAPIExternalReference xref = observation + .getExternalReferences() + .stream() + .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATIONS.getName()).equals(reference.getReferenceSource())) + .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); + programObservationsMap.put(xref.getReferenceID(), observation); + } + return programObservationsMap; } public List getObservationsByVariableDbId(String observationVariableDbId, UUID programId) { From 6a631d0b11f17d0a925197cbbe68b57c8d3c8e55 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:53:34 -0400 Subject: [PATCH 03/18] [BI-2058] - prevent possible NPEs --- .../brapi/v2/dao/BrAPIGermplasmDAO.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java index 58f0653bc..c4dd54233 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIGermplasmDAO.java @@ -294,15 +294,15 @@ private String processBreedbasePedigree(String pedigree) { public List createBrAPIGermplasm(List postBrAPIGermplasmList, UUID programId, ImportUpload upload) { GermplasmApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), GermplasmApi.class); var program = programDAO.fetchOneById(programId); - Callable> postFunction = null; try { if (!postBrAPIGermplasmList.isEmpty()) { - postFunction = () -> { + Callable> postFunction = () -> { List postResponse = brAPIDAOUtil.post(postBrAPIGermplasmList, upload, api::germplasmPost, importDAO::update); return processGermplasmForDisplay(postResponse, program.getKey()); }; + return programGermplasmCache.post(programId, postFunction); } - return programGermplasmCache.post(programId, postFunction); + return new ArrayList<>(); } catch (Exception e) { throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); } @@ -311,15 +311,15 @@ public List createBrAPIGermplasm(List postBrAPIG public List updateBrAPIGermplasm(List putBrAPIGermplasmList, UUID programId, ImportUpload upload) { GermplasmApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), GermplasmApi.class); var program = programDAO.fetchOneById(programId); - Callable> postFunction = null; try { if (!putBrAPIGermplasmList.isEmpty()) { - postFunction = () -> { + Callable> postFunction = () -> { List putResponse = putGermplasm(putBrAPIGermplasmList, api); return processGermplasmForDisplay(putResponse, program.getKey()); }; + return programGermplasmCache.post(programId, postFunction); } - return programGermplasmCache.post(programId, postFunction); + return new ArrayList<>(); } catch (Exception e) { throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); } From 3ff2443abbc236307b36f835f116f41142b7133b Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:54:59 -0400 Subject: [PATCH 04/18] [BI-2058] - revert unnecessary changes --- .../breedinginsight/daos/ObservationDAO.java | 74 +------------------ 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/src/main/java/org/breedinginsight/daos/ObservationDAO.java b/src/main/java/org/breedinginsight/daos/ObservationDAO.java index 33f3935b0..5f3d3a566 100644 --- a/src/main/java/org/breedinginsight/daos/ObservationDAO.java +++ b/src/main/java/org/breedinginsight/daos/ObservationDAO.java @@ -49,84 +49,12 @@ public class ObservationDAO { private final BrAPIDAOUtil brAPIDAOUtil; private ProgramDAO programDAO; private final BrAPIEndpointProvider brAPIEndpointProvider; - private final String referenceSource; - private boolean runScheduledTasks; - private final ProgramCache programObservationCache; @Inject - public ObservationDAO(BrAPIDAOUtil brAPIDAOUtil, - ProgramDAO programDAO, - BrAPIEndpointProvider brAPIEndpointProvider, - @Property(name = "brapi.server.reference-source") String referenceSource, - @Property(name = "micronaut.bi.api.run-scheduled-tasks") boolean runScheduledTasks, - ProgramCacheProvider programCacheProvider) { + public ObservationDAO(BrAPIDAOUtil brAPIDAOUtil, ProgramDAO programDAO, BrAPIEndpointProvider brAPIEndpointProvider) { this.brAPIDAOUtil = brAPIDAOUtil; this.programDAO = programDAO; this.brAPIEndpointProvider = brAPIEndpointProvider; - this.referenceSource = referenceSource; - this.runScheduledTasks = runScheduledTasks; - this.programObservationCache = programCacheProvider.getProgramCache(this::fetchProgramObservations, BrAPIObservation.class); - } - - @Scheduled(initialDelay = "2s") - public void setup() { - if(!runScheduledTasks) { - return; - } - // Populate the observation cache for all programs on startup. - log.debug("populating observation cache"); - List programs = programDAO.getActive(); - if (programs != null) { - programObservationCache.populate(programs.stream().map(Program::getId).collect(Collectors.toList())); - } - } - - /** - * Fetch formatted observation for this program. - * @param programId - * @return Map - * @throws ApiException - */ - private Map fetchProgramObservations(UUID programId) throws ApiException { - ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); - // Get the program key. - List programs = programDAO.get(programId); - if (programs.size() != 1) { - throw new InternalServerException("Program was not found for given key"); - } - Program program = programs.get(0); - - // Set query params and make call. - BrAPIObservationSearchRequest observationSearch = new BrAPIObservationSearchRequest(); - observationSearch.externalReferenceIds(List.of(programId.toString())); - observationSearch.externalReferenceSources(List.of(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS))); - return processObservationsForCache(brAPIDAOUtil.search( - api::searchObservationsPost, - api::searchObservationsSearchResultsDbIdGet, - observationSearch - ), program.getKey()); - } - - // TODO: use program key, strip from observationUnitName, etc. - /** - * Process a list of observations for insertion into the cache. - * @param programObservations - * @param programKey - * @return - */ - private Map processObservationsForCache(List programObservations, String programKey) { - // Build map. - Map programObservationsMap = new HashMap<>(); - log.trace("processing observationUnits for cache: " + programObservations); - for (BrAPIObservation observation: programObservations) { - BrAPIExternalReference xref = observation - .getExternalReferences() - .stream() - .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATIONS.getName()).equals(reference.getReferenceSource())) - .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); - programObservationsMap.put(xref.getReferenceID(), observation); - } - return programObservationsMap; } public List getObservationsByVariableDbId(String observationVariableDbId, UUID programId) { From a0837838d007f4541e201791ec08a64cbc7dd17a Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:58:21 -0400 Subject: [PATCH 05/18] [BI-2058] - work in progress on caching observations and observationUnits --- .../brapi/v2/dao/BrAPIObservationDAO.java | 173 ++++++++++++++++-- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 20 +- 2 files changed, 165 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java index b52aeff22..6549e8a4f 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -16,19 +16,28 @@ */ package org.breedinginsight.brapi.v2.dao; +import io.micronaut.context.annotation.Property; +import io.micronaut.http.server.exceptions.InternalServerException; +import io.micronaut.scheduling.annotation.Scheduled; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.brapi.client.v2.ApiResponse; import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.client.v2.modules.phenotype.ObservationsApi; import org.brapi.v2.model.BrAPIAcceptedSearchResponse; +import org.brapi.v2.model.BrAPIExternalReference; +import org.brapi.v2.model.germ.BrAPIGermplasm; import org.brapi.v2.model.pheno.BrAPIObservation; import org.brapi.v2.model.pheno.request.BrAPIObservationSearchRequest; import org.brapi.v2.model.pheno.response.BrAPIObservationListResponse; import org.brapi.v2.model.pheno.response.BrAPIObservationSingleResponse; 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.daos.cache.ProgramCache; +import org.breedinginsight.daos.cache.ProgramCacheProvider; import org.breedinginsight.model.Program; import org.breedinginsight.services.brapi.BrAPIEndpointProvider; import org.breedinginsight.utilities.BrAPIDAOUtil; @@ -38,6 +47,8 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.util.*; +import java.util.concurrent.Callable; +import java.util.stream.Collectors; import static org.brapi.v2.model.BrAPIWSMIMEDataTypes.APPLICATION_JSON; @@ -49,19 +60,117 @@ public class BrAPIObservationDAO { private ImportDAO importDAO; private final BrAPIDAOUtil brAPIDAOUtil; private final BrAPIEndpointProvider brAPIEndpointProvider; + private final String referenceSource; + private boolean runScheduledTasks; + private final ProgramCache programObservationCache; @Inject - public BrAPIObservationDAO(ProgramDAO programDAO, ImportDAO importDAO, BrAPIDAOUtil brAPIDAOUtil, BrAPIEndpointProvider brAPIEndpointProvider) { + public BrAPIObservationDAO(ProgramDAO programDAO, + ImportDAO importDAO, + BrAPIDAOUtil brAPIDAOUtil, + BrAPIEndpointProvider brAPIEndpointProvider, + @Property(name = "brapi.server.reference-source") String referenceSource, + @Property(name = "micronaut.bi.api.run-scheduled-tasks") boolean runScheduledTasks, + ProgramCacheProvider programCacheProvider) { this.programDAO = programDAO; this.importDAO = importDAO; this.brAPIDAOUtil = brAPIDAOUtil; this.brAPIEndpointProvider = brAPIEndpointProvider; + this.referenceSource = referenceSource; + this.runScheduledTasks = runScheduledTasks; + this.programObservationCache = programCacheProvider.getProgramCache(this::fetchProgramObservations, BrAPIObservation.class); + } + + @Scheduled(initialDelay = "3s") + public void setup() { + if(!runScheduledTasks) { + return; + } + // Populate the observation cache for all programs on startup. + log.debug("populating observation cache"); + List programs = programDAO.getActive(); + if (programs != null) { + programObservationCache.populate(programs.stream().map(Program::getId).collect(Collectors.toList())); + } + } + + /** + * Fetch formatted observations for this program. + */ + private Map fetchProgramObservations(UUID programId) throws ApiException { + ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); + // Get the program. + List programs = programDAO.get(programId); + if (programs.size() != 1) { + throw new InternalServerException("Program was not found for given id"); + } + Program program = programs.get(0); + + // Set query params and make call. + BrAPIObservationSearchRequest observationSearch = new BrAPIObservationSearchRequest(); + observationSearch.externalReferenceIds(List.of(programId.toString())); + observationSearch.externalReferenceSources(List.of(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS))); + return processObservationsForCache(brAPIDAOUtil.search( + api::searchObservationsPost, + api::searchObservationsSearchResultsDbIdGet, + observationSearch + ), program.getKey()); + } + + /** + * Process a list of observations for insertion into the cache. + */ + private Map processObservationsForCache(List programObservations, String programKey) { + // Process programObservations in place (strip program key, etc.). + processObservations(programKey, programObservations); + // Build map. + Map programObservationsMap = new HashMap<>(); + log.trace("processing observationUnits for cache: " + programObservations); + for (BrAPIObservation observation: programObservations) { + BrAPIExternalReference xref = observation + .getExternalReferences() + .stream() + .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATIONS.getName()).equals(reference.getReferenceSource())) + .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); + programObservationsMap.put(xref.getReferenceID(), observation); + } + return programObservationsMap; + } + + /** + * Process BrAPIObservations for use in DeltaBreed (e.g. strip program key). + */ + private void processObservations(String programKey, List observations) { + for (BrAPIObservation obs: observations) { + // Strip program key from observationVariableName. + if (StringUtils.isNotBlank(obs.getObservationVariableName())) { + obs.setObservationVariableName(Utilities.removeProgramKey(obs.getObservationVariableName(), programKey)); + } + // Strip program key and unknown info from germplasmName and observationUnitName. + if (StringUtils.isNotBlank(obs.getGermplasmName())) { + obs.setGermplasmName(Utilities.removeProgramKeyAndUnknownAdditionalData(obs.getGermplasmName(), programKey)); + } + if (StringUtils.isNotBlank(obs.getObservationUnitName())) { + obs.setObservationUnitName(Utilities.removeProgramKeyAndUnknownAdditionalData(obs.getObservationUnitName(), programKey)); + } + } + } + + private Map getProgramObservations(UUID programId) throws ApiException { + return programObservationCache.get(programId); } public List getObservationsByStudyName(List studyNames, Program program) throws ApiException { if(studyNames.isEmpty()) { return Collections.emptyList(); } +// // Strip program key and unknown additional data from studyNames. +// List cleanedStudyNames = studyNames.stream() +// .map(n -> Utilities.removeProgramKeyAndUnknownAdditionalData(n, program.getKey())) +// .collect(Collectors.toList()); +// return getProgramObservations(program.getId()).values().stream() +// .filter(o -> cleanedStudyNames.contains(o.getAdditionalInfo().get("studyName").getAsString())) +// .collect(Collectors.toList()); BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); @@ -79,6 +188,12 @@ public List getObservationsByTrialDbId(List trialDbIds return Collections.emptyList(); } + // TODO: get all observationUnits, then observation. +// return getProgramObservations(program.getId()).values().stream() +// .filter(o -> ) +// .collect(Collectors.toList()); + + // TODO: remove old code ------ BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); observationSearchRequest.setTrialDbIds(new ArrayList<>(trialDbIds)); @@ -88,12 +203,16 @@ public List getObservationsByTrialDbId(List trialDbIds (brAPIWSMIMEDataTypes, searchResultsDbId, page, pageSize) -> searchObservationsSearchResultsDbIdGet(program.getId(), searchResultsDbId, page, pageSize), observationSearchRequest ); + // TODO: end old code ------ } public List getObservationsByObservationUnitsAndVariables(Collection ouDbIds, Collection variableDbIds, Program program) throws ApiException { if(ouDbIds.isEmpty() || variableDbIds.isEmpty()) { return Collections.emptyList(); } +// return getProgramObservations(program.getId()).values().stream() +// .filter(o -> ouDbIds.contains(o.getObservationDbId()) && variableDbIds.contains(o.getObservationVariableDbId())) +// .collect(Collectors.toList()); BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); @@ -115,28 +234,50 @@ private ApiResponse, Optional createBrAPIObservations(List brAPIObservationList, UUID programId, ImportUpload upload) throws ApiException { ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); - return brAPIDAOUtil.post(brAPIObservationList, upload, api::observationsPost, importDAO::update); + var program = programDAO.fetchOneById(programId); + Callable> postFunction = null; + try { + if (!brAPIObservationList.isEmpty()) { + postFunction = () -> { + List postResponse = brAPIDAOUtil.post(brAPIObservationList, upload, api::observationsPost, importDAO::update); + return processObservationsForCache(postResponse, program.getKey()); + }; + return programObservationCache.post(programId, postFunction); + } + return new ArrayList<>(); + } catch (Exception e) { + throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); + } } public BrAPIObservation updateBrAPIObservation(String dbId, BrAPIObservation observation, UUID programId) throws ApiException { ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); - ApiResponse response; - BrAPIObservation updatedObservation = null; + var program = programDAO.fetchOneById(programId); + Callable> postFunction = null; + try { - response = api.observationsObservationDbIdPut(dbId, observation); - if (response != null) { - BrAPIObservationSingleResponse body = response.getBody(); - if (body == null) { - throw new ApiException("Response is missing body", 0, response.getHeaders(), null); - } - updatedObservation = body.getResult(); - if (updatedObservation == null) { - throw new ApiException("Response body is missing result", 0, response.getHeaders(), response.getBody().toString()); - } - } + postFunction = () -> { + ApiResponse response = api.observationsObservationDbIdPut(dbId, observation); + if (response == null) + { + throw new ApiException("Response is null", 0, null, null); + } + BrAPIObservationSingleResponse body = response.getBody(); + if (body == null) { + throw new ApiException("Response is missing body", 0, response.getHeaders(), null); + } + BrAPIObservation updatedObservation = body.getResult(); + if (updatedObservation == null) { + throw new ApiException("Response body is missing result", 0, response.getHeaders(), response.getBody().toString()); + } + return processObservationsForCache(List.of(updatedObservation), program.getKey()); + }; + return programObservationCache.post(programId, postFunction).get(0); } catch (ApiException e) { log.error(Utilities.generateApiExceptionLogMessage(e)); + throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); + } catch (Exception e) { + throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); } - return updatedObservation; } } diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 23e4c6fa2..a7d82f337 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -97,7 +97,8 @@ public BrAPIObservationUnitDAO(ProgramDAO programDAO, this.programObservationUnitCache = programCacheProvider.getProgramCache(this::fetchProgramObservationUnits, BrAPIObservationUnit.class); } - @Scheduled(initialDelay = "2s") + // TODO: 2s? 3s? + @Scheduled(initialDelay = "3s") public void setup() { if(!runScheduledTasks) { return; @@ -112,16 +113,13 @@ public void setup() { /** * Fetch formatted observation units for this program. - * @param programId - * @return Map - * @throws ApiException */ private Map fetchProgramObservationUnits(UUID programId) throws ApiException { ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationUnitsApi.class); - // Get the program key. + // Get the program. List programs = programDAO.get(programId); if (programs.size() != 1) { - throw new InternalServerException("Program was not found for given key"); + throw new InternalServerException("Program was not found for given id"); } Program program = programs.get(0); @@ -133,17 +131,15 @@ private Map fetchProgramObservationUnits(UUID prog api::searchObservationunitsPost, api::searchObservationunitsSearchResultsDbIdGet, observationUnitSearch - ), program.getKey()); + ), program); } - // TODO: use program key, strip from observationUnitName, etc. /** * Process a list of observation units for insertion into the cache. - * @param programObservationUnits - * @param programKey - * @return */ - private Map processObservationUnitsForCache(List programObservationUnits, String programKey) { + private Map processObservationUnitsForCache(List programObservationUnits, Program program) throws ApiException { + // Process programObservationUnits in place (strip program key, etc.). + processObservationUnits(program, programObservationUnits, true); // Build map. Map programObservationUnitsMap = new HashMap<>(); for (BrAPIObservationUnit observationUnit: programObservationUnits) { From 7a80d9e8ad7daa083f3693b9787d0cf1eb0df076 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:49:00 -0400 Subject: [PATCH 06/18] [BI-2058] - optimized imports --- .../org/breedinginsight/daos/ObservationDAO.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/breedinginsight/daos/ObservationDAO.java b/src/main/java/org/breedinginsight/daos/ObservationDAO.java index 5f3d3a566..0802c923f 100644 --- a/src/main/java/org/breedinginsight/daos/ObservationDAO.java +++ b/src/main/java/org/breedinginsight/daos/ObservationDAO.java @@ -16,31 +16,25 @@ */ package org.breedinginsight.daos; -import io.micronaut.context.annotation.Property; import io.micronaut.http.server.exceptions.InternalServerException; -import io.micronaut.scheduling.annotation.Scheduled; import lombok.extern.slf4j.Slf4j; import org.brapi.client.v2.ApiResponse; import org.brapi.client.v2.BrAPIClient; import org.brapi.client.v2.model.exceptions.ApiException; import org.brapi.client.v2.model.queryParams.phenotype.ObservationQueryParams; import org.brapi.client.v2.modules.phenotype.ObservationsApi; -import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.pheno.BrAPIObservation; import org.brapi.v2.model.pheno.request.BrAPIObservationSearchRequest; import org.brapi.v2.model.pheno.response.BrAPIObservationListResponse; -import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; -import org.breedinginsight.daos.cache.ProgramCache; -import org.breedinginsight.daos.cache.ProgramCacheProvider; -import org.breedinginsight.model.Program; import org.breedinginsight.services.brapi.BrAPIEndpointProvider; import org.breedinginsight.utilities.BrAPIDAOUtil; import org.breedinginsight.utilities.Utilities; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Collections; +import java.util.List; +import java.util.UUID; @Singleton From b96b75aa81ebd4bef86fbc2e041a716fe43a787f Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:51:58 -0400 Subject: [PATCH 07/18] [BI-2058] - linter fixes --- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index a7d82f337..b69d5918d 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -69,7 +69,7 @@ public class BrAPIObservationUnitDAO { private final BrAPIGermplasmService germplasmService; private final String referenceSource; - private boolean runScheduledTasks; + private final boolean runScheduledTasks; private final Gson gson = new JSON().getGson(); private final Type treatmentlistType = new TypeToken>(){}.getType(); @@ -148,7 +148,7 @@ private Map processObservationUnitsForCache(List String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATION_UNITS.getName()).equals(reference.getReferenceSource())) .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); - programObservationUnitsMap.put(xref.getReferenceID(), observationUnit); + programObservationUnitsMap.put(xref.getReferenceId(), observationUnit); } return programObservationUnitsMap; } @@ -296,15 +296,15 @@ public List getObservationUnits(Program program, //xref search does an OR, so we need to convert the searching for ouId/expId/envId to be an AND boolean matches = observationUnitId.map(id -> id.equals(Utilities.getExternalReference(ou.getExternalReferences(), Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.OBSERVATION_UNITS)) .get() - .getReferenceID())) + .getReferenceId())) .orElse(true); matches = matches && experimentId.map(id -> id.equals(Utilities.getExternalReference(ou.getExternalReferences(), Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.TRIALS)) .get() - .getReferenceID())) + .getReferenceId())) .orElse(true); matches = matches && environmentId.map(id -> id.equals(Utilities.getExternalReference(ou.getExternalReferences(), Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.STUDIES)) .get() - .getReferenceID())) + .getReferenceId())) .orElse(true); //adding filter for germplasmDbId because we can't easily search that in the stored data object @@ -372,7 +372,7 @@ private void processObservationUnits(Program program, List ou.putAdditionalInfoItem(BrAPIAdditionalInfoFields.GERMPLASM_UUID, Utilities.getExternalReference(germplasm.getExternalReferences(), referenceSource) .orElseThrow(() -> new IllegalStateException("Germplasm UUID not found")) - .getReferenceID()); + .getReferenceId()); } } ou.setObservationUnitName(Utilities.removeProgramKeyAndUnknownAdditionalData(ou.getObservationUnitName(), program.getKey())); From 08b803dc0ca67e925003ae71252fc6f6f53aaf5b Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 16:59:40 -0400 Subject: [PATCH 08/18] [BI-2058] - utilized cache in most observation unit DAO methods --- .../brapi/v2/dao/BrAPIObservationDAO.java | 11 ++- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 85 +++++++++---------- 2 files changed, 44 insertions(+), 52 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java index 6549e8a4f..a78aa9caf 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -27,7 +27,6 @@ import org.brapi.client.v2.modules.phenotype.ObservationsApi; import org.brapi.v2.model.BrAPIAcceptedSearchResponse; import org.brapi.v2.model.BrAPIExternalReference; -import org.brapi.v2.model.germ.BrAPIGermplasm; import org.brapi.v2.model.pheno.BrAPIObservation; import org.brapi.v2.model.pheno.request.BrAPIObservationSearchRequest; import org.brapi.v2.model.pheno.response.BrAPIObservationListResponse; @@ -156,6 +155,9 @@ private void processObservations(String programKey, List obser } } + /** + * Get all observations for a program from the cache. + */ private Map getProgramObservations(UUID programId) throws ApiException { return programObservationCache.get(programId); } @@ -235,10 +237,9 @@ private ApiResponse, Optional createBrAPIObservations(List brAPIObservationList, UUID programId, ImportUpload upload) throws ApiException { ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); var program = programDAO.fetchOneById(programId); - Callable> postFunction = null; try { if (!brAPIObservationList.isEmpty()) { - postFunction = () -> { + Callable> postFunction = () -> { List postResponse = brAPIDAOUtil.post(brAPIObservationList, upload, api::observationsPost, importDAO::update); return processObservationsForCache(postResponse, program.getKey()); }; @@ -253,10 +254,8 @@ public List createBrAPIObservations(List brA public BrAPIObservation updateBrAPIObservation(String dbId, BrAPIObservation observation, UUID programId) throws ApiException { ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); var program = programDAO.fetchOneById(programId); - Callable> postFunction = null; - try { - postFunction = () -> { + Callable> postFunction = () -> { ApiResponse response = api.observationsObservationDbIdPut(dbId, observation); if (response == null) { diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index b69d5918d..d1b1f830c 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -55,6 +55,7 @@ import javax.validation.constraints.NotNull; import java.lang.reflect.Type; import java.util.*; +import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -138,8 +139,11 @@ private Map fetchProgramObservationUnits(UUID prog * Process a list of observation units for insertion into the cache. */ private Map processObservationUnitsForCache(List programObservationUnits, Program program) throws ApiException { + return processObservationUnitsForCache(programObservationUnits, program, true); + } + private Map processObservationUnitsForCache(List programObservationUnits, Program program, boolean withGID) throws ApiException { // Process programObservationUnits in place (strip program key, etc.). - processObservationUnits(program, programObservationUnits, true); + processObservationUnits(program, programObservationUnits, withGID); // Build map. Map programObservationUnitsMap = new HashMap<>(); for (BrAPIObservationUnit observationUnit: programObservationUnits) { @@ -153,16 +157,20 @@ private Map processObservationUnitsForCache(List getProgramObservationUnits(UUID programId) throws ApiException { + return programObservationUnitCache.get(programId); + } + public List getObservationUnitByName(List observationUnitNames, Program program) throws ApiException { if(observationUnitNames.isEmpty()) { return Collections.emptyList(); } - - BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); - observationUnitSearchRequest.programDbIds(List.of(program.getBrapiProgram().getProgramDbId())); - observationUnitSearchRequest.observationUnitNames(observationUnitNames); - - return searchObservationUnitsAndProcess(observationUnitSearchRequest, program, false); + return getProgramObservationUnits(program.getId()).values().stream() + .filter(ou -> observationUnitNames.contains(ou.getObservationUnitName())) + .collect(Collectors.toList()); } /** @@ -171,20 +179,16 @@ public List getObservationUnitByName(List observat public List createBrAPIObservationUnits(List brAPIObservationUnitList, UUID programId, ImportUpload upload) throws ApiException, DoesNotExistException { Program program = programService.getById(programId).orElseThrow(() -> new DoesNotExistException("Program id does not exist")); ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationUnitsApi.class); - preprocessObservationUnits(brAPIObservationUnitList); - List ous = brAPIDAOUtil.post(brAPIObservationUnitList, upload, api::observationunitsPost, importDAO::update); - processObservationUnits(program, ous, false); - return ous; - } - - public BrAPIObservationUnit updateBrAPIObservationUnit(String ouDbId, BrAPIObservationUnit ou, UUID programId) { - ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationUnitsApi.class); - BrAPIObservationUnit updatedOu = null; try { - if (ou != null && !ouDbId.isBlank()) { - updatedOu = brAPIDAOUtil.put(ouDbId, ou, api::observationunitsObservationUnitDbIdPut); + if (!brAPIObservationUnitList.isEmpty()) { + Callable> postFunction = () -> { + preprocessObservationUnits(brAPIObservationUnitList); + List ous = brAPIDAOUtil.post(brAPIObservationUnitList, upload, api::observationunitsPost, importDAO::update); + return processObservationUnitsForCache(ous, program, false); + }; + return programObservationUnitCache.post(programId, postFunction); } - return updatedOu; + return new ArrayList<>(); } catch (Exception e) { throw new InternalServerException("Unknown error has occurred: " + e.getMessage(), e); } @@ -194,23 +198,16 @@ public List getObservationUnitsById(Collection obs if(observationUnitExternalIds.isEmpty()) { return Collections.emptyList(); } - - BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); - observationUnitSearchRequest.programDbIds(List.of(program.getBrapiProgram() - .getProgramDbId())); - observationUnitSearchRequest.externalReferenceIDs(new ArrayList<>(observationUnitExternalIds)); - observationUnitSearchRequest.externalReferenceSources(List.of(String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATION_UNITS.getName()))); - - return searchObservationUnitsAndProcess(observationUnitSearchRequest, program, false); + return getProgramObservationUnits(program.getId()).entrySet().stream() + .filter(entry -> observationUnitExternalIds.contains(entry.getKey())) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); } public List getObservationUnitsForStudyDbId(@NotNull String studyDbId, Program program) throws ApiException { - BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); - observationUnitSearchRequest.programDbIds(List.of(program.getBrapiProgram() - .getProgramDbId())); - observationUnitSearchRequest.studyDbIds(List.of(studyDbId)); - - return searchObservationUnitsAndProcess(observationUnitSearchRequest, program, false); + return getProgramObservationUnits(program.getId()).values().stream() + .filter(ou -> ou.getStudyDbId().equals(studyDbId)) + .collect(Collectors.toList()); } public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId) throws ApiException, DoesNotExistException { @@ -218,23 +215,19 @@ public List getObservationUnitsForTrialDbId(@NotNull UUID } public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId, boolean withGID) throws ApiException, DoesNotExistException { - Program program = programService.getById(programId).orElseThrow(() -> new DoesNotExistException("Program id does not exist")); - - BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); - observationUnitSearchRequest.programDbIds(List.of(program.getBrapiProgram() - .getProgramDbId())); - observationUnitSearchRequest.trialDbIds(List.of(trialDbId)); - - return searchObservationUnitsAndProcess(observationUnitSearchRequest, program, withGID); + return getProgramObservationUnits(programId).values().stream() + .filter(ou -> ou.getTrialDbId().equals(trialDbId)) + .collect(Collectors.toList()); } public List getObservationUnitsForDataset(@NotNull String datasetId, @NotNull Program program) throws ApiException { String datasetReferenceSource = Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.DATASET); - BrAPIObservationUnitSearchRequest ouSearchRequest = new BrAPIObservationUnitSearchRequest(); - ouSearchRequest.programDbIds(List.of(program.getBrapiProgram().getProgramDbId())); - ouSearchRequest.externalReferenceSources(List.of(datasetReferenceSource)); - ouSearchRequest.externalReferenceIDs(List.of(datasetId)); - return searchObservationUnitsAndProcess(ouSearchRequest, program, true); + return getProgramObservationUnits(program.getId()).values().stream() + .filter(ou -> { + Optional exRef = Utilities.getExternalReference(ou.getExternalReferences(), referenceSource + ExternalReferenceSource.DATASET); + return exRef.map(brAPIExternalReference -> brAPIExternalReference.getReferenceId().equals(datasetId)).orElse(false); + }) + .collect(Collectors.toList()); } public List getObservationUnits(Program program, From a2da205aad55408b62d6f40f9949566f5236aabb Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:00:04 -0400 Subject: [PATCH 09/18] [BI-2058] - updated unit test data to include xref --- .../importer/daos/BrAPIObservationUnitDAOTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAOTest.java b/src/test/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAOTest.java index b7a2ba564..c4c214682 100644 --- a/src/test/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAOTest.java +++ b/src/test/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAOTest.java @@ -2,11 +2,13 @@ import com.google.gson.Gson; import io.kowalski.fannypack.FannyPack; +import io.micronaut.context.annotation.Property; import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import lombok.SneakyThrows; import org.brapi.client.v2.JSON; +import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.pheno.BrAPIObservationTreatment; import org.brapi.v2.model.pheno.BrAPIObservationUnit; import org.breedinginsight.BrAPITest; @@ -17,17 +19,20 @@ import org.breedinginsight.brapi.v2.dao.BrAPIObservationUnitDAO; import org.breedinginsight.brapps.importer.model.ImportProgress; import org.breedinginsight.brapps.importer.model.ImportUpload; +import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; import org.breedinginsight.dao.db.tables.pojos.SpeciesEntity; import org.breedinginsight.daos.SpeciesDAO; import org.breedinginsight.daos.UserDAO; import org.breedinginsight.model.Program; import org.breedinginsight.model.User; import org.breedinginsight.services.ProgramService; +import org.breedinginsight.utilities.Utilities; import org.jooq.DSLContext; import org.junit.jupiter.api.*; import javax.inject.Inject; import java.util.List; +import java.util.UUID; import static org.breedinginsight.TestUtils.insertAndFetchTestProgram; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -65,6 +70,9 @@ public class BrAPIObservationUnitDAOTest extends BrAPITest { @Client("/${micronaut.bi.api.version}") RxHttpClient biClient; + @Property(name = "brapi.server.reference-source") + String referenceSource; + @BeforeAll @SneakyThrows public void setup() { @@ -117,6 +125,11 @@ public void testCreateObservationUnitAdditionalInfoSingleTreatmentFactor() { ou1.setObservationUnitName("test1"); ou1.putAdditionalInfoItem(BrAPIAdditionalInfoFields.TREATMENTS, List.of(testTreatment)); ou1.setProgramDbId(validProgram.getBrapiProgram().getProgramDbId()); + // Set xref. + BrAPIExternalReference xref = new BrAPIExternalReference(); + xref.setReferenceSource(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.OBSERVATION_UNITS)); + xref.setReferenceId(UUID.randomUUID().toString()); + ou1.setExternalReferences(List.of(xref)); List ous = List.of(ou1); List createdOus = obsUnitDAO.createBrAPIObservationUnits(ous, validProgram.getId(), upload); From 2d580341b2d0ab41deef6cb1529f28dcc2248862 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Mon, 18 Mar 2024 12:58:31 -0400 Subject: [PATCH 10/18] [BI-2058] - modified exception handling --- src/main/java/org/breedinginsight/utilities/FileUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/breedinginsight/utilities/FileUtil.java b/src/main/java/org/breedinginsight/utilities/FileUtil.java index b7b9ea3a2..3e084752d 100644 --- a/src/main/java/org/breedinginsight/utilities/FileUtil.java +++ b/src/main/java/org/breedinginsight/utilities/FileUtil.java @@ -199,7 +199,7 @@ public static Table parseTableFromJson(String jsonString) throws ParsingExceptio .builderFromString(jsonString) .columnTypesToDetect(List.of(ColumnType.STRING)) ); - } catch (IOException e) { + } catch (Exception e) { log.debug(e.getMessage()); throw new ParsingException(ParsingExceptionType.ERROR_READING_FILE); } From fd39c6eaba624a51bafc22f6d08030fe76b6e527 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:03:28 -0400 Subject: [PATCH 11/18] [BI-2058] - fixed dataset loading bug --- .../breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index d1b1f830c..04ad0efed 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -224,7 +224,7 @@ public List getObservationUnitsForDataset(@NotNull String String datasetReferenceSource = Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.DATASET); return getProgramObservationUnits(program.getId()).values().stream() .filter(ou -> { - Optional exRef = Utilities.getExternalReference(ou.getExternalReferences(), referenceSource + ExternalReferenceSource.DATASET); + Optional exRef = Utilities.getExternalReference(ou.getExternalReferences(), datasetReferenceSource); return exRef.map(brAPIExternalReference -> brAPIExternalReference.getReferenceId().equals(datasetId)).orElse(false); }) .collect(Collectors.toList()); From 93f16b66fb1d2fc3acca3a5961fb5180759926bc Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:08:29 -0400 Subject: [PATCH 12/18] [BI-2058] - made getObservationsByObservationUnitsAndVariables use cache --- .../brapi/v2/dao/BrAPIObservationDAO.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java index a78aa9caf..c706b10c0 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -212,20 +212,9 @@ public List getObservationsByObservationUnitsAndVariables(Coll if(ouDbIds.isEmpty() || variableDbIds.isEmpty()) { return Collections.emptyList(); } -// return getProgramObservations(program.getId()).values().stream() -// .filter(o -> ouDbIds.contains(o.getObservationDbId()) && variableDbIds.contains(o.getObservationVariableDbId())) -// .collect(Collectors.toList()); - - BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); - observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); - observationSearchRequest.setObservationUnitDbIds(new ArrayList<>(ouDbIds)); - observationSearchRequest.setObservationVariableDbIds(new ArrayList<>(variableDbIds)); - ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), ObservationsApi.class); - return brAPIDAOUtil.search( - api::searchObservationsPost, - (brAPIWSMIMEDataTypes, searchResultsDbId, page, pageSize) -> searchObservationsSearchResultsDbIdGet(program.getId(), searchResultsDbId, page, pageSize), - observationSearchRequest - ); + return getProgramObservations(program.getId()).values().stream() + .filter(o -> ouDbIds.contains(o.getObservationUnitDbId()) && variableDbIds.contains(o.getObservationVariableDbId())) + .collect(Collectors.toList()); } @NotNull From d27b3187b8a362a78ac2a5475e63eab9fae8a574 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Mon, 25 Mar 2024 15:41:11 -0400 Subject: [PATCH 13/18] [BI-2058] - removed unused method --- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 04ad0efed..76c90abe7 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -132,15 +132,12 @@ private Map fetchProgramObservationUnits(UUID prog api::searchObservationunitsPost, api::searchObservationunitsSearchResultsDbIdGet, observationUnitSearch - ), program); + ), program, true); } /** * Process a list of observation units for insertion into the cache. */ - private Map processObservationUnitsForCache(List programObservationUnits, Program program) throws ApiException { - return processObservationUnitsForCache(programObservationUnits, program, true); - } private Map processObservationUnitsForCache(List programObservationUnits, Program program, boolean withGID) throws ApiException { // Process programObservationUnits in place (strip program key, etc.). processObservationUnits(program, programObservationUnits, withGID); From 9203985ce3860ace517a9bee20ae13d3e108727a Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:33:26 -0400 Subject: [PATCH 14/18] [BI-2058] - made getObservationsByTrialDbId use cache --- .../brapi/v2/dao/BrAPIObservationDAO.java | 36 +++++++------------ .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 9 +++++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java index c706b10c0..053aaac89 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -28,6 +28,7 @@ import org.brapi.v2.model.BrAPIAcceptedSearchResponse; import org.brapi.v2.model.BrAPIExternalReference; import org.brapi.v2.model.pheno.BrAPIObservation; +import org.brapi.v2.model.pheno.BrAPIObservationUnit; import org.brapi.v2.model.pheno.request.BrAPIObservationSearchRequest; import org.brapi.v2.model.pheno.response.BrAPIObservationListResponse; import org.brapi.v2.model.pheno.response.BrAPIObservationSingleResponse; @@ -57,6 +58,7 @@ public class BrAPIObservationDAO { private ProgramDAO programDAO; private ImportDAO importDAO; + private BrAPIObservationUnitDAO observationUnitDAO; private final BrAPIDAOUtil brAPIDAOUtil; private final BrAPIEndpointProvider brAPIEndpointProvider; private final String referenceSource; @@ -66,6 +68,7 @@ public class BrAPIObservationDAO { @Inject public BrAPIObservationDAO(ProgramDAO programDAO, ImportDAO importDAO, + BrAPIObservationUnitDAO observationUnitDAO, BrAPIDAOUtil brAPIDAOUtil, BrAPIEndpointProvider brAPIEndpointProvider, @Property(name = "brapi.server.reference-source") String referenceSource, @@ -73,6 +76,7 @@ public BrAPIObservationDAO(ProgramDAO programDAO, ProgramCacheProvider programCacheProvider) { this.programDAO = programDAO; this.importDAO = importDAO; + this.observationUnitDAO = observationUnitDAO; this.brAPIDAOUtil = brAPIDAOUtil; this.brAPIEndpointProvider = brAPIEndpointProvider; this.referenceSource = referenceSource; @@ -162,17 +166,11 @@ private Map getProgramObservations(UUID programId) thr return programObservationCache.get(programId); } + // Note: not using cache, because unique studyName (with "[ProgramKey-ExtraInfo]") is not stored directly on Observation. public List getObservationsByStudyName(List studyNames, Program program) throws ApiException { if(studyNames.isEmpty()) { return Collections.emptyList(); } -// // Strip program key and unknown additional data from studyNames. -// List cleanedStudyNames = studyNames.stream() -// .map(n -> Utilities.removeProgramKeyAndUnknownAdditionalData(n, program.getKey())) -// .collect(Collectors.toList()); -// return getProgramObservations(program.getId()).values().stream() -// .filter(o -> cleanedStudyNames.contains(o.getAdditionalInfo().get("studyName").getAsString())) -// .collect(Collectors.toList()); BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); @@ -189,23 +187,13 @@ public List getObservationsByTrialDbId(List trialDbIds if(trialDbIds.isEmpty()) { return Collections.emptyList(); } - - // TODO: get all observationUnits, then observation. -// return getProgramObservations(program.getId()).values().stream() -// .filter(o -> ) -// .collect(Collectors.toList()); - - // TODO: remove old code ------ - BrAPIObservationSearchRequest observationSearchRequest = new BrAPIObservationSearchRequest(); - observationSearchRequest.setProgramDbIds(List.of(program.getBrapiProgram().getProgramDbId())); - observationSearchRequest.setTrialDbIds(new ArrayList<>(trialDbIds)); - ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), ObservationsApi.class); - return brAPIDAOUtil.search( - api::searchObservationsPost, - (brAPIWSMIMEDataTypes, searchResultsDbId, page, pageSize) -> searchObservationsSearchResultsDbIdGet(program.getId(), searchResultsDbId, page, pageSize), - observationSearchRequest - ); - // TODO: end old code ------ + // First, get all ObservationUnits for the given trialDbIds. + List observationUnitDbIds = observationUnitDAO.getObservationUnitsForTrialDbIds(program.getId(), trialDbIds) + .stream().map(BrAPIObservationUnit::getObservationUnitDbId).collect(Collectors.toList()); + // Finally, return all Observations for those ObservationUnits (Observations are linked to Trial through ObservationUnits). + return getProgramObservations(program.getId()).values().stream() + .filter(o -> observationUnitDbIds.contains(o.getObservationUnitDbId())) + .collect(Collectors.toList()); } public List getObservationsByObservationUnitsAndVariables(Collection ouDbIds, Collection variableDbIds, Program program) throws ApiException { diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 76c90abe7..828f4eab3 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -207,6 +207,15 @@ public List getObservationUnitsForStudyDbId(@NotNull Strin .collect(Collectors.toList()); } + public List getObservationUnitsForTrialDbIds(@NotNull UUID programId, List trialDbIds) throws ApiException { + if (trialDbIds.isEmpty()) { + return Collections.emptyList(); + } + return getProgramObservationUnits(programId).values().stream() + .filter(ou -> trialDbIds.contains(ou.getTrialDbId())) + .collect(Collectors.toList()); + } + public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId) throws ApiException, DoesNotExistException { return getObservationUnitsForTrialDbId(programId, trialDbId, false); } From 1872d6d7961d53e4dc51b6070b061edfb902f360 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:26:39 -0400 Subject: [PATCH 15/18] [BI-2058] - fixed Enum issue --- .../java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2901baa4e..870b0579b 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIStudyDAO.java @@ -189,7 +189,7 @@ private Map environmentById(List studies) { BrAPIExternalReference xref = environment .getExternalReferences() .stream() - .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.STUDIES).equalsIgnoreCase(reference.getReferenceSource())) + .filter(reference -> String.format("%s/%s", referenceSource, ExternalReferenceSource.STUDIES.getName()).equals(reference.getReferenceSource())) .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); environmentById.put(xref.getReferenceID(), environment); } From 2bfc02a6f668621d5a1878f111d0939ffbbce738 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:24:23 -0400 Subject: [PATCH 16/18] [BI-2058] - consolidated methods --- .../brapi/v2/dao/BrAPIObservationUnitDAO.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 828f4eab3..49e2dd511 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -216,11 +216,7 @@ public List getObservationUnitsForTrialDbIds(@NotNull UUID .collect(Collectors.toList()); } - public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId) throws ApiException, DoesNotExistException { - return getObservationUnitsForTrialDbId(programId, trialDbId, false); - } - - public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId, boolean withGID) throws ApiException, DoesNotExistException { + public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId) throws ApiException { return getProgramObservationUnits(programId).values().stream() .filter(ou -> ou.getTrialDbId().equals(trialDbId)) .collect(Collectors.toList()); @@ -236,6 +232,7 @@ public List getObservationUnitsForDataset(@NotNull String .collect(Collectors.toList()); } + // Note: does not use cache, impractical to implement all search parameters client-side. public List getObservationUnits(Program program, Optional observationUnitId, Optional observationUnitName, From e36666e2d2050ea8a4cb45661cd7fa19fda5ef4b Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Fri, 29 Mar 2024 09:16:52 -0400 Subject: [PATCH 17/18] [BI-2058] - cleaned up TODO --- .../breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java index 49e2dd511..7d8fd9651 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationUnitDAO.java @@ -98,7 +98,6 @@ public BrAPIObservationUnitDAO(ProgramDAO programDAO, this.programObservationUnitCache = programCacheProvider.getProgramCache(this::fetchProgramObservationUnits, BrAPIObservationUnit.class); } - // TODO: 2s? 3s? @Scheduled(initialDelay = "3s") public void setup() { if(!runScheduledTasks) { From 00bc7d83fa393c4f4b35dff1dfd0f3a830e24615 Mon Sep 17 00:00:00 2001 From: mlm483 <128052931+mlm483@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:21:19 -0400 Subject: [PATCH 18/18] [BI-2058] - utilized non-deprecated method --- .../org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java index 053aaac89..6eb4c2761 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -135,7 +135,7 @@ private Map processObservationsForCache(List String.format("%s/%s", referenceSource, ExternalReferenceSource.OBSERVATIONS.getName()).equals(reference.getReferenceSource())) .findFirst().orElseThrow(() -> new IllegalStateException("No BI external reference found")); - programObservationsMap.put(xref.getReferenceID(), observation); + programObservationsMap.put(xref.getReferenceId(), observation); } return programObservationsMap; }