Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
e6374e5
[BI-2578] Support for unpaginated RQs to BrAPI server for cache loading
jloux-brapi Mar 14, 2025
78c699e
[BI-2579] Forgo cache refresh on response from server during germ imp…
jloux-brapi Mar 14, 2025
9c07244
Add comment about configurable variable on brapi test server side
jloux-brapi Mar 17, 2025
550a00b
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Mar 17, 2025
14c1ee3
[BI-2578] Add config props for max rq page size and pagination flippe…
jloux-brapi Mar 19, 2025
9f42685
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Mar 19, 2025
fa32de4
Fully populate program germplasm cache when upload completes
jloux-brapi Mar 20, 2025
51c9f7f
Add test server template props to bi-api
jloux-brapi Mar 31, 2025
df83a2c
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Mar 31, 2025
dcfd786
Add properties added to test server properties file
jloux-brapi Mar 31, 2025
5fe02f2
Restore functionality of using post return values
jloux-brapi Mar 31, 2025
6691029
Merge branch 'develop' into feature/BI-2578
jloux-brapi Apr 2, 2025
cb260ec
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Apr 2, 2025
bb359fd
Fix unit test errors related to new property not loading
jloux-brapi Apr 2, 2025
d970231
Fix unit test failure related to searchNoPaging function
jloux-brapi Apr 2, 2025
fd3d6c6
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Apr 2, 2025
dc5c9ed
Merge branch 'develop' into feature/BI-2578
jloux-brapi Apr 4, 2025
4e9a87d
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Apr 4, 2025
0b51b1f
[autocommit] bumping build number
rob-ouser-bi Apr 9, 2025
aeb24cc
Merge branch 'bug/BI-2594' into develop
nickpalladino Apr 9, 2025
32ac1b2
[autocommit] bumping build number
rob-ouser-bi Apr 9, 2025
7212dc0
Merge branch 'develop' into feature/BI-2578
jloux-brapi Apr 14, 2025
bba6175
Merge branch 'feature/BI-2578' into feature/BI-2579
jloux-brapi Apr 14, 2025
5159c9d
Merge pull request #447 from Breeding-Insight/feature/BI-2578
nickpalladino Apr 16, 2025
9b54794
[autocommit] bumping build number
rob-ouser-bi Apr 16, 2025
438ee08
Merge branch 'develop' into feature/BI-2579
jloux-brapi Apr 18, 2025
f4ff8b3
Merge pull request #448 from Breeding-Insight/feature/BI-2579
nickpalladino Apr 24, 2025
5c969e3
[autocommit] bumping build number
rob-ouser-bi Apr 24, 2025
c6d599d
Update src/test/java/org/breedinginsight/BrAPITest.java
mlm483 Apr 30, 2025
74201d7
[autocommit] bumping build number
rob-ouser-bi Apr 30, 2025
6904ba5
Merge branch 'develop' into release/1.1
mlm483 Apr 30, 2025
b9b0cfe
[autocommit] bumping build number
rob-ouser-bi Apr 30, 2025
738dee1
Merge pull request #461 from Breeding-Insight/release/1.1
mlm483 Apr 30, 2025
c66193a
[autocommit] bumping build number
rob-ouser-bi Apr 30, 2025
1b45178
[autocommit] bumping build number
rob-ouser-bi May 19, 2025
bcd7f16
Update version number
nickpalladino May 19, 2025
0a9f8ba
[autocommit] bumping build number
rob-ouser-bi May 19, 2025
da98919
[BI-2654] - replaced reserved keyword with allowed value
mlm483 May 29, 2025
fc36129
Increased signup token expiration from 1hr to 24hr
nickpalladino May 29, 2025
a290899
Merge pull request #465 from Breeding-Insight/bug/BI-2654
mlm483 May 30, 2025
a3b80c7
[autocommit] bumping build number
rob-ouser-bi May 30, 2025
1842f02
Update species migration to work with new uuids
nickpalladino Jun 3, 2025
f97f6d4
[autocommit] bumping build number
rob-ouser-bi Jun 3, 2025
7a6be40
Update species sql for tests
nickpalladino Jun 4, 2025
e916fc3
Merge branch 'release/1.1.1' of https://github.com/Breeding-Insight/b…
nickpalladino Jun 4, 2025
dbec72a
[autocommit] bumping build number
rob-ouser-bi Jun 4, 2025
7129705
Add security issuer env for tests
nickpalladino Jun 4, 2025
fab1f52
Merge branch 'release/1.1.1' of https://github.com/Breeding-Insight/b…
nickpalladino Jun 4, 2025
e05bad5
[autocommit] bumping build number
rob-ouser-bi Jun 4, 2025
c0e1e99
Change dbid to uuid
nickpalladino Jun 4, 2025
4dd0964
[autocommit] bumping build number
rob-ouser-bi Jun 4, 2025
1492b12
Update postgres to 17.5
nickpalladino Jun 4, 2025
d6242a6
[autocommit] bumping build number
rob-ouser-bi Jun 4, 2025
cd4148b
Merge branch 'release/1.1.1' into feature/BI-2616
nickpalladino Jun 5, 2025
942ebf1
Merge pull request #467 from Breeding-Insight/feature/BI-2616
nickpalladino Jun 5, 2025
aac64d8
[autocommit] bumping build number
rob-ouser-bi Jun 5, 2025
a9fd111
[BI-2632] added back germplasmListExport()
davedrp Jun 11, 2025
b424fbf
[BI-2632] added test for germplasmListExport()
davedrp Jun 11, 2025
3a374ed
Merge pull request #471 from Breeding-Insight/bug/BI-2632
davedrp Jun 11, 2025
75dca96
[autocommit] bumping build number
rob-ouser-bi Jun 11, 2025
522a191
Merge pull request #470 from Breeding-Insight/bug/BI-2664
nickpalladino Jun 12, 2025
9ed32eb
[autocommit] bumping build number
rob-ouser-bi Jun 12, 2025
44114ed
First pass fix, new list only case looks good
nickpalladino Jun 12, 2025
eb98f66
Update pedigree count to handle update case
nickpalladino Jun 13, 2025
2b10e02
Only update pedigree if no existing and file has pedigree
nickpalladino Jun 13, 2025
1ad3176
Merge pull request #472 from Breeding-Insight/bug/BI-2639
nickpalladino Jun 17, 2025
4ff31d3
[autocommit] bumping build number
rob-ouser-bi Jun 17, 2025
f48c2a0
Update version
nickpalladino Jun 18, 2025
ba5f963
[autocommit] bumping build number
rob-ouser-bi Jun 18, 2025
d9e1ca0
Fix version number
nickpalladino Jun 19, 2025
3c86f26
[autocommit] bumping build number
rob-ouser-bi Jun 19, 2025
62f8b18
[BI-2656] - added null check
mlm483 Jul 9, 2025
5d25aab
[BI-2656] - prevent setting timestamp to null
mlm483 Jul 10, 2025
14eeca3
[BI-2656] - added integration test
mlm483 Jul 16, 2025
35f6303
[BI-2656] - cleaned up test
mlm483 Jul 16, 2025
42c9c2f
[BI-2656] - handled timestamp edge case
mlm483 Jul 29, 2025
35238b1
Merge pull request #475 from Breeding-Insight/bug/BI-2656-release
mlm483 Jul 30, 2025
b8ba6f9
[autocommit] bumping build number
rob-ouser-bi Jul 30, 2025
365c3b2
[BI-2656] - added error logging
mlm483 Aug 8, 2025
2ddc8c9
Merge pull request #484 from Breeding-Insight/bug/BI-2656-logging
mlm483 Aug 8, 2025
77f5a1f
[autocommit] bumping build number
rob-ouser-bi Aug 8, 2025
d4d3873
[BI-2656] - updated isChanged logic
mlm483 Aug 12, 2025
64c0cf8
Merge pull request #485 from Breeding-Insight/bug/BI-2656-qa
mlm483 Aug 13, 2025
49d7ef6
[autocommit] bumping build number
rob-ouser-bi Aug 13, 2025
4497ad6
Merge branch 'main' into release/1.1.1
mlm483 Aug 13, 2025
7112d7e
[autocommit] bumping build number
rob-ouser-bi Aug 13, 2025
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
4 changes: 4 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ BRAPI_READ_TIMEOUT=60m
# Max number of records to POST to the BrAPI service per request
POST_CHUNK_SIZE=1000

