[BI-1465] 6.1 Observation Dataset Export File#259
Conversation
| @Property(name = "brapi.server.reference-source") | ||
| private String referenceSource; |
There was a problem hiding this comment.
For testability, this should be included as a parameter to the constructor. See BrAPIObservationUnitDAO as an example
| List<BrAPIObservationVariable> obsVars = new ArrayList<>(); | ||
| Map<String, Map<String, Object>> rowByOUId = new HashMap<>(); | ||
| Map<String, BrAPIStudy> studyByDbId = new HashMap<>(); | ||
| List<String> requestedEnvNames = StringUtils.isNotBlank(params.getEnvironments()) ? |
There was a problem hiding this comment.
It may be better for this code to assume that environments is a list of environment UUIDs instead of names. That can help the code further down in this method to be more succinct
There was a problem hiding this comment.
agreed, and made the change
| } catch (ApiException err) { | ||
| log.error("Error fetching observation units for a study by its DbId" + | ||
| Utilities.generateApiExceptionLogMessage(err), err); | ||
| err.printStackTrace(); |
There was a problem hiding this comment.
This isn't needed as you've already passed the exception object to the log.error method (and that method will print the stack trace)
| BrAPIObservationUnit ou = ous.stream() | ||
| .filter(unit -> obs.getObservationUnitDbId().equals(unit.getObservationUnitDbId())) | ||
| .findAny() | ||
| .orElseThrow(RuntimeException::new); |
There was a problem hiding this comment.
I think it would be worth creating a map outside of the for loop of ouByOUId to reduce the runtime complexity
| BrAPIObservationVariable var = obsVars.stream() | ||
| .filter(obsVar -> obs.getObservationVariableName().equals(obsVar.getObservationVariableName())) | ||
| .collect(Collectors.toList()).get(0); |
There was a problem hiding this comment.
It would also be worth changing this to make a map of variableByDbId, and have that map be created and held in addBrAPIObsToRecords. This will also reduce the runtime complexity. This method could then be updated to accept a single BrAPIObservationVariable instead of a list of BrAPIObservationVariables
|
|
||
| public BrAPITrial getExperiment(Program program, UUID experimentId) throws ApiException { | ||
| List<BrAPITrial> experiments = trialDAO.getTrialsByExperimentIds(List.of(experimentId), program); | ||
| return experiments.get(0); |
There was a problem hiding this comment.
May be worth having a check here to ensure the list returned has at least one element. If it doesn't, throw an error. This will prevent ArrayIndexOutOfBounds errors from occurring
| Column obsVarColumn = new Column(); | ||
| obsVarColumn.setDataType(Column.ColumnDataType.STRING); | ||
| if (var.getScale().getDataType().equals(BrAPITraitDataType.ORDINAL)) { | ||
| obsVarColumn.setDataType(Column.ColumnDataType.INTEGER); |
| if (fileType.equals(FileType.CSV)){ | ||
| downloadFile = CSVWriter.writeToDownload(columns, exportRows, fileType); | ||
| } else { | ||
| downloadFile = ExcelWriter.writeToDownload("Dataset Export", columns, exportRows, fileType); |
There was a problem hiding this comment.
I think the sheetName should be "Experiment Data" to match the experiment import template
| // For backward compatibility | ||
| private static final String OLD_GERMPLASM_EXCEL_DATA_SHEET_NAME = "Germplasm Import"; | ||
| private static final String OLD_EXPERIMENT_EXCEL_DATA_SHEET_NAME = "Experiment Data"; | ||
| private static final String DATASET_EXPORT_EXCEL_DATA_SHEET_NAME = "Dataset Export"; |
There was a problem hiding this comment.
This isn't needed if the sheet name on export is "Experiment Data"
| //For backward compatibility allow old sheet names | ||
| if( sheet == null){ sheet = workbook.getSheet(OLD_GERMPLASM_EXCEL_DATA_SHEET_NAME); } | ||
| if( sheet == null){ sheet = workbook.getSheet(OLD_EXPERIMENT_EXCEL_DATA_SHEET_NAME); } | ||
| if( sheet == null){ sheet = workbook.getSheet(DATASET_EXPORT_EXCEL_DATA_SHEET_NAME); } |
There was a problem hiding this comment.
This isn't needed if the sheet name on export is "Experiment Data"
mlm483
left a comment
There was a problem hiding this comment.
This is a big feature, overall looks good! I found one bug, and I requested a few changes, mostly cleanup and documentation.
ExperimentControllerIntegrationTestlooks good. I don't see any of the test files insrc/test/resources/files/experiment_controller/being used, you may want to remove them.- There seems to be an issue casting timestamps to strings when generating Excel files. BrAPI Java TestServer was backing service. To reproduce:
- Import Germplasm: RILS and Parents.xls
- Import Ontology: bi_lettuce_ontology_v1.xlsx
- Import Experiment: SCY RIL exp2 TRUNC.xls
- Download KRSP22-2 dataset With Timestamps, select .xlsx file type.
- Error.
- in browser:
An error occurred while generating the download file. Contact the development team at bidevteam@cornell.edu.(Good actionable message! 👍) - bi-api stacktrace:
o.b.brapi.v2.ExperimentController - class java.time.OffsetDateTime cannot be cast to class java.lang.String (java.time.OffsetDateTime and java.lang.String are in module java.base of loader 'bootstrap') java.lang.ClassCastException: class java.time.OffsetDateTime cannot be cast to class java.lang.String (java.time.OffsetDateTime and java.lang.String are in module java.base of loader 'bootstrap') at org.breedinginsight.services.writers.ExcelWriter.writeToWorkbook(ExcelWriter.java:58) at org.breedinginsight.services.writers.ExcelWriter.writeToDownload(ExcelWriter.java:77) at org.breedinginsight.brapi.v2.services.BrAPITrialService.exportObservations(BrAPITrialService.java:172) at org.breedinginsight.brapi.v2.ExperimentController.datasetExport(ExperimentController.java:101)
src/main/java/org/breedinginsight/utilities/response/ResponseUtils.java
Outdated
Show resolved
Hide resolved
src/main/java/org/breedinginsight/brapi/v2/services/BrAPITrialService.java
Show resolved
Hide resolved
|
Testing Results: |
|
@davedrp Row and Column types were changed from double to string, and the download works now. |
|
@mlm483 Observation timestamps are being parsed to strings now, and the export works. |
| try { | ||
| for (BrAPIStudy study: expStudies) { | ||
| ous.addAll(ouDAO.getObservationUnitsForStudyDbId(study.getStudyDbId(), program)); | ||
| ous.forEach(ou -> ouByOUDbId.put(ou.getObservationUnitDbId(), ou)); |
There was a problem hiding this comment.
I think this will end up looping over all OUs for X number of studies. So during the first iteration, just the OUs for the first study will be added to the map. In the second iteration, all the OUs from the first study and the second study will be added to the map (although the OUs from the first study will just overwrite the existing records in the map), and so on until all studies have been iterated over.
There was a problem hiding this comment.
Good catch. I changed the forEach to loop over the current study ous instead of all ous.
| return response; | ||
| } catch (Exception e) { | ||
| log.info(e.getMessage(), e); | ||
| e.printStackTrace(); |
There was a problem hiding this comment.
This can be removed as the log.info will print the stack trace
| if (var.getScale().getDataType().equals(BrAPITraitDataType.ORDINAL)) { | ||
| row.put(varName, Integer.parseInt(obs.getValue())); |
There was a problem hiding this comment.
I think this has to be set as a String type for the same reason specified on this comment
mlm483
left a comment
There was a problem hiding this comment.
Looks good. Approved, I would just recommend explaining the call to addBrAPIObsToRecords on line 161 of BrAPITrialService.java, see comment.
| addBrAPIObsToRecords( | ||
| dataset, | ||
| experiment, | ||
| program, | ||
| ouByOUDbId, | ||
| studyByDbId, | ||
| rowByOUId, | ||
| params.isIncludeTimestamps(), | ||
| obsVars | ||
| ); |
There was a problem hiding this comment.
Again, because there are so many parameters and it's not immediately obvious which is being mutated, I would add a comment above this method call.
There was a problem hiding this comment.
np, added a comment that rowByOUId is being updated.
|
Dev-Test Passed |

Description
Story: BI-1465
ExperimentController#datasetExportwas created to add the GET endpoint/${micronaut.bi.api.version}/programs/{programId}/experiments/{experimentId}/export?{params}BrAPITrialService#exportObservationsand various helper functions in the same service were created to map existing observation data (if any) for the requested experiment and environments to table rows matching the structure of the experiment import template.ExperimentControllerIntegrationTestclass was created to test the various combinations of query param values to the export endpoint.Dependencies
bi-web
feature/BI-1465Testing
Checklist: