diff --git a/bescheid-manager/pom.xml b/bescheid-manager/pom.xml index 5f5e43c0d1204185e1f1473897ea2e7d76babb0e..07ca67426a2042ed3f702a4c3ef65e621c984e13 100644 --- a/bescheid-manager/pom.xml +++ b/bescheid-manager/pom.xml @@ -15,7 +15,7 @@ <version>1.10.0-SNAPSHOT</version> <properties> - <vorgang-manager.version>2.5.0</vorgang-manager.version> + <vorgang-manager.version>2.6.0-SNAPSHOT</vorgang-manager.version> <api-lib.version>0.7.0-SNAPSHOT</api-lib.version> </properties> diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java index fb1cce79ca8b440566661cede1b0ff50cc4036d8..84d0d11a5d44d852abf7d4e2ea7c027a8cc946be 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java @@ -17,7 +17,7 @@ class BescheidGrpcService extends BescheidServiceImplBase { @Override public void getBescheidDraft(GrpcGetBescheidDraftRequest request, StreamObserver<GrpcGetBescheidDraftResponse> responseObserver) { - var response = attachedItemService.getBescheidItem(request.getVorgangId()) + var response = attachedItemService.findBescheidItem(request.getVorgangId()) .map(this::buildResponse) .orElseGet(GrpcGetBescheidDraftResponse::getDefaultInstance); diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItem.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItem.java new file mode 100644 index 0000000000000000000000000000000000000000..f2ba902117c7b2b566957955d9c0a1591cbc5e0f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItem.java @@ -0,0 +1,52 @@ +/* + * 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.bescheid.attacheditem; + +import java.util.Map; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class AttachedItem { + + public static final String PROPERTY_ID = "id"; + public static final String PROPERTY_CLIENT = "client"; + public static final String PROPERTY_VORGANG_ID = "vorgangId"; + public static final String PROPERTY_ITEM_NAME = "itemName"; + public static final String PROPERTY_VERSION = "version"; + public static final String PROPERTY_ITEM = "item"; + + private String id; + @Builder.Default + private long version = 0L; + + private String client; + private String vorgangId; + private String itemName; + + private Map<String, Object> item; + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..c2b373a33138cc4df45ea98c5f516921713f4863 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapper.java @@ -0,0 +1,36 @@ +/* + * 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.bescheid.attacheditem; + +import org.mapstruct.Mapper; + +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItem; + +@Mapper(uses = { GrpcObjectMapper.class}) +interface AttachedItemMapper { + + AttachedItem mapFromVorgangAttachedItem(GrpcVorgangAttachedItem item); + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java index 5362b2a489b9616f9ecb606446ea1f713e9ecb7e..53e246ff9d1e9d293badd27fdca83e97771977ae 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java @@ -48,7 +48,6 @@ import lombok.extern.log4j.Log4j2; public class AttachedItemService { static final String BESCHEID_ITEM_NAME = "Bescheid"; - static final String BESCHEID_DRAFT_STATUS = "DRAFT"; static final String CREATE_ATTACHED_ITEM_ORDER = "CREATE_ATTACHED_ITEM"; static final String UPDATE_ATTACHED_ITEM_ORDER = "UPDATE_ATTACHED_ITEM"; static final String DELETE_ATTACHED_ITEM = "DELETE_ATTACHED_ITEM"; @@ -59,10 +58,14 @@ public class AttachedItemService { private final VorgangAttachedItemRemoteService remoteService; private final CommandMapper commandMapper; - public Optional<BescheidItem> getBescheidItem(String vorgangId) { + public Optional<BescheidItem> findBescheidItem(String vorgangId) { return remoteService.findBescheidDraft(vorgangId); } + public BescheidItem getBescheidItem(String id) { + return remoteService.getBescheid(id); + } + public String createBescheidDraft(Command command) { validateBescheidData(command.getBodyObject()); return remoteService.findBescheidDraft(command.getVorgangId()) @@ -129,7 +132,7 @@ public class AttachedItemService { Map<String, Object> buildItemMapWithExistingBescheidFields(Command command) { var result = new HashMap<String, Object>(); - result.put(BescheidItem.FIELD_STATUS, BESCHEID_DRAFT_STATUS); + result.put(BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT.name()); addValueFromMapIfExists(command.getBodyObject(), BescheidItem.FIELD_BESCHIEDEN_AM, result); addValueFromMapIfExists(command.getBodyObject(), BescheidItem.FIELD_BEWILLIGT, result); addValueFromMapIfExists(command.getBodyObject(), BescheidItem.FIELD_BESCHEID_DOCUMENT, result); @@ -168,7 +171,7 @@ public class AttachedItemService { void validateBescheidStatus(BescheidItem bescheid) { var bescheidStatus = MapUtils.getString(bescheid.getBescheidData(), BescheidItem.FIELD_STATUS); - if (!BESCHEID_DRAFT_STATUS.equals(bescheidStatus)) { + if (BescheidItem.Status.DRAFT.not(bescheidStatus)) { throw new TechnicalException("Bescheid draft with ID '%s' has an unexpected status: '%s'".formatted(bescheid.getId(), bescheidStatus)); } } @@ -182,4 +185,7 @@ public class AttachedItemService { .build(); } + public AttachedItem getItem(String id) { + return remoteService.getItem(id); + } } diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItem.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItem.java index 57d6eac58ed8fe7681dbf4e28500d8ca53871205..4bc85092889c6449e0ed12193079734cc6e78459 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItem.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItem.java @@ -31,6 +31,7 @@ import lombok.Getter; @Builder(toBuilder = true) @Getter +@Deprecated(since = "2.6.0") public class BescheidItem { static final Set<String> ACCEPTED_SEND_BY_VALUES = Set.of("POSTFACH", "MANUAL"); @@ -60,4 +61,16 @@ public class BescheidItem { private String itemName; private Map<String, Object> bescheidData; + + public enum Status { + DRAFT, BESCHEID; + + public boolean not(String value) { + return !hasValue(value); + } + + public boolean hasValue(String value) { + return this.name().equalsIgnoreCase(value); + } + } } diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItemMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItemMapper.java index ff92f8c2f43b6525dbac9a44db3e573c4931e62e..2c915d65d934abab2636433b02e30a1eaf8e764d 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItemMapper.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/BescheidItemMapper.java @@ -42,6 +42,7 @@ import lombok.RequiredArgsConstructor; @Component @RequiredArgsConstructor +@Deprecated(since = "2.6.0") public class BescheidItemMapper { private final GrpcObjectMapper grpcObjectMapper; diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteService.java index 192f16e46ab7308c6230b208e88bbdb8093674ce..aa6709149d8d968e263c86e0197e281ff99c3a8e 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteService.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteService.java @@ -57,6 +57,8 @@ class VorgangAttachedItemRemoteService { private ClientInterceptor bescheidCallContextInterceptor; @Autowired private BescheidItemMapper bescheidItemMapper; + @Autowired + private AttachedItemMapper attachedItemMapper; public Optional<BescheidItem> findBescheidDraft(String vorgangId) { return findBescheidDraft(buildFindRequest(vorgangId)); @@ -72,14 +74,17 @@ class VorgangAttachedItemRemoteService { Optional<BescheidItem> findBescheidDraft(GrpcFindVorgangAttachedItemRequest request) { var grpcResponse = getServiceStub().find(request); - var bescheidItems = bescheidItemMapper.fromFindVorgangAttachedItemResponse(grpcResponse) - .filter(item -> BESCHEID_DRAFT_STATUS.equals(MapUtils.getString(item.getBescheidData(), BescheidItem.FIELD_STATUS))) + var bescheidItems = bescheidItemMapper.fromFindVorgangAttachedItemResponse(grpcResponse).filter(this::hasStatusDraft) .sorted(BY_BESCHIEDEN_AM_DESC).toList(); if (bescheidItems.size() > 1) { LOG.error("Found more than one ({}) draft bescheid for vorgangId: {}. Return one with last beschiedenAm date", bescheidItems.size(), - bescheidItems.get(0).getVorgangId()); + bescheidItems.getFirst().getVorgangId()); } - return bescheidItems.isEmpty() ? Optional.empty() : Optional.of(bescheidItems.get(0)); + return bescheidItems.isEmpty() ? Optional.empty() : Optional.of(bescheidItems.getFirst()); + } + + boolean hasStatusDraft(BescheidItem bescheidItem) { + return BescheidItem.Status.DRAFT.hasValue(MapUtils.getString(bescheidItem.getBescheidData(), BescheidItem.FIELD_STATUS)); } public BescheidItem getBescheid(String bescheidId) { @@ -87,6 +92,11 @@ class VorgangAttachedItemRemoteService { return bescheidItemMapper.mapFromVorgangAttachedItem(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()); } + public AttachedItem getItem(String id) { + var grpcVorgangAttachedItemResponse = getServiceStub().getById(buildGetByIdRequest(id)); + return attachedItemMapper.mapFromVorgangAttachedItem(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()); + } + GrpcVorgangAttachedItemRequest buildGetByIdRequest(String bescheidId) { return GrpcVorgangAttachedItemRequest.newBuilder().setId(bescheidId).build(); } diff --git a/bescheid-manager/src/main/java/de/ozgcloud/document/Document.java b/bescheid-manager/src/main/java/de/ozgcloud/document/Document.java new file mode 100644 index 0000000000000000000000000000000000000000..fc0d09b53f1d9cbc4d3792dca94c429f46d3e5e1 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/document/Document.java @@ -0,0 +1,44 @@ +/* + * 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.document; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class Document { + + public static final String FIELD_DOCUMENT_TYPE = "type"; + public static final String FIELD_DOCUMENT_FILE = "documentFile"; + public static final String FIELD_NACHRICHT_TEXT = "nachrichtText"; + public static final String FIELD_NACHRICHT_SUBJECT = "nachrichtSubject"; + + private String id; + private String type; + private String fileId; + private String nachrichtSubject; + private String nachrichtText; + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentGrpcService.java b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentGrpcService.java new file mode 100644 index 0000000000000000000000000000000000000000..673935d696777f3708fafbe134a8a496541b0d02 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentGrpcService.java @@ -0,0 +1,48 @@ +/* + * 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.document; + +import de.ozgcloud.document.DocumentServiceGrpc.DocumentServiceImplBase; +import io.grpc.stub.StreamObserver; +import lombok.RequiredArgsConstructor; +import net.devh.boot.grpc.server.service.GrpcService; + +@GrpcService +@RequiredArgsConstructor +public class DocumentGrpcService extends DocumentServiceImplBase { + + private final DocumentService documentService; + private final DocumentMapper documentMapper; + + @Override + public void getDocument(GrpcGetDocumentRequest request, StreamObserver<GrpcGetDocumentResponse> responseObserver) { + var document = documentService.getDocument(request.getId()); + responseObserver.onNext(buildGetDocumentResponse(document)); + responseObserver.onCompleted(); + } + + GrpcGetDocumentResponse buildGetDocumentResponse(Document document) { + return GrpcGetDocumentResponse.newBuilder().setDocument(documentMapper.toGrpcDocument(document)).build(); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..41180bab88ef3c302300bd1e51ca34e3ed89619b --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentMapper.java @@ -0,0 +1,58 @@ +/* + * 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.document; + +import org.apache.commons.collections.MapUtils; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; + +import de.ozgcloud.bescheid.attacheditem.AttachedItem; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +interface DocumentMapper { + + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "typeBytes", ignore = true) + @Mapping(target = "nachrichtTextBytes", ignore = true) + @Mapping(target = "nachrichtSubjectBytes", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "idBytes", ignore = true) + @Mapping(target = "fileIdBytes", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "clearField", ignore = true) + GrpcDocument toGrpcDocument(Document document); + + default Document fromAttachedItem(AttachedItem attachedItem) { + return Document.builder() + .id(attachedItem.getId()) + .type(MapUtils.getString(attachedItem.getItem(), Document.FIELD_DOCUMENT_TYPE)) + .fileId(MapUtils.getString(attachedItem.getItem(), Document.FIELD_DOCUMENT_FILE)) + .nachrichtText(MapUtils.getString(attachedItem.getItem(), Document.FIELD_NACHRICHT_TEXT)) + .nachrichtSubject(MapUtils.getString(attachedItem.getItem(), Document.FIELD_NACHRICHT_SUBJECT)) + .build(); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentService.java b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentService.java index 1846fb93799c2b8dedffc2f3baa2c57f1e2d587a..f290e57572d8bf1a95a9dec9a8b54671a6b179c8 100644 --- a/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentService.java +++ b/bescheid-manager/src/main/java/de/ozgcloud/document/DocumentService.java @@ -27,12 +27,14 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; +import org.apache.commons.collections.MapUtils; import org.springframework.stereotype.Service; import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommandService; import de.ozgcloud.apilib.common.command.grpc.CommandMapper; import de.ozgcloud.bescheid.BescheidCallContextAttachingInterceptor; +import de.ozgcloud.bescheid.attacheditem.AttachedItemService; import de.ozgcloud.bescheid.attacheditem.BescheidItem; import de.ozgcloud.command.Command; import de.ozgcloud.common.errorhandling.TechnicalException; @@ -42,26 +44,38 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class DocumentService { + public static final String DOCUMENT_ITEM_NAME = "Document"; + public static final String DOCUMENT_TYPE = "BESCHEID"; + static final String CREATE_ATTACHED_ITEM_ORDER = "CREATE_ATTACHED_ITEM"; - static final String DOCUMENT_ITEM_NAME = "Document"; static final String FIELD_DOCUMENT_TYPE = "type"; - static final String DOCUMENT_TYPE = "BESCHEID"; static final String FIELD_DOCUMENT_FILE = "documentFile"; + private final AttachedItemService attachedItemService; private final OzgCloudCommandService commandService; private final CommandMapper commandMapper; + private final DocumentMapper documentMapper; public String createBescheidDocument(Command command) { + validateBescheidItem(command.getRelationId()); var ozgCloudCommand = buildCreateDocumentOzgCommand(command); var executedCommand = commandService.createAndWaitUntilDone(ozgCloudCommand); return executedCommand.getCreatedResource(); } + void validateBescheidItem(String bescheidId) { + var bescheidData = attachedItemService.getBescheidItem(bescheidId).getBescheidData(); + var status = MapUtils.getString(bescheidData, BescheidItem.FIELD_STATUS); + if (BescheidItem.Status.DRAFT.not(status)) { + throw new TechnicalException("Bescheid is not in draft status"); + } + } + OzgCloudCommand buildCreateDocumentOzgCommand(Command command) { return OzgCloudCommand.builder() .order(CREATE_ATTACHED_ITEM_ORDER) .vorgangId(commandMapper.toOzgCloudVorgangId(command.getVorgangId())) - .relationId(commandMapper.mapRelationId(command.getRelationId())) + .relationId(commandMapper.mapRelationId(command.getVorgangId())) .bodyObject(buildAttachedItem(command)) .build(); } @@ -81,4 +95,7 @@ public class DocumentService { return Map.of(FIELD_DOCUMENT_TYPE, DOCUMENT_TYPE, FIELD_DOCUMENT_FILE, fileId); } + public Document getDocument(String id) { + return documentMapper.fromAttachedItem(attachedItemService.getItem(id)); + } } diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java index 9cb416ff02f582ac1b8d6e535ab583fb704a661f..4d965a689be4c55ce1a9909c85fa8e013eb2da7e 100644 --- a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java @@ -45,7 +45,7 @@ class BescheidGrpcServiceTest { @Test void shouldBuildResponse() { when(mapper.toBescheid(any())).thenReturn(GrpcBescheidTestFactory.create()); - when(attachedItemService.getBescheidItem(any())).thenReturn(Optional.of(BescheidItemTestFactory.create())); + when(attachedItemService.findBescheidItem(any())).thenReturn(Optional.of(BescheidItemTestFactory.create())); service.getBescheidDraft(request, responseObserver); @@ -56,7 +56,7 @@ class BescheidGrpcServiceTest { void shouldCallNext() { when(mapper.toBescheid(any())).thenReturn(GrpcBescheidTestFactory.create()); when(service.buildResponse(any())).thenReturn(response); - when(attachedItemService.getBescheidItem(any())).thenReturn(Optional.of(BescheidItemTestFactory.create())); + when(attachedItemService.findBescheidItem(any())).thenReturn(Optional.of(BescheidItemTestFactory.create())); service.getBescheidDraft(request, responseObserver); diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapperTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..782c98d8cc4bc4066b43d34e9a45334d724ca7d5 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemMapperTest.java @@ -0,0 +1,61 @@ +/* + * 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.bescheid.attacheditem; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.document.DocumentService; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; + +class AttachedItemMapperTest { + + @InjectMocks + private AttachedItemMapper mapper = Mappers.getMapper(AttachedItemMapper.class); + + @Mock + private GrpcObjectMapper grpcObjectMapper; + + @BeforeEach + void init() { + when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(AttachedItemTestFactory.createDocumentItem()); + } + + @Test + void shouldMapFromVorgangAttachedItem() { + var grpcVorgangAttachedItem = GrpcVorgangAttachedItemTestFactory.createBuilder().setItemName(DocumentService.DOCUMENT_ITEM_NAME) + .setVersion(AttachedItemTestFactory.VERSION).build(); + + var result = mapper.mapFromVorgangAttachedItem(grpcVorgangAttachedItem); + + assertThat(result).usingRecursiveComparison().isEqualTo(AttachedItemTestFactory.createDocument()); + } + +} \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemServiceTest.java index d81c4212494dea994091fafc85cc78f8d1b56ee7..107f4e3caa00e1fde61ad8d7b14bad6e0e62eb79 100644 --- a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemServiceTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemServiceTest.java @@ -72,7 +72,7 @@ class AttachedItemServiceTest { @Test void shouldCallGetBescheidDraft() { - service.getBescheidItem(CommandTestFactory.VORGANG_ID); + service.findBescheidItem(CommandTestFactory.VORGANG_ID); verify(remoteService).findBescheidDraft(CommandTestFactory.VORGANG_ID); } @@ -82,12 +82,33 @@ class AttachedItemServiceTest { var expected = BescheidItemTestFactory.create(); when(remoteService.findBescheidDraft(anyString())).thenReturn(Optional.of(expected)); - var actual = service.getBescheidItem(CommandTestFactory.VORGANG_ID); + var actual = service.findBescheidItem(CommandTestFactory.VORGANG_ID); assertThat(actual).contains(expected); } } + @Nested + class TestGetBescheidItem { + + @Test + void shouldCallGetBescheid() { + service.getBescheidItem(BescheidItemTestFactory.ID); + + verify(remoteService).getBescheid(BescheidItemTestFactory.ID); + } + + @Test + void shouldReturnBescheidItem() { + var expected = BescheidItemTestFactory.create(); + when(remoteService.getBescheid(anyString())).thenReturn(expected); + + var actual = service.getBescheidItem(BescheidItemTestFactory.ID); + + assertThat(actual).isEqualTo(expected); + } + } + @Nested class TestCreateBescheidDraft { @@ -484,7 +505,7 @@ class AttachedItemServiceTest { void shouldSetStatus() { var bescheidMap = service.buildItemMapWithExistingBescheidFields(command); - assertThat(bescheidMap).containsEntry(BescheidItem.FIELD_STATUS, AttachedItemService.BESCHEID_DRAFT_STATUS); + assertThat(bescheidMap).containsEntry(BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT.name()); } @Test @@ -706,4 +727,25 @@ class AttachedItemServiceTest { } } + + @Nested + class TestGetItem { + + @Test + void shouldCallRemoteService() { + service.getItem(BescheidItemTestFactory.ID); + + verify(service).getItem(BescheidItemTestFactory.ID); + } + + @Test + void shouldReturnValue() { + var expectedItem = AttachedItemTestFactory.createDocument(); + doReturn(expectedItem).when(remoteService).getItem(any()); + + var result = service.getItem(BescheidItemTestFactory.ID); + + assertThat(result).isEqualTo(expectedItem); + } + } } \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..56fb0e8ad3050b0dc143f888671c4ef9c59bb8f2 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/AttachedItemTestFactory.java @@ -0,0 +1,95 @@ +/* + * 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.bescheid.attacheditem; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import de.ozgcloud.bescheid.attacheditem.AttachedItem.AttachedItemBuilder; +import de.ozgcloud.command.CommandTestFactory; +import de.ozgcloud.document.Document; +import de.ozgcloud.document.DocumentService; +import de.ozgcloud.document.DocumentTestFactory; + +public class AttachedItemTestFactory { + + public static final String ID = "bescheid-item-id"; + public static final long VERSION = 10L; + public static final String CLIENT = "client"; + + public static final String BESCHEIDEN_AM = "2024-01-01"; + public static final String BESCHEID_DOCUMENT = "bescheid-document"; + public static final String ATTACHMENT = "attachment-id"; + public static final String SEND_BY = "POSTFACH"; + public static final String NACHRICHT_TEXT = "nachricht-text"; + public static final String NACHRICHT_SUBJECT = "nachricht-subject"; + + public static AttachedItem createBescheid() { + return createBuilder() + .itemName(AttachedItemService.BESCHEID_ITEM_NAME) + .item(createBescheidItem()) + .build(); + } + + public static Map<String, Object> createBescheidItem() { + return Map.of( + BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT, + BescheidItem.FIELD_BESCHIEDEN_AM, BESCHEIDEN_AM, + BescheidItem.FIELD_BEWILLIGT, true, + BescheidItem.FIELD_BESCHEID_DOCUMENT, BESCHEID_DOCUMENT, + BescheidItem.FIELD_ATTACHMENTS, List.of(ATTACHMENT), + BescheidItem.FIELD_SEND_BY, SEND_BY, + BescheidItem.FIELD_NACHRICHT_TEXT, NACHRICHT_TEXT, + BescheidItem.FIELD_NACHRICHT_SUBJECT, NACHRICHT_SUBJECT); + } + + public static AttachedItem createDocument() { + return createDocumentBuilder().build(); + } + + public static AttachedItem.AttachedItemBuilder createDocumentBuilder() { + return createBuilder() + .itemName(DocumentService.DOCUMENT_ITEM_NAME) + .item(createDocumentItem()); + } + + public static HashMap<String, Object> createDocumentItem() { + var map = new HashMap<String, Object>(); + map.put(Document.FIELD_DOCUMENT_TYPE, DocumentService.DOCUMENT_TYPE); + map.put(Document.FIELD_DOCUMENT_FILE, DocumentTestFactory.DOCUMENT_FILE); + map.put(Document.FIELD_NACHRICHT_TEXT, DocumentTestFactory.NACHRICHT_TEXT); + map.put(Document.FIELD_NACHRICHT_SUBJECT, DocumentTestFactory.NACHRICHT_SUBJECT); + return map; + } + + public static AttachedItemBuilder createBuilder() { + return AttachedItem.builder() + .id(ID) + .version(VERSION) + .client(CLIENT) + .vorgangId(CommandTestFactory.VORGANG_ID); + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/BescheidItemTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/BescheidItemTestFactory.java index b053862753311d75651238ead6f5ae4492b6a124..1299edf5394b1d9a8ec0d804663dbd450b3d741c 100644 --- a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/BescheidItemTestFactory.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/BescheidItemTestFactory.java @@ -58,7 +58,7 @@ public class BescheidItemTestFactory { public static Map<String, Object> createBescheidBody() { return Map.of( - BescheidItem.FIELD_STATUS, AttachedItemService.BESCHEID_DRAFT_STATUS, + BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT, BescheidItem.FIELD_BESCHIEDEN_AM, BESCHEIDEN_AM, BescheidItem.FIELD_BEWILLIGT, true, BescheidItem.FIELD_BESCHEID_DOCUMENT, BESCHEID_DOCUMENT, diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteServiceTest.java index 257cbc65ee52e8660fa93be4912f321e01d8089e..444249e06cc391cd8b6d05304ab33f93134cb899 100644 --- a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteServiceTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/attacheditem/VorgangAttachedItemRemoteServiceTest.java @@ -26,7 +26,6 @@ package de.ozgcloud.bescheid.attacheditem; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Map; @@ -51,7 +50,6 @@ import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; import de.ozgcloud.vorgang.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceBlockingStub; import io.grpc.ClientInterceptor; -import io.grpc.StatusRuntimeException; class VorgangAttachedItemRemoteServiceTest { @@ -67,6 +65,8 @@ class VorgangAttachedItemRemoteServiceTest { private ClientInterceptor bescheidCallContextInterceptor; @Mock private BescheidItemMapper bescheidItemMapper; + @Mock + private AttachedItemMapper attachedItemMapper; @Nested class TestFindBescheidDraft { @@ -130,11 +130,40 @@ class VorgangAttachedItemRemoteServiceTest { verify(bescheidItemMapper).fromFindVorgangAttachedItemResponse(response); } + @Test + void shouldCallHasStatusDraft() { + var item = BescheidItemTestFactory.create(); + when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.of(item)); + + service.findBescheidDraft(request); + + verify(service).hasStatusDraft(item); + } + @Test void shouldFilterDraftItems() { - var item1 = BescheidItemTestFactory.createBuilder().bescheidData(Map.of( - BescheidItem.FIELD_STATUS, "other")).build(); - when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.of(item1)); + var item = BescheidItemTestFactory.create(); + when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.of(item)); + doReturn(true).when(service).hasStatusDraft(any()); + + var result = service.findBescheidDraft(request); + + assertThat(result).contains(item); + } + + @Test + void shouldReturnEmptyWhenNotFound() { + when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.empty()); + + var result = service.findBescheidDraft(request); + + assertThat(result).isEmpty(); + } + + @Test + void shouldReturnEmptyWhenNotDraft() { + when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.of(BescheidItemTestFactory.create())); + doReturn(false).when(service).hasStatusDraft(any()); var result = service.findBescheidDraft(request); @@ -144,10 +173,10 @@ class VorgangAttachedItemRemoteServiceTest { @Test void shouldReturnLastBescheid() { var item1 = BescheidItemTestFactory.createBuilder().bescheidData(Map.of( - BescheidItem.FIELD_BESCHIEDEN_AM, "2021-01-01", - BescheidItem.FIELD_STATUS, AttachedItemService.BESCHEID_DRAFT_STATUS)).build(); + BescheidItem.FIELD_BESCHIEDEN_AM, "2021-01-01")).build(); var item2 = BescheidItemTestFactory.create(); when(bescheidItemMapper.fromFindVorgangAttachedItemResponse(any())).thenReturn(Stream.of(item1, item2)); + doReturn(true).when(service).hasStatusDraft(any()); var result = service.findBescheidDraft(request); @@ -191,6 +220,30 @@ class VorgangAttachedItemRemoteServiceTest { } } + @Nested + class TestHasStatusDraft { + + @Test + void shouldReturnTrueIfDraft() { + var item = BescheidItemTestFactory.createBuilder().bescheidData(Map.of(BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT.name())) + .build(); + + var result = service.hasStatusDraft(item); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnFalseIfNotDraft() { + var item = BescheidItemTestFactory.createBuilder().bescheidData(Map.of(BescheidItem.FIELD_STATUS, BescheidItem.Status.BESCHEID.name())) + .build(); + + var result = service.hasStatusDraft(item); + + assertThat(result).isFalse(); + } + } + @Nested class TestGetBescheid { @@ -255,15 +308,77 @@ class VorgangAttachedItemRemoteServiceTest { assertThat(result).isEqualTo(expectedBescheid); } + private BescheidItem getBescheid() { + return service.getBescheid(BescheidItemTestFactory.ID); + } + } + + @Nested + class TestGetItem { + + @Mock + private GrpcVorgangAttachedItemRequest grpcVorgangAttachedItemRequest; + @Mock + private GrpcVorgangAttachedItemResponse grpcVorgangAttachedItemResponse; + @Mock + private GrpcVorgangAttachedItem grpcVorgangAttachedItem; + + @BeforeEach + void init() { + when(serviceStub.getById(any())).thenReturn(grpcVorgangAttachedItemResponse); + doReturn(serviceStub).when(service).getServiceStub(); + } + @Test - void shouldThrowExceptionIfNotFound() { - when(serviceStub.getById(any())).thenThrow(StatusRuntimeException.class); + void shouldCallGetServiceStab() { + when(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()).thenReturn(grpcVorgangAttachedItem); + + getItem(); - assertThrows(StatusRuntimeException.class, this::getBescheid); + verify(service).getServiceStub(); } - private BescheidItem getBescheid() { - return service.getBescheid(BescheidItemTestFactory.ID); + @Test + void shouldCallBuildRequest() { + when(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()).thenReturn(grpcVorgangAttachedItem); + + getItem(); + + verify(service).buildGetByIdRequest(AttachedItemTestFactory.ID); + } + + @Test + void shouldCallGetById() { + when(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()).thenReturn(grpcVorgangAttachedItem); + doReturn(grpcVorgangAttachedItemRequest).when(service).buildGetByIdRequest(any()); + + getItem(); + + verify(serviceStub).getById(grpcVorgangAttachedItemRequest); + } + + @Test + void shouldCallMapper() { + when(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()).thenReturn(grpcVorgangAttachedItem); + + getItem(); + + verify(attachedItemMapper).mapFromVorgangAttachedItem(grpcVorgangAttachedItem); + } + + @Test + void shouldReturnFoundBescheid() { + var expectedItem = AttachedItemTestFactory.createDocument(); + when(attachedItemMapper.mapFromVorgangAttachedItem(any())).thenReturn(expectedItem); + when(grpcVorgangAttachedItemResponse.getVorgangAttachedItem()).thenReturn(grpcVorgangAttachedItem); + + var result = getItem(); + + assertThat(result).isEqualTo(expectedItem); + } + + private AttachedItem getItem() { + return service.getItem(BescheidItemTestFactory.ID); } } diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java deleted file mode 100644 index a7f40a347744785b1be6cee7580c7efe9cfceddd..0000000000000000000000000000000000000000 --- a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.document; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Map; - -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.Mock; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.context.ApplicationEventPublisher; - -import de.ozgcloud.apilib.common.command.OzgCloudCommand; -import de.ozgcloud.apilib.common.command.OzgCloudCommandService; -import de.ozgcloud.apilib.common.command.grpc.CommandMapper; -import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; -import de.ozgcloud.bescheid.common.callcontext.UserProfile; -import de.ozgcloud.command.Command; -import de.ozgcloud.command.CommandCreatedEventTestFactory; -import de.ozgcloud.command.CommandTestFactory; -import de.ozgcloud.common.test.ITCase; - -@SpringBootTest(classes = DocumentTestApplication.class) -@ITCase -class DocumentEventListenerITCase { - - @Spy - @Autowired - private ApplicationEventPublisher eventPublisher; - - @SpyBean - private DocumentEventListener documentEventListener; - - @MockBean - private OzgCloudCommandService ozgCloudCommandService; - @MockBean - private CommandMapper commandMapper; - @MockBean - private CurrentUserService userService; - - @Mock - private UserProfile userProfile; - - @BeforeEach - void init() { - when(userService.getUserProfile()).thenReturn(userProfile); - } - - @Nested - class TestCreateBescheidDocument { - - private static final String CREATED_RESOURCE_ID = "created-resource-id"; - - @Mock - private OzgCloudCommand executedCommand; - - @Captor - private ArgumentCaptor<BescheidDocumentCreatedEvent> documentCreatedEventCaptor; - - private Command command = CommandTestFactory.createBuilder() - .order(DocumentEventListener.CREATE_BESCHEID_DOCUMENT_FROM_FILE_ORDER) - .bodyObject(Map.of(DocumentService.FIELD_DOCUMENT_FILE, "file-id")) - .build(); - - @Test - void shouldPublishBescheidDocumentCreatedEvent() { - when(executedCommand.getCreatedResource()).thenReturn(CREATED_RESOURCE_ID); - when(ozgCloudCommandService.createAndWaitUntilDone(any())).thenReturn(executedCommand); - - eventPublisher.publishEvent(CommandCreatedEventTestFactory.withCommand(command)); - - verify(documentEventListener, timeout(60000)).publishEvent(documentCreatedEventCaptor.capture()); - assertThat(documentCreatedEventCaptor.getValue()).satisfies(event -> { - assertThat(event.getCommand()).isEqualTo(command); - assertThat(event.getCreatedResource()).isEqualTo(CREATED_RESOURCE_ID); - }); - } - } -} \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentGrpcServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentGrpcServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e2157ed90a4161e3e67bfd1dcc30f0010c5ca390 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentGrpcServiceTest.java @@ -0,0 +1,120 @@ +/* + * 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.document; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import io.grpc.stub.StreamObserver; + +class DocumentGrpcServiceTest { + + @Spy + @InjectMocks + private DocumentGrpcService service; + + @Mock + private DocumentService documentService; + @Mock + private DocumentMapper documentMapper; + + @Nested + class TestGetDocument { + + private final static GrpcGetDocumentRequest REQUEST = GrpcGetDocumentRequest.newBuilder().setId(DocumentTestFactory.ID).build(); + + @Mock + private GrpcGetDocumentResponse response; + @Mock + private StreamObserver<GrpcGetDocumentResponse> responseObserver; + + @BeforeEach + void init() { + doReturn(response).when(service).buildGetDocumentResponse(any()); + } + + @Test + void shouldCallDocumentService() { + service.getDocument(REQUEST, responseObserver); + + verify(documentService).getDocument(DocumentTestFactory.ID); + } + + @Test + void shouldCallBuildResponse() { + service.getDocument(REQUEST, responseObserver); + + verify(service).buildGetDocumentResponse(any()); + } + + @Test + void shouldCallOnNext() { + service.getDocument(REQUEST, responseObserver); + + verify(responseObserver).onNext(response); + } + + @Test + void shouldCallOnCompleted() { + service.getDocument(REQUEST, responseObserver); + + verify(responseObserver).onCompleted(); + } + } + + @Nested + class TestBuildGetDocumentResponse { + + @Mock + private GrpcDocument grpcDocument; + + @BeforeEach + void init() { + when(documentMapper.toGrpcDocument(any())).thenReturn(grpcDocument); + } + + @Test + void shouldCallDocumentMapper() { + var document = DocumentTestFactory.create(); + + service.buildGetDocumentResponse(document); + + verify(documentMapper).toGrpcDocument(document); + } + + @Test + void shouldSetDocument() { + var result = service.buildGetDocumentResponse(DocumentTestFactory.create()); + + assertThat(result.getDocument()).isEqualTo(grpcDocument); + } + } +} \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentMapperTest.java b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9ba02e1e11c796f19fc771e9ed29000f911690cd --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentMapperTest.java @@ -0,0 +1,107 @@ +/* + * 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.document; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import de.ozgcloud.bescheid.attacheditem.AttachedItemTestFactory; + +class DocumentMapperTest { + + private DocumentMapper mapper = Mappers.getMapper(DocumentMapper.class); + + @DisplayName("To grpc document") + @Nested + class TestToGrpcDocument { + + @Test + void shouldMapDocument() { + var result = mapper.toGrpcDocument(DocumentTestFactory.create()); + + assertThat(result).usingRecursiveComparison().isEqualTo(GrpcDocumentTestFactory.create()); + } + + @Test + void shouldMapEmptyDocument() { + var result = mapper.toGrpcDocument(Document.builder().build()); + + assertThat(result).isEqualTo(GrpcDocument.newBuilder().build()); + } + } + + @DisplayName("From attached item") + @Nested + class TestFromAttachedItem { + + @Test + void shouldMapId() { + var document = AttachedItemTestFactory.createDocument(); + + var result = mapper.fromAttachedItem(document); + + assertThat(result.getId()).isEqualTo(AttachedItemTestFactory.ID); + } + + @Test + void shouldMapType() { + var document = AttachedItemTestFactory.createDocument(); + + var result = mapper.fromAttachedItem(document); + + assertThat(result.getType()).isEqualTo(DocumentService.DOCUMENT_TYPE); + } + + @Test + void shouldMapFileId() { + var document = AttachedItemTestFactory.createDocument(); + + var result = mapper.fromAttachedItem(document); + + assertThat(result.getFileId()).isEqualTo(DocumentTestFactory.DOCUMENT_FILE); + } + + @Test + void shouldMapNachrichtText() { + var document = AttachedItemTestFactory.createDocument(); + + var result = mapper.fromAttachedItem(document); + + assertThat(result.getNachrichtText()).isEqualTo(DocumentTestFactory.NACHRICHT_TEXT); + } + + @Test + void shouldMapNachrichtSubject() { + var document = AttachedItemTestFactory.createDocument(); + + var result = mapper.fromAttachedItem(document); + + assertThat(result.getNachrichtSubject()).isEqualTo(DocumentTestFactory.NACHRICHT_SUBJECT); + } + } +} \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentServiceTest.java index 559c3bc73436f3d87fd4df9e07b12f29d3eb74ef..736947b3a9ede6e9fbd04893ae3f6079887b4fcd 100644 --- a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentServiceTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentServiceTest.java @@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.springframework.web.server.ResponseStatusException; import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommandService; @@ -42,7 +43,10 @@ import de.ozgcloud.apilib.common.command.grpc.CommandMapper; import de.ozgcloud.apilib.common.datatypes.GenericId; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.bescheid.BescheidCallContextAttachingInterceptor; +import de.ozgcloud.bescheid.attacheditem.AttachedItemService; +import de.ozgcloud.bescheid.attacheditem.AttachedItemTestFactory; import de.ozgcloud.bescheid.attacheditem.BescheidItem; +import de.ozgcloud.bescheid.attacheditem.BescheidItemTestFactory; import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandTestFactory; import de.ozgcloud.common.errorhandling.TechnicalException; @@ -60,6 +64,10 @@ class DocumentServiceTest { private OzgCloudCommandService commandService; @Mock private CommandMapper commandMapper; + @Mock + private AttachedItemService attachedItemService; + @Mock + private DocumentMapper documentMapper; private Command command = CommandTestFactory.createBuilder() .relationId(RELATION_ID) @@ -76,6 +84,14 @@ class DocumentServiceTest { @BeforeEach void init() { when(commandService.createAndWaitUntilDone(any())).thenReturn(ozgCommand); + doNothing().when(service).validateBescheidItem(any()); + } + + @Test + void shouldCallValidateBescheidItem() { + service.createBescheidDocument(command); + + verify(service).validateBescheidItem(RELATION_ID); } @Test @@ -104,6 +120,44 @@ class DocumentServiceTest { } } + @Nested + class TestValidateBescheidItem { + + @Test + void shouldCallGetBescheidItem() { + when(attachedItemService.getBescheidItem(any())).thenReturn(BescheidItemTestFactory.create()); + + validateBescheidItem(); + + verify(attachedItemService).getBescheidItem(BescheidItemTestFactory.ID); + } + + @Test + void shouldThrowExceptionWhenNoBescheidDraft() { + when(attachedItemService.getBescheidItem(any())).thenThrow(ResponseStatusException.class); + + assertThrows(ResponseStatusException.class, this::validateBescheidItem); + } + + @Test + void shouldNotThrowExceptionIfNotDraft() { + when(attachedItemService.getBescheidItem(any())).thenReturn( + BescheidItemTestFactory.createBuilder().bescheidData(Map.of(BescheidItem.FIELD_STATUS, "not-draft")).build()); + + assertThrows(TechnicalException.class, this::validateBescheidItem); + } + + @Test + void shouldValidateBescheidItem() { + when(attachedItemService.getBescheidItem(any())).thenReturn(BescheidItemTestFactory.create()); + + assertDoesNotThrow(this::validateBescheidItem); + } + void validateBescheidItem() { + service.validateBescheidItem(BescheidItemTestFactory.ID); + } + } + @Nested class TestBuildCreateDocumentOzgCommand { @@ -135,7 +189,7 @@ class DocumentServiceTest { void shouldCallRelationIdMapper() { service.buildCreateDocumentOzgCommand(command); - verify(commandMapper).mapRelationId(RELATION_ID); + verify(commandMapper).mapRelationId(CommandTestFactory.VORGANG_ID); } @Test @@ -242,4 +296,34 @@ class DocumentServiceTest { } } + @Nested + class TestGetDocument { + + @Test + void shouldCallAttachedItemService() { + service.getDocument(AttachedItemTestFactory.ID); + + verify(attachedItemService).getItem(AttachedItemTestFactory.ID); + } + + @Test + void shouldCallDocumentMapper() { + var expectedItem = AttachedItemTestFactory.createDocument(); + when(attachedItemService.getItem(any())).thenReturn(expectedItem); + + service.getDocument(AttachedItemTestFactory.ID); + + verify(documentMapper).fromAttachedItem(expectedItem); + } + + @Test + void shouldReturnDocument() { + var expectedDocument = DocumentTestFactory.create(); + when(documentMapper.fromAttachedItem(any())).thenReturn(expectedDocument); + + Document document = service.getDocument(AttachedItemTestFactory.ID); + + assertThat(document).isEqualTo(expectedDocument); + } + } } \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..0484d6f5492a0b4fe72bbd87b6980797c9bb6110 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/document/DocumentTestFactory.java @@ -0,0 +1,48 @@ +/* + * 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.document; + +import de.ozgcloud.document.Document.DocumentBuilder; + +public class DocumentTestFactory { + + public static final String ID = "documentId"; + public static final String TYPE = "type"; + public static final String DOCUMENT_FILE = "file-id"; + public static final String NACHRICHT_SUBJECT = "subject"; + public static final String NACHRICHT_TEXT = "text"; + + public static Document create() { + return createBuilder().build(); + } + + public static DocumentBuilder createBuilder() { + return Document.builder() + .id(ID) + .type(TYPE) + .fileId(DOCUMENT_FILE) + .nachrichtSubject(NACHRICHT_SUBJECT) + .nachrichtText(NACHRICHT_TEXT); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/document/GrpcDocumentTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/document/GrpcDocumentTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..5c56530f7b13a986c3cd6fd0914bfc9201d152b7 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/document/GrpcDocumentTestFactory.java @@ -0,0 +1,40 @@ +/* + * 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.document; + +public class GrpcDocumentTestFactory { + + public static GrpcDocument create() { + return createBuilder().build(); + } + + public static GrpcDocument.Builder createBuilder() { + return GrpcDocument.newBuilder() + .setId(DocumentTestFactory.ID) + .setType(DocumentTestFactory.TYPE) + .setFileId(DocumentTestFactory.DOCUMENT_FILE) + .setNachrichtSubject(DocumentTestFactory.NACHRICHT_SUBJECT) + .setNachrichtText(DocumentTestFactory.NACHRICHT_TEXT); + } +} diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml index e0effc809597979a1cdb01c636f868c63574f617..95cd70f64a419cc1e585a2f977f48d45aae0eaee 100644 --- a/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml @@ -44,6 +44,9 @@ spec: component: vorgang-manager {{- with (.Values.networkPolicy).additionalIngressConfig }} {{ toYaml . | indent 2 }} +{{- end }} +{{- with (.Values.networkPolicy).additionalIngressConfigNamespace }} +{{ toYaml . | indent 2 }} {{- end }} egress: - to: @@ -62,5 +65,8 @@ spec: {{- with (.Values.networkPolicy).additionalEgressConfig }} {{ toYaml . | indent 2 }} {{- end }} +{{- with (.Values.networkPolicy).additionalEgressConfigNamespace }} +{{ toYaml . | indent 2 }} +{{- end }} {{- end }} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml index 7382ad0947be9db238ff1b5d7f9de08439716165..6942329e62a7ca2a0544cc56d6f3d6d76e9b2120 100644 --- a/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml +++ b/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml @@ -91,16 +91,15 @@ tests: - port: 5353 protocol: TCP - - it: add ingress rule by values + - it: should add additionalIngressConfig set: networkPolicy: - ssoPublicIp: 51.89.117.53/32 - dnsServerNamespace: test-namespace-dns + dnsServerNamespace: test-dns-namespace additionalIngressConfig: - from: - podSelector: matchLabels: - component: client2 + additionalIngressConfig: yes asserts: - contains: path: spec.ingress @@ -108,41 +107,62 @@ tests: from: - podSelector: matchLabels: - component: client2 + additionalIngressConfig: yes - - it: add egress rules by values + - it: should add additionalEgressConfig set: - networkPolicy: + networkPolicy: + dnsServerNamespace: test-dns-namespace additionalEgressConfig: - - to: - - ipBlock: - cidr: 1.2.3.4/32 - to: - podSelector: matchLabels: - component: ozg-testservice - ports: - - port: 12345 - protocol: TCP - - dnsServerNamespace: test-dns-namespace + additionalEgressConfig: yes asserts: - contains: path: spec.egress content: to: - - ipBlock: - cidr: 1.2.3.4/32 + - podSelector: + matchLabels: + additionalEgressConfig: yes + + + - it: should add additionalIngressConfigNamespace + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + additionalIngressConfigNamespace: + - from: + - podSelector: + matchLabels: + additionalIngressConfigNamespace: yes + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + additionalIngressConfigNamespace: yes + + - it: should add additionalEgressConfigNamespace + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + additionalEgressConfigNamespace: + - to: + - podSelector: + matchLabels: + additionalEgressConfigNamespace: yes + asserts: - contains: path: spec.egress content: to: - podSelector: matchLabels: - component: ozg-testservice - ports: - - port: 12345 - protocol: TCP + additionalEgressConfigNamespace: yes - it: test network policy disabled set: diff --git a/src/main/helm/templates/network_policy.yaml b/src/main/helm/templates/network_policy.yaml index fb20373df7e5cf5c1045657b25fb3df4057f48cc..88ad059ed4898240276aa3f9a0dc05775705a87e 100644 --- a/src/main/helm/templates/network_policy.yaml +++ b/src/main/helm/templates/network_policy.yaml @@ -47,6 +47,9 @@ spec: ozg-component: eingangsadapter {{- with (.Values.networkPolicy).additionalIngressConfig }} {{ toYaml . | indent 2 }} +{{- end }} +{{- with (.Values.networkPolicy).additionalIngressConfigNamespace }} +{{ toYaml . | indent 2 }} {{- end }} egress: - to: @@ -101,5 +104,8 @@ spec: {{- with (.Values.networkPolicy).additionalEgressConfig }} {{ toYaml . | indent 2 }} {{- end }} +{{- with (.Values.networkPolicy).additionalEgressConfigNamespace }} +{{ toYaml . | indent 2 }} +{{- end }} {{- end }} \ No newline at end of file diff --git a/src/test/helm/network_policy_test.yaml b/src/test/helm/network_policy_test.yaml index 16661a34b0b43473c82029e7496f2867220dd785..ac7df6574a59eae14b64a88872f8f37a182dfa89 100644 --- a/src/test/helm/network_policy_test.yaml +++ b/src/test/helm/network_policy_test.yaml @@ -253,39 +253,78 @@ tests: matchLabels: component: client2 - - it: add egress rules by values + - it: should add additionalIngressConfig set: networkPolicy: + dnsServerNamespace: test-namespace-dns + additionalIngressConfig: + - from: + - podSelector: + matchLabels: + additionalIngressConfig: yes + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + additionalIngressConfig: yes + + - it: should add additionalEgressConfig + set: + networkPolicy: + dnsServerNamespace: test-namespace-dns additionalEgressConfig: - - to: - - ipBlock: - cidr: 1.2.3.4/32 - to: - podSelector: matchLabels: - component: ozg-testservice - ports: - - port: 12345 - protocol: TCP - - dnsServerNamespace: test-dns-namespace + additionalEgressConfig: yes asserts: - contains: path: spec.egress content: to: - - ipBlock: - cidr: 1.2.3.4/32 + - podSelector: + matchLabels: + additionalEgressConfig: yes + + + - it: should add additionalIngressConfigNamespace + set: + networkPolicy: + dnsServerNamespace: test-namespace-dns + additionalIngressConfigNamespace: + - from: + - podSelector: + matchLabels: + additionalIngressConfigNamespace: yes + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + additionalIngressConfigNamespace: yes + + - it: should add additionalEgressConfigNamespace + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + additionalEgressConfigNamespace: + - to: + - podSelector: + matchLabels: + additionalEgressConfigNamespace: yes + asserts: - contains: path: spec.egress content: to: - podSelector: matchLabels: - component: ozg-testservice - ports: - - port: 12345 - protocol: TCP + additionalEgressConfigNamespace: yes - it: test network policy disabled set: diff --git a/vorgang-manager-interface/src/main/protobuf/document.model.proto b/vorgang-manager-interface/src/main/protobuf/document.model.proto new file mode 100644 index 0000000000000000000000000000000000000000..ff0025a2197b3ba328547cd595f741ea95852310 --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/document.model.proto @@ -0,0 +1,46 @@ +/* + * 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. + */ + syntax = "proto3"; + + package de.ozgcloud.document; + + option java_multiple_files = true; + option java_package = "de.ozgcloud.document"; + option java_outer_classname = "DocumentModelProto"; + +message GrpcGetDocumentRequest { + string id = 1; +} + +message GrpcGetDocumentResponse { + GrpcDocument document = 1; +} + +message GrpcDocument { + string id = 1; + string type = 2; + string fileId = 3; + string nachrichtSubject = 4; + string nachrichtText = 5; +} \ No newline at end of file diff --git a/vorgang-manager-interface/src/main/protobuf/document.proto b/vorgang-manager-interface/src/main/protobuf/document.proto new file mode 100644 index 0000000000000000000000000000000000000000..c2a903373b229e3461932fa15e50706a9e5b41af --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/document.proto @@ -0,0 +1,36 @@ +/* + * 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. + */ +syntax = "proto3"; + +package de.ozgcloud.document; + +import "document.model.proto"; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.document"; +option java_outer_classname = "DocumentProto"; + +service DocumentService { + rpc GetDocument(GrpcGetDocumentRequest) returns (GrpcGetDocumentResponse) {} +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..bdbcf04f6d8bb24fdfb319fdd45a57c0bcbf9835 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentEventListenerITCase.java @@ -0,0 +1,149 @@ +/* + * 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.document; + +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; +import static org.mockito.Mockito.*; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.test.annotation.DirtiesContext; + +import de.ozgcloud.apilib.common.command.grpc.CommandMapper; +import de.ozgcloud.bescheid.common.callcontext.CallContextUser; +import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; + +@SpringBootTest(classes = VorgangManagerServerApplication.class, properties = { + "grpc.server.inProcessName=test", + "grpc.server.port=-1", + "grpc.client.ozgcloud-command-manager.address=in-process:test", + "grpc.client.vorgang-manager.address=in-process:test" +}) +@DataITCase +@DirtiesContext +class DocumentEventListenerITCase { + + private static final String FILE_ID = "file-id"; + + @Autowired + private ApplicationEventPublisher eventPublisher; + @SpyBean + private DocumentEventListener eventListener; + @Autowired + private CommandMapper mapper; + @Autowired + private MongoOperations mongoOperations; + + @MockBean + private CurrentUserService currentUserService; + @Mock + private CallContextUser callContextUser; + + @Captor + private ArgumentCaptor<BescheidDocumentCreatedEvent> bescheidDocumentCreatedEventCaptor; + @Captor + private ArgumentCaptor<CommandFailedEvent> commandFailedEventCaptor; + + @BeforeEach + void init() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + when(currentUserService.getUser()).thenReturn(callContextUser); + } + + @Test + void shouldCreateDocument() { + var bescheidItem = mongoOperations.save(createBescheidItem("DRAFT")); + var command = createCommand(bescheidItem.getId()); + + eventPublisher.publishEvent(new CommandCreatedEvent(command)); + + assertThat(loadBescheidDocument()).containsEntry(DocumentService.FIELD_DOCUMENT_FILE, FILE_ID); + } + + @Test + void shouldFailWhenNoBescheidFound() { + var command = createCommand("non-existing-id"); + + eventPublisher.publishEvent(new CommandCreatedEvent(command)); + + await().atMost(60, TimeUnit.SECONDS).untilAsserted(() -> { + verify(eventListener, timeout(5000)).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(command.getId()); + }); + } + + @Test + void shouldFailWhenNotDraft() { + var bescheidItem = mongoOperations.save(createBescheidItem("BESCHEID")); + var command = createCommand(bescheidItem.getId()); + + eventPublisher.publishEvent(new CommandCreatedEvent(command)); + + await().atMost(60, TimeUnit.SECONDS).untilAsserted(() -> { + verify(eventListener, timeout(5000)).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(command.getId()); + }); + } + + private VorgangAttachedItem createBescheidItem(String status) { + return VorgangAttachedItemTestFactory.createBuilder().id(null).version(0) + .item(Map.of("status", status)) + .build(); + } + + private Map<String, Object> loadBescheidDocument() { + verify(eventListener, timeout(5000)).publishEvent(bescheidDocumentCreatedEventCaptor.capture()); + var bescheidDocumentId = bescheidDocumentCreatedEventCaptor.getValue().getCreatedResource(); + return mongoOperations.findById(bescheidDocumentId, VorgangAttachedItem.class).getItem(); + } + + private Command createCommand(String relationId) { + return CommandTestFactory.createBuilder() + .relationId(relationId) + .order(DocumentEventListener.CREATE_BESCHEID_DOCUMENT_FROM_FILE_ORDER) + .bodyObject(Map.of(DocumentService.FIELD_DOCUMENT_FILE, FILE_ID)) + .build(); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentGrpcServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentGrpcServiceITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..95720de7ca399b35508f54d47da2550cb858dadd --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/document/DocumentGrpcServiceITCase.java @@ -0,0 +1,110 @@ +/* + * 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.document; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Map; +import java.util.Optional; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.test.annotation.DirtiesContext; + +import de.ozgcloud.bescheid.common.callcontext.CallContextUser; +import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.document.DocumentServiceGrpc.DocumentServiceBlockingStub; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import io.grpc.StatusRuntimeException; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@SpringBootTest(classes = VorgangManagerServerApplication.class, properties = { + "grpc.server.inProcessName=test", + "grpc.server.port=-1", + "grpc.client.vorgang-manager.address=in-process:test", + "grpc.client.inProcess.address=in-process:test", +}) +@DataITCase +@DirtiesContext +class DocumentGrpcServiceITCase { + + @GrpcClient("inProcess") + private DocumentServiceBlockingStub documentServiceStub; + + @Autowired + private MongoOperations mongoOperations; + + @MockBean + private CurrentUserService currentUserService; + @Mock + private CallContextUser callContextUser; + + @BeforeEach + void init() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + when(currentUserService.findUser()).thenReturn(Optional.of(callContextUser)); + when(currentUserService.getUser()).thenReturn(callContextUser); + } + + @Test + void shouldGetDocument() { + var documentId = saveDocument(); + + var response = documentServiceStub.getDocument(GrpcGetDocumentRequest.newBuilder().setId(documentId).build()); + + assertThat(response.hasDocument()).isTrue(); + } + + @Test + void shouldThrowExceptionWhenDocumentNotFound() { + saveDocument(); + var request = GrpcGetDocumentRequest.newBuilder().setId("not-found").build(); + + Assertions.assertThrows(StatusRuntimeException.class, () -> documentServiceStub.getDocument(request)); + } + + private String saveDocument() { + var document = VorgangAttachedItemTestFactory.createBuilder() + .id(null) + .version(0) + .itemName(DocumentService.DOCUMENT_ITEM_NAME) + .item(Map.of( + Document.FIELD_DOCUMENT_TYPE, DocumentService.DOCUMENT_TYPE, + Document.FIELD_DOCUMENT_FILE, "file-id", + Document.FIELD_NACHRICHT_TEXT, "nachricht-text", + Document.FIELD_NACHRICHT_SUBJECT, "nachricht-subject")) + .build(); + return mongoOperations.save(document, VorgangAttachedItem.COLLECTION_NAME).getId(); + } +}