# Request cache records paginating through available records per program by CACHE_BRAPI_FETCH_PAGE_SIZE
CACHE_PAGINATE_GERMPLASM=false
CACHE_BRAPI_FETCH_PAGE_SIZE=65000

# BrAPI Server Variables
BRAPI_SERVER_PORT=8083

Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ services:
networks:
- backend
bidb:
image: postgres:11.4
image: postgres:17.5
container_name: bidb
environment:
- POSTGRES_DB=${DB_NAME}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,26 @@ public HttpResponse<Response<DataResponse<List<BrAPIGermplasm>>>> getGermplasm(
}
}

@Get("/programs/{programId}/germplasm/lists/{listDbId}/export{?fileExtension}")
@Produces(value = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES})
public HttpResponse<StreamedFile> germplasmListExport(
@PathVariable("programId") UUID programId, @PathVariable("listDbId") String listDbId, @QueryValue(defaultValue = "XLSX") String fileExtension) {
String downloadErrorMessage = "An error occurred while generating the download file. Contact the development team at bidevteam@cornell.edu.";
try {
FileType extension = Enum.valueOf(FileType.class, fileExtension);
DownloadFile germplasmListFile = germplasmService.exportGermplasmList(programId, listDbId, extension);
HttpResponse<StreamedFile> germplasmListExport = HttpResponse.ok(germplasmListFile.getStreamedFile()).header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename="+germplasmListFile.getFileName()+extension.getExtension());
return germplasmListExport;
}
catch (Exception e) {
log.info(e.getMessage(), e);
e.printStackTrace();
HttpResponse response = HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR, downloadErrorMessage).contentType(MediaType.TEXT_PLAIN).body(downloadErrorMessage);
return response;
}
}

