Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import spock.lang.Specification
*
* @since 1.0.0
*/
class OntologyTermRepositorySpec extends Specification{
class OntologyTermV1RepositorySpec extends Specification {

def "Given a one-word search, the correct ontology searchterm is created"() {
given:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package life.qbic.projectmanagement.application;
package life.qbic.application.commons;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import life.qbic.domain.concepts.DomainEventDispatcher;
import life.qbic.domain.concepts.LocalDomainEventDispatcher;
import life.qbic.projectmanagement.application.experiment.ExperimentInformationService.ExperimentCreatedDomainEventSubscriber;
import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;
import life.qbic.projectmanagement.domain.model.experiment.Experiment;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
import life.qbic.projectmanagement.domain.model.project.Project;
Expand Down Expand Up @@ -54,11 +54,9 @@ public AddExperimentToProjectService(
@PreAuthorize("hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE')")
public Result<ExperimentId, RuntimeException> addExperimentToProject(ProjectId projectId,
String experimentName,
List<OntologyTerm> species,
List<OntologyTerm> specimens,
List<OntologyTerm> analytes,
String speciesIconLabel,
String specimenIconLabel) {
List<OntologyTermV1> species,
List<OntologyTermV1> specimens,
List<OntologyTermV1> analytes) {
requireNonNull(projectId, "project id must not be null during experiment creation");
if (experimentName.isBlank()) {
experimentName = "Unnamed Experiment";
Expand Down Expand Up @@ -91,7 +89,6 @@ public Result<ExperimentId, RuntimeException> addExperimentToProject(ProjectId p
.onValue(exp -> exp.addAnalytes(analytes))
.onValue(exp -> exp.addSpecies(species))
.onValue(exp -> exp.addSpecimens(specimens))
.onValue(exp -> exp.setIconNames(speciesIconLabel, specimenIconLabel, "default"))
.onValue(experiment -> {
project.addExperiment(experiment);
projectRepository.update(project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import life.qbic.application.commons.SortOrder;
import life.qbic.application.commons.VirtualThreadScheduler;
import life.qbic.logging.api.Logger;
import life.qbic.logging.service.LoggerFactory;
import life.qbic.projectmanagement.application.AddExperimentToProjectService;
import life.qbic.projectmanagement.application.ProjectInformationService;
import life.qbic.projectmanagement.application.ValidationResult;
import life.qbic.projectmanagement.application.VirtualThreadScheduler;
import life.qbic.projectmanagement.application.api.fair.ContactPoint;
import life.qbic.projectmanagement.application.api.fair.DigitalObject;
import life.qbic.projectmanagement.application.api.fair.DigitalObjectFactory;
Expand All @@ -37,6 +38,7 @@
import life.qbic.projectmanagement.application.sample.SampleInformationService;
import life.qbic.projectmanagement.application.sample.SamplePreview;
import life.qbic.projectmanagement.application.sample.SampleValidationService;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;
import life.qbic.projectmanagement.domain.model.experiment.Experiment;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
import life.qbic.projectmanagement.domain.model.project.Contact;
Expand All @@ -47,7 +49,6 @@
import life.qbic.projectmanagement.domain.repository.ProjectRepository.ProjectNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -82,6 +83,7 @@ public class AsyncProjectServiceImpl implements AsyncProjectService {
private final ExperimentInformationService experimentInformationService;
private final TerminologyService terminologyService;
private final SpeciesLookupService taxaService;
private final AddExperimentToProjectService addExperimentToProjectService;

public AsyncProjectServiceImpl(
@Autowired ProjectInformationService projectService,
Expand All @@ -93,7 +95,8 @@ public AsyncProjectServiceImpl(
@Autowired MeasurementValidationService measurementValidationService,
@Autowired ExperimentInformationService experimentInformationService,
@Autowired TerminologyService termService,
@Autowired SpeciesLookupService taxaService) {
@Autowired SpeciesLookupService taxaService,
AddExperimentToProjectService addExperimentToProjectService) {
this.projectService = Objects.requireNonNull(projectService);
this.sampleInfoService = Objects.requireNonNull(sampleInfoService);
this.scheduler = Objects.requireNonNull(scheduler);
Expand All @@ -104,6 +107,7 @@ public AsyncProjectServiceImpl(
this.experimentInformationService = Objects.requireNonNull(experimentInformationService);
this.terminologyService = Objects.requireNonNull(termService);
this.taxaService = Objects.requireNonNull(taxaService);
this.addExperimentToProjectService = Objects.requireNonNull(addExperimentToProjectService);
}

private static Retry defaultRetryStrategy() {
Expand All @@ -112,12 +116,12 @@ private static Retry defaultRetryStrategy() {
}

private static Set<OntologyTerm> convertToApi(
Collection<life.qbic.projectmanagement.domain.model.OntologyTerm> terms) {
Collection<OntologyTermV1> terms) {
return terms.stream().map(AsyncProjectServiceImpl::convertToApi).collect(Collectors.toSet());
}

private static OntologyTerm convertToApi(
life.qbic.projectmanagement.domain.model.OntologyTerm term) {
OntologyTermV1 term) {
return new OntologyTerm(term.getLabel(), term.getDescription(),
Curie.parse(term.oboId().toString()),
URI.create(term.getClassIri()), term.getOntologyAbbreviation());
Expand All @@ -131,12 +135,37 @@ private static OntologyTerm convertToApi(OntologyClass term) {

@Override
public Mono<ExperimentCreationResponse> create(ExperimentCreationRequest request) {
throw new RuntimeException("Not implemented");
var securityContext = SecurityContextHolder.getContext();
var call = Mono.fromSupplier(() -> {
Objects.requireNonNull(request.experimentDescription());
var species = request.experimentDescription().species().stream().map(
it -> new OntologyTermV1(it.label(), null, null,
null, null, null, null)).toList(); //todo replace with v2
var specimen = request.experimentDescription().specimen().stream().map(
it -> new OntologyTermV1(it.label(), null, null,
null, null, null, null)).toList(); //todo replace with v2
var analytes = request.experimentDescription().analytes().stream().map(
it -> new OntologyTermV1(it.label(), null, null,
null, null, null, null)).toList(); //todo replace with v2
ProjectId parse = ProjectId.parse(request.projectId());
String experimentName = request.experimentDescription().experimentName();

ExperimentId res = addExperimentToProjectService.addExperimentToProject(parse, experimentName,
species, specimen, analytes)
.valueOrElseThrow(e -> new RuntimeException(e));
return new ExperimentCreationResponse(request.projectId(), res.value(),
request.experimentDescription(), request.requestId());
});
return applySecurityContext(call)
.contextWrite(reactiveSecurity(securityContext))
.subscribeOn(VirtualThreadScheduler.getScheduler())
.retryWhen(defaultRetryStrategy());
}

@Override
public Mono<ExperimentalGroupCreationResponse> create(ExperimentalGroupCreationRequest request) {
throw new RuntimeException("not implemented");
//TODO implement
throw new RuntimeException("Not implemented");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package life.qbic.projectmanagement.application.batch;

import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentalGroup;
import life.qbic.projectmanagement.domain.model.sample.AnalysisMethod;
import life.qbic.projectmanagement.domain.model.sample.SampleId;
Expand Down Expand Up @@ -29,8 +29,8 @@ public record SampleUpdateRequest(SampleId sampleId, SampleInformation sampleInf
*/
public record SampleInformation(String sampleName, String biologicalReplicate,
AnalysisMethod analysisMethod,
ExperimentalGroup experimentalGroup, OntologyTerm species,
OntologyTerm specimen, OntologyTerm analyte,
ExperimentalGroup experimentalGroup, OntologyTermV1 species,
OntologyTermV1 specimen, OntologyTermV1 analyte,
String comment) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import life.qbic.logging.service.LoggerFactory;
import life.qbic.projectmanagement.application.DeletionService;
import life.qbic.projectmanagement.application.sample.SampleInformationService;
import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;
import life.qbic.projectmanagement.domain.model.experiment.Experiment;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentalDesign.AddExperimentalGroupResponse.ResponseCode;
Expand Down Expand Up @@ -245,7 +245,7 @@ public List<Experiment> findAllForProject(ProjectId projectId) {
@PreAuthorize(
"hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE') ")
public void addSpeciesToExperiment(String projectId, ExperimentId experimentId,
OntologyTerm... species) {
OntologyTermV1... species) {
Arrays.stream(species).forEach(Objects::requireNonNull);
if (species.length < 1) {
return;
Expand Down Expand Up @@ -274,7 +274,7 @@ public void addSpeciesToExperiment(String projectId, ExperimentId experimentId,
@PreAuthorize(
"hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE') ")
public void addSpecimenToExperiment(String projectId, ExperimentId experimentId,
OntologyTerm... specimens) {
OntologyTermV1... specimens) {
Arrays.stream(specimens).forEach(Objects::requireNonNull);
if (specimens.length < 1) {
return;
Expand Down Expand Up @@ -303,7 +303,7 @@ public void addSpecimenToExperiment(String projectId, ExperimentId experimentId,
@PreAuthorize(
"hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE') ")
public void addAnalyteToExperiment(String projectId, ExperimentId experimentId,
OntologyTerm... analytes) {
OntologyTermV1... analytes) {
Arrays.stream(analytes).forEach(Objects::requireNonNull);
if (analytes.length < 1) {
return;
Expand Down Expand Up @@ -452,7 +452,7 @@ public List<ExperimentalVariableInformation> addVariablesToExperiment(String pro
* @param experimentId the Id of the experiment for which the analytes should be retrieved
* @return a collection of analytes in the active experiment.
*/
public Collection<OntologyTerm> getAnalytesOfExperiment(ExperimentId experimentId) {
public Collection<OntologyTermV1> getAnalytesOfExperiment(ExperimentId experimentId) {
Experiment experiment = loadExperimentById(experimentId);
return experiment.getAnalytes();
}
Expand All @@ -463,7 +463,7 @@ public Collection<OntologyTerm> getAnalytesOfExperiment(ExperimentId experimentI
* @param experimentId the Id of the experiment for which the species should be retrieved
* @return a collection of species in the active experiment.
*/
public Collection<OntologyTerm> getSpeciesOfExperiment(ExperimentId experimentId) {
public Collection<OntologyTermV1> getSpeciesOfExperiment(ExperimentId experimentId) {
Experiment experiment = loadExperimentById(experimentId);
return experiment.getSpecies();
}
Expand All @@ -474,7 +474,7 @@ public Collection<OntologyTerm> getSpeciesOfExperiment(ExperimentId experimentId
* @param experimentId the Id of the experiment for which the specimen should be retrieved
* @return a collection of specimen in the active experiment.
*/
public Collection<OntologyTerm> getSpecimensOfExperiment(ExperimentId experimentId) {
public Collection<OntologyTermV1> getSpecimensOfExperiment(ExperimentId experimentId) {
Experiment experiment = loadExperimentById(experimentId);
return experiment.getSpecimens();
}
Expand Down Expand Up @@ -532,10 +532,9 @@ public void deleteExperimentalGroupsWithIds(String projectId, ExperimentId id, L
handleLocalEventCache(domainEventsCache);
}

@Transactional
/**
* Updates experimental groups in a given experiment.
*
* <p>
* Compares the provided list of experimental groups of an experiment with the persistent state.
* Removes groups from the experiment that are not in the new list, adds groups that are not in
* the experiment yet and updates the other groups of the experiment.
Expand All @@ -545,6 +544,7 @@ public void deleteExperimentalGroupsWithIds(String projectId, ExperimentId id, L
* @param experimentalGroupDTOS the new list of experimental groups including all updates
* @since 1.0.0
*/
@Transactional
@PreAuthorize(
"hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE') ")
public void updateExperimentalGroupsOfExperiment(String projectId, ExperimentId experimentId,
Expand Down Expand Up @@ -600,8 +600,7 @@ private List<Long> getGroupIdsToDelete(List<ExperimentalGroup> existingGroups,
"hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE') ")
public void editExperimentInformation(String projectId, ExperimentId experimentId,
String experimentName,
List<OntologyTerm> species, List<OntologyTerm> specimens, List<OntologyTerm> analytes,
String speciesIconName, String specimenIconName) {
List<OntologyTermV1> species, List<OntologyTermV1> specimens, List<OntologyTermV1> analytes) {

List<DomainEvent> domainEventsCache = new ArrayList<>();
var localDomainEventDispatcher = LocalDomainEventDispatcher.instance();
Expand All @@ -614,7 +613,6 @@ public void editExperimentInformation(String projectId, ExperimentId experimentI
experiment.setSpecies(species);
experiment.setSpecimens(specimens);
experiment.setAnalytes(analytes);
experiment.setIconNames(speciesIconName, specimenIconName, "default");
experimentRepository.update(experiment);

handleLocalEventCache(domainEventsCache);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import life.qbic.projectmanagement.application.ontology.TerminologyService;
import life.qbic.projectmanagement.application.sample.SampleIdCodeEntry;
import life.qbic.projectmanagement.application.sample.SampleInformationService;
import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
import life.qbic.projectmanagement.domain.model.measurement.MeasurementCode;
import life.qbic.projectmanagement.domain.model.measurement.MeasurementId;
Expand Down Expand Up @@ -778,7 +778,7 @@ private boolean allMeasurementCodesExist(List<String> measurementCode) {
.allMatch(measurementRepository::existsMeasurement);
}

private Optional<OntologyTerm> resolveOntologyCURI(String ontologyCURI) {
private Optional<OntologyTermV1> resolveOntologyCURI(String ontologyCURI) {
return terminologyService.findByCurie(ontologyCURI);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.List;
import java.util.Optional;
import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.OntologyTermV1;

/**
* <b>API for ontology term selection or lookup for autocomplete use cases</b>
Expand All @@ -18,7 +18,7 @@ public interface TerminologySelect {
* <p>
* <b>NOTE!</b>
* <p>
* The resulting {@link OntologyTerm} objects are not guaranteed to contain values for properties
* The resulting {@link OntologyTermV1} objects are not guaranteed to contain values for properties
* like "description". This depends highly on the implementation, use the
* {@link TerminologySelect#search(String, int, int)} method for a rich search.
*
Expand All @@ -44,7 +44,7 @@ public interface TerminologySelect {
Optional<OntologyClass> searchByCurie(String curie) throws LookupException;

/**
* Searches for possible matching ontology terms. This search returns rich {@link OntologyTerm}
* Searches for possible matching ontology terms. This search returns rich {@link OntologyTermV1}
* objects, and should be used when information for properties like "description" needs to be
* used.
*
Expand Down
Loading