diff --git a/vorgang-manager-interface/src/main/protobuf/vorgang.proto b/vorgang-manager-interface/src/main/protobuf/vorgang.proto index 2dbba69a45b32a58ba87a368eba75bf1e03102a9..fe49a87a5e9bfb7ba504a043a94b871cbae38dd4 100644 --- a/vorgang-manager-interface/src/main/protobuf/vorgang.proto +++ b/vorgang-manager-interface/src/main/protobuf/vorgang.proto @@ -47,6 +47,9 @@ service VorgangService { rpc CreateCollaborationVorgang(GrpcCreateCollaborationVorgangRequest) returns (GrpcCreateCollaborationVorgangResponse) { } + + rpc FindDeletedVorgang(GrpcFindDeletedVorgangRequest) returns (stream GrpcVorgangHeader) { + } } message GrpcCreateVorgangRequest { @@ -107,4 +110,7 @@ message GrpcFinishCreationRequest { message GrpcFinishCreationResponse { string message = 1; +} + +message GrpcFindDeletedVorgangRequest { } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcService.java index 82270add8423926bfb236532c940880c9c85ab5e..bdb2c373dd0715bbf1f4b38e13749036e4a2b69d 100644 --- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcService.java @@ -48,6 +48,7 @@ class VorgangGrpcService extends VorgangServiceGrpc.VorgangServiceImplBase { private final IncomingFileGroupMapper incomingFileGroupMapper; private final CollaborationService collaborationService; private final CreateCollaborationVorgangRequestMapper createCollaborationVorgangRequestMapper; + private final VorgangStubMapper vorgangStubMapper; @Override public void startCreation(GrpcCreateVorgangRequest request, StreamObserver<GrpcCreateVorgangResponse> responseObserver) { @@ -138,4 +139,10 @@ class VorgangGrpcService extends VorgangServiceGrpc.VorgangServiceImplBase { GrpcCreateCollaborationVorgangResponse buildCreateCollaborationVorgangResponse(Vorgang vorgang) { return GrpcCreateCollaborationVorgangResponse.newBuilder().setVorgangId(vorgang.getId()).build(); } + + @Override + public void findDeletedVorgang(GrpcFindDeletedVorgangRequest request, StreamObserver<GrpcVorgangHeader> responseObserver) { + vorgangService.findDeleted().map(vorgangStubMapper::toGrpcVorgangHeader).forEach(responseObserver::onNext); + responseObserver.onCompleted(); + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java index 125315d1d5dbf4b03b9cdddc8f95e1d9bdf9992b..4363b1e02331dd3fc92a5de2de17a51c1d43e744 100644 --- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java @@ -27,6 +27,7 @@ import static de.ozgcloud.vorgang.common.db.CriteriaUtil.*; import static org.springframework.data.mongodb.core.query.Query.*; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; @@ -127,4 +128,8 @@ class VorgangRepository { return new Criteria().andOperator(CriteriaUtil.isId(vorgangId), CriteriaUtil.isNotDeleted(), Criteria.where(VorgangService.KEY_HEADER_LOCK).ne(null)); } + + public Stream<VorgangStub> findDeleted() { + return mongoOperations.stream(query(CriteriaUtil.vorgangInStatus(List.of(Vorgang.Status.DELETED))), VorgangStub.class); + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java index bd1b375f8556d3c29615e7e85fc171e1c73a81a8..3cbc342a0f46aad3c4131a1d2033996f0d372eb2 100644 --- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java @@ -33,8 +33,6 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; -import jakarta.validation.Valid; - import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -53,6 +51,7 @@ import de.ozgcloud.vorgang.clientattribute.ClientAttributeReadPermitted; import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; import de.ozgcloud.vorgang.servicekonto.ServiceKonto; +import jakarta.validation.Valid; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -275,4 +274,7 @@ public class VorgangService { return lock.map(Lock::getClientName).filter(lockingClient -> !lockingClient.equals(clientName)).isPresent(); } + public Stream<VorgangStub> findDeleted() { + return repository.findDeleted(); + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java index a7562d92ed862323042a5b57ea63195a0268cbfe..0268e82bc6391ce102f71829d3d53388e41a7358 100644 --- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java @@ -36,7 +36,7 @@ import lombok.Getter; @Getter @Document(collection = Vorgang.COLLECTION_NAME) @TypeAlias("VorgangStub") -class VorgangStub { +public class VorgangStub { @Id private String id; diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java index 098b34a18b1156ce2f2e87117b97a3ede918ff6b..741c8288296a85af7895aec113add813e6a2d47a 100644 --- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java @@ -60,4 +60,5 @@ interface VorgangStubMapper { } } + GrpcVorgangHeader toGrpcVorgangHeader(VorgangStub vorgangStub); } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindDeletedVorgangRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindDeletedVorgangRequestTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..91d47686cb2356fb5df9e4cd0920cb81baa3c62e --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindDeletedVorgangRequestTestFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2025 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.vorgang; + +class GrpcFindDeletedVorgangRequestTestFactory { + + public static GrpcFindDeletedVorgangRequest create() { + return createBuilder().build(); + } + + public static GrpcFindDeletedVorgangRequest.Builder createBuilder() { + return GrpcFindDeletedVorgangRequest.newBuilder(); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcServiceTest.java index 1fcfd3b108caaf4decd0382b0c0274edd5fb1ee1..265b788a76b63d903bd050b4bd9b989a067e0698 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangGrpcServiceTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.*; import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -42,6 +43,7 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.data.domain.Page; +import de.ozgcloud.nachrichten.common.vorgang.GrpcVorgangHeaderTestFactory; import de.ozgcloud.vorgang.collaboration.CollaborationService; import de.ozgcloud.vorgang.collaboration.CreateCollaborationVorgangBadRequestException; import de.ozgcloud.vorgang.collaboration.CreateCollaborationVorgangRequest; @@ -66,6 +68,8 @@ class VorgangGrpcServiceTest { private VorgangHeaderService headerService; @Mock private VorgangHeaderMapper vorgangHeaderMapper; + @Mock + private VorgangStubMapper vorgangStubMapper; @Mock private EingangMapper eingangMapper; @@ -510,4 +514,61 @@ class VorgangGrpcServiceTest { assertThat(result.getVorgangId()).isEqualTo(VorgangTestFactory.ID); } } + + @Nested + class TestFindDeleteVorgang { + + private final GrpcFindDeletedVorgangRequest request = GrpcFindDeletedVorgangRequestTestFactory.create(); + @Mock + private StreamObserver<GrpcVorgangHeader> responseObserver; + + private final VorgangStub vorgangStub = VorgangStubTestFactory.create(); + private final GrpcVorgangHeader grpcVorgangHeader = GrpcVorgangHeaderTestFactory.create(); + + @BeforeEach + void init() { + when(vorgangService.findDeleted()).thenReturn(Stream.of(vorgangStub)); + when(vorgangStubMapper.toGrpcVorgangHeader(vorgangStub)).thenReturn(grpcVorgangHeader); + } + + @Test + void shouldFindDeleted() { + findDeletedVorgang(); + + verify(vorgangService).findDeleted(); + } + + @Test + void shouldMapToGrpc() { + findDeletedVorgang(); + + verify(vorgangStubMapper).toGrpcVorgangHeader(vorgangStub); + } + + @Test + void shouldCallOnNext() { + findDeletedVorgang(); + + verify(responseObserver).onNext(grpcVorgangHeader); + } + + @Test + void shouldCallOnCompleted() { + findDeletedVorgang(); + + verify(responseObserver).onCompleted(); + } + + @Test + void shouldNotCatchExceptions() { + var exception = new RuntimeException(); + when(vorgangStubMapper.toGrpcVorgangHeader(vorgangStub)).thenThrow(exception); + + assertThatThrownBy(this::findDeletedVorgang).isSameAs(exception); + } + + private void findDeletedVorgang() { + service.findDeletedVorgang(request, responseObserver); + } + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java index 719ae2ead5bfda1dda98281e146e0a3850b478a8..74d47f18f4bca9929b2de9497a7bef7658c31f71 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java @@ -141,7 +141,7 @@ class VorgangHeaderServiceTest { } @Nested - class TestGEtById { + class TestGetById { @Test void shouldCallFindById() { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java index 5244ce68773a36de27d72361380c0946266b9774..8f81b6fd4323fda2e60732eab71b5d7833bbf84f 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java @@ -23,6 +23,7 @@ */ package de.ozgcloud.vorgang.vorgang; +import static de.ozgcloud.vorgang.vorgang.Vorgang.Status.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -41,6 +42,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; +import com.thedeanda.lorem.LoremIpsum; + import de.ozgcloud.common.test.DataITCase; @DataITCase @@ -255,7 +258,7 @@ class VorgangRepositoryITCase { @Test void shouldNotExistsDELETEDVorgang() { - mongoOperations.save(VorgangTestFactory.createBuilder().status(Vorgang.Status.DELETED).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().status(DELETED).build()); var exists = repository.exists(VorgangTestFactory.ID, Collections.singleton(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); @@ -435,4 +438,20 @@ class VorgangRepositoryITCase { return mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); } } + + @Nested + class TestFindDeleted { + + private static final String DELETED_VORGANG_NAME = LoremIpsum.getInstance().getWords(3); + + @Test + void shouldReturnOnlyWhereStatusIsDeleted() { + mongoOperations.save(VorgangStubTestFactory.createBuilder().build()); + mongoOperations.save(VorgangStubTestFactory.createBuilder().name(DELETED_VORGANG_NAME).status(DELETED).build()); + + var deleted = repository.findDeleted().toList(); + + assertThat(deleted).hasSize(1).extracting(VorgangStub::getName).contains(DELETED_VORGANG_NAME); + } + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java index 53df957e740b3479162ea94de6f2dcee7c16f80c..3449659b130bca698edbf9b3b88daf73fe867efc 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java @@ -24,7 +24,6 @@ package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; -import static org.assertj.core.api.InstanceOfAssertFactories.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -35,7 +34,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.core.api.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -760,4 +759,26 @@ class VorgangServiceTest { assertThat(result).isFalse(); } } + + + @Nested + class TestFindDeleted { + + @Test + void shouldCallRepository() { + service.findDeleted(); + + verify(repository).findDeleted(); + } + + @Test + void shouldReturnRepositoryResult() { + var repositoryResult = List.of(VorgangStubTestFactory.create()); + when(repository.findDeleted()).thenReturn(repositoryResult.stream()); + + var serviceResult = service.findDeleted().toList(); + + assertThat(serviceResult).isEqualTo(repositoryResult); + } + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java index c1d2c25865eeb820b8a1f1d5528881688d656004..087abf2267bccc8efe37ddb0d27a46a156c09312 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java @@ -64,4 +64,22 @@ class VorgangStubMapperTest { } } + @Nested + class TestToGrpcVorgangHeader { + + @Test + void shouldMapFields() { + var vorgangStub = VorgangStubTestFactory.createBuilder().status(Vorgang.Status.DELETED).build(); + var expectedGrpcVorgangHeader = GrpcVorgangHeader.newBuilder() + .setId(VorgangStubTestFactory.ID) + .setName(VorgangStubTestFactory.NAME) + .setCreatedAt(VorgangStubTestFactory.CREATED_AT_STR) + .setStatus(Vorgang.Status.DELETED.name()) + .build(); + + var mappedGrpcVorgangHeader = mapper.toGrpcVorgangHeader(vorgangStub); + + assertThat(mappedGrpcVorgangHeader).isEqualTo(expectedGrpcVorgangHeader); + } + } } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java index 1a5b3eff69bb7beeef81a7d84e0f15b34e4dfef6..8833e98ec2f1a0074d9fc3b89bb736ee3c63b76a 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java @@ -23,8 +23,15 @@ */ package de.ozgcloud.vorgang.vorgang; +import java.time.ZonedDateTime; + public class VorgangStubTestFactory { + public static final String ID = VorgangTestFactory.ID; + public static final String NAME = VorgangTestFactory.NAME; + public static final String CREATED_AT_STR = VorgangTestFactory.CREATED_AT_STR; + public static final ZonedDateTime CREATED_AT = VorgangTestFactory.CREATED_AT; + public static VorgangStub create() { return createBuilder().build(); } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java index 6c7e4c40b0f9f508a90eb8ddb37e3c13dcb7c75c..1f95514a96ce44e06fe9ba8cc348d19a767dc11e 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java @@ -30,9 +30,9 @@ import org.bson.types.ObjectId; import com.thedeanda.lorem.LoremIpsum; import de.ozgcloud.vorgang.callcontext.UserTestFactory; -import de.ozgcloud.vorgang.vorgang.Vorgang.Status; import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; public class VorgangTestFactory { @@ -44,7 +44,8 @@ public class VorgangTestFactory { public static final String INITIAL_DATE = "2021-01-10"; public static final String INITIAL_TIME = "10:30:00"; public static final String INITIAL_DATE_STR = "%sT%sZ".formatted(INITIAL_DATE, INITIAL_TIME); - public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(INITIAL_DATE_STR); + public static final String CREATED_AT_STR = INITIAL_DATE_STR; + public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); public static final String VORGANG_NUMMER = "VOR-GANG-NUMMER-1"; public static final String AKTENZEICHEN = LoremIpsum.getInstance().getWords(1);