@Get("/programs/{programId}/germplasm/export{?fileExtension,list}")
@Produces(value = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public class BrAPIGermplasmDAO {
@Property(name = "micronaut.bi.api.run-scheduled-tasks")
private boolean runScheduledTasks;

@Property(name = "brapi.paginate.germplasm")
private boolean paginateGermplasm;

private final ProgramCache<BrAPIGermplasm> programGermplasmCache;

private final BrAPIEndpointProvider brAPIEndpointProvider;
Expand Down Expand Up @@ -141,11 +144,26 @@ private Map<String, BrAPIGermplasm> fetchProgramGermplasm(UUID programId) throws
BrAPIGermplasmSearchRequest germplasmSearch = new BrAPIGermplasmSearchRequest();
germplasmSearch.externalReferenceIDs(List.of(programId.toString()));
germplasmSearch.externalReferenceSources(List.of(Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS)));
return processGermplasmForDisplay(brAPIDAOUtil.search(
api::searchGermplasmPost,
api::searchGermplasmSearchResultsDbIdGet,
germplasmSearch
), program.getKey());

if (paginateGermplasm) {
log.debug("Fetching germplasm with pagination to BrAPI");
return processGermplasmForDisplay(brAPIDAOUtil.search(
api::searchGermplasmPost,
api::searchGermplasmSearchResultsDbIdGet,
germplasmSearch),
program.getKey());
} else {
log.debug("Fetching germplasm without pagination to BrAPI");
return processGermplasmForDisplay(brAPIDAOUtil.searchNoPaging(
api::searchGermplasmPost,
api::searchGermplasmSearchResultsDbIdGet,
germplasmSearch),
program.getKey());
}
}

public void repopulateGermplasmCacheForProgram(UUID programId) {
programGermplasmCache.populate(programId);
}

