Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,49 +1,28 @@
package org.breedinginsight.brapi.v2.services;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
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.ObservationUnitsApi;
import org.brapi.v2.model.pheno.BrAPIObservationUnitHierarchyLevel;
import org.brapi.v2.model.pheno.BrAPIObservationUnitLevelRelationship;
import org.brapi.v2.model.pheno.response.BrAPIObservationLevelListResponse;
import org.breedinginsight.brapi.v2.dao.BrAPIObservationLevelDAO;
import org.breedinginsight.model.DatasetLevel;
import org.breedinginsight.model.Program;
import org.breedinginsight.services.ProgramService;
import org.breedinginsight.services.exceptions.DoesNotExistException;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Singleton
public class BrAPIObservationLevelService {
private final BrAPIObservationLevelDAO brAPIObservationLevelDAO;
private final ProgramService programService;


@Inject
public BrAPIObservationLevelService(BrAPIObservationLevelDAO brAPIObservationLevelDAO,
ProgramService programService) {
public BrAPIObservationLevelService(BrAPIObservationLevelDAO brAPIObservationLevelDAO) {
this.brAPIObservationLevelDAO = brAPIObservationLevelDAO;
this.programService = programService;
}

/**
* @return Pair[GlobalLevelNames, ProgrammaticLevelNames]
*/
public Pair<List<BrAPIObservationUnitHierarchyLevel>, List<BrAPIObservationUnitHierarchyLevel>> getGlobalAndProgrammaticLevelNames(Program program, String brapiProgramDbId) {
List<BrAPIObservationUnitHierarchyLevel> globalLevels = brAPIObservationLevelDAO.getGlobalObservationLevelNames(program);
List<BrAPIObservationUnitHierarchyLevel> programmaticLevels = brAPIObservationLevelDAO.getObservationLevelNamesByProgramId(program, brapiProgramDbId);


return new ImmutablePair<>(globalLevels, programmaticLevels);
public List<BrAPIObservationUnitHierarchyLevel> getGlobalLevelNames(Program program) {
return brAPIObservationLevelDAO.getGlobalObservationLevelNames(program);
}

public List<BrAPIObservationUnitHierarchyLevel> getProgrammaticLevelNames(Program program, String brapiProgramDbId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.StringUtils;
import org.brapi.client.v2.model.exceptions.ApiException;
import org.brapi.v2.model.core.BrAPIListSummary;
import org.brapi.v2.model.core.BrAPIProgram;
import org.brapi.v2.model.core.BrAPIStudy;
import org.brapi.v2.model.core.BrAPITrial;
import org.brapi.v2.model.core.request.BrAPIListNewRequest;
Expand All @@ -43,6 +44,7 @@
import org.breedinginsight.brapps.importer.services.processors.experiment.ExperimentUtilities;
import org.breedinginsight.brapps.importer.services.processors.experiment.create.model.PendingData;
import org.breedinginsight.brapps.importer.services.processors.experiment.create.model.ProcessContext;
import org.breedinginsight.brapps.importer.services.processors.experiment.service.DatasetService;
import org.breedinginsight.model.DatasetLevel;
import org.breedinginsight.model.Program;
import org.breedinginsight.model.ProgramLocation;
Expand All @@ -55,10 +57,7 @@

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;

import static org.breedinginsight.brapps.importer.services.processors.experiment.ExperimentUtilities.PREEXISTING_EXPERIMENT_TITLE;
Expand All @@ -74,7 +73,7 @@ public class CommitPendingImportObjectsStep {
private final BrAPIObservationUnitDAO brAPIObservationUnitDAO;
private final ProgramLocationService locationService;
private final OntologyService ontologyService;
private final BrAPIObservationLevelDAO brAPIObservationLevelDAO;
private final DatasetService datasetService;

@Inject
public CommitPendingImportObjectsStep(BrAPIListDAO brAPIListDAO,
Expand All @@ -84,19 +83,21 @@ public CommitPendingImportObjectsStep(BrAPIListDAO brAPIListDAO,
BrAPIObservationUnitDAO brAPIObservationUnitDAO,
ProgramLocationService locationService,
OntologyService ontologyService,
BrAPIObservationLevelDAO brAPIObservationLevelDAO) {
DatasetService datasetService) {
this.brAPIListDAO = brAPIListDAO;
this.brapiTrialDAO = brapiTrialDAO;
this.brAPIStudyDAO = brAPIStudyDAO;
this.brAPIObservationDAO = brAPIObservationDAO;
this.brAPIObservationUnitDAO = brAPIObservationUnitDAO;
this.locationService = locationService;
this.ontologyService = ontologyService;
this.brAPIObservationLevelDAO = brAPIObservationLevelDAO;
this.datasetService = datasetService;
}

// TODO: some common code between workflows here that could be broken out, removed append/update specific code
public void process(ProcessContext processContext, ProcessedData processedData) throws UnprocessableEntityException {
// TODO: For instance, multiple trials don't really exist in the use case which this code is used for: creating an experiment.
// TODO: This means having a Map of trials doesn't really make sense anymore, and should be replaced with a singular PendingImportObject<Trial>
public void process(ProcessContext processContext, ProcessedData processedData) throws UnprocessableEntityException, ApiException {

PendingData pendingData = processContext.getPendingData();
ImportContext importContext = processContext.getImportContext();
Expand All @@ -113,6 +114,32 @@ public void process(ProcessContext processContext, ProcessedData processedData)
Map<String, PendingImportObject<BrAPIObservation>> observationByHash = pendingData.getObservationByHash();
Map<String, String> expUnitbyTrialName = pendingData.getExpUnitByTrialName();

// Assume that there's only one expUnit per trial in this workflow.
// This should be a safe assumption to make considering this workflow is for the creation of a single experiment.
// If that changes in the future, this code will break and need to be dealt with.

if (expUnitbyTrialName.size() > 1) {
throw new InternalServerException("Multiple Experiment names exist during commit stage");
}

String expUnitName = expUnitbyTrialName.values()
.stream()
.findFirst()
.orElse(null);

if (expUnitName == null) {
throw new InternalServerException("Experiment unit name not found during commit stage");
}

String brapiProgramId = Optional.of(program)
.map(Program::getBrapiProgram)
.map(BrAPIProgram::getProgramDbId)
.orElse(null);

if (brapiProgramId == null) {
throw new InternalServerException("BrAPI program not found during commit stage");
}

List<BrAPITrial> newTrials = ProcessorData.getNewObjects(pendingData.getTrialByNameNoScope());

List<ProgramLocationRequest> newLocations = ProcessorData.getNewObjects(pendingData.getLocationByName())
Expand All @@ -139,6 +166,14 @@ public void process(ProcessContext processContext, ProcessedData processedData)

List<BrAPIObservationUnit> newObservationUnits = ProcessorData.getNewObjects(pendingData.getObservationUnitByNameNoScope());

// Inject level names here
datasetService.updateObservationUnitsWithLevelNameDbIds(newObservationUnits,
program,
brapiProgramId,
expUnitName,
DatasetLevel.EXP_UNIT
);

// filter out observations with no 'value' so they will not be saved
List<BrAPIObservation> newObservations = ProcessorData.getNewObjects(observationByHash)
.stream()
Expand Down Expand Up @@ -176,8 +211,6 @@ public void process(ProcessContext processContext, ProcessedData processedData)
trialByNameNoScope.get(createdTrialName)
.getBrAPIObject()
.setTrialDbId(createdTrial.getTrialDbId());

createObservationLevel(createdTrialName, expUnitbyTrialName, program);
}

List<ProgramLocation> createdLocations = new ArrayList<>(locationService.create(actingUser, program.getId(), newLocations));
Expand Down Expand Up @@ -251,22 +284,6 @@ public void process(ProcessContext processContext, ProcessedData processedData)

}

//Check if the experimental unit associated with the trial does not exist in the system and if so create a new observation level
private void createObservationLevel(String trialName, Map<String, String> expUnitByTrialName, Program program) throws ApiException, InternalServerException {
String expUnit = expUnitByTrialName.get(trialName).toLowerCase();
String programDbId = program.getBrapiProgram() != null ? program.getBrapiProgram().getProgramDbId() : null;
HttpResponse<String> levelResponse = brAPIObservationLevelDAO.createObservationLevelName(program, expUnit, DatasetLevel.EXP_UNIT, programDbId);

if (levelResponse.getStatus().getCode() == 409) {
log.info(String.format("Level with name=%s, order=%s, programDbId=%s already exists in database", expUnit, DatasetLevel.EXP_UNIT, programDbId));
} else if (levelResponse.getStatus().getCode() == 200) {
log.info(String.format("Level with name=%s, order=%s, programDbId=%s created in database", expUnit, DatasetLevel.EXP_UNIT, programDbId));
} else {
log.error("Error saving experiment import: " + levelResponse.getStatus().getReason());
throw new InternalServerException("Unable to create observation level: " + levelResponse.getStatus().getReason());
}
}

private void updateStudyDependencyValues(PendingData pendingData, Map<Integer, PendingImport> mappedBrAPIImport, String programKey) {
// update location DbIds in studies for all distinct locations
Map<String, PendingImportObject<BrAPITrial>> trialByNameNoScope = pendingData.getTrialByNameNoScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.breedinginsight.brapps.importer.services.processors.experiment.service;

import io.micronaut.context.annotation.Property;
import io.micronaut.http.server.exceptions.InternalServerException;
import org.apache.commons.lang3.StringUtils;
import org.brapi.client.v2.model.exceptions.ApiException;
import org.brapi.v2.model.BrAPIExternalReference;
Expand All @@ -26,14 +27,16 @@
import org.brapi.v2.model.core.BrAPITrial;
import org.brapi.v2.model.core.request.BrAPIListNewRequest;
import org.brapi.v2.model.core.response.BrAPIListDetails;
import org.brapi.v2.model.pheno.BrAPIObservationUnit;
import org.brapi.v2.model.pheno.BrAPIObservationUnitHierarchyLevel;
import org.brapi.v2.model.pheno.BrAPIObservationUnitLevelRelationship;
import org.breedinginsight.brapi.v2.constants.BrAPIAdditionalInfoFields;
import org.breedinginsight.brapi.v2.dao.BrAPIListDAO;
import org.breedinginsight.brapi.v2.dao.BrAPIObservationLevelDAO;
import org.breedinginsight.brapi.v2.services.BrAPIObservationLevelService;
import org.breedinginsight.brapps.importer.model.response.ImportObjectState;
import org.breedinginsight.brapps.importer.model.response.PendingImportObject;
import org.breedinginsight.brapps.importer.services.ExternalReferenceSource;
import org.breedinginsight.model.BrAPIConstants;
import org.breedinginsight.model.DatasetLevel;
import org.breedinginsight.model.DatasetMetadata;
import org.breedinginsight.model.Program;
Expand Down Expand Up @@ -216,4 +219,42 @@ private String findLevelNameByNameAndOrder(Program program,

return levelNameStreamResult.get(0).getLevelNameDbId();
}

public void updateObservationUnitsWithLevelNameDbIds(List<BrAPIObservationUnit> observationUnits,
Program program,
String brapiProgramDbId,
String expUnitName,
DatasetLevel levelOrder) throws ApiException {
Map<String, String> levelNameDbIdByName = new HashMap<>();

String expLevelName = expUnitName.toLowerCase();

String existingLevelNameDbId = getOrCreateLevelNameForDataset(program, brapiProgramDbId, expLevelName, levelOrder);
levelNameDbIdByName.put(expLevelName, existingLevelNameDbId);

List<BrAPIObservationUnitHierarchyLevel> globalLevelNames = observationLevelService.getGlobalLevelNames(program);

globalLevelNames.forEach(ouln -> levelNameDbIdByName.put(ouln.getLevelName(), ouln.getLevelNameDbId()));

for (BrAPIObservationUnit observationUnit : observationUnits) {

String positionLevelName = observationUnit.getObservationUnitPosition().getObservationLevel().getLevelName().toLowerCase();

observationUnit.getObservationUnitPosition().getObservationLevel().setLevelNameDbId(levelNameDbIdByName.get(positionLevelName));

for (BrAPIObservationUnitLevelRelationship lvlRelationship : observationUnit.getObservationUnitPosition().getObservationLevelRelationships()) {
if (lvlRelationship.getLevelName().equals(BrAPIConstants.BLOCK.getValue())) {
lvlRelationship.setLevelNameDbId(levelNameDbIdByName.get(lvlRelationship.getLevelName()));
} else if (lvlRelationship.getLevelName().equals(BrAPIConstants.REPLICATE.getValue())) {
lvlRelationship.setLevelNameDbId(levelNameDbIdByName.get(lvlRelationship.getLevelName()));
} else {
throw new InternalServerException(String.format("Level name [%s] detected in OU Level Relationship " +
"for experiment with Exp Unit name [%s]. This is unexpected and the new level " +
"name must be retrieved properly from BrAPI to insert its DbId into BrAPI request for proper creation and assignment.",
lvlRelationship.getLevelName(), expUnitName));
}
}
}

}
}
Loading