diff --git a/src/main/java/org/breedinginsight/brapi/v2/ExperimentController.java b/src/main/java/org/breedinginsight/brapi/v2/ExperimentController.java index e68202a6b..787f9edc4 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/ExperimentController.java +++ b/src/main/java/org/breedinginsight/brapi/v2/ExperimentController.java @@ -24,6 +24,7 @@ import javax.inject.Inject; import javax.validation.Valid; +import java.util.HashMap; import java.util.List; import java.util.UUID; @@ -61,4 +62,25 @@ public HttpResponse>>> getExperiments( return HttpResponse.status(HttpStatus.NOT_FOUND, e.getMessage()); } } + + @Get("/${micronaut.bi.api.version}/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/trials/{trialId}") + @Produces(MediaType.APPLICATION_JSON) + @ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.ALL}) + public HttpResponse> getExperimentById( + @PathVariable("programId") UUID programId, + @PathVariable("trialId") UUID trialId, + @QueryValue(defaultValue = "false") Boolean stats){ + try { + String logMsg = "fetching trial id:" + trialId +" for program: " + programId; + if(stats){ + logMsg += " with stats"; + } + log.debug(logMsg); + Response response = new Response<>(experimentService.getTrialDataByUUID(programId, trialId, stats)); + return HttpResponse.ok(response); + } catch (DoesNotExistException e) { + log.info(e.getMessage(), e); + return HttpResponse.status(HttpStatus.NOT_FOUND, e.getMessage()); + } + } } diff --git a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java index aa8517e5f..7bee585a3 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java +++ b/src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java @@ -1,13 +1,14 @@ package org.breedinginsight.brapi.v2.services; -import io.micronaut.context.annotation.Property; import io.micronaut.http.server.exceptions.InternalServerException; import org.brapi.client.v2.model.exceptions.ApiException; import lombok.extern.slf4j.Slf4j; import org.brapi.v2.model.core.BrAPITrial; +import org.brapi.v2.model.pheno.BrAPIObservationUnit; +import org.breedinginsight.brapps.importer.daos.BrAPIObservationUnitDAO; import org.breedinginsight.brapps.importer.daos.BrAPITrialDAO; -import org.breedinginsight.services.ProgramService; import org.breedinginsight.services.exceptions.DoesNotExistException; +import org.breedinginsight.utilities.Utilities; import javax.inject.Inject; import javax.inject.Singleton; @@ -17,19 +18,38 @@ @Singleton public class BrAPITrialService { - @Property(name = "brapi.server.reference-source") - private String referenceSource; - private final BrAPITrialDAO trialDAO; - private final ProgramService programService; + private final BrAPIObservationUnitDAO ouDAO; @Inject - public BrAPITrialService(ProgramService programService, BrAPITrialDAO trialDAO) { - this.programService = programService; + public BrAPITrialService( BrAPITrialDAO trialDAO,BrAPIObservationUnitDAO ouDAO) { this.trialDAO = trialDAO; + this.ouDAO = ouDAO; } public List getExperiments(UUID programId) throws ApiException, DoesNotExistException { return trialDAO.getTrials(programId); } + + public BrAPITrial getTrialDataByUUID(UUID programId, UUID trialId, boolean stats) throws DoesNotExistException { + try { + BrAPITrial trial = trialDAO.getTrialById(programId,trialId).orElseThrow(() -> new DoesNotExistException("Trial does not exist")); + //Remove the [program key] from the trial name + trial.setTrialName( Utilities.removeUnknownProgramKey( trial.getTrialName()) ); + if( stats ){ + int environmentsCount = 1; // For now this is hardcoded to 1, because we are only supporting one environment per experiment + long germplasmCount = countGermplasm(programId, trial.getTrialDbId()); + trial.putAdditionalInfoItem("environmentsCount", environmentsCount); + trial.putAdditionalInfoItem("germplasmCount", germplasmCount); + } + return trial; + } catch (ApiException e) { + throw new InternalServerException(e.getMessage(), e); + } + } + + private long countGermplasm(UUID programId, String trialDbId) throws ApiException, DoesNotExistException{ + List obUnits = ouDAO.getObservationUnitsForTrialDbId(programId, trialDbId); + return obUnits.stream().map(BrAPIObservationUnit::getGermplasmDbId).distinct().count(); + } } diff --git a/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAO.java b/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAO.java index 59c2a3041..6401c031e 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAO.java +++ b/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPIObservationUnitDAO.java @@ -26,7 +26,9 @@ 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; import javax.inject.Inject; @@ -36,44 +38,24 @@ @Singleton public class BrAPIObservationUnitDAO { - - public static String OU_ID_REFERENCE_SOURCE = "ou_id"; - - private ProgramDAO programDAO; - private ImportDAO importDAO; + private final ProgramDAO programDAO; + private final ImportDAO importDAO; private final BrAPIDAOUtil brAPIDAOUtil; private final BrAPIEndpointProvider brAPIEndpointProvider; + private final ProgramService programService; private final String referenceSource; @Inject - public BrAPIObservationUnitDAO(ProgramDAO programDAO, ImportDAO importDAO, BrAPIDAOUtil brAPIDAOUtil, BrAPIEndpointProvider brAPIEndpointProvider, @Property(name = "brapi.server.reference-source") String referenceSource) { + public BrAPIObservationUnitDAO(ProgramDAO programDAO, ImportDAO importDAO, BrAPIDAOUtil brAPIDAOUtil, BrAPIEndpointProvider brAPIEndpointProvider, ProgramService programService, @Property(name = "brapi.server.reference-source") String referenceSource) { this.programDAO = programDAO; this.importDAO = importDAO; this.brAPIDAOUtil = brAPIDAOUtil; this.brAPIEndpointProvider = brAPIEndpointProvider; this.referenceSource = referenceSource; + this.programService = programService; } - /* - public List getObservationUnitsByNameAndStudyName(List> nameStudyPairs, BrAPIProgram brAPIProgram) throws ApiException { - - List observationUnitNames = nameStudyPairs.stream().map(Pair::getLeft).collect(Collectors.toList()); - BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); - observationUnitSearchRequest.setObservationUnitNames(new ArrayList<>(observationUnitNames)); - observationUnitSearchRequest.setProgramDbIds(List.of(brAPIProgram.getProgramDbId())); - ObservationUnitsApi api = brAPIProvider.getObservationUnitApi(BrAPIClientType.CORE); - List observationUnits = BrAPIDAOUtil.search( - api::searchObservationunitsPost, - api::searchObservationunitsSearchResultsDbIdGet, - observationUnitSearchRequest - ); - - // TODO: Select for study as well - return observationUnits; - } - */ - public List getObservationUnitByName(List observationUnitNames, Program program) throws ApiException { if(observationUnitNames.isEmpty()) { return Collections.emptyList(); @@ -115,12 +97,25 @@ public List getObservationUnitsById(Collection obs public List getObservationUnitsForStudyDbId(@NotNull String studyDbId, Program program) throws ApiException { BrAPIObservationUnitSearchRequest observationUnitSearchRequest = new BrAPIObservationUnitSearchRequest(); observationUnitSearchRequest.programDbIds(List.of(program.getBrapiProgram() - .getProgramDbId())); + .getProgramDbId())); observationUnitSearchRequest.studyDbIds(List.of(studyDbId)); ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), ObservationUnitsApi.class); return brAPIDAOUtil.search(api::searchObservationunitsPost, - api::searchObservationunitsSearchResultsDbIdGet, - observationUnitSearchRequest); + api::searchObservationunitsSearchResultsDbIdGet, + observationUnitSearchRequest); + } + public List getObservationUnitsForTrialDbId(@NotNull UUID programId, @NotNull String trialDbId) 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)); + + ObservationUnitsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), ObservationUnitsApi.class); + return brAPIDAOUtil.search(api::searchObservationunitsPost, + api::searchObservationunitsSearchResultsDbIdGet, + observationUnitSearchRequest); } } diff --git a/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPITrialDAO.java b/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPITrialDAO.java index 742afd2a3..ab9de443c 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPITrialDAO.java +++ b/src/main/java/org/breedinginsight/brapps/importer/daos/BrAPITrialDAO.java @@ -21,9 +21,6 @@ import org.brapi.client.v2.modules.core.TrialsApi; import org.brapi.v2.model.core.BrAPITrial; import org.brapi.v2.model.core.request.BrAPITrialSearchRequest; -import org.brapi.v2.model.core.response.BrAPIListDetails; -import org.brapi.v2.model.core.response.BrAPIListResponse; -import org.brapi.v2.model.core.response.BrAPITrialSingleResponse; import org.breedinginsight.brapps.importer.model.ImportUpload; import org.breedinginsight.brapps.importer.services.ExternalReferenceSource; import org.breedinginsight.daos.ProgramDAO; @@ -40,11 +37,13 @@ @Singleton public class BrAPITrialDAO { + @Property(name = "brapi.server.reference-source") + private String BRAPI_REFERENCE_SOURCE; - private ProgramDAO programDAO; - private ImportDAO importDAO; + private final ProgramDAO programDAO; + private final ImportDAO importDAO; private final BrAPIDAOUtil brAPIDAOUtil; - private ProgramService programService; + private final ProgramService programService; private final BrAPIEndpointProvider brAPIEndpointProvider; private final String referenceSource; @@ -75,6 +74,19 @@ public List getTrialsByName(List trialNames, Program program ); } + private List getTrialsByExRef(String referenceSource, String referenceId, Program program) throws ApiException { + BrAPITrialSearchRequest trialSearch = new BrAPITrialSearchRequest(); + trialSearch.programDbIds(List.of(program.getBrapiProgram().getProgramDbId())); + trialSearch.externalReferenceSources(List.of(referenceSource)); + trialSearch.externalReferenceIDs(List.of(referenceId)); + TrialsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(program.getId()), TrialsApi.class); + return brAPIDAOUtil.search( + api::searchTrialsPost, + api::searchTrialsSearchResultsDbIdGet, + trialSearch + ); + } + public List createBrAPITrials(List brAPITrialList, UUID programId, ImportUpload upload) throws ApiException { TrialsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), TrialsApi.class); return brAPIDAOUtil.post(brAPITrialList, upload, api::trialsPost, importDAO::update); @@ -123,12 +135,18 @@ private List processExperimentsForDisplay(List trials, S return displayExperiments; } - public Optional getTrialByDbId(String trialDbId, Program program) throws ApiException { - List trials = getTrialsByDbIds(List.of(trialDbId), program); + public Optional getTrialById(UUID programId, UUID trialDbId) throws ApiException, DoesNotExistException { + Program program = programService.getById(programId).orElseThrow(() -> new DoesNotExistException("Program id does not exist")); + String refSoure = Utilities.generateReferenceSource(BRAPI_REFERENCE_SOURCE, ExternalReferenceSource.TRIALS); + List trials = getTrialsByExRef(refSoure, trialDbId.toString(), program); return Utilities.getSingleOptional(trials); } + public Optional getTrialByDbId(String trialDbId, Program program) throws ApiException { + List trials = getTrialsByDbIds(List.of(trialDbId), program); + return Utilities.getSingleOptional(trials); + } public List getTrialsByDbIds(Collection trialDbIds, Program program) throws ApiException { if(trialDbIds.isEmpty()) { return Collections.emptyList(); diff --git a/src/main/java/org/breedinginsight/utilities/Utilities.java b/src/main/java/org/breedinginsight/utilities/Utilities.java index 59a4be0e9..52e85ad2d 100644 --- a/src/main/java/org/breedinginsight/utilities/Utilities.java +++ b/src/main/java/org/breedinginsight/utilities/Utilities.java @@ -71,6 +71,17 @@ public static String appendProgramKey( String original, String programKey ){ return appendProgramKey( original, programKey, null); } + /** + * Remove unknown program key from a string. Returns a new value instead of altering original string. + * + * @param original - The string with a [program key] + * @return - the original string without the [program key] + */ + public static String removeUnknownProgramKey(String original) { + return original.replaceAll("\\[.*\\]", "").trim(); + } + + /** * Remove program key from a string. Returns a new value instead of altering original string. *