Skip to content

Commit

Permalink
Fix issues while testing the code
Browse files Browse the repository at this point in the history
  • Loading branch information
forus committed Jan 17, 2025
1 parent e186354 commit 31c3842
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;

import java.util.concurrent.Executor;

@Configuration
@ConditionalOnProperty(name = "vs_mode", havingValue = "true")
Expand All @@ -19,9 +23,20 @@ public class VSAwareServicesConfiguration {
@Autowired
private ReadPermissionService readPermissionService;

@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("AsyncThread-");
executor.initialize();
return new DelegatingSecurityContextExecutor(executor);
}

@Primary
@Bean
public StudyService studyService(StudyService studyService) {
return new VSAwareStudyServiceImpl(studyService, sessionServiceRequestHandler, readPermissionService);
public StudyService studyService(StudyService studyService, Executor asyncExecutor) {
return new VSAwareStudyServiceImpl(studyService, sessionServiceRequestHandler, readPermissionService, asyncExecutor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import org.cbioportal.utils.security.AccessLevel;
import org.cbioportal.web.parameter.VirtualStudy;
import org.cbioportal.web.parameter.VirtualStudyData;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.stream.Stream;

Expand All @@ -26,18 +28,19 @@ public class VSAwareStudyServiceImpl implements StudyService {
private final SessionServiceRequestHandler sessionServiceRequestHandler;

private final ReadPermissionService readPermissionService;
private final Executor asyncExecutor;

public VSAwareStudyServiceImpl(StudyService studyService, SessionServiceRequestHandler sessionServiceRequestHandler, ReadPermissionService readPermissionService) {
public VSAwareStudyServiceImpl(StudyService studyService, SessionServiceRequestHandler sessionServiceRequestHandler, ReadPermissionService readPermissionService, Executor asyncExecutor) {
this.studyService = studyService;
this.sessionServiceRequestHandler = sessionServiceRequestHandler;
this.readPermissionService = readPermissionService;
this.asyncExecutor = asyncExecutor;
}

@Override
public List<CancerStudy> getAllStudies(String keyword, String projection, Integer pageSize, Integer pageNumber, String sortBy, String direction, Authentication authentication, AccessLevel accessLevel) {
CompletableFuture<List<CancerStudy>> materialisedStudies = CompletableFuture.supplyAsync(() -> studyService.getAllStudies(keyword, projection, null, null, null, null, authentication, accessLevel));
CompletableFuture<List<CancerStudy>> virtualStudies = CompletableFuture.supplyAsync(() -> sessionServiceRequestHandler.getVirtualStudiesAccessibleToUser("*").stream()
.map(VSAwareStudyServiceImpl::toCancerStudy).filter(cs -> shouldSelect(cs, keyword)).toList());
CompletableFuture<List<CancerStudy>> materialisedStudies = getMaterialisedStudiesAsync(keyword, projection, authentication, accessLevel);
CompletableFuture<List<CancerStudy>> virtualStudies = getVirtualStudiesAsync(keyword);

Stream<CancerStudy> resultStream = Stream.concat(
materialisedStudies.join().stream(),
Expand All @@ -49,14 +52,25 @@ public List<CancerStudy> getAllStudies(String keyword, String projection, Intege
}

if (pageSize != null && pageNumber != null) {
resultStream = resultStream.skip((long) pageSize * (pageNumber - 1)).limit(pageSize);
resultStream = resultStream.skip((long) pageSize * pageNumber).limit(pageSize);
}

List<CancerStudy> result = resultStream.toList();
readPermissionService.setReadPermission(result, authentication);
return result;
}

@Async
private CompletableFuture<List<CancerStudy>> getVirtualStudiesAsync(String keyword) {
return CompletableFuture.supplyAsync(() -> sessionServiceRequestHandler.getVirtualStudiesAccessibleToUser("*").stream()
.map(VSAwareStudyServiceImpl::toCancerStudy).filter(cs -> shouldSelect(cs, keyword)).toList(), asyncExecutor);
}

@Async
private CompletableFuture<List<CancerStudy>> getMaterialisedStudiesAsync(String keyword, String projection, Authentication authentication, AccessLevel accessLevel) {
return CompletableFuture.supplyAsync(() -> studyService.getAllStudies(keyword, projection, null, null, null, null, authentication, accessLevel), asyncExecutor);
}

private static CancerStudy toCancerStudy(VirtualStudy vs) {
VirtualStudyData vsd = vs.getData();
CancerStudy cs = new CancerStudy();
Expand Down Expand Up @@ -98,15 +112,25 @@ public BaseMeta getMetaStudies(String keyword) {

@Override
public CancerStudy getStudy(String studyId) throws StudyNotFoundException {
CompletableFuture<Optional<CancerStudy>> materialisedStudy = CompletableFuture.supplyAsync(() -> {
CompletableFuture<Optional<CancerStudy>> materialisedStudy = getMaterialisedStudyAsync(studyId);
CompletableFuture<Optional<CancerStudy>> virtualStudy = getVirtualStudyAsync(studyId);
return firstPresent(materialisedStudy, virtualStudy).join().orElseThrow(() -> new StudyNotFoundException(studyId));
}

@Async
private CompletableFuture<Optional<CancerStudy>> getVirtualStudyAsync(String studyId) {
return CompletableFuture.supplyAsync(() -> Optional.ofNullable(sessionServiceRequestHandler.getVirtualStudyById(studyId)).map(VSAwareStudyServiceImpl::toCancerStudy), asyncExecutor);
}

@Async
private CompletableFuture<Optional<CancerStudy>> getMaterialisedStudyAsync(String studyId) {
return CompletableFuture.supplyAsync(() -> {
try {
return Optional.of(studyService.getStudy(studyId));
} catch (StudyNotFoundException e) {
return Optional.empty();
}
});
CompletableFuture<Optional<CancerStudy>> virtualStudy = CompletableFuture.supplyAsync(() -> Optional.ofNullable(sessionServiceRequestHandler.getVirtualStudyById(studyId)).map(VSAwareStudyServiceImpl::toCancerStudy));
return firstPresent(materialisedStudy, virtualStudy).join().orElseThrow(() -> new StudyNotFoundException(studyId));
}, asyncExecutor);
}

private static <T> CompletableFuture<Optional<T>> firstPresent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public PublicVirtualStudiesController(
@Value("${session.endpoint.publisher-api-key:}") String requiredPublisherApiKey,
SessionServiceRequestHandler sessionServiceRequestHandler,
CancerTypeService cancerTypeService,
@Value("vs_mode") Boolean vsMode
@Value("${vs_mode:false}") Boolean vsMode
) {
this.requiredPublisherApiKey = requiredPublisherApiKey;
this.sessionServiceRequestHandler = sessionServiceRequestHandler;
Expand Down

0 comments on commit 31c3842

Please sign in to comment.