Skip to content
Snippets Groups Projects
Commit 1941f588 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' of git.ozg-sh.de:ozgcloud-app/vorgang-manager

parents 4beb9eb1 df76ce6e
Branches
Tags
No related merge requests found
Showing
with 657 additions and 157 deletions
......@@ -58,6 +58,21 @@ spec:
component: antragsraum-server
{{- end }}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: {{ (.Values.networkPolicy).zentralerEingangNamespace }}
podSelector:
matchExpressions:
- key: ozg-component
operator: In
values:
- eingangsadapter
- xta-adapter
ports:
- protocol: TCP
port: 9090
{{- with (.Values.networkPolicy).additionalIngressConfigLocal }}
{{ toYaml . | indent 2 }}
{{- end }}
......
......@@ -58,7 +58,10 @@ vorgangmanagerName: vorgang-manager
usermanagerName: user-manager
zufiManager:
address: dns://zufi.zufi-manager:9090
address: dns://zufi-manager.zufi:9090
elasticsearch:
certificateSecretName: elasticsearch-certificate
networkPolicy:
zentralerEingangNamespace: zentraler-eingang
\ No newline at end of file
......@@ -39,4 +39,4 @@ tests:
path: spec.template.spec.containers[0].env
content:
name: ozgcloud_zufi-manager_address
value: dns://zufi.zufi-manager:9090
value: dns://zufi-manager.zufi:9090
......@@ -158,6 +158,53 @@ tests:
- failedTemplate:
errorMessage: ozgcloud.antragraum.namespace must be set if antragraum is enabled
- it: should add default ingress rule for zentraler-eingang
set:
networkPolicy:
dnsServerNamespace: test-dns-namespace
asserts:
- contains:
path: spec.ingress
content:
from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: zentraler-eingang
podSelector:
matchExpressions:
- key: ozg-component
operator: In
values:
- eingangsadapter
- xta-adapter
ports:
- protocol: TCP
port: 9090
- it: should add ingress rule for zentraler-eingang
set:
networkPolicy:
dnsServerNamespace: test-dns-namespace
zentralerEingangNamespace: custom-namespace
asserts:
- contains:
path: spec.ingress
content:
from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: custom-namespace
podSelector:
matchExpressions:
- key: ozg-component
operator: In
values:
- eingangsadapter
- xta-adapter
ports:
- protocol: TCP
port: 9090
- it: should add egress rule to elasticsearch
set:
......
......@@ -26,7 +26,7 @@ syntax = "proto3";
package de.ozgcloud.vorgang.grpc.binaryFile;
import "callcontext.proto";
import "filemodel.proto";
import "file.model.proto";
option java_multiple_files = true;
option java_package = "de.ozgcloud.vorgang.grpc.binaryFile";
......@@ -42,12 +42,6 @@ service BinaryFileService {
rpc FindBinaryFilesMetaData(GrpcBinaryFilesRequest) returns (GrpcFindFilesResponse) {
}
rpc GetAttachments(GrpcGetAttachmentsRequest) returns (GrpcGetAttachmentsResponse) {
}
rpc GetRepresentations(GrpcGetRepresentationsRequest) returns (GrpcGetRepresentationsResponse) {
}
}
message GrpcBinaryFilesRequest {
......@@ -93,22 +87,6 @@ message GrpcGetBinaryFileDataResponse {
bytes fileContent = 1;
}
message GrpcGetAttachmentsRequest {
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1;
string eingangId = 2;
}
message GrpcGetAttachmentsResponse {
repeated GrpcBinaryFile file = 1;
}
message GrpcGetRepresentationsRequest {
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1;
string eingangId = 2;
}
message GrpcGetRepresentationsResponse {
repeated GrpcBinaryFile file = 1;
}
message GrpcBinaryFile {
string id = 1;
string name = 2;
......
......@@ -29,19 +29,22 @@ import "callcontext.proto";
option java_multiple_files = true;
option java_outer_classname = "FileModelProto";
option deprecated = true;
message GrpcGetAttachmentsRequest {
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1;
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1 [deprecated = true];
string eingangId = 2;
string vorgangId = 3;
}
message GrpcGetAttachmentsResponse {
repeated GrpcOzgFile file = 1;
}
message GrpcGetRepresentationsRequest {
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1;
de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1 [deprecated = true];
string eingangId = 2;
string vorgangId = 3;
}
message GrpcGetRepresentationsResponse {
repeated GrpcOzgFile file = 1;
......
......@@ -25,12 +25,11 @@ syntax = "proto3";
package de.ozgcloud.vorgang.grpc.file;
import "filemodel.proto";
import "file.model.proto";
option java_multiple_files = true;
option java_package = "de.ozgcloud.vorgang.grpc.file";
option java_outer_classname = "FileProto";
option deprecated = true;
service FileService {
rpc GetAttachments(GrpcGetAttachmentsRequest) returns (GrpcGetAttachmentsResponse) {
......
......@@ -25,9 +25,6 @@ import java.net.URLConnection;
import java.util.Base64;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Stream;
import jakarta.activation.MimetypesFileTypeMap;
......@@ -98,12 +95,7 @@ class PersistPostfachNachrichtByCommandService implements PersistPostfachNachric
createUploadedFilesReference(vorgangId),
createOzgFile(attachment.getName(), contentType, decContent.length),
Optional.empty(),
new ByteArrayInputStream(decContent)).get(10, TimeUnit.MINUTES).toString();
} catch (ExecutionException | TimeoutException e) {
throw new TechnicalException(e.getMessage(), e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new TechnicalException(e.getMessage(), e);
new ByteArrayInputStream(decContent)).toString();
} catch (IOException e) {
throw new TechnicalException("Can not read attached file", e);
}
......
......@@ -25,6 +25,7 @@ package de.ozgcloud.vorgang.files;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
......@@ -33,6 +34,7 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Repository;
import de.ozgcloud.vorgang.common.db.CriteriaUtil;
import de.ozgcloud.vorgang.vorgang.Vorgang;
@Repository
......@@ -41,61 +43,62 @@ class EingangFilesRepository {
@Autowired
private MongoTemplate mongoTemplate;
private static final String DB_FIELDNAME_EINGANG_ID = "eingangs._id";
private static final String DB_FIELDNAME_EINGANGS = "eingangs";
private static final String DB_FIELDNAME_ATTACHMENTS = "attachments";
private static final String FIELD_EINGANG_ID = DB_FIELDNAME_EINGANGS + "._id";
private static final String DB_FIELDNAME_FILES = "files";
private static final String DB_FIELDNAME_REPRESENTATIONS = "representations";
private static final String FIELD_ATTACHMENT_FILES = DB_FIELDNAME_EINGANGS + ".attachments." + DB_FIELDNAME_FILES;
private static final String FIELD_REPRESENTATION_FILES = DB_FIELDNAME_EINGANGS + ".representations";
private static final String DB_FIELDNAME_FILE_ID = "id";
private static final String DB_FIELDNAME_FILE_NAME = "name";
private static final String DB_FIELDNAME_FILE_SIZE = "size";
private static final String DB_FIELDNAME_FILE_CONTENT_TYPE = "contentType";
public List<OzgFile> findAttachments(Optional<String> vorgangId, Optional<String> eingangId) {
return findFiles(buildSearchCriteria(vorgangId, eingangId), buildExtractAttachmentsAggregation());
}
public List<OzgFile> findAttachmentsByEingangId(String eingangId) {
private List<AggregationOperation> buildExtractAttachmentsAggregation() {
return List.of(
Aggregation.project().andExpression(FIELD_ATTACHMENT_FILES).as(DB_FIELDNAME_FILES), //
// extract 'files' from deeply nested arrays within 'eingangs[].attachments[].files[]' and promote each file to a separate document
// at the root level.
Aggregation.unwind(DB_FIELDNAME_FILES),
Aggregation.unwind(DB_FIELDNAME_FILES),
Aggregation.unwind(DB_FIELDNAME_FILES),
Aggregation.replaceRoot(DB_FIELDNAME_FILES)
);
}
List<AggregationOperation> operations = new ArrayList<>();
public List<OzgFile> findRepresentations(Optional<String> vorgangId, Optional<String> eingangId) {
return findFiles(buildSearchCriteria(vorgangId, eingangId), buildFindRepresentationsAggregation());
}
operations.add(Aggregation.match(new Criteria(DB_FIELDNAME_EINGANG_ID).is(eingangId)));
operations.addAll(buildFindAttachmentsAggregation());
operations.add(Aggregation.project(DB_FIELDNAME_FILE_ID, DB_FIELDNAME_FILE_NAME, DB_FIELDNAME_FILE_SIZE, DB_FIELDNAME_FILE_CONTENT_TYPE));
private Criteria buildSearchCriteria(Optional<String> vorgangId, Optional<String> eingangId) {
if (vorgangId.isEmpty()) {
return eingangId.map(this::buildIsEingangIdCriteria)
.orElseThrow(() -> new IllegalArgumentException("vorgangId or eingangId must be present"));
}
return eingangId.map(eid -> buildIsVorganIdAndEingangIdCriteria(vorgangId.get(), eid)).orElseGet(() -> CriteriaUtil.isId(vorgangId.get()));
}
return mongoTemplate.aggregate(Aggregation.newAggregation(operations), Vorgang.COLLECTION_NAME, OzgFile.class).getMappedResults();
private Criteria buildIsVorganIdAndEingangIdCriteria(String vorgangId, String eingangId) {
return new Criteria().andOperator(CriteriaUtil.isId(vorgangId), buildIsEingangIdCriteria(eingangId));
}
private List<AggregationOperation> buildFindAttachmentsAggregation() {
private Criteria buildIsEingangIdCriteria(String eingangId) {
return Criteria.where(FIELD_EINGANG_ID).is(eingangId);
}
private List<AggregationOperation> buildFindRepresentationsAggregation() {
return List.of(
Aggregation.project(DB_FIELDNAME_EINGANGS),
Aggregation.unwind(DB_FIELDNAME_EINGANGS),
Aggregation.replaceRoot(DB_FIELDNAME_EINGANGS),
Aggregation.project(DB_FIELDNAME_ATTACHMENTS),
Aggregation.unwind(DB_FIELDNAME_ATTACHMENTS),
Aggregation.replaceRoot(DB_FIELDNAME_ATTACHMENTS),
Aggregation.project(DB_FIELDNAME_FILES),
Aggregation.project().andExpression(FIELD_REPRESENTATION_FILES).as(DB_FIELDNAME_FILES),
// extract 'files' from deeply nested arrays within 'eingangs[].representations[]' and promote each file to a separate document at
// the root level.
Aggregation.unwind(DB_FIELDNAME_FILES),
Aggregation.unwind(DB_FIELDNAME_FILES),
Aggregation.replaceRoot(DB_FIELDNAME_FILES));
}
List<OzgFile> findRepresentationsByEingangId(String eingangId) {
private List<OzgFile> findFiles(Criteria criteria, List<AggregationOperation> extractOperations) {
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(new Criteria(DB_FIELDNAME_EINGANG_ID).is(eingangId)));
operations.addAll(buildFindRepresentationsAggregation());
operations.add(Aggregation.project(DB_FIELDNAME_FILE_ID, DB_FIELDNAME_FILE_NAME, DB_FIELDNAME_FILE_SIZE, DB_FIELDNAME_FILE_CONTENT_TYPE));
operations.add(Aggregation.match(criteria));
operations.addAll(extractOperations);
return mongoTemplate.aggregate(Aggregation.newAggregation(operations), Vorgang.COLLECTION_NAME, OzgFile.class).getMappedResults();
}
private List<AggregationOperation> buildFindRepresentationsAggregation() {
return List.of(
Aggregation.project(DB_FIELDNAME_EINGANGS),
Aggregation.unwind(DB_FIELDNAME_EINGANGS),
Aggregation.replaceRoot(DB_FIELDNAME_EINGANGS),
Aggregation.project(DB_FIELDNAME_REPRESENTATIONS),
Aggregation.unwind(DB_FIELDNAME_REPRESENTATIONS),
Aggregation.replaceRoot(DB_FIELDNAME_REPRESENTATIONS));
}
}
......@@ -52,25 +52,25 @@ public class FileService implements BinaryFileService {
@Autowired
private FileIdMapper fileIdMapper;
public List<OzgFile> getAttachments(String eingangId) {
return repository.findAttachmentsByEingangId(eingangId);
public List<OzgFile> getAttachments(Optional<String> vorgangId, Optional<String> eingangId) {
return repository.findAttachments(vorgangId, eingangId);
}
public List<OzgFile> getRepresentations(String eingangId) {
return repository.findRepresentationsByEingangId(eingangId);
public List<OzgFile> getRepresentations(Optional<String> vorgangId, Optional<String> eingangId) {
return repository.findRepresentations(vorgangId, eingangId);
}
public CompletableFuture<FileId> uploadFileStream(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) {
public FileId uploadFileStream(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) {
return uploadFile(ref, file, userId, content);
}
@Async
public CompletableFuture<FileId> uploadFileStreamAsync(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) {
return uploadFile(ref, file, userId, content);
return CompletableFuture.completedFuture(uploadFile(ref, file, userId, content));
}
CompletableFuture<FileId> uploadFile(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) {
return CompletableFuture.completedFuture(binaryFileRepository.addContentStream(ref, file, userId, content));
FileId uploadFile(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) {
return binaryFileRepository.addContentStream(ref, file, userId, content);
}
public InputStream getUploadedFileStream(FileId fileId) {
......
......@@ -24,7 +24,9 @@
package de.ozgcloud.vorgang.files;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import de.ozgcloud.vorgang.grpc.file.FileServiceGrpc.FileServiceImplBase;
......@@ -46,17 +48,33 @@ public class GrpcFileService extends FileServiceImplBase {
@Override
public void getAttachments(GrpcGetAttachmentsRequest request, StreamObserver<GrpcGetAttachmentsResponse> responseObserver) {
List<OzgFile> response = service.getAttachments(request.getEingangId());
List<OzgFile> response = service.getAttachments(getVorgangId(request), getEingangId(request));
responseObserver.onNext(GrpcGetAttachmentsResponse.newBuilder().addAllFile(fileMapper.map(response)).build());
responseObserver.onCompleted();
}
private Optional<String> getVorgangId(GrpcGetAttachmentsRequest request) {
return Optional.of(request.getVorgangId()).map(StringUtils::trimToNull);
}
private Optional<String> getEingangId(GrpcGetAttachmentsRequest request) {
return Optional.of(request.getEingangId()).map(StringUtils::trimToNull);
}
@Override
public void getRepresentations(GrpcGetRepresentationsRequest request, StreamObserver<GrpcGetRepresentationsResponse> responseObserver) {
List<OzgFile> response = service.getRepresentations(request.getEingangId());
List<OzgFile> response = service.getRepresentations(getVorgangId(request), getEingangId(request));
responseObserver.onNext(GrpcGetRepresentationsResponse.newBuilder().addAllFile(fileMapper.map(response)).build());
responseObserver.onCompleted();
}
private Optional<String> getVorgangId(GrpcGetRepresentationsRequest request) {
return Optional.of(request.getVorgangId()).map(StringUtils::trimToNull);
}
private Optional<String> getEingangId(GrpcGetRepresentationsRequest request) {
return Optional.of(request.getEingangId()).map(StringUtils::trimToNull);
}
}
......@@ -32,12 +32,7 @@ import org.mapstruct.NullValueCheckStrategy;
import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile;
// TODO rename to GrpcBinaryFileMapper
/**
* @deprecated will be renamed to GrpcBinaryFileMapper
*
*/
@Mapper(uses = FileIdMapper.class, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
@Deprecated(since = "0.25", forRemoval = true)
interface GrpcOzgFileMapper {
@Mapping(target = "mergeFrom", ignore = true)
......
......@@ -30,7 +30,6 @@ import static org.mockito.Mockito.*;
import java.io.InputStream;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import org.apache.http.entity.ContentType;
......@@ -196,7 +195,7 @@ class PersistPostfachNachrichtByCommandServiceTest {
class TestPersistAttachment {
@BeforeEach
void init() {
when(fileService.uploadFileStream(any(), any(), any(), any())).thenReturn(CompletableFuture.completedFuture(FileId.from("42")));
when(fileService.uploadFileStream(any(), any(), any(), any())).thenReturn(FileId.from("42"));
}
@DisplayName("Upload files Reference")
......
......@@ -26,6 +26,8 @@ package de.ozgcloud.vorgang.files;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
......@@ -61,16 +63,19 @@ class EingangFilesRepositoryITCase {
mongoOperations.save(createVorgang());
}
@Nested
class TestByEingangId {
@Test
void shouldHaveTwoAttachments() {
List<OzgFile> attachments = repository.findAttachmentsByEingangId(EingangTestFactory.ID);
var attachments = findAttachments();
assertThat(attachments).hasSize(2);
}
@Test
void validateFirstAttachment() {
OzgFile attachment = repository.findAttachmentsByEingangId(EingangTestFactory.ID).get(0);
OzgFile attachment = findAttachments().get(0);
assertThat(attachment.getId()).isEqualTo(IncomingFileTestFactory.ID);
assertThat(attachment.getName()).isEqualTo(IncomingFileTestFactory.NAME);
......@@ -79,10 +84,87 @@ class EingangFilesRepositoryITCase {
@Test
void validateSecondAttachment() {
OzgFile attachment = repository.findAttachmentsByEingangId(EingangTestFactory.ID).get(1);
var attachment = findAttachments().get(1);
assertThat(attachment.getId()).isEqualTo(ID2);
}
private List<OzgFile> findAttachments() {
return repository.findAttachments(Optional.empty(), Optional.of(EingangTestFactory.ID));
}
}
@Nested
class TestByVorgangId {
@Test
void shouldFindWhenOneEingang() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build());
var result = findAttachments(vorgang.getId());
assertThat(result).hasSize(1);
}
@Test
void shouldFindWhenManyEingangs() {
var vorang = mongoOperations.save(
VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().id(UUID.randomUUID().toString()).clearAttachments()
.attachment(IncomingFileGroupTestFactory.createBuilder().clearFiles().files(createTestFiles()).build())
.build())
.eingang(EingangTestFactory.createBuilder().id(UUID.randomUUID().toString()).clearAttachments()
.attachment(IncomingFileGroupTestFactory.create())
.attachment(IncomingFileGroupTestFactory.create())
.build())
.build());
var result = findAttachments(vorang.getId());
assertThat(result).hasSize(4);
}
@Test
void shouldReturnEmpty() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().clearAttachments().build()).build());
var result = findAttachments(vorgang.getId());
assertThat(result).isEmpty();
}
private List<OzgFile> findAttachments(String vorgangId) {
return repository.findAttachments(Optional.of(vorgangId), Optional.empty());
}
}
@Nested
class TestByVorgangIdAndEingangId {
@Test
void shouldReturnEmpty() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build());
var result = repository.findAttachments(Optional.ofNullable(vorgang.getId()), Optional.of("not-existing"));
assertThat(result).isEmpty();
}
@Test
void shouldFindAttachments() {
var eingangId = UUID.randomUUID().toString();
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().id(eingangId)
.attachment(IncomingFileGroupTestFactory.createBuilder().clearFiles().files(createTestFiles()).build())
.build())
.build());
var result = repository.findAttachments(Optional.ofNullable(vorgang.getId()), Optional.ofNullable(eingangId));
assertThat(result).hasSize(3);
}
}
}
@Nested
......@@ -96,16 +178,19 @@ class EingangFilesRepositoryITCase {
mongoOperations.save(vorgangWithRepresentations);
}
@Nested
class TestByEingangId {
@Test
void shouldHaveTwoRepresentations() {
List<OzgFile> representations = repository.findRepresentationsByEingangId(EingangTestFactory.ID);
List<OzgFile> representations = findRepresentations();
assertThat(representations).hasSize(2);
}
@Test
void validateFirstRepresentation() {
OzgFile representation = repository.findRepresentationsByEingangId(EingangTestFactory.ID).get(0);
OzgFile representation = findRepresentations().get(0);
assertThat(representation.getId()).isEqualTo(IncomingFileTestFactory.ID);
assertThat(representation.getName()).isEqualTo(IncomingFileTestFactory.NAME);
......@@ -114,12 +199,86 @@ class EingangFilesRepositoryITCase {
@Test
void validateSecondRepresentation() {
OzgFile representation = repository.findRepresentationsByEingangId(EingangTestFactory.ID).get(1);
OzgFile representation = findRepresentations().get(1);
assertThat(representation.getId()).isEqualTo(ID2);
assertThat(representation.getName()).isEqualTo(IncomingFileTestFactory.NAME);
assertThat(representation.getSize()).isEqualTo(IncomingFileTestFactory.SIZE);
}
private List<OzgFile> findRepresentations() {
return repository.findRepresentations(Optional.empty(), Optional.of(EingangTestFactory.ID));
}
}
@Nested
class TestByVorgangId {
@Test
void shouldFindWhenOneEingang() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build());
var result = findRepresentations(vorgang.getId());
assertThat(result).hasSize(1);
}
@Test
void shouldFindWhenManyEingangs() {
var vorang = mongoOperations.save(
VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().id(UUID.randomUUID().toString()).clearRepresentations()
.representation(IncomingFileTestFactory.create())
.representation(IncomingFileTestFactory.create())
.build())
.eingang(EingangTestFactory.createBuilder().id(UUID.randomUUID().toString()).clearRepresentations()
.representation(IncomingFileTestFactory.create())
.build())
.build());
var result = findRepresentations(vorang.getId());
assertThat(result).hasSize(3);
}
@Test
void shouldReturnEmpty() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().clearRepresentations().build()).build());
var result = findRepresentations(vorgang.getId());
assertThat(result).isEmpty();
}
private List<OzgFile> findRepresentations(String vorgangId) {
return repository.findRepresentations(Optional.of(vorgangId), Optional.empty());
}
}
@Nested
class TestByVorgangIdAndEingangId {
@Test
void shouldReturnEmpty() {
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build());
var result = repository.findAttachments(Optional.of(vorgang.getId()), Optional.of("not-existing"));
assertThat(result).isEmpty();
}
@Test
void shouldFindRepresentations() {
var eingangId = UUID.randomUUID().toString();
var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).clearEingangs()
.eingang(EingangTestFactory.createBuilder().id(eingangId).representation(IncomingFileTestFactory.create()).build()).build());
var result = repository.findRepresentations(Optional.ofNullable(vorgang.getId()), Optional.ofNullable(eingangId));
assertThat(result).hasSize(2);
}
}
}
private Vorgang createVorgang() {
......
......@@ -83,7 +83,16 @@ class FileITCase {
private StreamObserver<GrpcGetAttachmentsResponse> responseObserver;
@Captor
private ArgumentCaptor<GrpcGetAttachmentsResponse> responseCaptor;
private GrpcGetAttachmentsRequest request = GrpcGetAttachmentsRequestTestFactory.create();
private GrpcGetAttachmentsRequest request;
@Nested
class TestByEingangId {
@BeforeEach
void init() {
request = GrpcGetAttachmentsRequestTestFactory.createBuilder().clearVorgangId().build();
}
@Test
void getAttachmentsShouldReturnNonEmptyGrpcResponse() {
......@@ -118,9 +127,44 @@ class FileITCase {
void validateSecondAttachmentFileContent() {
callServiceGetAttachments();
var attachment1 = responseCaptor.getValue().getFile(1);
var attachment2 = responseCaptor.getValue().getFile(1);
assertThat(attachment1.getId()).isEqualTo(ID2.toString());
assertThat(attachment2.getId()).isEqualTo(ID2.toString());
}
}
@Nested
class TestByVorgangId {
@BeforeEach
void init() {
request = GrpcGetAttachmentsRequestTestFactory.createBuilder().clearEingangId().build();
}
@Test
void shouldGetAttachments() {
callServiceGetAttachments();
verify(responseObserver).onNext(responseCaptor.capture());
assertThat(responseCaptor.getValue().getFileCount()).isEqualTo(2);
}
}
@Nested
class TestByVorgangAndEingangId {
@BeforeEach
void init() {
request = GrpcGetAttachmentsRequestTestFactory.create();
}
@Test
void shouldGetAttachments() {
callServiceGetAttachments();
verify(responseObserver).onNext(responseCaptor.capture());
assertThat(responseCaptor.getValue().getFileCount()).isEqualTo(2);
}
}
private void callServiceGetAttachments() {
......@@ -137,7 +181,7 @@ class FileITCase {
private StreamObserver<GrpcGetRepresentationsResponse> responseObserver;
@Captor
private ArgumentCaptor<GrpcGetRepresentationsResponse> responseCaptor;
private GrpcGetRepresentationsRequest request = GrpcGetRepresentationsRequestTestFactory.create();
private final GrpcGetRepresentationsRequest request = GrpcGetRepresentationsRequestTestFactory.create();
@Test
void getRepresentationsShouldReturnNonEmptyGrpcResponse() {
......
......@@ -31,8 +31,8 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
......@@ -42,6 +42,7 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.vorgang.vorgang.EingangTestFactory;
import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory;
import de.ozgcloud.vorgang.vorgang.VorgangTestFactory;
......@@ -111,9 +112,8 @@ class FileServiceTest {
}
@Test
void shouldReturnId() throws Exception {
var id = service.uploadFileStream(ref, file, user, contentStream).get(5,
TimeUnit.SECONDS);
void shouldReturnId() {
var id = service.uploadFileStream(ref, file, user, contentStream);
assertThat(id).isEqualTo(IncomingFileTestFactory.ID);
}
......@@ -133,7 +133,7 @@ class FileServiceTest {
@Nested
class TestFindFilesMetaData {
private Collection<FileId> ids = Collections.singleton(OzgFileTestFactory.ID);
private final Collection<FileId> ids = Collections.singleton(OzgFileTestFactory.ID);
@BeforeEach
void mockFileMapper() {
......@@ -164,4 +164,46 @@ class FileServiceTest {
verify(binaryFileRepository).deleteAllByVorgang(VorgangTestFactory.ID);
}
}
@Nested
class TestGetAttachments {
@Test
void shouldCallFindAttachments() {
service.getAttachments(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
verify(repository).findAttachments(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
}
@Test
void shouldReturnAttachmentsByVorgangIdAndEingangId() {
var attachment = OzgFileTestFactory.create();
when(repository.findAttachments(any(), any())).thenReturn(List.of(attachment));
var result = service.getAttachments(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
assertThat(result).containsExactly(attachment);
}
}
@Nested
class TestGetRepresentations {
@Test
void shouldCallFindRepresentations() {
service.getRepresentations(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
verify(repository).findRepresentations(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
}
@Test
void shouldReturnRepresentationsByVorgangIdAndEingangId() {
var representation = OzgFileTestFactory.create();
when(repository.findRepresentations(any(), any())).thenReturn(List.of(representation));
var result = service.getRepresentations(Optional.of(VorgangTestFactory.ID), Optional.ofNullable(EingangTestFactory.ID));
assertThat(result).containsExactly(representation);
}
}
}
\ No newline at end of file
/*
* Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.vorgang.files;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsResponse;
import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsResponse;
import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile;
import io.grpc.stub.StreamObserver;
class GrpcFileServiceTest {
private static final GrpcOzgFile GRPC_OZG_FILE = GrpcOzgFileTestFactory.create();
@InjectMocks
private GrpcFileService grpcFileService;
@Mock
private FileService fileService;
@Mock
private GrpcOzgFileMapper fileMapper;
@BeforeEach
void init() {
when(fileMapper.map(anyList())).thenReturn(List.of(GRPC_OZG_FILE));
}
@Nested
class TestGetAttachments {
@Mock
private StreamObserver<GrpcGetAttachmentsResponse> responseObserver;
@Captor
private ArgumentCaptor<GrpcGetAttachmentsResponse> responseCaptor;
@Test
void shouldCallGetAttachments() {
getAttachments();
verify(fileService).getAttachments(Optional.ofNullable(GrpcGetAttachmentsRequestTestFactory.VORGANG_ID),
Optional.ofNullable(GrpcGetAttachmentsRequestTestFactory.EINGANG_ID));
}
@Test
void shouldCallFileMapper() {
var ozgFiles = List.of(OzgFileTestFactory.create());
when(fileService.getAttachments(any(), any())).thenReturn(ozgFiles);
getAttachments();
verify(fileMapper).map(ozgFiles);
}
@Test
void shouldAddFilesToResponse() {
getAttachments();
verify(responseObserver).onNext(responseCaptor.capture());
assertThat(responseCaptor.getValue().getFileList()).containsExactly(GRPC_OZG_FILE);
}
@Test
void shouldCallCompleted() {
getAttachments();
verify(responseObserver).onCompleted();
}
private void getAttachments() {
grpcFileService.getAttachments(GrpcGetAttachmentsRequestTestFactory.create(), responseObserver);
}
}
@Nested
class TestGetRepresentations {
@Mock
private StreamObserver<GrpcGetRepresentationsResponse> responseObserver;
@Captor
private ArgumentCaptor<GrpcGetRepresentationsResponse> responseCaptor;
@Test
void shouldCallGetRepresentations() {
getRepresentations();
verify(fileService).getRepresentations(Optional.of(GrpcGetRepresentationsRequestTestFactory.VORGANG_ID),
Optional.of(GrpcGetRepresentationsRequestTestFactory.EINGANG_ID));
}
@Test
void shouldCallFileMapper() {
var ozgFiles = List.of(OzgFileTestFactory.create());
when(fileService.getRepresentations(any(), any())).thenReturn(ozgFiles);
getRepresentations();
verify(fileMapper).map(ozgFiles);
}
@Test
void shouldAddFilesToResponse() {
getRepresentations();
verify(responseObserver).onNext(responseCaptor.capture());
assertThat(responseCaptor.getValue().getFileList()).containsExactly(GRPC_OZG_FILE);
}
@Test
void shouldCallCompleted() {
getRepresentations();
verify(responseObserver).onCompleted();
}
private void getRepresentations() {
grpcFileService.getRepresentations(GrpcGetRepresentationsRequestTestFactory.create(), responseObserver);
}
}
}
\ No newline at end of file
......@@ -25,9 +25,11 @@ package de.ozgcloud.vorgang.files;
import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest;
import de.ozgcloud.vorgang.vorgang.EingangTestFactory;
import de.ozgcloud.vorgang.vorgang.VorgangTestFactory;
public class GrpcGetAttachmentsRequestTestFactory {
public static final String VORGANG_ID = VorgangTestFactory.ID;
public static final String EINGANG_ID = EingangTestFactory.ID;
public static GrpcGetAttachmentsRequest create() {
......@@ -36,6 +38,7 @@ public class GrpcGetAttachmentsRequestTestFactory {
public static GrpcGetAttachmentsRequest.Builder createBuilder() {
return GrpcGetAttachmentsRequest.newBuilder()
.setEingangId(EINGANG_ID);
.setEingangId(EINGANG_ID)
.setVorgangId(VORGANG_ID);
}
}
......@@ -25,10 +25,12 @@ package de.ozgcloud.vorgang.files;
import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest;
import de.ozgcloud.vorgang.vorgang.EingangTestFactory;
import de.ozgcloud.vorgang.vorgang.VorgangTestFactory;
public class GrpcGetRepresentationsRequestTestFactory {
public static final String EINGANG_ID = EingangTestFactory.ID;
public static final String VORGANG_ID = VorgangTestFactory.ID;
public static GrpcGetRepresentationsRequest create() {
return createBuilder().build();
......@@ -36,6 +38,7 @@ public class GrpcGetRepresentationsRequestTestFactory {
public static GrpcGetRepresentationsRequest.Builder createBuilder() {
return GrpcGetRepresentationsRequest.newBuilder()
.setEingangId(EINGANG_ID);
.setEingangId(EINGANG_ID)
.setVorgangId(VORGANG_ID);
}
}
/*
* Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.vorgang.files;
import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile;
public class GrpcOzgFileTestFactory {
public static GrpcOzgFile create() {
return createBuilder().build();
}
public static GrpcOzgFile.Builder createBuilder() {
return GrpcOzgFile.newBuilder()
.setId(OzgFileTestFactory.ID.toString())
.setName(OzgFileTestFactory.NAME)
.setSize(OzgFileTestFactory.SIZE)
.setContentType(OzgFileTestFactory.CONTENT_TYPE);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment