Skip to content

Commit 67daa4a

Browse files
authored
Merge pull request #265 from qbicsoftware/development
Release
2 parents c77ac4b + dee5307 commit 67daa4a

File tree

86 files changed

+3601
-1371
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+3601
-1371
lines changed

database-connector/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<dependency>
2929
<groupId>life.qbic</groupId>
3030
<artifactId>openbis-client-lib</artifactId>
31-
<version>1.5.0</version>
31+
<version>1.6.0</version>
3232
<exclusions>
3333
<exclusion>
3434
<groupId>org.codehaus.groovy</groupId>

database-connector/src/main/java/life/qbic/projectmanagement/experiment/persistence/SampleCodeServiceImplementation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private static SampleCode generateSampleCode(ProjectCode code, int sampleNumber)
5959
String.format("%s%03d", code.value(), remainderCounter(sampleNumber)) + letterForMille(
6060
sampleNumber);
6161
String sampleCodeWithChecksum = sampleCode + checksum(sampleCode);
62-
return new SampleCode(sampleCodeWithChecksum);
62+
return SampleCode.create(sampleCodeWithChecksum);
6363
}
6464

6565
private static int remainderCounter(int sampleNumber) {

database-connector/src/main/java/life/qbic/projectmanagement/experiment/persistence/SampleJpaRepository.java

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
package life.qbic.projectmanagement.experiment.persistence;
22

3-
import static life.qbic.logging.service.LoggerFactory.logger;
4-
53
import life.qbic.application.commons.Result;
64
import life.qbic.logging.api.Logger;
75
import life.qbic.projectmanagement.domain.project.repository.SampleRepository;
86
import life.qbic.projectmanagement.domain.project.sample.Sample;
7+
import life.qbic.projectmanagement.domain.project.sample.SampleId;
98
import life.qbic.projectmanagement.domain.project.service.SampleDomainService.ResponseCode;
109
import org.springframework.beans.factory.annotation.Autowired;
1110
import org.springframework.stereotype.Repository;
1211

12+
import java.util.ArrayList;
13+
import java.util.Collection;
14+
import java.util.stream.Collectors;
15+
16+
import static life.qbic.logging.service.LoggerFactory.logger;
17+
1318
/**
1419
* <b>Sample JPA Repository</b>
1520
*
@@ -21,7 +26,6 @@
2126
public class SampleJpaRepository implements SampleRepository {
2227

2328
private static final Logger log = logger(SampleJpaRepository.class);
24-
2529
private final QbicSampleRepository qbicSampleRepository;
2630

2731
@Autowired
@@ -39,4 +43,18 @@ public Result<Sample, ResponseCode> add(Sample sample) {
3943
}
4044
return Result.fromValue(sample);
4145
}
46+
47+
@Override
48+
public Result<Collection<Sample>, ResponseCode> addAll(Collection<Sample> samples) {
49+
try {
50+
this.qbicSampleRepository.saveAll(samples);
51+
} catch (Exception e) {
52+
Collection<SampleId> failedSamples = new ArrayList<>();
53+
samples.forEach(sample -> failedSamples.add(sample.sampleId()));
54+
String commaSeperatedSampleIds = failedSamples.stream().map(Object::toString).collect(Collectors.joining(", "));
55+
log.error("The samples:" + commaSeperatedSampleIds + "could not be saved", e);
56+
return Result.fromError(ResponseCode.REGISTRATION_FAILED);
57+
}
58+
return Result.fromValue(samples);
59+
}
4260
}

database-connector/src/main/java/life/qbic/projectmanagement/persistence/repository/OpenbisConnector.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions;
1919
import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularyTermSearchCriteria;
2020
import java.util.ArrayList;
21-
import java.util.Arrays;
21+
import java.util.Collections;
2222
import java.util.List;
2323
import java.util.Objects;
2424
import life.qbic.logging.api.Logger;
@@ -159,9 +159,8 @@ private void deleteOpenbisProject(ProjectCode projectCode) {
159159

160160
private void handleOperations(IOperation operation) {
161161
IApplicationServerApi api = openBisClient.getV3();
162-
163162
SynchronousOperationExecutionOptions executionOptions = new SynchronousOperationExecutionOptions();
164-
List<IOperation> operationOptions = Arrays.asList(operation);
163+
List<IOperation> operationOptions = Collections.singletonList(operation);
165164
try {
166165
api.executeOperations(openBisClient.getSessionToken(), operationOptions, executionOptions);
167166
} catch (Exception e) {
@@ -186,7 +185,7 @@ public boolean projectExists(ProjectCode projectCode) {
186185
}
187186

188187
// Convenience RTE to describe connection issues
189-
class ConnectionException extends RuntimeException {
188+
static class ConnectionException extends RuntimeException {
190189

191190
}
192191

projectmanagement/src/main/java/life/qbic/projectmanagement/application/ExperimentInformationService.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
import java.util.Optional;
99
import java.util.Set;
1010
import life.qbic.application.commons.ApplicationException;
11+
import life.qbic.application.commons.Result;
1112
import life.qbic.logging.api.Logger;
1213
import life.qbic.logging.service.LoggerFactory;
1314
import life.qbic.projectmanagement.domain.project.experiment.Experiment;
1415
import life.qbic.projectmanagement.domain.project.experiment.ExperimentId;
1516
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalDesign.AddExperimentalGroupResponse;
1617
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalDesign.AddExperimentalGroupResponse.ResponseCode;
18+
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalGroup;
1719
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalValue;
1820
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalVariable;
1921
import life.qbic.projectmanagement.domain.project.experiment.VariableLevel;
@@ -60,18 +62,18 @@ private Experiment loadExperimentById(ExperimentId experimentId) {
6062
* @param experimentId the Id of the experiment for which to add the species
6163
* @param experimentalGroup the experimental groups to add
6264
*/
63-
public AddExperimentalGroupResponse addExperimentalGroupToExperiment(
65+
public Result<ExperimentalGroup, ResponseCode> addExperimentalGroupToExperiment(
6466
ExperimentId experimentId, ExperimentalGroupDTO experimentalGroup) {
6567
Objects.requireNonNull(experimentalGroup, "experimental group must not be null");
6668
Objects.requireNonNull(experimentId, "experiment id must not be null");
6769

6870
Experiment activeExperiment = loadExperimentById(experimentId);
69-
AddExperimentalGroupResponse response = activeExperiment.addExperimentalGroup(
71+
Result<ExperimentalGroup, ResponseCode> result = activeExperiment.addExperimentalGroup(
7072
experimentalGroup.levels(), experimentalGroup.sampleSize());
71-
if (response.responseCode() == ResponseCode.SUCCESS) {
73+
if(result.isValue()) {
7274
experimentRepository.update(activeExperiment);
7375
}
74-
return response;
76+
return result;
7577
}
7678

7779
/**
@@ -88,6 +90,18 @@ public List<ExperimentalGroupDTO> getExperimentalGroups(ExperimentId experimentI
8890
.toList();
8991
}
9092

93+
public List<ExperimentalGroup> experimentalGroupsFor(ExperimentId experimentId) {
94+
Experiment experiment = loadExperimentById(experimentId);
95+
return experiment.getExperimentalGroups().stream().toList();
96+
}
97+
98+
public void deleteExperimentGroup(ExperimentId experimentId, long groupId) {
99+
Experiment experiment = loadExperimentById(experimentId);
100+
experiment.removeExperimentGroup(groupId);
101+
experimentRepository.update(experiment);
102+
}
103+
104+
91105
public record ExperimentalGroupDTO(Set<VariableLevel> levels, int sampleSize) {
92106

93107
}

projectmanagement/src/main/java/life/qbic/projectmanagement/application/ProjectRegistrationService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public Result<Project, ApplicationException> registerProject(String sourceOffer,
6666
Optional.ofNullable(sourceOffer)
6767
.flatMap(it -> it.isBlank() ? Optional.empty() : Optional.of(it))
6868
.ifPresent(offerIdentifier -> project.linkOffer(OfferIdentifier.of(offerIdentifier)));
69-
addExperimentToProjectService.addExperimentToProject(project.getId(), "Experiment 0",
69+
addExperimentToProjectService.addExperimentToProject(project.getId(), "First Experiment",
7070
speciesList, specimenList, analyteList).onError(e -> {
7171
projectRepository.deleteByProjectCode(project.getProjectCode());
7272
throw new ApplicationException(
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package life.qbic.projectmanagement.application;
22

3-
import java.util.List;
4-
import java.util.Objects;
53
import life.qbic.application.commons.Result;
64
import life.qbic.projectmanagement.application.api.SampleCodeService;
75
import life.qbic.projectmanagement.domain.project.ProjectId;
8-
import life.qbic.projectmanagement.domain.project.repository.SampleRepository;
96
import life.qbic.projectmanagement.domain.project.sample.Sample;
7+
import life.qbic.projectmanagement.domain.project.sample.SampleCode;
108
import life.qbic.projectmanagement.domain.project.sample.SampleRegistrationRequest;
119
import life.qbic.projectmanagement.domain.project.service.SampleDomainService;
1210
import org.springframework.beans.factory.annotation.Autowired;
1311
import org.springframework.stereotype.Service;
1412

13+
import java.util.Collection;
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
import java.util.Objects;
17+
1518
/**
1619
* Sample Registration Service
1720
* <p>
@@ -20,56 +23,48 @@
2023
@Service
2124
public class SampleRegistrationService {
2225

23-
private final SampleRepository sampleRepository;
24-
25-
private final SampleCodeService sampleCodeService;
26-
27-
private final SampleDomainService sampleDomainService;
28-
29-
@Autowired
30-
public SampleRegistrationService(SampleRepository sampleRepository,
31-
SampleCodeService sampleCodeService, SampleDomainService sampleDomainService) {
32-
this.sampleRepository = Objects.requireNonNull(sampleRepository);
33-
this.sampleCodeService = Objects.requireNonNull(sampleCodeService);
34-
this.sampleDomainService = Objects.requireNonNull(sampleDomainService);
35-
}
26+
private final SampleCodeService sampleCodeService;
27+
private final SampleDomainService sampleDomainService;
3628

37-
public List<String> retrieveProteomics() {
38-
return List.of("Sample Name", "Biological Replicate", "Treatment", "Cell Line", "Species",
39-
"Specimen", "Analyte", "Comment");
40-
}
41-
42-
public List<String> retrieveLigandomics() {
43-
return List.of("Sample Name", "Biological Replicate", "Treatment", "Cell Line", "Species",
44-
"Specimen", "Analyte", "Comment");
45-
}
46-
47-
public List<String> retrieveMetabolomics() {
48-
return List.of("Sample Name", "Biological Replicate", "Treatment", "Cell Line", "Species",
49-
"Specimen", "Analyte", "Comment");
50-
}
51-
52-
public List<String> retrieveGenomics() {
53-
return List.of("Analysis to be performed", "Plate position (e.g. A1)", "Plate title",
54-
"Sample label", "Biological replicate reference id", "Species", "Specimen",
55-
"FFPE material");
56-
}
29+
@Autowired
30+
public SampleRegistrationService(SampleCodeService sampleCodeService,
31+
SampleDomainService sampleDomainService) {
32+
this.sampleCodeService = Objects.requireNonNull(sampleCodeService);
33+
this.sampleDomainService = Objects.requireNonNull(sampleDomainService);
34+
}
5735

58-
public Result<Sample, ResponseCode> registerSample(
59-
SampleRegistrationRequest sampleRegistrationRequest, ProjectId projectId) {
60-
var result = sampleCodeService.generateFor(projectId);
61-
if (result.isError()) {
62-
return Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED);
36+
public Result<Sample, ResponseCode> registerSample(SampleRegistrationRequest sampleRegistrationRequest, ProjectId projectId) {
37+
Objects.requireNonNull(sampleRegistrationRequest);
38+
Objects.requireNonNull(projectId);
39+
var sampleCode = sampleCodeService.generateFor(projectId);
40+
if (sampleCode.isError()) {
41+
return Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED);
42+
}
43+
var result = sampleDomainService.registerSample(sampleCode.getValue(), sampleRegistrationRequest);
44+
if (result.isError()) {
45+
return Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED);
46+
}
47+
return Result.fromValue(result.getValue());
6348
}
64-
var registration = sampleDomainService.registerSample(result.getValue(), sampleRegistrationRequest);
65-
if (registration.isValue()) {
66-
return Result.fromValue(registration.getValue());
49+
50+
public Result<Collection<Sample>, ResponseCode> registerSamples(
51+
Collection<SampleRegistrationRequest> sampleRegistrationRequests, ProjectId projectId) {
52+
Objects.requireNonNull(sampleRegistrationRequests);
53+
Objects.requireNonNull(projectId);
54+
if (sampleRegistrationRequests.size() < 1) {
55+
return Result.fromError(ResponseCode.NO_SAMPLES_DEFINED);
56+
}
57+
Map<SampleCode, SampleRegistrationRequest> sampleCodesToRegistrationRequests = new HashMap<>();
58+
sampleRegistrationRequests.forEach(sampleRegistrationRequest -> sampleCodeService.generateFor(projectId)
59+
.onValue(sampleCode -> sampleCodesToRegistrationRequests.put(sampleCode, sampleRegistrationRequest))
60+
.onError(responseCode -> Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED)));
61+
var result = sampleDomainService.registerSamples(sampleCodesToRegistrationRequests);
62+
return result.onValue(Result::fromValue).flatMapError(responseCode -> Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED));
6763
}
68-
return Result.fromError(ResponseCode.SAMPLE_REGISTRATION_FAILED);
69-
}
7064

71-
public enum ResponseCode {
72-
SAMPLE_REGISTRATION_FAILED
73-
}
65+
public enum ResponseCode {
66+
SAMPLE_REGISTRATION_FAILED,
67+
NO_SAMPLES_DEFINED
68+
}
7469

7570
}

projectmanagement/src/main/java/life/qbic/projectmanagement/application/batch/BatchRegistrationService.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@ public Result<BatchId, ResponseCode> addSampleToBatch(SampleId sampleId, BatchId
3737
var searchResult = batchRepository.find(batchId);
3838
if (searchResult.isEmpty()) {
3939
return Result.fromError(ResponseCode.BATCH_NOT_FOUND);
40-
}
41-
searchResult.ifPresent(batch -> {
40+
} else {
41+
Batch batch = searchResult.get();
4242
batch.addSample(sampleId);
43-
batchRepository.update(batch);
44-
});
45-
return Result.fromValue(batchId);
43+
var result = batchRepository.update(batch);
44+
if (result.isError()) {
45+
return Result.fromError(ResponseCode.BATCH_UPDATE_FAILED);
46+
}
47+
return Result.fromValue(batch.batchId());
48+
}
4649
}
4750

4851
public enum ResponseCode {

projectmanagement/src/main/java/life/qbic/projectmanagement/domain/project/experiment/Experiment.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
import java.util.Set;
1313
import life.qbic.application.commons.Result;
1414
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalDesign.AddExperimentalGroupResponse;
15+
import life.qbic.projectmanagement.domain.project.experiment.ExperimentalDesign.AddExperimentalGroupResponse.ResponseCode;
1516
import life.qbic.projectmanagement.domain.project.experiment.exception.ConditionExistsException;
1617
import life.qbic.projectmanagement.domain.project.experiment.exception.ExperimentalVariableExistsException;
1718
import life.qbic.projectmanagement.domain.project.experiment.exception.ExperimentalVariableNotDefinedException;
1819
import life.qbic.projectmanagement.domain.project.experiment.vocabulary.Analyte;
1920
import life.qbic.projectmanagement.domain.project.experiment.vocabulary.Species;
2021
import life.qbic.projectmanagement.domain.project.experiment.vocabulary.Specimen;
22+
import life.qbic.projectmanagement.domain.project.sample.SampleOrigin;
2123

2224

2325
/**
@@ -226,12 +228,16 @@ public Result<VariableName, Exception> addVariableToDesign(String variableName,
226228
* @param sampleSize the number of samples that are expected for this experimental group
227229
* @return
228230
*/
229-
public AddExperimentalGroupResponse addExperimentalGroup(Collection<VariableLevel> variableLevels,
231+
public Result<ExperimentalGroup, ResponseCode> addExperimentalGroup(Collection<VariableLevel> variableLevels,
230232
int sampleSize) {
231233
return experimentalDesign.addExperimentalGroup(variableLevels, sampleSize);
232234
}
233235

234236
public Set<ExperimentalGroup> getExperimentalGroups() {
235237
return experimentalDesign.getExperimentalGroups();
236238
}
239+
240+
public void removeExperimentGroup(long groupId) {
241+
experimentalDesign.removeExperimentalGroup(groupId);
242+
}
237243
}

projectmanagement/src/main/java/life/qbic/projectmanagement/domain/project/experiment/ExperimentalDesign.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public enum ResponseCode {
218218
* experiment
219219
* @param sampleSize the number of samples that are expected for this experimental group
220220
*/
221-
public AddExperimentalGroupResponse addExperimentalGroup(Collection<VariableLevel> variableLevels,
221+
public Result<ExperimentalGroup, ResponseCode> addExperimentalGroup(Collection<VariableLevel> variableLevels,
222222
int sampleSize) {
223223
variableLevels.forEach(Objects::requireNonNull);
224224
if (variableLevels.isEmpty()) {
@@ -234,13 +234,18 @@ public AddExperimentalGroupResponse addExperimentalGroup(Collection<VariableLeve
234234

235235
Condition condition = Condition.create(variableLevels);
236236
if (isConditionDefined(condition)) {
237-
return new AddExperimentalGroupResponse(ResponseCode.CONDITION_EXISTS);
237+
return Result.fromError(ResponseCode.CONDITION_EXISTS);
238238
}
239-
experimentalGroups.add(ExperimentalGroup.create(condition, sampleSize));
240-
return new AddExperimentalGroupResponse(ResponseCode.SUCCESS);
239+
var newExperimentalGroup = ExperimentalGroup.create(condition, sampleSize);
240+
experimentalGroups.add(newExperimentalGroup);
241+
return Result.fromValue(newExperimentalGroup);
241242
}
242243

243244
public Set<ExperimentalGroup> getExperimentalGroups() {
244245
return Collections.unmodifiableSet(experimentalGroups);
245246
}
247+
248+
public void removeExperimentalGroup(long groupId) {
249+
this.experimentalGroups.removeIf(experimentalGroup -> experimentalGroup.id() == groupId);
250+
}
246251
}

0 commit comments

Comments
 (0)