Skip to content

Commit 0a58759

Browse files
authored
Release 0.36.0
Release 0.36.0
2 parents 666b7e2 + 5212de4 commit 0a58759

File tree

36 files changed

+1675
-365
lines changed

36 files changed

+1675
-365
lines changed

identity/src/main/java/life/qbic/identity/application/token/PersonalAccessTokenServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ public Collection<PersonalAccessToken> find(String userId) {
6565

6666
@Override
6767
public void delete(String tokenId, String userId) {
68-
tokenRepository.findAllByUserId(userId).stream().filter(token -> token.userId().equals(userId))
68+
tokenRepository.findAllByUserId(userId).stream()
69+
.filter(token -> token.tokenId().equals(tokenId))
6970
.findAny().ifPresent(tokenRepository::delete);
7071
}
7172
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package life.qbic.projectmanagement.infrastructure.sample.qualitycontrol;
2+
3+
import java.util.List;
4+
import life.qbic.projectmanagement.domain.model.project.ProjectId;
5+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControl;
6+
import org.springframework.data.repository.CrudRepository;
7+
8+
/**
9+
* <b>Quality Control JPA</b>
10+
* <p>
11+
* JPA interface for {@link QualityControl} items.
12+
*/
13+
public interface QualityControlJpa extends CrudRepository<QualityControl, Long> {
14+
15+
List<QualityControl> findQualityControlAssociationByProjectIdEquals(ProjectId projectId);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package life.qbic.projectmanagement.infrastructure.sample.qualitycontrol;
2+
3+
import static org.apache.logging.log4j.LogManager.getLogger;
4+
5+
import java.util.Comparator;
6+
import java.util.List;
7+
import java.util.Optional;
8+
import life.qbic.application.commons.ApplicationException;
9+
import life.qbic.projectmanagement.application.sample.qualitycontrol.QualityControlStorage;
10+
import life.qbic.projectmanagement.application.sample.qualitycontrol.QualityControlStorageException;
11+
import life.qbic.projectmanagement.domain.model.project.ProjectId;
12+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControl;
13+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControlUpload;
14+
import org.apache.logging.log4j.Logger;
15+
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.stereotype.Component;
17+
18+
/**
19+
* <b>Quality Control Store</b>
20+
*
21+
* <p>Implementation of the {@link QualityControlStorage} interface.</p>
22+
*/
23+
@Component
24+
public class QualityControlStore implements QualityControlStorage {
25+
26+
private static final Logger log = getLogger(QualityControlStore.class);
27+
28+
private final QualityControlJpa persistenceStore;
29+
30+
@Autowired
31+
public QualityControlStore(QualityControlJpa persistenceStore) {
32+
this.persistenceStore = persistenceStore;
33+
}
34+
35+
/**
36+
* Stores a {@link QualityControl} item persistently.
37+
*
38+
* @param qualityControl the QualityControlUpload item to store
39+
* @throws QualityControlStorageException is thrown if the storage fails
40+
* @since 1.0.0
41+
*/
42+
@Override
43+
public void storeQualityControl(QualityControl qualityControl)
44+
throws QualityControlStorageException {
45+
try {
46+
persistenceStore.save(qualityControl);
47+
} catch (RuntimeException e) {
48+
throw new QualityControlStorageException(
49+
"Storing the quality control for project %s failed".formatted(qualityControl.project()),
50+
e);
51+
}
52+
}
53+
54+
@Override
55+
public void storeQualityControls(List<QualityControl> qualityControls)
56+
throws QualityControlStorageException {
57+
try {
58+
persistenceStore.saveAll(qualityControls);
59+
} catch (RuntimeException e) {
60+
throw new QualityControlStorageException((
61+
"Storing the quality control for project %s failed".formatted(
62+
qualityControls.stream().findFirst().orElseThrow().project())),
63+
e);
64+
}
65+
}
66+
67+
@Override
68+
public List<QualityControlUpload> findQualityControlsForProject(ProjectId projectId) {
69+
try {
70+
return persistenceStore.findQualityControlAssociationByProjectIdEquals(projectId).stream()
71+
.sorted(Comparator.comparing(QualityControl::providedOn)) //ensures same ordering
72+
.map(QualityControl::qualityControlUpload).toList();
73+
} catch (RuntimeException e) {
74+
throw new ApplicationException(
75+
"Retrieving quality controls for project %s failed.".formatted(projectId), e);
76+
}
77+
}
78+
79+
@Override
80+
public void deleteQualityControlForProject(String projectId, long qualityControlId) {
81+
List<QualityControl> associations = persistenceStore.findQualityControlAssociationByProjectIdEquals(
82+
ProjectId.parse(projectId));
83+
List<QualityControl> associationsWithQualityControl = associations.stream()
84+
.filter(association -> association.qualityControlUpload().id().equals(qualityControlId))
85+
.toList();
86+
persistenceStore.deleteAll(associationsWithQualityControl);
87+
}
88+
89+
@Override
90+
public Optional<QualityControlUpload> findQualityControlForProject(String projectId,
91+
Long qualityControlId) {
92+
try {
93+
List<QualityControl> associations = persistenceStore.findQualityControlAssociationByProjectIdEquals(
94+
ProjectId.parse(projectId));
95+
Optional<QualityControlUpload> foundQualityControl = associations.stream()
96+
.map(QualityControl::qualityControlUpload)
97+
.filter(qualityControl -> qualityControl.id().equals(qualityControlId))
98+
.findFirst();
99+
foundQualityControl.ifPresent(QualityControlUpload::fileContent); // make sure it is loaded
100+
return foundQualityControl;
101+
} catch (RuntimeException e) {
102+
throw new ApplicationException(
103+
"Retrieving quality control %d for project %s failed.".formatted(qualityControlId,
104+
projectId), e);
105+
}
106+
}
107+
}

project-management/src/main/java/life/qbic/projectmanagement/application/authorization/QbicUserDetails.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public String getUsername() {
5757
return user.id();
5858
}
5959

60+
public String fullName() {
61+
return user.fullName();
62+
}
63+
6064
@Override
6165
public boolean isAccountNonExpired() {
6266
return true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package life.qbic.projectmanagement.application.sample.qualitycontrol;
2+
3+
import java.util.Arrays;
4+
import java.util.Objects;
5+
import java.util.StringJoiner;
6+
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
7+
8+
/**
9+
* <b>Simple quality control information exchange object</b>
10+
*/
11+
public record QualityControlReport(String fileName, ExperimentId experimentId, byte[] content) {
12+
13+
@Override
14+
public boolean equals(Object o) {
15+
if (this == o) {
16+
return true;
17+
}
18+
if (o == null || getClass() != o.getClass()) {
19+
return false;
20+
}
21+
QualityControlReport qualityControlReport = (QualityControlReport) o;
22+
return Objects.equals(fileName, qualityControlReport.fileName) && Objects.equals(experimentId,
23+
qualityControlReport.experimentId)
24+
&& Arrays.equals(content, qualityControlReport.content);
25+
}
26+
27+
@Override
28+
public int hashCode() {
29+
int result = Objects.hash(experimentId, fileName);
30+
result = 31 * result + Arrays.hashCode(content);
31+
return result;
32+
}
33+
34+
@Override
35+
public String toString() {
36+
return new StringJoiner(", ", QualityControlReport.class.getSimpleName() + "[", "]")
37+
.add("fileName='" + fileName + "'")
38+
.add("experimentId='" + experimentId + "'")
39+
.add("content=" + Arrays.toString(content))
40+
.toString();
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package life.qbic.projectmanagement.application.sample.qualitycontrol;
2+
3+
import static java.util.Objects.requireNonNull;
4+
import static life.qbic.logging.service.LoggerFactory.logger;
5+
6+
import java.time.Instant;
7+
import java.util.List;
8+
import java.util.Optional;
9+
import life.qbic.application.commons.ApplicationException;
10+
import life.qbic.logging.api.Logger;
11+
import life.qbic.projectmanagement.application.api.PurchaseStoreException;
12+
import life.qbic.projectmanagement.domain.model.project.ProjectId;
13+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControl;
14+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControlUpload;
15+
import org.springframework.stereotype.Service;
16+
17+
/**
18+
* <b>Quality Control Service</b>
19+
* <p>
20+
* A service that enables actions on quality control services.
21+
*
22+
* @since 1.0.0
23+
*/
24+
@Service
25+
public class QualityControlService {
26+
27+
private static final Logger log = logger(QualityControlService.class);
28+
private final QualityControlStorage storage;
29+
30+
public QualityControlService(QualityControlStorage storage) {
31+
this.storage = storage;
32+
}
33+
34+
/**
35+
* Adds a quality controls to a project.
36+
*
37+
* @param projectId the project the quality control is related to
38+
* @param qualityControl the quality control information item
39+
*/
40+
public void addQualityControl(String projectId, QualityControlReport qualityControl) {
41+
addQualityControls(projectId, List.of(qualityControl));
42+
}
43+
44+
/**
45+
* Adds a list of quality controls to a project.
46+
*
47+
* @param projectId the project the quality control is related to
48+
* @param qualityControlsList list of quality controls information items to be added
49+
*/
50+
public void addQualityControls(String projectId, List<QualityControlReport> qualityControlsList) {
51+
var projectReference = ProjectId.parse(projectId);
52+
var qualityControlUploadDate = Instant.now();
53+
List<QualityControl> qualityControls = qualityControlsList.stream()
54+
.map(it -> QualityControlUpload.create(it.fileName(), it.experimentId(), it.content()))
55+
.map(it -> QualityControl.create(projectReference, qualityControlUploadDate, it))
56+
.toList();
57+
try {
58+
storage.storeQualityControls(qualityControls);
59+
} catch (PurchaseStoreException e) {
60+
throw ApplicationException.wrapping(e);
61+
}
62+
}
63+
64+
/**
65+
* Lists all quality controls files linked to a project
66+
*
67+
* @param projectId the projectId for which to search quality controls for
68+
* @return a list of all linked quality controls, can be empty, never null.
69+
*/
70+
public List<QualityControlUpload> linkedQualityControls(String projectId) {
71+
ProjectId parsedId = ProjectId.parse(projectId);
72+
return requireNonNull(storage.findQualityControlsForProject(parsedId),
73+
"Provided quality controls must not be null");
74+
}
75+
76+
/**
77+
* Triggers the deletion of a {@link QualityControl} item.
78+
*
79+
* @param projectId the projectId for which the {@link QualityControl} should be deleted
80+
* @param qualityControlId the id of the quality control to be deleted
81+
*/
82+
public void deleteQualityControl(String projectId, long qualityControlId) {
83+
storage.deleteQualityControlForProject(projectId, qualityControlId);
84+
}
85+
86+
/**
87+
* Returns a {@link QualityControlUpload} item with the provided qualityControlId which is
88+
* associated with the provided {@link ProjectId} from the database.
89+
*
90+
* @param projectId the projectId for which the {@link QualityControl} should be
91+
* returned
92+
* @param qualityControlId the id of the quality control to be returned
93+
*/
94+
public Optional<QualityControlUpload> getQualityControlWithContent(String projectId,
95+
Long qualityControlId) {
96+
return storage.findQualityControlForProject(projectId, qualityControlId);
97+
}
98+
99+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package life.qbic.projectmanagement.application.sample.qualitycontrol;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
import life.qbic.projectmanagement.domain.model.project.ProjectId;
6+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControl;
7+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControlUpload;
8+
9+
/**
10+
* <b>QualityControlUpload Storage</b>
11+
* <p>
12+
* Quality Control storage interface, that enables storing of {@link QualityControl}
13+
* items.
14+
* <p>
15+
*/
16+
public interface QualityControlStorage {
17+
18+
/**
19+
* Stores a {@link QualityControl} item persistently.
20+
*
21+
* @param qualityControl the QualityControl item to store
22+
* @throws QualityControlStorageException is thrown if the storage fails
23+
*/
24+
void storeQualityControl(QualityControl qualityControl)
25+
throws QualityControlStorageException;
26+
27+
/**
28+
* Stores a list of {@link QualityControl} item persistently.
29+
*
30+
* @param qualityControls the QualityControl item list to store
31+
* @throws QualityControlStorageException is thrown if the storage fails
32+
*/
33+
void storeQualityControls(List<QualityControl> qualityControls)
34+
throws QualityControlStorageException;
35+
36+
/**
37+
* Returns a list of {@link QualityControlUpload} items associated with the provided
38+
* {@link ProjectId} from the database.
39+
*
40+
* @param projectId the projectId for which the {@link QualityControl} should be returned
41+
*/
42+
List<QualityControlUpload> findQualityControlsForProject(ProjectId projectId);
43+
44+
/**
45+
* Deletes {@link QualityControl} item persistently.
46+
*
47+
* @param projectId the projectId for which the {@link QualityControl} should be
48+
* deleted
49+
* @param qualityControlId the id of the quality control to be deleted
50+
*/
51+
void deleteQualityControlForProject(String projectId, long qualityControlId);
52+
53+
54+
/**
55+
* Returns a {@link QualityControlUpload} item with the provided qualityControlId which is
56+
* associated with the provided {@link ProjectId} from the database.
57+
*
58+
* @param projectId the projectId for which the {@link QualityControl} should be
59+
* returned
60+
* @param qualityControlId the id of the quality control to be returned
61+
*/
62+
Optional<QualityControlUpload> findQualityControlForProject(String projectId,
63+
Long qualityControlId);
64+
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package life.qbic.projectmanagement.application.sample.qualitycontrol;
2+
3+
import java.io.Serial;
4+
import life.qbic.projectmanagement.domain.model.sample.qualitycontrol.QualityControlUpload;
5+
6+
/**
7+
* <b>QualityControlStorageException</b>
8+
* <p>
9+
* Exception that shall be thrown if a {@link QualityControlUpload} item cannot be stored in the
10+
* persistence storage implementation.
11+
*
12+
* @since 1.0.0
13+
*/
14+
public class QualityControlStorageException extends RuntimeException {
15+
16+
@Serial
17+
private static final long serialVersionUID = -3283512159754153169L;
18+
19+
public QualityControlStorageException() {
20+
}
21+
22+
public QualityControlStorageException(String message) {
23+
super(message);
24+
}
25+
26+
public QualityControlStorageException(String message, Throwable cause) {
27+
super(message, cause);
28+
}
29+
30+
public QualityControlStorageException(Throwable cause) {
31+
super(cause);
32+
}
33+
34+
public QualityControlStorageException(String message, Throwable cause, boolean enableSuppression,
35+
boolean writableStackTrace) {
36+
super(message, cause, enableSuppression, writableStackTrace);
37+
}
38+
}

0 commit comments

Comments
 (0)