From 0a32002e8a4163fde14d69245d9dddaf74b4be1b Mon Sep 17 00:00:00 2001 From: Karthik Date: Fri, 27 Sep 2024 10:35:53 -0400 Subject: [PATCH 1/2] Resolve censored event bug and add caching --- .../impl/ClinicalEventServiceImpl.java | 15 +++++------- .../web/ClinicalEventController.java | 23 +++++++++++-------- .../cbioportal/web/SurvivalController.java | 22 ++++++++++++------ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/cbioportal/service/impl/ClinicalEventServiceImpl.java b/src/main/java/org/cbioportal/service/impl/ClinicalEventServiceImpl.java index 6d70c1647f6..187bec33ef1 100644 --- a/src/main/java/org/cbioportal/service/impl/ClinicalEventServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/ClinicalEventServiceImpl.java @@ -150,12 +150,13 @@ public List getSurvivalData(List studyIds, ).toList(); List patientCensoredEvents = filterClinicalEvents(patientStartEvents, survivalRequest.getCensoredEventRequestIdentifier()); + Map patientCensoredEventsById = patientCensoredEvents.stream().collect(Collectors.toMap(ClinicalEventServiceImpl::getKey, Function.identity())); return patientStartEvents.stream() .flatMap(event -> { - ClinicalData clinicalDataMonths = buildClinicalSurvivalMonths(attributeIdPrefix, event, survivalRequest, patientEndEvents, patientCensoredEvents); + ClinicalData clinicalDataMonths = buildClinicalSurvivalMonths(attributeIdPrefix, event, survivalRequest, patientEndEventsById, patientCensoredEventsById); if (clinicalDataMonths == null) return Stream.empty(); - ClinicalData clinicalDataStatus = buildClinicalSurvivalStatus(attributeIdPrefix, event, patientEndEvents); + ClinicalData clinicalDataStatus = buildClinicalSurvivalStatus(attributeIdPrefix, event, patientEndEventsById); return Stream.of(clinicalDataMonths, clinicalDataStatus); }).toList(); @@ -200,22 +201,19 @@ private List filterClinicalEvents(List patientEven // only fetch end timeline events for patients that have endClinicalEventsMeta and start timeline events List queriedPatientEvents = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(clinicalEventsMeta) && CollectionUtils.isNotEmpty(filteredStudyIds)) { + if (CollectionUtils.isNotEmpty(filteredStudyIds)) { queriedPatientEvents = clinicalEventRepository.getTimelineEvents(filteredStudyIds, filteredPatientIds, clinicalEventsMeta); } return queriedPatientEvents; } - private ClinicalData buildClinicalSurvivalMonths(String attributeIdPrefix, ClinicalEvent event, SurvivalRequest survivalRequest, List patientEndEvents, List patientCensoredEvents) { + private ClinicalData buildClinicalSurvivalMonths(String attributeIdPrefix, ClinicalEvent event, SurvivalRequest survivalRequest, Map patientEndEventsById, Map patientCensoredEventsById) { final String SURVIVAL_MONTH_ATTRIBUTE = attributeIdPrefix + "_MONTHS"; ClinicalData clinicalDataMonths = new ClinicalData(); clinicalDataMonths.setStudyId(event.getStudyId()); clinicalDataMonths.setPatientId(event.getPatientId()); clinicalDataMonths.setAttrId(SURVIVAL_MONTH_ATTRIBUTE); - Map patientEndEventsById = patientEndEvents.stream().collect(Collectors.toMap(ClinicalEventServiceImpl::getKey, Function.identity())); - Map patientCensoredEventsById = patientCensoredEvents.stream().collect(Collectors.toMap(ClinicalEventServiceImpl::getKey, Function.identity())); - ToIntFunction startPositionIdentifier = getPositionIdentifier(survivalRequest.getStartEventRequestIdentifier().getPosition()); ToIntFunction endPositionIdentifier = survivalRequest.getEndEventRequestIdentifier() == null ? ClinicalEvent::getStopDate : getPositionIdentifier(survivalRequest.getEndEventRequestIdentifier().getPosition()); ToIntFunction censoredPositionIdentifier = survivalRequest.getCensoredEventRequestIdentifier() == null ? ClinicalEvent::getStopDate : getPositionIdentifier(survivalRequest.getCensoredEventRequestIdentifier().getPosition()); @@ -241,8 +239,7 @@ private ClinicalData buildClinicalSurvivalMonths(String attributeIdPrefix, Clini return clinicalDataMonths; } - private ClinicalData buildClinicalSurvivalStatus(String attributeIdPrefix, ClinicalEvent event, List patientEndEvents) { - Map patientEndEventsById = patientEndEvents.stream().collect(Collectors.toMap(ClinicalEventServiceImpl::getKey, Function.identity())); + private ClinicalData buildClinicalSurvivalStatus(String attributeIdPrefix, ClinicalEvent event, Map patientEndEventsById) { ClinicalData clinicalDataStatus = new ClinicalData(); clinicalDataStatus.setStudyId(event.getStudyId()); diff --git a/src/main/java/org/cbioportal/web/ClinicalEventController.java b/src/main/java/org/cbioportal/web/ClinicalEventController.java index cb8efec5e75..f8d98ceacd6 100644 --- a/src/main/java/org/cbioportal/web/ClinicalEventController.java +++ b/src/main/java/org/cbioportal/web/ClinicalEventController.java @@ -16,14 +16,10 @@ import org.cbioportal.service.exception.StudyNotFoundException; import org.cbioportal.web.config.InternalApiTags; import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.ClinicalEventAttributeRequest; -import org.cbioportal.web.parameter.Direction; -import org.cbioportal.web.parameter.HeaderKeyConstants; -import org.cbioportal.web.parameter.PagingConstants; -import org.cbioportal.web.parameter.PatientIdentifier; -import org.cbioportal.web.parameter.Projection; +import org.cbioportal.web.parameter.*; import org.cbioportal.web.parameter.sort.ClinicalEventSortBy; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -144,6 +140,15 @@ public ResponseEntity> fetchClinicalEventsMeta( @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. This attribute is needed for the @PreAuthorize tag above. @Valid @RequestAttribute(required = false, value = "interceptedClinicalEventAttributeRequest") ClinicalEventAttributeRequest interceptedClinicalEventAttributeRequest) { + return new ResponseEntity<>(cachedClinicalEventsMeta(interceptedClinicalEventAttributeRequest), HttpStatus.OK); + + } + + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabled()" + ) + public List cachedClinicalEventsMeta(ClinicalEventAttributeRequest interceptedClinicalEventAttributeRequest) { List studyIds = new ArrayList<>(); List patientIds = new ArrayList<>(); for (PatientIdentifier patientIdentifier : interceptedClinicalEventAttributeRequest.getPatientIdentifiers()) { @@ -160,9 +165,7 @@ public ResponseEntity> fetchClinicalEventsMeta( return clinicalEvent; }) .toList(); - - return new ResponseEntity<>(clinicalEventService.getClinicalEventsMeta( - studyIds, patientIds, clinicalEventsRequest), HttpStatus.OK); - + return clinicalEventService.getClinicalEventsMeta( + studyIds, patientIds, clinicalEventsRequest); } } diff --git a/src/main/java/org/cbioportal/web/SurvivalController.java b/src/main/java/org/cbioportal/web/SurvivalController.java index 202b344406c..7cb6ea89420 100644 --- a/src/main/java/org/cbioportal/web/SurvivalController.java +++ b/src/main/java/org/cbioportal/web/SurvivalController.java @@ -14,6 +14,7 @@ import org.cbioportal.web.parameter.PatientIdentifier; import org.cbioportal.web.parameter.SurvivalRequest; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -36,7 +37,7 @@ @Tag(name = "Survival", description = " ") public class SurvivalController { private final ClinicalEventService clinicalEventService; - + @Autowired public SurvivalController(ClinicalEventService clinicalEventService) { this.clinicalEventService = clinicalEventService; @@ -59,6 +60,15 @@ public ResponseEntity> fetchSurvivalData( // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. @Valid @RequestAttribute(required = false, value = "interceptedSurvivalRequest") SurvivalRequest interceptedSurvivalRequest) { + return new ResponseEntity<>(cachedSurvivalData(interceptedSurvivalRequest), + HttpStatus.OK); + } + + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabled()" + ) + public List cachedSurvivalData(SurvivalRequest interceptedSurvivalRequest) { List studyIds = new ArrayList<>(); List patientIds = new ArrayList<>(); for (PatientIdentifier patientIdentifier : interceptedSurvivalRequest.getPatientIdentifiers()) { @@ -66,11 +76,9 @@ public ResponseEntity> fetchSurvivalData( patientIds.add(patientIdentifier.getPatientId()); } - List result = clinicalEventService.getSurvivalData(studyIds, - patientIds, - interceptedSurvivalRequest.getAttributeIdPrefix(), - interceptedSurvivalRequest); - - return new ResponseEntity<>(result, HttpStatus.OK); + return clinicalEventService.getSurvivalData(studyIds, + patientIds, + interceptedSurvivalRequest.getAttributeIdPrefix(), + interceptedSurvivalRequest); } } From fef066a0b44aae3a192bb3a612c882a1437f03d0 Mon Sep 17 00:00:00 2001 From: Karthik Date: Fri, 27 Sep 2024 15:05:36 -0400 Subject: [PATCH 2/2] Update cache resolver --- src/main/java/org/cbioportal/web/ClinicalEventController.java | 2 +- src/main/java/org/cbioportal/web/SurvivalController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cbioportal/web/ClinicalEventController.java b/src/main/java/org/cbioportal/web/ClinicalEventController.java index f8d98ceacd6..487adbd479d 100644 --- a/src/main/java/org/cbioportal/web/ClinicalEventController.java +++ b/src/main/java/org/cbioportal/web/ClinicalEventController.java @@ -145,7 +145,7 @@ public ResponseEntity> fetchClinicalEventsMeta( } @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", + cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()" ) public List cachedClinicalEventsMeta(ClinicalEventAttributeRequest interceptedClinicalEventAttributeRequest) { diff --git a/src/main/java/org/cbioportal/web/SurvivalController.java b/src/main/java/org/cbioportal/web/SurvivalController.java index 7cb6ea89420..06e5e68b74d 100644 --- a/src/main/java/org/cbioportal/web/SurvivalController.java +++ b/src/main/java/org/cbioportal/web/SurvivalController.java @@ -65,7 +65,7 @@ public ResponseEntity> fetchSurvivalData( } @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", + cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()" ) public List cachedSurvivalData(SurvivalRequest interceptedSurvivalRequest) {