|
6 | 6 |
|
7 | 7 | import java.io.IOException;
|
8 | 8 | import java.io.InputStream;
|
| 9 | +import java.net.URI; |
9 | 10 | import java.nio.ByteBuffer;
|
10 | 11 | import java.util.ArrayList;
|
11 | 12 | import java.util.HashSet;
|
| 13 | +import java.util.Collection; |
12 | 14 | import java.util.List;
|
13 | 15 | import java.util.Objects;
|
| 16 | +import java.util.Set; |
14 | 17 | import java.util.concurrent.Callable;
|
15 | 18 | import java.util.function.Function;
|
16 | 19 | import java.util.function.UnaryOperator;
|
| 20 | +import java.util.stream.Collectors; |
17 | 21 | import life.qbic.application.commons.SortOrder;
|
18 | 22 | import life.qbic.logging.api.Logger;
|
19 | 23 | import life.qbic.logging.service.LoggerFactory;
|
|
27 | 31 | import life.qbic.projectmanagement.application.api.template.TemplateService;
|
28 | 32 | import life.qbic.projectmanagement.application.authorization.ReactiveSecurityContextUtils;
|
29 | 33 | import life.qbic.projectmanagement.application.experiment.ExperimentInformationService;
|
| 34 | +import life.qbic.projectmanagement.application.experiment.ExperimentInformationService; |
30 | 35 | import life.qbic.projectmanagement.application.experiment.ExperimentInformationService.ExperimentalVariableAddition;
|
31 | 36 | import life.qbic.projectmanagement.application.measurement.validation.MeasurementValidationService;
|
32 | 37 | import life.qbic.projectmanagement.application.sample.SampleInformationService;
|
@@ -99,6 +104,17 @@ private static Retry defaultRetryStrategy() {
|
99 | 104 | .doBeforeRetry(retrySignal -> log.warn("Operation failed (" + retrySignal + ")"));
|
100 | 105 | }
|
101 | 106 |
|
| 107 | + private static Set<OntologyTerm> convertToApi( |
| 108 | + Collection<life.qbic.projectmanagement.domain.model.OntologyTerm> terms) { |
| 109 | + return terms.stream().map(AsyncProjectServiceImpl::convertToApi).collect(Collectors.toSet()); |
| 110 | + } |
| 111 | + |
| 112 | + private static OntologyTerm convertToApi( |
| 113 | + life.qbic.projectmanagement.domain.model.OntologyTerm term) { |
| 114 | + return new OntologyTerm(term.getLabel(), Curie.parse(term.oboId().toString()), |
| 115 | + URI.create(term.getOntologyIri())); |
| 116 | + } |
| 117 | + |
102 | 118 | @Override
|
103 | 119 | public Mono<ProjectUpdateResponse> update(@NonNull ProjectUpdateRequest request)
|
104 | 120 | throws UnknownRequestException, RequestFailedException, AccessDeniedException {
|
@@ -168,7 +184,20 @@ public Flux<ByteBuffer> roCrateSummary(String projectId) {
|
168 | 184 |
|
169 | 185 | @Override
|
170 | 186 | public Flux<ExperimentDescription> getExperiments(String projectId) {
|
171 |
| - throw new RuntimeException("Not yet implemented"); |
| 187 | + var securityContext = SecurityContextHolder.getContext(); |
| 188 | + return applySecurityContextMany(Flux.fromIterable( |
| 189 | + () -> experimentInformationService.findAllForProject(ProjectId.parse(projectId)).iterator()) |
| 190 | + .map(e -> e.experimentId()) |
| 191 | + .flatMap(id -> { |
| 192 | + var analytes = experimentInformationService.getAnalytesOfExperiment(id); |
| 193 | + var specimen = experimentInformationService.getSpecimensOfExperiment(id); |
| 194 | + var species = experimentInformationService.getSpeciesOfExperiment(id); |
| 195 | + var experimentName = experimentInformationService.find(projectId, id) |
| 196 | + .map(Experiment::getName).orElse("not available"); |
| 197 | + return Mono.just(new ExperimentDescription(experimentName, convertToApi(species), |
| 198 | + convertToApi(specimen), convertToApi(analytes))); |
| 199 | + })).subscribeOn(VirtualThreadScheduler.getScheduler()) |
| 200 | + .contextWrite(reactiveSecurity(securityContext)); |
172 | 201 | }
|
173 | 202 |
|
174 | 203 | // Requires the SecurityContext to work
|
@@ -315,7 +344,8 @@ public Mono<DigitalObject> sampleRegistrationTemplate(String projectId, String e
|
315 | 344 | }
|
316 | 345 |
|
317 | 346 | @Override
|
318 |
| - public Mono<DigitalObject> sampleUpdateTemplate(String projectId, String experimentId, String batchId, |
| 347 | + public Mono<DigitalObject> sampleUpdateTemplate(String projectId, String experimentId, |
| 348 | + String batchId, |
319 | 349 | MimeType mimeType) {
|
320 | 350 | SecurityContext securityContext = SecurityContextHolder.getContext();
|
321 | 351 | return applySecurityContext(Mono.fromCallable(
|
@@ -542,7 +572,8 @@ private Mono<ProjectDeletionResponse> delete(String projectId, String requestId,
|
542 | 572 | return Mono.error(new AccessDeniedException(ACCESS_DENIED));
|
543 | 573 | } catch (Exception e) {
|
544 | 574 | log.error("Unexpected exception deleting funding information", e);
|
545 |
| - return Mono.error(new RequestFailedException("Unexpected exception deleting funding information")); |
| 575 | + return Mono.error( |
| 576 | + new RequestFailedException("Unexpected exception deleting funding information")); |
546 | 577 | }
|
547 | 578 | });
|
548 | 579 | }
|
@@ -605,20 +636,20 @@ private Mono<ExperimentUpdateResponse> addExperimentalVariables(
|
605 | 636 | private Mono<ProjectUpdateResponse> update(ProjectId projectId, String requestId,
|
606 | 637 | ProjectDesign design) {
|
607 | 638 | return
|
608 |
| - Mono.<ProjectUpdateResponse>create(sink -> { |
609 |
| - try { |
610 |
| - projectService.updateTitle(projectId, design.title()); |
611 |
| - projectService.updateObjective(projectId, design.objective()); |
612 |
| - sink.success(new ProjectUpdateResponse(projectId.value(), design, requestId)); |
613 |
| - } catch (IllegalArgumentException e) { |
614 |
| - sink.error(new RequestFailedException("Invalid project id: " + projectId)); |
615 |
| - } catch (org.springframework.security.access.AccessDeniedException e) { |
616 |
| - sink.error(new AccessDeniedException(ACCESS_DENIED)); |
617 |
| - } catch (RuntimeException e) { |
618 |
| - sink.error(new RequestFailedException("Update project design failed", e)); |
619 |
| - } |
620 |
| - } |
621 |
| - ); |
| 639 | + Mono.<ProjectUpdateResponse>create(sink -> { |
| 640 | + try { |
| 641 | + projectService.updateTitle(projectId, design.title()); |
| 642 | + projectService.updateObjective(projectId, design.objective()); |
| 643 | + sink.success(new ProjectUpdateResponse(projectId.value(), design, requestId)); |
| 644 | + } catch (IllegalArgumentException e) { |
| 645 | + sink.error(new RequestFailedException("Invalid project id: " + projectId)); |
| 646 | + } catch (org.springframework.security.access.AccessDeniedException e) { |
| 647 | + sink.error(new AccessDeniedException(ACCESS_DENIED)); |
| 648 | + } catch (RuntimeException e) { |
| 649 | + sink.error(new RequestFailedException("Update project design failed", e)); |
| 650 | + } |
| 651 | + } |
| 652 | + ); |
622 | 653 | }
|
623 | 654 |
|
624 | 655 | }
|
0 commit comments