Skip to content
Merged
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
108 changes: 107 additions & 1 deletion src/main/java/org/cbioportal/legacy/service/VirtualStudyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,42 @@

import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.cbioportal.legacy.service.exception.CancerTypeNotFoundException;
import org.cbioportal.legacy.service.exception.DuplicateVirtualStudyException;
import org.cbioportal.legacy.service.exception.StudyNotFoundException;
import org.cbioportal.legacy.service.util.SessionServiceRequestHandler;
import org.cbioportal.legacy.web.parameter.SampleIdentifier;
import org.cbioportal.legacy.web.parameter.VirtualStudy;
import org.cbioportal.legacy.web.parameter.VirtualStudyData;
import org.cbioportal.legacy.web.parameter.VirtualStudySamples;
import org.cbioportal.legacy.web.util.StudyViewFilterApplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class VirtualStudyService {
private static final Logger LOG = LoggerFactory.getLogger(VirtualStudyService.class);

public static final String ALL_USERS = "*";
private final SessionServiceRequestHandler sessionServiceRequestHandler;
private final StudyViewFilterApplier studyViewFilterApplier;
private final CancerTypeService cancerTypeService;
private final StudyService studyService;

public VirtualStudyService(
SessionServiceRequestHandler sessionServiceRequestHandler,
StudyViewFilterApplier studyViewFilterApplier) {
StudyViewFilterApplier studyViewFilterApplier,
CancerTypeService cancerTypeService,
StudyService studyService) {
this.sessionServiceRequestHandler = sessionServiceRequestHandler;
this.studyViewFilterApplier = studyViewFilterApplier;
this.cancerTypeService = cancerTypeService;
this.studyService = studyService;
}

public VirtualStudy getVirtualStudy(String id) {
Expand Down Expand Up @@ -59,6 +74,10 @@ public List<VirtualStudy> getUserVirtualStudies(String user) {
return virtualStudies;
}

public List<VirtualStudy> getPublicVirtualStudies() {
return getUserVirtualStudies(ALL_USERS);
}

/**
* This method populates the `virtualStudyData` object with a new set of sample IDs retrieved as
* the result of executing a query based on virtual study view filters. It first applies the
Expand Down Expand Up @@ -107,4 +126,91 @@ private Map<String, Set<String>> groupSampleIdsByStudyId(
SampleIdentifier::getStudyId,
Collectors.mapping(SampleIdentifier::getSampleId, Collectors.toSet())));
}

/**
* Publishes virtual study optionally updating metadata fields
*
* @param id - id of public virtual study to publish
* @param typeOfCancerId - if specified (not null) update type of cancer of published virtual
* study
* @param pmid - if specified (not null) update PubMed ID of published virtual study
* @param virtualStudyData - if specified (not null) create new virtual study with this data,
* otherwise updates virtual study with the given id
*/
public void publishVirtualStudy(
String id, String typeOfCancerId, String pmid, VirtualStudyData virtualStudyData) {
if (virtualStudyData == null) {
VirtualStudy virtualStudyDataToPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
VirtualStudyData storedVirtualStudyData = virtualStudyDataToPublish.getData();
updateStudyMetadataFieldsIfSpecified(storedVirtualStudyData, typeOfCancerId, pmid);
storedVirtualStudyData.setUsers(Set.of(ALL_USERS));
sessionServiceRequestHandler.updateVirtualStudy(virtualStudyDataToPublish);
} else {
updateStudyMetadataFieldsIfSpecified(virtualStudyData, typeOfCancerId, pmid);
virtualStudyData.setUsers(Set.of(ALL_USERS));
try {
studyService.getStudy(id);
throw new DuplicateVirtualStudyException(
"The study with id="
+ id
+ " already exists. Use a different id for the virtual study.");
} catch (StudyNotFoundException e) {
LOG.debug(
"The study with id={} does not exist, proceeding to create a new virtual study.", id);
}
sessionServiceRequestHandler.createVirtualStudy(id, virtualStudyData);
}
}

/**
* Un-publish virtual study
*
* @param id - id of public virtual study to un-publish
*/
public void unPublishVirtualStudy(String id) {
VirtualStudy virtualStudyToUnPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
if (virtualStudyToUnPublish == null) {
throw new NoSuchElementException(
"The virtual study with id=" + id + " has not been found in the public list.");
}
VirtualStudyData virtualStudyData = virtualStudyToUnPublish.getData();
checkIfVSWasPublished(id, virtualStudyData);
virtualStudyData.setUsers(Set.of(virtualStudyData.getOwner()));
sessionServiceRequestHandler.updateVirtualStudy(virtualStudyToUnPublish);
}

/**
* Drops public virtual study, removing it from the public list
*
* @param id - id of public virtual study to drop
*/
public void dropPublicVirtualStudyById(String id) {
VirtualStudy virtualStudyToUnPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
checkIfVSWasPublished(id, virtualStudyToUnPublish.getData());
sessionServiceRequestHandler.dropVirtualStudy(id);
}

private static void checkIfVSWasPublished(String id, VirtualStudyData virtualStudyData) {
Set<String> users = virtualStudyData.getUsers();
if (users == null || users.isEmpty() || !users.contains(ALL_USERS)) {
throw new NoSuchElementException(
"The virtual study with id=" + id + " has not been found in the public list.");
}
}

private void updateStudyMetadataFieldsIfSpecified(
VirtualStudyData virtualStudyData, String typeOfCancerId, String pmid) {
if (typeOfCancerId != null) {
try {
cancerTypeService.getCancerType(typeOfCancerId);
virtualStudyData.setTypeOfCancerId(typeOfCancerId);
} catch (CancerTypeNotFoundException e) {
LOG.error("No cancer type with id={} were found.", typeOfCancerId);
throw new IllegalArgumentException("The cancer type is not valid: " + typeOfCancerId);
}
}
if (pmid != null) {
virtualStudyData.setPmid(pmid);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import org.cbioportal.legacy.service.CancerTypeService;
import org.cbioportal.legacy.service.StudyService;
import org.cbioportal.legacy.service.VirtualStudyService;
import org.cbioportal.legacy.service.exception.AccessForbiddenException;
import org.cbioportal.legacy.service.exception.CancerTypeNotFoundException;
import org.cbioportal.legacy.service.exception.DuplicateVirtualStudyException;
import org.cbioportal.legacy.service.exception.StudyNotFoundException;
import org.cbioportal.legacy.service.util.SessionServiceRequestHandler;
import org.cbioportal.legacy.web.parameter.VirtualStudy;
import org.cbioportal.legacy.web.parameter.VirtualStudyData;
import org.slf4j.Logger;
Expand All @@ -36,25 +30,15 @@
public class PublicVirtualStudiesController {

private static final Logger LOG = LoggerFactory.getLogger(PublicVirtualStudiesController.class);

public static final String ALL_USERS = "*";

private final String requiredPublisherApiKey;

private final SessionServiceRequestHandler sessionServiceRequestHandler;

private final CancerTypeService cancerTypeService;
private final StudyService studyService;
private final VirtualStudyService virtualStudyService;

public PublicVirtualStudiesController(
@Value("${session.endpoint.publisher-api-key:}") String requiredPublisherApiKey,
SessionServiceRequestHandler sessionServiceRequestHandler,
CancerTypeService cancerTypeService,
StudyService studyService) {
VirtualStudyService virtualStudyService) {
this.requiredPublisherApiKey = requiredPublisherApiKey;
this.sessionServiceRequestHandler = sessionServiceRequestHandler;
this.cancerTypeService = cancerTypeService;
this.studyService = studyService;
this.virtualStudyService = virtualStudyService;
}

@GetMapping
Expand All @@ -63,8 +47,7 @@ public PublicVirtualStudiesController(
description = "OK",
content = @Content(schema = @Schema(implementation = VirtualStudy.class)))
public ResponseEntity<List<VirtualStudy>> getPublicVirtualStudies() {
List<VirtualStudy> virtualStudies =
sessionServiceRequestHandler.getVirtualStudiesAccessibleToUser(ALL_USERS);
List<VirtualStudy> virtualStudies = virtualStudyService.getPublicVirtualStudies();
return new ResponseEntity<>(virtualStudies, HttpStatus.OK);
}

Expand All @@ -80,7 +63,7 @@ public ResponseEntity<Void> publishVirtualStudy(
@RequestParam(required = false) String pmid,
@RequestBody(required = false) VirtualStudyData virtualStudyData) {
ensureProvidedPublisherApiKeyCorrect(providedPublisherApiKey);
publishVirtualStudy(id, typeOfCancerId, pmid, virtualStudyData);
virtualStudyService.publishVirtualStudy(id, typeOfCancerId, pmid, virtualStudyData);
return ResponseEntity.ok().build();
}

Expand All @@ -92,45 +75,17 @@ public ResponseEntity<Void> unPublishVirtualStudy(
@RequestHeader(value = "X-PUBLISHER-API-KEY") String providedPublisherApiKey) {
ensureProvidedPublisherApiKeyCorrect(providedPublisherApiKey);
if (softDelete) {
unPublishVirtualStudy(id);
virtualStudyService.unPublishVirtualStudy(id);
} else {
dropPublicVirtualStudyById(id);
virtualStudyService.dropPublicVirtualStudyById(id);
}
return ResponseEntity.ok().build();
}

/**
* Publishes virtual study optionally updating metadata fields
*
* @param id - id of public virtual study to publish
* @param typeOfCancerId - if specified (not null) update type of cancer of published virtual
* study
* @param pmid - if specified (not null) update PubMed ID of published virtual study
* @param virtualStudyData - if specified (not null) create new virtual study with this data,
* otherwise updates virtual study with the given id
*/
private void publishVirtualStudy(
String id, String typeOfCancerId, String pmid, VirtualStudyData virtualStudyData) {
if (virtualStudyData == null) {
VirtualStudy virtualStudyDataToPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
VirtualStudyData storedVirtualStudyData = virtualStudyDataToPublish.getData();
updateStudyMetadataFieldsIfSpecified(storedVirtualStudyData, typeOfCancerId, pmid);
storedVirtualStudyData.setUsers(Set.of(ALL_USERS));
sessionServiceRequestHandler.updateVirtualStudy(virtualStudyDataToPublish);
} else {
updateStudyMetadataFieldsIfSpecified(virtualStudyData, typeOfCancerId, pmid);
virtualStudyData.setUsers(Set.of(ALL_USERS));
try {
studyService.getStudy(id);
throw new DuplicateVirtualStudyException(
"The study with id="
+ id
+ " already exists. Use a different id for the virtual study.");
} catch (StudyNotFoundException e) {
LOG.debug(
"The study with id={} does not exist, proceeding to create a new virtual study.", id);
}
sessionServiceRequestHandler.createVirtualStudy(id, virtualStudyData);
private void ensureProvidedPublisherApiKeyCorrect(String providedPublisherApiKey) {
if (requiredPublisherApiKey.isBlank()
|| !requiredPublisherApiKey.equals(providedPublisherApiKey)) {
throw new AccessForbiddenException("The provided publisher API key is not correct.");
}
}

Expand All @@ -140,63 +95,4 @@ public ResponseEntity<String> handleDuplicateVirtualStudyException(
LOG.error("Duplicate virtual study error: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.CONFLICT).body(e.getMessage());
}

/**
* Un-publish virtual study
*
* @param id - id of public virtual study to un-publish
*/
private void unPublishVirtualStudy(String id) {
VirtualStudy virtualStudyToUnPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
if (virtualStudyToUnPublish == null) {
throw new NoSuchElementException(
"The virtual study with id=" + id + " has not been found in the public list.");
}
VirtualStudyData virtualStudyData = virtualStudyToUnPublish.getData();
checkIfVSWasPublished(id, virtualStudyData);
virtualStudyData.setUsers(Set.of(virtualStudyData.getOwner()));
sessionServiceRequestHandler.updateVirtualStudy(virtualStudyToUnPublish);
}

/**
* Drops public virtual study, removing it from the public list
*
* @param id - id of public virtual study to drop
*/
private void dropPublicVirtualStudyById(String id) {
VirtualStudy virtualStudyToUnPublish = sessionServiceRequestHandler.getVirtualStudyById(id);
checkIfVSWasPublished(id, virtualStudyToUnPublish.getData());
sessionServiceRequestHandler.dropVirtualStudy(id);
}

private static void checkIfVSWasPublished(String id, VirtualStudyData virtualStudyData) {
Set<String> users = virtualStudyData.getUsers();
if (users == null || users.isEmpty() || !users.contains(ALL_USERS)) {
throw new NoSuchElementException(
"The virtual study with id=" + id + " has not been found in the public list.");
}
}

private void ensureProvidedPublisherApiKeyCorrect(String providedPublisherApiKey) {
if (requiredPublisherApiKey.isBlank()
|| !requiredPublisherApiKey.equals(providedPublisherApiKey)) {
throw new AccessForbiddenException("The provided publisher API key is not correct.");
}
}

private void updateStudyMetadataFieldsIfSpecified(
VirtualStudyData virtualStudyData, String typeOfCancerId, String pmid) {
if (typeOfCancerId != null) {
try {
cancerTypeService.getCancerType(typeOfCancerId);
virtualStudyData.setTypeOfCancerId(typeOfCancerId);
} catch (CancerTypeNotFoundException e) {
LOG.error("No cancer type with id={} were found.", typeOfCancerId);
throw new IllegalArgumentException("The cancer type is not valid: " + typeOfCancerId);
}
}
if (pmid != null) {
virtualStudyData.setPmid(pmid);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.cbioportal.legacy.web;

import static org.cbioportal.legacy.web.PublicVirtualStudiesController.ALL_USERS;
import static org.cbioportal.legacy.service.VirtualStudyService.ALL_USERS;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand Down
Loading