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 92b45633c..fc9970b75 100644 --- a/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java +++ b/src/main/java/org/breedinginsight/brapi/v2/dao/BrAPIObservationDAO.java @@ -250,10 +250,57 @@ public BrAPIObservation updateBrAPIObservation(String dbId, BrAPIObservation obs ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); var program = programDAO.fetchOneById(programId); try { + Callable> postFunction = () -> { + ApiResponse response = api.observationsObservationDbIdPut(dbId, observation); - if (response == null) - { + 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()); + }; + // returns ListArray<> = postFunction.call().values() + 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); + } + } + + // This method overloads updateBrAPIObservation(String dbId, BrAPIObservation observation, UUID programId) + // It was added to increase efficiency. It insures that ProgramCache.populate() is called only once + // not once per observation. + public void updateBrAPIObservation(Map mutatedObservationByDbId, UUID programId) throws ApiException { + ObservationsApi api = brAPIEndpointProvider.get(programDAO.getCoreClient(programId), ObservationsApi.class); + var program = programDAO.fetchOneById(programId); + + List updatedObservations = new ArrayList<>(); + try { + Map updatedObservationsByDbId = new HashMap<>(); + for (Map.Entry entry : mutatedObservationByDbId.entrySet()) { + String dbId = entry.getKey(); + BrAPIObservation observation = entry.getValue(); + if (observation == null) { + throw new Exception("Null observation"); + } + + ApiResponse response = null; + try { + response = api.observationsObservationDbIdPut(dbId, observation); + } catch (ApiException e) { + throw new RuntimeException(e); + } + if (response == null) { throw new ApiException("Response is null", 0, null, null); } BrAPIObservationSingleResponse body = response.getBody(); @@ -264,14 +311,29 @@ public BrAPIObservation updateBrAPIObservation(String dbId, BrAPIObservation obs 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); - } + updatedObservations.add(updatedObservation); + + if (!Objects.equals(observation.getValue(), updatedObservation.getValue()) + || !Objects.equals(observation.getObservationTimeStamp(), updatedObservation.getObservationTimeStamp())) { + String message; + if (!Objects.equals(observation.getValue(), updatedObservation.getValue())) { + message = String.format("Updated observation, %s, from BrAPI service does not match requested update %s.", updatedObservation.getValue(), observation.getValue()); + } else { + message = String.format("Updated observation timestamp, %s, from BrAPI service does not match requested update timestamp %s.", updatedObservation.getObservationTimeStamp(), observation.getObservationTimeStamp()); + } + throw new Exception(message); + } + } + + } catch (ApiException e) { + log.error("Error updating observation: " + Utilities.generateApiExceptionLogMessage(e), e); + throw new InternalServerException("Error saving experiment import", e); + } catch (Exception e) { + log.error("Error updating observation: ", e); + throw new InternalServerException(e.getMessage(), e); + } + processObservationsForCache(updatedObservations, program.getKey()); + programObservationCache.populate(programId); + return; } } diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java index c0f5c4c1f..4e4aaf9cc 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java @@ -300,13 +300,16 @@ public void validateDependencies(Map mappedBrAPIImport) } @Override - public void postBrapiData(Map mappedBrAPIImport, Program program, ImportUpload upload) { + public void postBrapiData(Map mappedBrAPIImport, Program program, ImportUpload upload) { log.debug("starting post of experiment data to BrAPI server"); List newTrials = ProcessorData.getNewObjects(this.trialByNameNoScope); Map mutatedTrialsById = ProcessorData .getMutationsByObjectId(trialByNameNoScope, BrAPITrial::getTrialDbId); + //getMutationsByObjectId() will return a HashMap of just the mutated Observations, + // key = BrAPIObservation::getObservationDbId + // value = mutated BrAPIObservation Map mutatedObservationByDbId = ProcessorData .getMutationsByObjectId(observationByHash, BrAPIObservation::getObservationDbId); @@ -428,36 +431,16 @@ public void postBrapiData(Map mappedBrAPIImport, Program throw new InternalServerException(e.getMessage(), e); } }); - - mutatedObservationByDbId.forEach((id, observation) -> { - try { - if (observation == null) { - throw new Exception("Null observation"); - } - BrAPIObservation updatedObs = brAPIObservationDAO.updateBrAPIObservation(id, observation, program.getId()); - - if (updatedObs == null) { - throw new Exception("Null updated observation"); - } - - if (!Objects.equals(observation.getValue(), updatedObs.getValue()) - || !Objects.equals(observation.getObservationTimeStamp(), updatedObs.getObservationTimeStamp())) { - String message; - if(!Objects.equals(observation.getValue(), updatedObs.getValue())) { - message = String.format("Updated observation, %s, from BrAPI service does not match requested update %s.", updatedObs.getValue(), observation.getValue()); - } else { - message = String.format("Updated observation timestamp, %s, from BrAPI service does not match requested update timestamp %s.", updatedObs.getObservationTimeStamp(), observation.getObservationTimeStamp()); - } - throw new Exception(message); - } - } catch (ApiException e) { + try { + brAPIObservationDAO.updateBrAPIObservation( mutatedObservationByDbId, program.getId() ); + } catch (ApiException e) { log.error("Error updating observation: " + Utilities.generateApiExceptionLogMessage(e), e); throw new InternalServerException("Error saving experiment import", e); } catch (Exception e) { log.error("Error updating observation: ", e); throw new InternalServerException(e.getMessage(), e); } - }); + log.debug("experiment import complete"); }