/**
Expand Down Expand Up @@ -296,11 +314,8 @@ public List<BrAPIGermplasm> createBrAPIGermplasm(List<BrAPIGermplasm> postBrAPIG
var program = programDAO.fetchOneById(programId);
try {
if (!postBrAPIGermplasmList.isEmpty()) {
Callable<Map<String, BrAPIGermplasm>> postFunction = () -> {
List<BrAPIGermplasm> postResponse = brAPIDAOUtil.post(postBrAPIGermplasmList, upload, api::germplasmPost, importDAO::update);
return processGermplasmForDisplay(postResponse, program.getKey());
};
return programGermplasmCache.post(programId, postFunction);
return new ArrayList<>(processGermplasmForDisplay(postResponse, program.getKey()).values());
}
return new ArrayList<>();
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,19 @@ public static String constructGermplasmListName(String listName, Program program
return String.format("%s [%s-germplasm]", listName, program.getKey());
}

public void updateBrAPIGermplasm(BrAPIGermplasm germplasm, Program program, UUID listId, boolean commit, boolean updatePedigree) {
/**
* Will mutate synonym and pedigree fields if changed and meet change criteria
*
* @param germplasm germplasm object
* @param program program
* @param listId list id
* @param commit flag indicating if commit changes should be made
* @param updatePedigree flag indicating if pedigree should be updated
* @return mutated indicator
*/
public boolean updateBrAPIGermplasm(BrAPIGermplasm germplasm, Program program, UUID listId, boolean commit, boolean updatePedigree) {

boolean mutated = false;

if (updatePedigree) {
if (!StringUtils.isBlank(getFemaleParentAccessionNumber())) {
Expand All @@ -170,6 +182,7 @@ public void updateBrAPIGermplasm(BrAPIGermplasm germplasm, Program program, UUID
if (!StringUtils.isBlank(getMaleParentEntryNo())) {
germplasm.putAdditionalInfoItem(BrAPIAdditionalInfoFields.GERMPLASM_MALE_PARENT_ENTRY_NO, getMaleParentEntryNo());
}
mutated = true;
}

// Append synonyms to germplasm that don't already exist
Expand All @@ -181,6 +194,7 @@ public void updateBrAPIGermplasm(BrAPIGermplasm germplasm, Program program, UUID
brapiSynonym.setSynonym(synonym);
if (!existingSynonyms.contains(brapiSynonym)) {
germplasm.addSynonymsItem(brapiSynonym);
mutated = true;
}
}
}
Expand All @@ -193,6 +207,8 @@ public void updateBrAPIGermplasm(BrAPIGermplasm germplasm, Program program, UUID
if (commit) {
setUpdateCommitFields(germplasm, program.getKey());
}

return mutated;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public PendingImportObject<BrAPIObservation> constructPendingObservation() {
original = observation.getValue();
}

if (!isTimestampMatched()) {
if (!isTimestampMatched() && StringUtils.isNotBlank(timestamp)) {
// Update the timestamp
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
String formattedTimeStampValue = formatter.format(observationService.parseDateTime(timestamp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public AppendOverwriteMiddlewareContext process(AppendOverwriteMiddlewareContext
BrAPIObservation observation = gson.fromJson(gson.toJson(observationByObsHash.get(observationHash)), BrAPIObservation.class);

// Is there a change to the prior data?
if (isChanged(cellData, observation, cell.timestamp)) {
if (isChanged(cellData, observation, cell.timestamp, tsColByPheno.containsKey(phenoColumnName))) {

// Is prior data protected?
/**
Expand Down Expand Up @@ -394,14 +394,15 @@ public AppendOverwriteMiddlewareContext process(AppendOverwriteMiddlewareContext
}
}

private boolean isChanged(String cellData, BrAPIObservation observation, String newTimestamp) {
private boolean isChanged(String cellData, BrAPIObservation observation, String newTimestamp, boolean timestampColumnPresent) {
if (!cellData.isBlank() && !cellData.equals(observation.getValue())){
return true;
}
if (StringUtils.isBlank(newTimestamp)) {
return (observation.getObservationTimeStamp()!=null);
// Only check timestamp if the TS:<trait> column was present in the uploaded file and there's a valid timestamp.
if (timestampColumnPresent && !StringUtils.isBlank(newTimestamp)) {
return !observationService.parseDateTime(newTimestamp).equals(observation.getObservationTimeStamp());
}
return !observationService.parseDateTime(newTimestamp).equals(observation.getObservationTimeStamp());
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.breedinginsight.brapps.importer.services.processors.experiment.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.brapi.v2.model.core.BrAPISeason;
Expand All @@ -42,6 +43,7 @@
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Singleton
public class ObservationService {
private final ExperimentUtilities experimentUtilities;
Expand Down Expand Up @@ -115,6 +117,7 @@ public OffsetDateTime parseDateTime(String dateString) {
LocalDate localDate = LocalDate.parse(dateString, formatter);
return localDate.atStartOfDay().atOffset(ZoneOffset.UTC);
} catch (DateTimeParseException ex) {
log.error("Failed to parse timestamp: \"{}\".", dateString);
// If both parsing attempts fail, return null
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public class GermplasmProcessor implements Processor {
List<List<BrAPIGermplasm>> postOrder = new ArrayList<>();
BrAPIListNewRequest importList = new BrAPIListNewRequest();

private int numNewPedigreeConnections = 0;

public static String missingGIDsMsg = "The following GIDs were not found in the database: %s";
public static String missingParentalGIDsMsg = "The following parental GIDs were not found in the database: %s";
public static String missingParentalEntryNoMsg = "The following parental entry numbers were not found in the database: %s";
Expand Down Expand Up @@ -332,7 +334,7 @@ public Map<String, ImportPreviewStatistics> process(ImportUpload upload, List<Br
createPostOrder();

// Construct our response object
return getStatisticsMap(importRows);
return getStatisticsMap();
}

private void processNewGermplasm(Germplasm germplasm, ValidationErrors validationErrors, Map<String, ProgramBreedingMethodEntity> breedingMethods,
Expand All @@ -359,6 +361,10 @@ private void processNewGermplasm(Germplasm germplasm, ValidationErrors validatio

validatePedigree(germplasm, i + 2, validationErrors);

if (germplasm.pedigreeExists()) {
numNewPedigreeConnections++;
}

BrAPIGermplasm newGermplasm = germplasm.constructBrAPIGermplasm(program, breedingMethod, user, commit, BRAPI_REFERENCE_SOURCE, nextVal, importListId);

newGermplasmList.add(newGermplasm);
Expand All @@ -383,6 +389,9 @@ private Germplasm removeBreedingMethodBlanks(Germplasm germplasm) {
private boolean processExistingGermplasm(Germplasm germplasm, ValidationErrors validationErrors, List<BrAPIImport> importRows, Program program, UUID importListId, boolean commit, PendingImport mappedImportRow, int rowIndex) {
BrAPIGermplasm existingGermplasm;
String gid = germplasm.getAccessionNumber();
boolean mutated = false;
boolean updatePedigree = false;

if (germplasmByAccessionNumber.containsKey(gid)) {
existingGermplasm = germplasmByAccessionNumber.get(gid).getBrAPIObject();
// Serialize and deserialize to deep copy
Expand All @@ -408,17 +417,26 @@ private boolean processExistingGermplasm(Germplasm germplasm, ValidationErrors v
}
}

if(germplasm.pedigreeExists()) {
// if no existing pedigree and file has pedigree then validate and update
if(germplasm.pedigreeExists() && !hasPedigree(existingGermplasm)) {
validatePedigree(germplasm, rowIndex + 2, validationErrors);
updatePedigree = true;
}

germplasm.updateBrAPIGermplasm(existingGermplasm, program, importListId, commit, true);

updatedGermplasmList.add(existingGermplasm);
mappedImportRow.setGermplasm(new PendingImportObject<>(ImportObjectState.MUTATED, existingGermplasm));
importList.addDataItem(existingGermplasm.getGermplasmName());
mutated = germplasm.updateBrAPIGermplasm(existingGermplasm, program, importListId, commit, updatePedigree);

if (mutated) {
updatedGermplasmList.add(existingGermplasm);
mappedImportRow.setGermplasm(new PendingImportObject<>(ImportObjectState.MUTATED, existingGermplasm));
if (updatePedigree) {
numNewPedigreeConnections++;
}
} else {
mappedImportRow.setGermplasm(new PendingImportObject<>(ImportObjectState.EXISTING, existingGermplasm));
}

// add to list regardless of mutated or not
importList.addDataItem(existingGermplasm.getGermplasmName());
return true;
}

Expand Down Expand Up @@ -521,20 +539,17 @@ private boolean canUpdatePedigreeNoEqualsCheck(BrAPIGermplasm existingGermplasm,
germplasm.pedigreeExists();
}

private Map<String, ImportPreviewStatistics> getStatisticsMap(List<BrAPIImport> importRows) {
private Map<String, ImportPreviewStatistics> getStatisticsMap() {

ImportPreviewStatistics germplasmStats = ImportPreviewStatistics.builder()
.newObjectCount(newGermplasmList.size())
.ignoredObjectCount(germplasmByAccessionNumber.size())
.build();

//Modified logic here to check for female parent accession number or entry no, removed check for male due to assumption that shouldn't have only male parent
int newObjectCount = newGermplasmList.stream().filter(newGermplasm -> newGermplasm != null).collect(Collectors.toList()).size();
// TODO: numNewPedigreeConnections is global modified in existing and new flows, refactor at some point
ImportPreviewStatistics pedigreeConnectStats = ImportPreviewStatistics.builder()
.newObjectCount(importRows.stream().filter(germplasmImport ->
germplasmImport.getGermplasm() != null &&
(germplasmImport.getGermplasm().getFemaleParentAccessionNumber() != null || germplasmImport.getGermplasm().getFemaleParentEntryNo() != null)
).collect(Collectors.toList()).size()).build();
.newObjectCount(numNewPedigreeConnections)
.build();

return Map.of(
"Germplasm", germplasmStats,
Expand Down Expand Up @@ -631,10 +646,13 @@ public void postBrapiData(Map<Integer, PendingImport> mappedBrAPIImport, Program
}

// Create list
if (!newGermplasmList.isEmpty() || !updatedGermplasmList.isEmpty()) {
// create & update flows both unconditionally add germplasm names to importList so use that for check
if (!importList.getData().isEmpty()) {
try {
// Create germplasm list
brAPIListDAO.createBrAPILists(List.of(importList), program.getId(), upload);
// Now that we have finished uploading, fetch all the data posted to BrAPI to the cache so it is up-to-date.
brAPIGermplasmDAO.repopulateGermplasmCacheForProgram(program.getId());
} catch (ApiException e) {
throw new InternalServerException(e.toString(), e);
}
Expand Down
Loading
Loading