From ce48edc19fb14bf3ac64a0fc0e51742d6d6bccae Mon Sep 17 00:00:00 2001 From: Stefan Hauffe <stefan.hauffe@mgm-tp.com> Date: Mon, 22 Apr 2024 13:04:49 +0000 Subject: [PATCH] OpenSource Release 2.0.0 --- .helmignore | 1 + README.md | 6 +- bescheid-manager/pom.xml | 135 +++ .../java/de/ozgcloud/bescheid/Bescheid.java | 56 ++ ...scheidCallContextAttachingInterceptor.java | 84 ++ .../bescheid/BescheidCreatedEvent.java | 34 + .../bescheid/BescheidEventListener.java | 135 +++ .../bescheid/BescheidGrpcService.java | 53 ++ .../bescheid/BescheidRemoteService.java | 31 + .../de/ozgcloud/bescheid/BescheidRequest.java | 43 + .../de/ozgcloud/bescheid/BescheidService.java | 77 ++ .../ozgcloud/bescheid/GrpcBescheidMapper.java | 59 ++ .../java/de/ozgcloud/bescheid/UserId.java | 44 + .../binaryfile/BinaryFileRemoteService.java | 123 +++ .../binaryfile/BinaryFileService.java | 43 + .../CallContextAuthenticationToken.java | 64 ++ .../common/callcontext/CallContextUser.java | 58 ++ .../callcontext/CurrentUserService.java | 119 +++ .../common/callcontext/UserProfile.java | 38 + .../common/callcontext/UserProfileMapper.java | 40 + .../callcontext/UserProfileTestFactory.java | 53 ++ .../dummy/DummyBescheidRemoteService.java | 57 ++ .../bescheid/nachricht/Nachricht.java | 56 ++ .../bescheid/nachricht/NachrichtId.java | 37 + .../bescheid/nachricht/NachrichtMapper.java | 78 ++ .../nachricht/NachrichtRemoteService.java | 57 ++ .../bescheid/nachricht/NachrichtService.java | 103 +++ .../SmartDocumentsBescheidRemoteService.java | 245 ++++++ .../SmartDocumentsConfiguration.java | 76 ++ .../SmartDocumentsProperties.java | 111 +++ .../smartdocuments/SmartDocumentsRequest.java | 91 ++ .../vorgang/BescheidVorgangMapper.java | 71 ++ .../bescheid/vorgang/FormDataEntry.java | 86 ++ .../bescheid/vorgang/FormDataEntryMapper.java | 57 ++ .../vorgang/FormDataEntrySerializer.java | 104 +++ .../de/ozgcloud/bescheid/vorgang/Vorgang.java | 110 +++ .../ozgcloud/bescheid/vorgang/VorgangId.java | 38 + .../vorgang/VorgangRemoteService.java | 54 ++ .../bescheid/vorgang/VorgangService.java | 40 + ...ot.autoconfigure.AutoConfiguration.imports | 8 + .../src/main/resources/dummy-bescheid.pdf | Bin 0 -> 10120 bytes .../bescheid.nachrichtTemplate.txt.ftlh | 8 + .../bescheid/BescheidEventListenerITCase.java | 69 ++ .../bescheid/BescheidEventListenerTest.java | 191 +++++ .../bescheid/BescheidGrpcServiceTest.java | 103 +++ .../bescheid/BescheidRequestTestFactory.java | 51 ++ .../bescheid/BescheidServiceTest.java | 86 ++ .../bescheid/BescheidTestApplication.java | 40 + .../bescheid/BescheidTestFactory.java | 65 ++ .../bescheid/GrpcBescheidMapperTest.java | 16 +- .../bescheid/GrpcBescheidTestFactory.java | 37 + .../callcontext/CurrentUserServiceTest.java | 37 +- .../GrpcPostfachNachrichtTestFactory.java | 40 + .../nachricht/NachrichtMapperTest.java | 71 ++ .../nachricht/NachrichtRemoteServiceTest.java | 82 ++ .../nachricht/NachrichtServiceITCase.java | 65 ++ .../nachricht/NachrichtServiceTest.java | 121 +++ .../nachricht/NachrichtTestFactory.java | 55 ++ ...tDocumentsBescheidRemoteServiceITCase.java | 51 ++ ...artDocumentsBescheidRemoteServiceTest.java | 112 +++ .../SmartDocumentsResponseTestFactory.java | 51 ++ .../vorgang/BescheidVorgangMapperTest.java | 54 ++ .../vorgang/FormDataEntrySerializerTest.java | 95 ++ .../vorgang/GrpcEingangTestFactory.java | 37 + .../GrpcVorgangWithEingangTestFactory.java | 49 ++ .../vorgang/ServiceKontoTestFactory.java | 39 + .../vorgang/VorgangRemoteServiceTest.java | 94 ++ .../bescheid/vorgang/VorgangServiceTest.java | 40 +- .../bescheid/vorgang/VorgangTestFactory.java | 45 + .../org.junit.jupiter.api.extension.Extension | 0 .../src/test/resources/SD_answer.xml | 399 +++++++++ .../src/test/resources/application-itcase.yml | 16 + .../test/resources/junit-platform.properties | 0 .../org.mockito.plugins.MockMaker | 0 dependency-check-supressions.xml | 31 + pluto-server/lombok.config => lombok.config | 2 +- mail-service/lombok.config | 28 - .../mail/postfach/PostfachEventListener.java | 99 --- .../ozg/mail/postfach/PostfachMailMapper.java | 124 --- .../ozg/mail/postfach/PostfachService.java | 168 ---- .../postfach/PostfachEventListenerTest.java | 144 ---- .../mail/postfach/PostfachMailMapperTest.java | 142 --- .../postfach/PostfachMailTestFactory.java | 91 -- .../mail/postfach/PostfachServiceTest.java | 523 ----------- mongodb/docker-compose.yml | 30 + .../bayernid-proxy-impl/pom.xml | 224 +++++ .../bayernid/proxy/BayernIdProperties.java | 46 + .../proxy/BayernIdProxyApplication.java | 43 + .../proxy/BayernIdProxyConfiguration.java | 88 ++ .../proxy/BayernIdProxyGrpcService.java | 43 + .../bayernid/proxy/BayernIdProxyService.java | 43 + .../proxy/DeleteOnCloseInputStream.java | 46 + .../bayernid/proxy/UploadStreamObserver.java | 153 ++++ .../proxy/akdb/BayernIdRemoteService.java | 91 ++ .../proxy/errorhandling/ExceptionHandler.java | 74 ++ .../bayernid/proxy/message/Absender.java | 42 + .../bayernid/proxy/message/Attachment.java | 39 + .../proxy/message/BayernIdMessage.java | 46 + .../proxy/message/BayernIdMessageMapper.java | 115 +++ .../proxy/message/BayernIdResponse.java | 37 + .../bayernid/proxy/message/Empfaenger.java | 36 + ...ot.autoconfigure.AutoConfiguration.imports | 14 + .../src/main/resources/application-dev.yml | 5 + .../src/main/resources/application-local.yml | 11 + .../src/main/resources/application.yml | 29 + .../PostfachnachrichtenServiceBy.wsdl | 108 +++ .../bayernid/bspnachrichten-2.13.xsd | 343 ++++++++ .../src/main/resources/log4j2-local.xml | 14 + .../proxy/BayernIdProxyGrpcServiceITCase.java | 170 ++++ .../proxy/BayernIdProxyServiceTest.java | 68 ++ .../proxy/BayernIdResponseTestFactory.java | 44 + .../proxy/GrpcAbsenderTestFactory.java | 50 +- .../GrpcAttachmentMetadataTestFactory.java | 40 + ...rpcBayernIdMessageMetadataTestFactory.java | 64 ++ .../proxy/GrpcEmpfaengerTestFactory.java | 42 + .../proxy/UploadStreamObserverTest.java | 404 +++++++++ .../proxy/akdb/BayernIdRemoteServiceTest.java | 233 +++++ .../errorhandling/ExceptionHandlerTest.java | 195 +++++ .../proxy/message/AbsenderTestFactory.java | 56 ++ .../proxy/message/AttachmentTestFactory.java | 46 + .../message/BayernIdMessageMapperTest.java | 506 +++++++++++ .../message/BayernIdMessageTestFactory.java | 57 ++ .../message/BayernIdRsponseTestFactory.java | 9 +- .../proxy/message/BspQuitungTestFactory.java | 43 + .../proxy/message/EmpfaengerTestFactory.java | 42 + .../bayernid/proxy/mock/BayernIdResponse.java | 37 + .../mock/GrpcBayernIdProxyTestClient.java | 56 ++ .../proxy/mock/MockBayernIdInitializer.java | 88 ++ .../mock/MockBayernIdSendStreamObserver.java | 68 ++ .../proxy/mock/MockChunkedDataStreamer.java | 126 +++ .../org.junit.jupiter.api.extension.Extension | 0 .../src/test/resources/application-itcase.yml | 10 + .../test/resources/junit-platform.properties | 0 .../org.mockito.plugins.MockMaker | 1 + .../src/test/resources/test.pdf | Bin 0 -> 5705 bytes .../src/test/resources/test.txt | 1 + .../bayernid-proxy-interface}/pom.xml | 107 +-- .../main/protobuf/bayernidproxy.model.proto | 83 ++ .../src/main/protobuf/bayernproxy.proto | 38 + nachrichten-bayernid-proxy/pom.xml | 69 ++ nachrichten-bayernid-proxy/run_helm_test.sh | 32 + .../src/main/helm/.helmignore | 1 + .../src/main/helm/Chart.yaml | 30 + .../src/main/helm/templates/_helpers.tpl | 47 + .../templates/configmap_bindings_type.yaml | 32 + .../src/main/helm/templates/deployment.yaml | 166 ++++ .../main/helm/templates/network_policy.yaml | 66 ++ .../src/main/helm/templates/service.yaml | 42 + .../main/helm/templates/service_account.yaml | 31 + .../src/main/helm/values.yaml | 39 + .../src/test/helm-linter-values.yaml | 33 + .../helm/configmap_bindings_type_test.yaml | 46 + .../test/helm/deployment_actuator_test.yaml | 67 ++ .../deployment_bayernid_certificate_test.yaml | 114 +++ .../test/helm/deployment_bindings_test.yaml | 72 ++ .../helm/deployment_container_basic_test.yaml | 64 ++ ...eployment_container_other_values_test.yaml | 76 ++ ...yment_container_security_context_test.yaml | 69 ++ .../helm/deployment_defaults_labels_test.yaml | 75 ++ .../src/test/helm/deployment_env_test.yaml | 53 ++ .../deployment_imagepull_secret_test.yaml | 42 + .../deployment_ozgcloud_base_values_test.yaml | 46 + .../test/helm/deployment_resources_test.yaml | 63 ++ .../helm/deployment_service_account_test.yaml | 57 ++ .../helm/deployment_springProfile_test.yaml | 52 ++ ...deployment_template_other_values_test.yaml | 81 ++ .../helm/deyploment_general_value_test.yaml | 78 ++ .../src/test/helm/network_policy_test.yaml | 163 ++++ .../src/test/helm/service_account_test.yaml | 65 ++ .../src/test/helm/service_test.yaml | 85 ++ nachrichten-manager/lombok.config | 30 + {mail-service => nachrichten-manager}/pom.xml | 141 ++- .../NachrichtenManagerProperties.java | 39 + .../ClientAttributeRemoteService.java | 16 +- .../attributes/ClientAttributeService.java | 4 +- .../ClientAttributeTestFactory.java | 4 +- .../errorhandling/FunctionalException.java | 4 +- .../errorhandling/TechnicalException.java | 6 +- ...ichtenCallContextAttachingInterceptor.java | 14 +- .../nachrichten}/email/EMailService.java | 15 +- .../nachrichten}/email/EmailGrpcService.java | 15 +- .../nachrichten}/email/MailRecipient.java | 4 +- .../email/MailSendErrorEvent.java | 4 +- .../nachrichten}/email/MailSendRequest.java | 7 +- .../nachrichten}/email/MailSentEvent.java | 4 +- .../nachrichten}/email/MailService.java | 4 +- .../nachrichten/postfach/AttachmentFile.java | 53 ++ .../postfach/BinaryFileService.java | 4 +- .../nachrichten}/postfach/FileId.java | 6 +- .../postfach/GrpcPostfachNachrichtMapper.java | 50 ++ .../postfach/NotConfiguredException.java | 10 +- .../PersistPostfachNachrichtService.java | 10 +- .../nachrichten/postfach/Postfach.java | 36 + .../nachrichten/postfach/PostfachAddress.java | 42 + .../postfach/PostfachAddressIdentifier.java | 28 + .../postfach/PostfachBadRequestException.java | 10 +- .../postfach/PostfachEventListener.java | 125 +++ .../postfach/PostfachException.java | 14 +- .../postfach/PostfachGrpcService.java | 36 +- .../postfach/PostfachMailSentEvent.java | 6 +- .../postfach/PostfachMailSentFailedEvent.java | 6 +- .../nachrichten/postfach/PostfachMapper.java | 32 + .../postfach/PostfachMessageCode.java | 6 +- .../postfach/PostfachNachricht.java | 18 +- .../postfach/PostfachNachrichtMapper.java | 159 ++++ .../postfach/PostfachRemoteService.java | 39 + .../postfach/PostfachRuntimeException.java | 10 +- .../postfach/PostfachScheduler.java | 12 +- .../nachrichten/postfach/PostfachService.java | 245 ++++++ .../SendPostfachNachrichtResponse.java | 6 +- .../postfach/StringBasedIdentifier.java | 34 + .../antragsraum/AntragsraumProperties.java | 49 ++ .../antragsraum/AntragsraumService.java | 94 ++ .../antragsraum/InfomanagerNachricht.java | 37 + .../InfomanagerNachrichtMapper.java | 37 + .../antragsraum/InfomanagerProperties.java | 47 + .../antragsraum/InfomanagerRemoteService.java | 51 ++ .../postfach/bayernid/Absender.java | 46 + .../postfach/bayernid/BayernIdAttachment.java | 38 + .../bayernid/BayernIdAttachmentService.java | 68 ++ .../BayernIdPostfachNachrichtMapper.java | 96 +++ .../BayernIdPostfachRemoteService.java | 155 ++++ .../BayernIdPostfachResponseHandler.java | 32 +- .../postfach/bayernid/BayernIdProperties.java | 49 ++ .../postfach/bayernid/BayernIdResponse.java | 37 + .../bayernid/BayernIdServerException.java | 53 ++ .../postfach/bayernid/FileSender.java | 132 +++ .../bayernid/MailSendingResponseStatus.java | 66 ++ .../bayernid/MessageWithFilesSender.java | 132 +++ .../nachrichten/postfach/osi}/Message.java | 19 +- .../postfach/osi}/MessageAttachment.java | 4 +- .../osi/MessageAttachmentService.java | 35 +- .../osi}/MockOsiPostfachConfiguration.java | 4 +- .../osi}/MockOsiPostfachRestTemplate.java | 4 +- .../osi/OsiPostfachMessageMapper.java | 107 +++ .../postfach/osi}/OsiPostfachProperties.java | 8 +- .../osi/OsiPostfachRemoteService.java | 68 +- .../OsiPostfachServerProcessException.java | 36 + .../postfach/osi}/PostfachConfiguration.java | 25 +- .../nachrichten/postfach/osi/ReplyOption.java | 40 + ...ot.autoconfigure.AutoConfiguration.imports | 20 + .../PostfachnachrichtenServiceBy.wsdl | 108 +++ .../bayernid/bspnachrichten-2.13.xsd | 343 ++++++++ .../ClientAttributeRemoteServiceTest.java | 12 +- .../ClientAttributeServiceTest.java | 4 +- .../GrpcClientAttributeTestFactory.java | 10 +- ...cSetClientAttributeRequestTestFactory.java | 10 +- .../nachrichten}/email/EMailServiceTest.java | 15 +- .../email/EmailGrpcServiceTest.java | 4 +- ...GrpcNotificationRecipientsTestFactory.java | 4 +- .../email/GrpcRecipientTestFactory.java | 4 +- .../email/MailRecipientTestFactory.java | 4 +- .../email/MailSendErrorEventTestFactory.java | 4 +- .../email/MailSendRequestTestFactory.java | 9 +- .../email/MailSentEventTestFactory.java | 4 +- .../GrpcPostfachAddressTestFactory.java | 51 ++ .../postfach/GrpcPostfachMailTestFactory.java | 15 +- ...cResendPostfachMailRequestTestFactory.java | 10 +- ...cSaveNachrichtDraftRequestTestFactory.java | 39 + ...rpcSendPostfachMailRequestTestFactory.java | 8 +- .../postfach/PostfachAddressTestFactory.java | 47 + .../postfach/PostfachEventListenerTest.java | 215 +++++ .../postfach/PostfachGrpcServiceTest.java | 143 ++- .../postfach/PostfachMapperTest.java | 49 ++ .../postfach/PostfachNachrichtMapperTest.java | 209 +++++ .../PostfachNachrichtTestFactory.java | 109 +++ .../postfach/PostfachSchedulerTest.java | 4 +- .../postfach/PostfachServiceTest.java | 811 ++++++++++++++++++ .../postfach/PostfachTestFactory.java | 43 + ...dPostfachNachrichtResponseTestFactory.java | 6 +- .../antragsraum/AntragsraumServiceTest.java | 144 ++++ .../InfomanagerNachrichtTestFactory.java | 44 + .../InfomanagerRemoteServiceTest.java | 116 +++ .../bayernid/AbsenderTestFactory.java | 49 ++ .../bayernid/AbsenderTypeTestFactory.java | 40 + .../BayernIdAttachmentServiceTest.java | 179 ++++ .../BayernIdAttachmentTestFactory.java | 52 ++ .../BayernIdPostfachNachrichtMapperTest.java | 295 +++++++ .../BayernIdPostfachRemoteServiceTest.java | 455 ++++++++++ .../BayernIdPostfachResponseHandlerTest.java | 66 ++ .../bayernid/BayernIdPropertiesITCase.java | 111 +++ .../bayernid/BayernIdResponseTestFactory.java | 44 + .../bayernid/BspNachrichtTestFactory.java | 39 + .../bayernid/EmpfaengerTypeTestFactory.java | 39 + .../postfach/bayernid/FileSenderTest.java | 214 +++++ .../bayernid/FreiTextTypeTestFactory.java | 38 + ...endBayernIdMessageResponseTestFactory.java | 43 + ...dentifikationNachrichtTypeTestFactory.java | 59 ++ .../MailSendingResponseStatusTest.java | 41 + .../bayernid/MessageWithFilesSenderTest.java | 405 +++++++++ .../NachrichtenInhaltTypeTestFactory.java | 37 + .../NachrichtenKopfTypeTestFactory.java | 45 + ...ndBspNachrichtNativeOutputTestFactory.java | 38 + .../bayernid/ZuVorgangTypeTestFactory.java | 39 + .../osi/MessageAttachmentServiceTest.java | 38 +- .../osi}/MessageAttachmentTestFactory.java | 8 +- .../osi/MessageJsonReplyTestFactory.java | 60 ++ .../postfach/osi}/MessageTestFactory.java | 9 +- .../osi/OsiPostfachMessageMapperTest.java | 200 +++++ .../osi/OsiPostfachRemoteServiceTest.java | 141 +-- ...fachServerProcessExceptionTestFactory.java | 32 + .../src/test/resources/BspQuittung.xml | 6 + .../src/test/resources/BspQuittungError.xml | 11 + .../org.junit.jupiter.api.extension.Extension | 0 .../src/test/resources/bayernid.p12 | Bin 0 -> 6349 bytes .../test/resources/junit-platform.properties | 0 .../org.mockito.plugins.MockMaker | 1 + notification-manager/lombok.config | 40 +- notification-manager/pom.xml | 71 +- ...ntragstellerNotificationEventListener.java | 62 -- ...anagerCallContextAttachingInterceptor.java | 14 +- ...ntragstellerNotificationEventListener.java | 93 ++ .../AntragstellerNotificationService.java | 13 +- .../notification/command/Command.java | 6 +- .../notification/command/CommandBody.java | 4 +- .../notification/command/CommandMapper.java | 20 +- .../command/CommandRemoteService.java | 8 +- .../notification/command/CommandService.java | 38 +- .../email/EmailRecipientMapper.java | 9 +- .../email/EmailRemoteService.java | 22 +- .../notification/email/UserEmail.java | 6 +- .../postfach/PostfachAddress.java | 40 + .../postfach/PostfachAddressIdentifier.java | 28 + .../postfach/PostfachNachricht.java | 10 +- .../postfach/PostfachRemoteService.java | 50 ++ .../postfach/PostfachService.java | 38 + .../postfach/StringBasedIdentifier.java | 37 + .../notification/user/Recipient.java | 4 +- .../user/UserNotificationEventListener.java | 18 +- .../user/UserNotificationService.java | 25 +- .../user/UserRecipientMapper.java | 7 +- .../notification/user/UserRemoteService.java | 14 +- .../notification/vorgang/Vorgang.java | 13 +- .../notification/vorgang/VorgangId.java | 6 +- .../notification/vorgang/VorgangMapper.java | 79 ++ .../vorgang/VorgangRemoteService.java | 12 +- .../notification/vorgang/VorgangService.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 20 + ...gstellerNotificationEventListenerTest.java | 94 -- ...erCallContextAttachingInterceptorTest.java | 7 +- ...gstellerNotificationEventListenerTest.java | 238 +++++ .../AntragstellerNotificationServiceTest.java | 22 +- .../command/CommandMapperTest.java | 34 +- .../command/CommandRemoteServiceTest.java | 6 +- .../command/CommandServiceTest.java | 12 +- .../command/CommandTestFactory.java | 10 +- .../GrpcCreateCommandRequestTestFactory.java | 10 +- .../email/EmailRecipientMapperTest.java | 7 +- .../email/EmailRemoteServiceTest.java | 51 +- .../email/GrpcEmailRecipientTestFactory.java | 8 +- .../email/UserEmailTestFactory.java | 17 +- .../GrpcPostfachAddressTestFactory.java | 50 ++ .../postfach/PostfachAddressTestFactory.java | 46 + .../PostfachNachrichtTestFactory.java | 22 +- .../postfach/PostfachRemoteServiceTest.java | 78 ++ .../postfach/PostfachServiceTest.java | 55 ++ .../GrpcFindRecipientRequestTestFactory.java | 9 +- .../user/GrpcUserRecipientTestFactory.java | 6 +- .../user/RecipientTestFactory.java | 6 +- .../UserNotificationEventListenerTest.java | 33 +- .../user/UserNotificationServiceTest.java | 52 +- .../user/UserRecipientMapperTest.java | 4 +- .../user/UserRemoteServiceTest.java | 72 ++ .../vorgang/GrpcServiceKontoTestFactory.java | 42 + .../vorgang/GrpcVorgangHeadTestFactory.java | 38 + .../vorgang/GrpcVorgangTestFactory.java | 13 +- .../vorgang/VorgangMapperTest.java | 73 ++ .../vorgang/VorgangRemoteServiceTest.java | 14 +- .../vorgang/VorgangServiceTest.java | 4 +- .../vorgang/VorgangTestFactory.java | 7 +- pluto-interface/lombok.config | 28 - .../src/main/protobuf/vorgangmodel.proto | 143 --- .../VorgangAttachedItemEventListener.java | 87 -- .../PersistPostfachMailByCommandService.java | 210 ----- .../itvsh/ozg/pluto/command/StatusOrder.java | 76 -- ...inheitenIdForNordfrieslandWhenMissing.java | 64 -- ...MigrateMailServiceAttachmentsToGridFs.java | 179 ---- ...AttachmentsAndRepresentationsToGridFs.java | 173 ---- .../migration/M004_RemoveWiedervorlagen.java | 73 -- .../M005_CreateIndexesInVorgang.java | 80 -- .../migration/M006_MigrateKommentar.java | 116 --- ...IdOnUpdateVorgangAttachedItemCommands.java | 100 --- .../M009_RemoveAttachmentContent.java | 66 -- .../M010_RemoveRepresentationContent.java | 64 -- .../common/migration/M011_FixTypeAlias.java | 106 --- .../migration/M012_MigrationUserId.java | 210 ----- .../SearchVorgangCustomRepositoryImpl.java | 117 --- .../common/security/PolicyRepository.java | 101 --- .../pluto/vorgang/VorgangEventListener.java | 62 -- .../src/main/resources/application-dev.yml | 11 - .../src/main/resources/application-e2e.yml | 12 - .../src/main/resources/application-local.yml | 54 -- .../src/main/resources/application-prod.yml | 6 - .../src/main/resources/application-test.yml | 8 - .../main/resources/application-withdevdb.yml | 4 - pluto-server/src/main/resources/banner.txt | 5 - .../VorgangAttachedItemRepositoryITCase.java | 157 ---- .../command/CommandRepositoryITCase.java | 184 ---- ...M000_AddOrganisationIdMigrationITCase.java | 103 --- ...eMailServiceAttachmentsToGridFsITCase.java | 140 --- ...etInCreationFalseForAllVorgangsITCase.java | 86 -- ...mentsAndRepresentationsToGridFsITCase.java | 322 ------- .../M004_RemoveWiedervorlagenITCase.java | 113 --- .../M005_CreateIndexesInVorgangITCase.java | 80 -- .../M006_MigrateKommentarITCase.java | 145 ---- ...dateVorgangAttachedItemCommandsITCase.java | 222 ----- .../M008_DropBinaryFilesCollectionITCase.java | 71 -- .../M009_RemoveAttachmentContentITCase.java | 127 --- ...10_RemoveRepresentationsContentITCase.java | 120 --- .../migration/M011_FixTypeAliasITCase.java | 286 ------ .../migration/M012_MigrationUserIdITCase.java | 439 ---------- .../MigrationAttachmentTestFactory.java | 64 -- .../MigrationBinaryFileTestFactory.java | 61 -- .../migration/MigrationDbTestUtils.java | 175 ---- .../MigrationEingangHeaderTestFactory.java | 75 -- .../MigrationEingangTestFactory.java | 60 -- .../MigrationGridFSFileTestFactory.java | 34 - .../MigrationIncomingFileTestFactory.java | 78 -- .../MigrationKommentarTestFactory.java | 61 -- ...grationVorgangAttachedItemTestFactory.java | 52 -- .../MigrationVorgangTestFactory.java | 67 -- .../MigrationWiedervorlageTestFactory.java | 50 -- ...MigrationZustaendigeStelleTestFactory.java | 43 - .../search/SearchRequestTestFactory.java | 54 -- .../common/search/SearchServiceITCase.java | 260 ------ ...SearchVorgangCustomRepositoryImplTest.java | 196 ----- .../vorgang/EingangHeaderMapperTest.java | 79 -- .../pluto/vorgang/VorgangServiceITCase.java | 121 --- .../src/test/resources/application-itcase.yml | 26 - .../pluto/common/grpc/GrpcObjectMapper.java | 114 --- .../common/grpc/GrpcFormDataMapperTest.java | 337 -------- .../common/grpc/GrpcObjectMapperTest.java | 167 ---- .../common/grpc/GrpcObjectTestFactory.java | 96 --- .../common/grpc/GrpcSubFormTestFactory.java | 51 -- pom.xml | 64 +- release-erstellen.sh | 51 ++ release-startdev.sh | 84 ++ run_helm_test.sh | 33 + src/main/helm/Chart.yaml | 30 + src/main/helm/README.md | 41 + src/main/helm/templates/_helpers.tpl | 99 +++ .../templates/configmap_bindings_type.yaml | 32 + src/main/helm/templates/deployment.yaml | 333 +++++++ src/main/helm/templates/elasticsearch_cr.yaml | 31 + .../helm/templates/image-pull-secret.yaml | 34 + src/main/helm/templates/network_policy.yaml | 105 +++ ...sticsearch_operator_secrets_read_role.yaml | 42 + ...ch_operator_secrets_read_role_binding.yaml | 39 + ...ticsearch_operator_secrets_write_role.yaml | 38 + ...h_operator_secrets_write_role_binding.yaml | 39 + .../helm/templates/rabbitmq_exchange.yaml | 40 + .../helm/templates/rabbitmq_permissions.yaml | 42 + src/main/helm/templates/rabbitmq_queue.yaml | 42 + src/main/helm/templates/rabbitmq_secret.yaml | 40 + src/main/helm/templates/rabbitmq_user.yaml | 38 + .../templates/secret_ozgcloud_proxyapi.yaml | 34 + src/main/helm/templates/service.yaml | 44 + src/main/helm/templates/service_account.yaml | 31 + src/main/helm/templates/service_monitor.yaml | 43 + .../tests/test-service-connection.yaml | 39 + src/main/helm/values.yaml | 64 ++ src/test/helm-linter-values.yaml | 31 + .../helm/configmap_bindings_type_test.yaml | 46 + src/test/helm/deployment_63_chars_test.yaml | 57 ++ src/test/helm/deployment_bayernid_test.yaml | 183 ++++ src/test/helm/deployment_bindings_test.yaml | 57 ++ ...yment_container_security_context_test.yaml | 91 ++ .../helm/deployment_defaults_labels_test.yaml | 71 ++ src/test/helm/deployment_env_test.yaml | 122 +++ ...oyment_grpc_info_manager_address_test.yaml | 43 + ...oyment_grpc_user_manager_address_test.yaml | 63 ++ .../helm/deployment_host_aliases_test.yaml | 53 ++ .../deployment_imagepull_secret_test.yaml | 50 ++ .../helm/deployment_liveness_probe_test.yaml | 56 ++ src/test/helm/deployment_mongodb_test.yaml | 148 ++++ ...ment_nachrichten_manager_address_test.yaml | 43 + src/test/helm/deployment_rabbitmq_test.yaml | 98 +++ src/test/helm/deployment_resources_test.yaml | 62 ++ .../helm/deployment_service_account_test.yaml | 55 ++ .../helm/deployment_springProfile_test.yaml | 61 ++ src/test/helm/deployment_test.yaml | 42 + ...oyment_test_ozgcloud_base_values_test.yaml | 45 + .../helm/deployment_usermanager_url_test.yaml | 43 + .../deployment_zufimanager_address_test.yaml | 43 + src/test/helm/elasticsearch_cr_test.yaml | 76 ++ .../helm/elasticsearch_deployment_test.yaml | 186 ++++ src/test/helm/image_pull_secret_test.yaml | 59 ++ src/test/helm/network_policy_test.yaml | 306 +++++++ ...erator_secrets_read_role_binding_test.yaml | 97 +++ ...earch_operator_secrets_read_role_test.yaml | 86 ++ ...rator_secrets_write_role_binding_test.yaml | 104 +++ ...arch_operator_secrets_write_role_test.yaml | 81 ++ src/test/helm/rabbitmq_exchange_test.yaml | 59 ++ src/test/helm/rabbitmq_permissions_test.yaml | 72 ++ src/test/helm/rabbitmq_queue_test.yaml | 50 ++ src/test/helm/rabbitmq_user_test.yaml | 52 ++ src/test/helm/service_account_test.yaml | 62 ++ src/test/helm/service_monitor_test.yaml | 65 ++ src/test/helm/service_test.yaml | 77 ++ vorgang-manager-base/pom.xml | 86 ++ .../java/de/ozgcloud/vorgang/LogRunner.java | 44 + .../VorgangManagerServerApplication.java | 41 +- .../vorgang/callcontext}/CallContext.java | 9 +- .../CallContextAuthenticationToken.java | 4 +- .../CallContextHandleInterceptor.java | 33 +- .../vorgang}/callcontext/CallContextUser.java | 4 +- .../callcontext/CurrentUserService.java | 4 +- .../ozgcloud/vorgang/callcontext}/User.java | 10 +- ...ClientCallContextAttachingInterceptor.java | 72 ++ .../src/main/resources/.empty | 0 .../CallContextHandleInterceptorTest.java | 10 +- .../callcontext/CallContextTestFactory.java | 24 +- .../CallContextUserTestFactory.java | 10 +- .../callcontext/CurrentUserServiceITCase.java | 10 +- .../callcontext/CurrentUserServiceTest.java | 4 +- .../TestCallContextAttachingInterceptor.java | 16 +- .../vorgang/callcontext}/UserTestFactory.java | 6 +- ...ntCallContextAttachingInterceptorTest.java | 99 +++ .../org.junit.jupiter.api.extension.Extension | 1 + .../test/resources/junit-platform.properties | 1 + .../org.mockito.plugins.MockMaker | 1 + vorgang-manager-command/lombok.config | 30 + vorgang-manager-command/pom.xml | 79 ++ .../java/de/ozgcloud}/command/Command.java | 9 +- .../command/CommandCreatedEvent.java | 4 +- .../command/CommandExecutedEvent.java | 73 ++ .../ozgcloud}/command/CommandFailedEvent.java | 4 +- .../command/CommandRevokeFailedEvent.java | 13 +- .../ozgcloud/command/CommandRevokedEvent.java | 16 +- .../de/ozgcloud}/command/CommandStatus.java | 4 +- .../ozgcloud/command/RevokeCommandEvent.java | 40 + .../command/VorgangCreatedEvent.java | 6 +- .../CommandCreatedEventTestFactory.java | 36 + .../ozgcloud/command/CommandTestFactory.java | 49 ++ .../java/de/ozgcloud/command/TestCommand.java | 56 ++ vorgang-manager-interface/pom.xml | 198 +++++ .../src/main/protobuf/bescheid.model.proto | 48 ++ .../src/main/protobuf/bescheid.proto | 37 + .../src/main/protobuf/binaryfile.proto | 21 +- .../src/main/protobuf/callcontext.proto | 6 +- .../main/protobuf/clientattribute.model.proto | 6 +- .../src/main/protobuf/clientattribute.proto | 6 +- .../src/main/protobuf/command.model.proto | 34 +- .../src/main/protobuf/command.proto | 10 +- .../src/main/protobuf/common.model.proto | 19 +- .../src/main/protobuf/email.model.proto | 6 +- .../src/main/protobuf/email.proto | 6 +- .../src/main/protobuf/file.proto | 6 +- .../src/main/protobuf/filemodel.proto | 8 +- .../src/main/protobuf/forwarding.model.proto | 6 +- .../src/main/protobuf/forwarding.proto | 8 +- .../src/main/protobuf/postfach.model.proto | 61 +- .../src/main/protobuf/postfach.proto | 15 +- .../protobuf/route-forwarding.model.proto | 10 +- .../src/main/protobuf/route-forwarding.proto | 6 +- .../src/main/protobuf/statistic.model.proto | 92 ++ .../src/main/protobuf/statistic.proto | 38 + .../src/main/protobuf/system.model.proto | 6 +- .../src/main/protobuf/system.proto | 6 +- .../src/main/protobuf/vorgang.model.proto | 197 +++++ .../src/main/protobuf/vorgang.proto | 20 +- .../protobuf/vorgangattacheditem.model.proto | 8 +- .../main/protobuf/vorgangattacheditem.proto | 6 +- .../.mvn/wrapper/MavenWrapperDownloader.java | 0 .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 vorgang-manager-server/lombok.config | 30 + {pluto-server => vorgang-manager-server}/mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 219 +++-- vorgang-manager-server/run_local.sh | 25 + .../sonar-project.properties | 2 +- .../src/db/cleanup_vorgang.mongodb | 4 + .../src/license/eupl/header.txt | 40 + .../src/license/eupl/license.txt | 125 +++ .../src/license/licenses.properties | 25 + .../VorgangManagerServerConfiguration.java | 38 + .../VorgangProcessorConfiguration.java | 61 ++ .../GrpcVorgangAttachedItemMapper.java | 8 +- .../GrpcVorgangAttachedItemService.java | 16 +- .../attached_item/VorgangAttachedItem.java | 10 +- .../VorgangAttachedItemCreatedEvent.java | 10 +- .../VorgangAttachedItemCustomRepository.java | 8 +- ...rgangAttachedItemCustomRepositoryImpl.java | 60 +- .../VorgangAttachedItemDeletedEvent.java | 37 + .../VorgangAttachedItemEventListener.java | 144 ++++ .../VorgangAttachedItemMapper.java | 13 +- .../VorgangAttachedItemRepository.java | 17 +- .../VorgangAttachedItemService.java | 50 +- .../VorgangAttachedItemUpdatedEvent.java | 6 +- .../clientattribute/ClientAttribute.java | 7 +- ...ClientAttributeAlreadyExistsException.java | 6 +- .../ClientAttributeHasValueConstraint.java | 12 +- .../ClientAttributeIdentificator.java | 7 +- .../clientattribute/ClientAttributeMap.java | 4 +- .../ClientAttributeMapper.java | 12 +- .../ClientAttributeNotExistingException.java | 6 +- .../ClientAttributeReadPermitted.java | 8 +- .../ClientAttributeRepository.java | 12 +- .../ClientAttributeService.java | 7 +- .../clientattribute/ClientAttributesMap.java | 4 +- .../GrpcClientAttributeService.java | 20 +- .../vorgang}/command/CommandBodyMapper.java | 21 +- .../command/CommandDeletionScheduler.java | 65 ++ .../command/CommandEventListener.java | 19 +- .../vorgang}/command/CommandRepository.java | 62 +- .../vorgang}/command/CommandResponse.java | 11 +- .../vorgang}/command/CommandService.java | 73 +- .../command/CreateCommandRequest.java | 14 +- .../vorgang}/command/GrpcCommandMapper.java | 11 +- .../command/GrpcCommandResponseMapper.java | 8 +- .../vorgang}/command/GrpcCommandService.java | 113 ++- .../GrpcCreateCommandRequestMapper.java | 22 +- .../de/ozgcloud/vorgang}/command/Order.java | 11 +- ...sistPostfachNachrichtByCommandService.java | 256 ++++++ .../vorgang}/command/PersistedCommand.java | 17 +- .../common/converter/CustomConverters.java | 6 +- .../common/converter/FileIdConverter.java | 6 +- .../converter/ZonedDateTimeReadConverter.java | 4 +- .../ZonedDateTimeWriteConverter.java | 4 +- .../vorgang/common/db/CollisionVerifier.java | 62 ++ .../vorgang/common/db}/CriteriaUtil.java | 78 +- .../errorhandling/ExceptionHandler.java | 8 +- .../errorhandling/FunctionalException.java | 10 +- .../errorhandling/NotFoundException.java | 6 +- .../SearchServiceUnavailableException.java | 6 +- .../logging/RepositoryAspectPointcut.java | 4 +- .../logging/RepositoryLoggingAspect.java | 6 +- ...01_UpdateClientNameInClientAttributes.java | 52 ++ .../M002_UpdateClientNameInGridFs.java | 54 ++ ...UpdateClientNameInVorgangAttachedItem.java | 20 +- ...anagerClientNameInVorgangAttachedItem.java | 30 +- ...enManagerClientNameInClientAttributes.java | 52 ++ ...erviceClientNameInVorgangAttachedItem.java | 52 ++ ...ilServiceClientNameInClientAttributes.java | 52 ++ ...8_UpdateMailServiceClientNameInGridFs.java | 54 ++ .../common/migration/MigrationException.java | 4 +- .../migration/MongockFailedEventListener.java | 4 +- .../migration/MongockStartEventListener.java | 4 +- .../MongockSuccessEventListener.java | 4 +- .../vorgang/common/migration/RenameUtil.java | 83 ++ .../common/operator/EqualOperator.java | 52 ++ .../common/operator/ExistsOperator.java | 42 + .../common/operator/FieldPathProcessor.java | 98 +++ .../common/operator/GreaterThenOperator.java | 40 + .../operator/GreaterThenOrEqualOperator.java | 41 + .../common/operator/LessThenOperator.java | 41 + .../operator/LessThenOrEqualOperator.java | 41 + .../operator/OperandFunctionParser.java | 42 + .../vorgang/common/operator/Operator.java | 39 + .../common/operator/OperatorBuilder.java | 137 +++ .../common/operator/OperatorFactory.java | 37 + .../common/operator/UnequalOperator.java | 52 ++ .../operator/UnsupportedEntityException.java | 34 + .../common/search/IndexedVorgang.java | 13 +- .../common/search/IndexedVorgangMapper.java | 33 +- .../vorgang/common/search/SearchConfig.java | 73 ++ .../common/search/SearchEventListener.java | 46 +- .../common/search/SearchIndexInitializer.java | 12 +- .../common/search/SearchProperties.java | 15 +- .../vorgang}/common/search/SearchRequest.java | 4 +- .../vorgang}/common/search/SearchService.java | 47 +- .../search/SearchVorgangCustomRepository.java | 17 +- .../SearchVorgangCustomRepositoryImpl.java | 220 +++++ .../search/SearchVorgangRepository.java | 8 +- .../common/security/PolicyRepository.java | 129 +++ .../common/security/PolicyService.java | 18 +- .../userconfig/UserConfigRemoteService.java | 56 ++ .../common/userconfig/UserConfigService.java | 37 + .../vorgang}/files/BinaryFileRepository.java | 13 +- .../files/EingangFilesRepository.java | 6 +- .../de/ozgcloud/vorgang}/files/FileId.java | 6 +- .../ozgcloud/vorgang}/files/FileIdMapper.java | 4 +- .../ozgcloud/vorgang}/files/FileService.java | 24 +- .../vorgang}/files/GrpcBinaryFileService.java | 26 +- .../vorgang}/files/GrpcFileService.java | 14 +- .../vorgang}/files/GrpcOzgFileMapper.java | 6 +- .../de/ozgcloud/vorgang}/files/OzgFile.java | 10 +- .../vorgang}/files/UploadStreamObserver.java | 14 +- .../files/UploadedFilesReference.java | 4 +- .../vorgang/registry/RegistryScheduler.java | 60 ++ .../vorgang/registry/RegistryService.java | 66 ++ .../vorgang/registry/ZufiRemoteService.java | 57 ++ .../vorgang/servicekonto/PostfachAddress.java | 40 + .../vorgang/servicekonto/ServiceKonto.java | 43 + .../servicekonto/ServiceKontoMapper.java | 49 ++ .../vorgang/statistic/CountByPath.java | 39 + .../vorgang/statistic/CountResult.java | 39 + .../statistic/CountStatisticMapper.java | 97 +++ .../statistic/InvalidFieldPathException.java | 35 + .../ozgcloud/vorgang/statistic/Statistic.java | 47 + .../vorgang/statistic/StatisticFilter.java | 55 ++ .../statistic/StatisticGroupMethod.java | 37 + .../statistic/StatisticGrpcService.java | 57 ++ .../vorgang/statistic/StatisticMapper.java | 109 +++ .../statistic/StatisticRepository.java | 115 +++ .../vorgang/statistic/StatisticService.java | 157 ++++ .../statistic/VorgangCountRequest.java | 38 + .../VorgangStatisticBadRequestException.java | 33 + .../statistic/VorgangStatisticRequest.java | 39 + .../vorgang/status}/StatusChangedEvent.java | 9 +- .../vorgang/status/StatusEventListener.java | 169 ++++ .../vorgang/status/StatusRepository.java | 88 ++ .../vorgang/status/StatusService.java | 138 +++ .../system/SystemStatusGrpcService.java | 13 +- .../vorgang/user/DeleteUserScheduler.java | 57 ++ .../user/UserProfileRemoteService.java | 64 ++ .../de/ozgcloud/vorgang/user/UserService.java | 45 + ...anagerCallContextAttachingInterceptor.java | 82 ++ .../vorgang/AktenzeichenProvider.java | 4 +- .../AktenzeichenProviderConfiguration.java | 10 +- .../vorgang/AktenzeichenProviderEA.java | 4 +- .../vorgang}/vorgang/Antragsteller.java | 6 +- .../vorgang}/vorgang/AntragstellerMapper.java | 6 +- .../CustomVorgangHeaderRepository.java | 4 +- .../vorgang/DefaultAktenzeichenProvider.java | 4 +- .../de/ozgcloud/vorgang}/vorgang/Eingang.java | 4 +- .../vorgang}/vorgang/EingangHeader.java | 9 +- .../vorgang}/vorgang/EingangHeaderMapper.java | 13 +- .../vorgang}/vorgang/EingangMapper.java | 11 +- .../vorgang}/vorgang/FilterByMapper.java | 8 +- .../vorgang}/vorgang/FilterCriteria.java | 8 +- .../vorgang/FilterCriteriaDefault.java | 4 +- .../vorgang/vorgang/FindVorgangQuery.java | 45 + .../vorgang/FindVorgangQueryMapper.java | 81 ++ .../vorgang}/vorgang/FindVorgangRequest.java | 7 +- .../vorgang/FindVorgangRequestMapper.java | 8 +- .../vorgang}/vorgang/GrpcVorgangService.java | 33 +- .../vorgang}/vorgang/IncomingFile.java | 6 +- .../vorgang}/vorgang/IncomingFileGroup.java | 4 +- .../vorgang/IncomingFileGroupMapper.java | 5 +- .../vorgang}/vorgang/IncomingFileMapper.java | 6 +- .../vorgang/vorgang/LabelProcessor.java | 214 +++++ .../vorgang/vorgang/QueryCriteriaBuilder.java | 65 ++ .../SetAktenzeichenCompletedEvent.java | 34 + .../vorgang/VorgagnQueryExpression.java | 27 + .../de/ozgcloud/vorgang}/vorgang/Vorgang.java | 33 +- .../vorgang/VorgangAssignedEvent.java | 10 +- .../vorgang/VorgangAuthorizationService.java | 4 +- .../vorgang/vorgang/VorgangDeletedEvent.java | 37 + .../vorgang/vorgang/VorgangEventListener.java | 127 +++ .../ozgcloud/vorgang/vorgang/VorgangHead.java | 40 + .../vorgang}/vorgang/VorgangHeader.java | 8 +- .../vorgang}/vorgang/VorgangHeaderMapper.java | 6 +- .../vorgang/VorgangHeaderRepository.java | 4 +- .../vorgang/VorgangHeaderRepositoryImpl.java | 119 ++- .../vorgang/VorgangHeaderService.java | 21 +- .../vorgang}/vorgang/VorgangRepository.java | 61 +- .../vorgang}/vorgang/VorgangService.java | 174 ++-- .../ozgcloud/vorgang/vorgang/VorgangStub.java | 73 ++ .../vorgang/vorgang/VorgangStubMapper.java | 63 ++ .../vorgang/VorgangWithEingangMapper.java | 14 +- .../vorgang}/vorgang/ZustaendigeStelle.java | 10 +- .../vorgang/ZustaendigeStelleMapper.java | 4 +- .../vorgang}/vorgang/redirect/Forwarding.java | 4 +- .../redirect/ForwardingEventListener.java | 52 +- .../redirect/ForwardingGrpcService.java | 10 +- .../vorgang/redirect/ForwardingMapper.java | 6 +- .../redirect/ForwardingRepository.java | 6 +- .../vorgang/redirect/ForwardingService.java | 63 +- .../vorgang/redirect/RedirectRequest.java | 4 +- .../redirect/RedirectRequestMapper.java | 6 +- .../redirect/VorgangForwardFailedEvent.java | 8 +- .../VorgangForwardSuccessfullEvent.java | 8 +- .../redirect/VorgangRedirectFailedEvent.java | 6 +- .../redirect/VorgangRedirectedEvent.java | 4 +- .../vorgang/redirect/ZipBuilderService.java | 20 +- ...itional-spring-configuration-metadata.json | 20 +- .../src/main/resources/META-INF/mime.types | 0 ...ot.autoconfigure.AutoConfiguration.imports | 20 + .../main/resources/application-a12proc.yml | 23 + .../src/main/resources/application-bayern.yml | 29 + .../src/main/resources/application-dev.yml | 9 + .../src/main/resources/application-e2e.yml | 14 + .../src/main/resources/application-local.yml | 124 +++ .../src/main/resources/application-oc.yml | 0 .../src/main/resources/application-prod.yml | 3 + .../src/main/resources/application-stage.yml | 1 + .../src/main/resources/application-test.yml | 7 + .../main/resources/application-withdevdb.yml | 5 + .../src/main/resources/application.yml | 41 +- .../src/main/resources/banner.txt | 7 + .../src/main/resources/elastic/settings.json | 10 + .../src/main/resources/images/logo-ea-sh.png | Bin .../src/main/resources/images/logo-itvsh.png | Bin .../src/main/resources/log4j2-local.xml | 39 + .../mail/redirect.confirmation.txt.ftlh | 2 +- .../templates/mail/redirect.txt.ftlh | 2 +- .../attributes/ClientAttributeITCase.java | 22 +- .../postfach/PostfachEventListenerITCase.java | 33 +- .../postfach/PostfachMailITCase.java | 107 ++- ...nIdPostfachServiceConfigurationITCase.java | 85 ++ .../postfach/osi}/OsiPostfachApiTestCase.java | 32 +- .../osi/OsiPostfachRemoteServiceITCase.java | 53 +- .../ozgcloud/processor/ProcessorITCase.java | 129 +++ .../de/ozgcloud/vorgang}/DbInitializer.java | 4 +- .../ozgcloud/vorgang}/TestConfiguration.java | 5 +- .../VorgangManagerServerApplicationTests.java | 8 +- ...VorgangAttachedItemRequestTestFactory.java | 8 +- .../GrpcVorgangAttachedItemMapperTest.java | 10 +- ...VorgangAttachedItemRequestTestFactory.java | 6 +- ...organgAttachedItemResponseTestFactory.java | 6 +- .../GrpcVorgangAttachedItemServiceTest.java | 16 +- .../GrpcVorgangAttachedItemTestFactory.java | 10 +- ...gAttachedItemCustomRepositoryImplTest.java | 79 ++ ...organgAttachedItemEventListenerITCase.java | 71 +- .../VorgangAttachedItemEventListenerTest.java | 92 +- .../VorgangAttachedItemITCase.java | 72 +- .../VorgangAttachedItemMapperTest.java | 4 +- .../VorgangAttachedItemRepositoryITCase.java | 297 +++++++ .../VorgangAttachedItemServiceITCase.java | 77 ++ .../VorgangAttachedItemServiceTest.java | 130 ++- .../VorgangAttachedItemTestFactory.java | 15 +- .../ClientAttributeHasValueValidatorTest.java | 10 +- .../ClientAttributeITCase.java | 20 +- ...ientAttributeIdentificatorTestFactory.java | 8 +- .../ClientAttributeMapperTest.java | 12 +- .../ClientAttributeReadPermittedTest.java | 10 +- .../ClientAttributeRepositoryITCase.java | 34 +- .../ClientAttributeServiceITCase.java | 11 +- .../ClientAttributeServiceTest.java | 6 +- .../ClientAttributeTestFactory.java | 10 +- .../ClientAttributesMapTestFactory.java | 6 +- .../GrpcClientAttributeServiceITCase.java | 14 +- .../GrpcClientAttributeServiceTest.java | 20 +- .../GrpcClientAttributeTestFactory.java | 14 +- ...leteClientAttributeRequestTestFactory.java | 10 +- ...cSetClientAttributeRequestTestFactory.java | 12 +- ...dateClientAttributeRequestTestFactory.java | 6 +- .../command/AttachmentFileTestFactory.java | 56 ++ .../CommandCreatedEventTestFactory.java | 11 +- .../command/CommandDeletionSchedulerTest.java | 92 ++ .../command/CommandEventListenerTest.java | 90 ++ .../CommandExecutedEventTestFactory.java | 35 + .../vorgang}/command/CommandITCase.java | 189 ++-- .../command/CommandRepositoryITCase.java | 376 ++++++++ .../command/CommandResponseMapperTest.java | 10 +- .../command/CommandResponseTestFactory.java | 9 +- .../CommandRevokedEventTestFactory.java | 33 + .../command/CommandServiceITCase.java | 52 +- .../vorgang}/command/CommandServiceTest.java | 146 +++- .../vorgang}/command/CommandTestFactory.java | 17 +- .../CreateCommandRequestTestFactory.java | 9 +- .../command/GrpcCallContextTestFactory.java | 12 +- .../command/GrpcCommandMapperTest.java | 8 +- .../command/GrpcCommandServiceITCase.java | 123 +++ .../command/GrpcCommandServiceTest.java | 151 ++-- .../GrpcCreateCommandRequestMapperTest.java | 12 +- .../GrpcCreateCommandRequestTestFactory.java | 12 +- .../vorgang}/command/GrpcUserTestFactory.java | 7 +- ...istPostfachMailByCommandServiceITCase.java | 27 +- ...rsistPostfachMailByCommandServiceTest.java | 127 +-- .../ZonedDateTimeReadConverterTest.java | 4 +- .../ZonedDateTimeWriteConverterTest.java | 4 +- .../common/db/CollisionVerifierTest.java | 147 ++++ .../vorgang/common/db}/CriteriaUtilTest.java | 10 +- .../errorhandling/ExceptionHandlerTest.java | 15 +- .../FunctionalExceptionTest.java | 4 +- ...ateClientNameInClientAttributesITCase.java | 99 +++ .../M002_UpdateClientNameInGridFsITCase.java | 110 +++ ...ClientNameInVorgangAttachedItemITCase.java | 95 ++ ...ClientNameInVorgangAttachedItemITCase.java | 94 ++ ...gerClientNameInClientAttributesITCase.java | 97 +++ ...ClientNameInVorgangAttachedItemITCase.java | 94 ++ ...iceClientNameInClientAttributesITCase.java | 97 +++ ...teMailServiceClientNameInGridFsITCase.java | 110 +++ .../migration/MigrationDbTestUtils.java | 114 +++ .../common/migration/MigrationTestUtils.java | 4 +- .../common/migration/RenameTestFactory.java | 141 +++ .../common/migration/RenameUtilITCase.java | 153 ++++ .../operator/FieldPathProcessorTest.java | 92 ++ .../operator/OperandFunctionParserTest.java | 42 + .../common/operator/OperatorBuilderTest.java | 305 +++++++ .../common/operator/OperatorTestFactory.java | 54 ++ .../search/IndexedVorgangMapperTest.java | 15 +- .../search/IndexedVorgangTestFactory.java | 18 +- .../common/search/SearchConfigTest.java | 59 +- .../search/SearchEventListenerTest.java | 88 +- .../vorgang}/common/search/SearchITCase.java | 8 +- .../search/SearchIndexEnabledInitializer.java | 6 +- .../search/SearchIndexInitializerITCase.java | 22 +- .../common/search/SearchInitializer.java | 19 +- .../common/search/SearchServiceITCase.java | 449 ++++++++++ .../common/search/SearchServiceTest.java | 43 +- .../SearchVorgangCustomRepositoryITCase.java | 135 +++ ...SearchVorgangCustomRepositoryImplTest.java | 553 ++++++++++++ .../search/SearchVorgangRepositoryITCase.java | 24 +- .../security/PolicyRepositoryITCase.java | 37 +- .../common/security/PolicyRepositoryTest.java | 102 +++ .../common/security/PolicyServiceTest.java | 28 +- ...anisationEinheitenResponseTestFactory.java | 40 + .../UserConfigRemoteServiceTest.java | 74 ++ .../userconfig/UserConfigServiceTest.java | 27 +- .../vorgang}/files/BinaryFileITCase.java | 31 +- .../files/BinaryFileRepositoryITCase.java | 68 +- .../files/BinaryFileRepositoryTest.java | 31 +- .../files/EingangFilesRepositoryITCase.java | 18 +- .../ozgcloud/vorgang}/files/FileITCase.java | 26 +- .../vorgang}/files/FileServiceTest.java | 65 +- .../vorgang}/files/GridFsTestFactory.java | 10 +- .../files/GrpcBinaryFileServiceTest.java | 27 +- .../GrpcBinaryFilesRequestTestFactory.java | 6 +- .../GrpcGetAttachmentsRequestTestFactory.java | 8 +- ...pcGetBinaryFileDataRequestTestFactory.java | 8 +- ...cGetRepresentationsRequestTestFactory.java | 8 +- .../vorgang}/files/GrpcOzgFileMapperTest.java | 6 +- ...pcUploadBinaryFileMetaDataTestFactory.java | 10 +- ...rpcUploadBinaryFileRequestTestFactory.java | 8 +- ...rpcUploadedFilesReferencesTestFactory.java | 6 +- .../vorgang}/files/OzgFileTestFactory.java | 8 +- .../files/UploadStreamObserverTest.java | 20 +- .../UploadedFilesReferenceTestFactory.java | 8 +- .../GrpcRegistrationResponseTestFactory.java | 36 + .../registry/RegistrySchedulerTest.java | 86 ++ .../vorgang/registry/RegistryServiceTest.java | 83 ++ .../registry/ZufiRemoteServiceTest.java | 78 ++ .../GrpcPostfachAddressTestFactory.java | 51 ++ .../GrpcServiceKontoTestFactory.java | 39 + .../PostfachAddressTestFactory.java | 47 + .../servicekonto/ServiceKontoMapperTest.java | 76 ++ .../servicekonto/ServiceKontoTestFactory.java | 39 + .../vorgang/statistic/CountByPathTest.java | 46 + .../statistic/CountByPathTestFactory.java | 40 + .../CountPathRequestTestFactory.java | 39 + .../statistic/CountResultTestFactory.java | 38 + .../statistic/CountStatisticMapperTest.java | 184 ++++ .../GrpcVorgangStatisticQueryTestFactory.java | 49 ++ ...rpcVorgangStatisticRequestTestFactory.java | 36 + ...pcVorgangStatisticResponseTestFactory.java | 37 + ...GrpcVorgangStatisticResultTestFactory.java | 39 + .../statistic/OperatorTestFactory.java | 41 + .../statistic/StatisticGrpcServiceTest.java | 167 ++++ .../statistic/StatisticMapperTest.java | 345 ++++++++ .../statistic/StatisticRepositoryITCase.java | 285 ++++++ .../statistic/StatisticRepositoryTest.java | 254 ++++++ .../statistic/StatisticServiceTest.java | 437 ++++++++++ .../statistic/StatisticTestFactory.java | 66 ++ .../VorgangCountRequestTestFactory.java | 35 + .../VorgangStatisticRequestTestFactory.java | 46 + .../status/StatusEventListenerITCase.java | 180 ++++ .../status/StatusEventListenerTest.java | 267 ++++++ .../status/StatusRepositoryITCase.java | 125 +++ .../vorgang/status/StatusRepositoryTest.java | 61 ++ .../vorgang/status/StatusServiceTest.java | 383 +++++++++ .../system/SystemStatusGrpcServiceTest.java | 13 +- .../vorgang/user/DeleteUserSchedulerTest.java | 104 +++ .../user/UserProfileRemoteServiceTest.java | 137 +++ .../vorgang/user/UserServiceTest.java | 65 ++ ...erCallContextAttachingInterceptorTest.java | 106 +++ .../vorgang/AktenzeichenProviderEATest.java | 4 +- .../vorgang/AktenzeichenServiceITCase.java | 6 +- .../vorgang/AntragstellerMapperTest.java | 6 +- .../vorgang/AntragstellerTestFactory.java | 4 +- .../DefaultAktenzeichenProviderTest.java | 4 +- .../vorgang/EingangHeaderMapperTest.java | 113 +++ .../vorgang/EingangHeaderTestFactory.java | 12 +- .../vorgang}/vorgang/EingangMapperTest.java | 46 +- .../vorgang}/vorgang/EingangTestFactory.java | 19 +- .../vorgang}/vorgang/FilterByMapperTest.java | 10 +- .../vorgang/FilterCriteriaTestFactory.java | 14 +- .../vorgang/FindVorgangQueryMapperTest.java | 262 ++++++ .../vorgang/FindVorgangQueryTestFactory.java | 42 + .../vorgang/FindVorgangRequestMapperTest.java | 16 +- .../FindVorgangRequestTestFactory.java | 6 +- .../vorgang/GrpcAntragstellerTestFactory.java | 4 +- .../GrpcCreateVorgangRequestTestFactory.java | 8 +- .../vorgang/GrpcEingangHeaderTestFactory.java | 12 +- .../vorgang/GrpcEingangTestFactory.java | 6 +- .../vorgang/GrpcFilterByTestFactory.java | 8 +- .../GrpcFindVorgangRequestTestFactory.java | 6 +- .../GrpcFinishCreationRequestTestFactory.java | 11 +- .../GrpcIncomingFileGroupTestFactory.java | 4 +- .../vorgang/GrpcIncomingFileTestFactory.java | 4 +- .../vorgang/vorgang/GrpcQueryTestFactory.java | 39 + .../vorgang/GrpcVorgangHeadTestFactory.java | 38 + ...GrpcVorgangQueryExpressionTestFactory.java | 45 + .../GrpcVorgangServiceFindQueryITCase.java | 183 ++++ .../vorgang/GrpcVorgangServiceITCase.java | 256 ++++++ .../vorgang/GrpcVorgangServiceTest.java | 104 +-- .../GrpcVorgangWithEingangTestFactory.java | 13 +- .../GrpcZustaendigeStelleTestFactory.java | 4 +- .../vorgang/IncomingFileGroupMapperTest.java | 6 +- .../vorgang/IncomingFileGroupTestFactory.java | 4 +- .../vorgang/IncomingFileMapperTest.java | 6 +- .../vorgang/IncomingFileTestFactory.java | 8 +- .../vorgang/vorgang/LabelProcessorTest.java | 481 +++++++++++ .../vorgang/QueryCriteriaBuilderTest.java | 136 +++ .../VorgangAuthorizationServiceTest.java | 4 +- .../VorgangDeletedEventTestFactory.java | 34 + .../vorgang/VorgangEventListenerITCase.java | 152 ++++ .../vorgang/VorgangEventListenerTest.java | 234 +++++ .../vorgang/VorgangHeadTestFactory.java | 38 + .../VorgangHeaderRepositoryITCase.java | 515 ++++++++--- .../VorgangHeaderRepositoryImplITCase.java | 68 +- .../VorgangHeaderRepositoryImplTest.java | 4 +- .../vorgang/VorgangHeaderServiceTest.java | 63 +- .../vorgang/VorgangHeaderTestFactory.java | 6 +- .../vorgang}/vorgang/VorgangITCase.java | 190 ++-- .../vorgang/VorgangRepositoryITCase.java | 146 +++- .../vorgang/vorgang/VorgangServiceITCase.java | 84 ++ .../vorgang}/vorgang/VorgangServiceTest.java | 374 ++++---- .../vorgang/VorgangStubMapperTest.java | 67 ++ .../vorgang/VorgangStubTestFactory.java | 41 + .../vorgang}/vorgang/VorgangTestFactory.java | 19 +- .../vorgang/VorgangWithEingangMapperTest.java | 20 +- .../vorgang/ZustaendigeStelleMapperTest.java | 4 +- .../vorgang/ZustaendigeStelleTestFactory.java | 18 +- .../redirect/ForwardVorgangITCase.java | 98 ++- .../ForwardingEventListenerITCase.java | 29 +- .../redirect/ForwardingEventListenerTest.java | 51 +- .../redirect/ForwardingGrpcServiceTest.java | 10 +- .../vorgang/redirect/ForwardingITCase.java | 84 ++ .../redirect/ForwardingRepositoryITCase.java | 12 +- .../redirect/ForwardingServiceITCase.java | 16 +- .../redirect/ForwardingServiceTest.java | 113 ++- .../redirect/ForwardingTestFactory.java | 10 +- ...GrpcFindForwardingsRequestTestFactory.java | 10 +- .../redirect/RedirectRequestTestFactory.java | 6 +- .../VorgangForwardFailedEventTestFactory.java | 8 +- .../VorgangRedirectedEventTestFactory.java | 4 +- .../redirect/ZipBuilderServiceTest.java | 18 +- .../org.junit.jupiter.api.extension.Extension | 1 + .../src/test/resources/TestDoc.docx | Bin .../src/test/resources/application-itcase.yml | 17 + .../test/resources/application-with_db.yml | 2 +- .../src/test/resources/bayernid.p12 | Bin 0 -> 6349 bytes .../src/test/resources/bayernid/bsp-nachricht | 1 + .../src/test/resources/bayernid/test.txt | 1 + .../test/resources/junit-platform.properties | 1 + .../pom.xml | 100 ++- .../common/grpc/FormDataMappingUtils.java | 147 ++++ .../common/grpc/GrpcFormDataMapper.java | 136 +-- .../vorgang/common/grpc/GrpcObjectMapper.java | 119 +++ .../common/grpc/FormDataMappingUtilsTest.java | 251 ++++++ .../common/grpc/GrpcFormDataMapperTest.java | 516 +++++++++++ .../common/grpc/GrpcFormDataTestFactory.java | 39 + .../common/grpc/GrpcFormFieldTestFactory.java | 18 +- .../common/grpc/GrpcObjectMapperTest.java | 362 ++++++++ .../common/grpc/GrpcObjectTestFactory.java | 50 ++ .../common/grpc/GrpcPropertyTestFactory.java | 56 ++ .../common/grpc/GrpcSubFormTestFactory.java | 85 ++ .../common/grpc/GrpcSubObjectTestFactory.java | 48 ++ .../org.junit.jupiter.api.extension.Extension | 1 + .../test/resources/junit-platform.properties | 1 + 1044 files changed, 49724 insertions(+), 12312 deletions(-) create mode 100644 .helmignore create mode 100644 bescheid-manager/pom.xml create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/Bescheid.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCallContextAttachingInterceptor.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCreatedEvent.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRequest.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/GrpcBescheidMapper.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/UserId.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextAuthenticationToken.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextUser.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfile.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileMapper.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileTestFactory.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/dummy/DummyBescheidRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/Nachricht.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtId.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtMapper.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsConfiguration.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsProperties.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsRequest.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapper.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntry.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntryMapper.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializer.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/Vorgang.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangId.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteService.java create mode 100644 bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangService.java create mode 100644 bescheid-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 bescheid-manager/src/main/resources/dummy-bescheid.pdf create mode 100644 bescheid-manager/src/main/resources/templates/bescheid.nachrichtTemplate.txt.ftlh create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidRequestTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidServiceTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestApplication.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestFactory.java rename notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangMapperTest.java => bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidMapperTest.java (72%) create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidTestFactory.java rename pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsTest.java => bescheid-manager/src/test/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserServiceTest.java (59%) create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/GrpcPostfachNachrichtTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtMapperTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteServiceTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceITCase.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceITCase.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsResponseTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapperTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializerTest.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcEingangTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcVorgangWithEingangTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/ServiceKontoTestFactory.java create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteServiceTest.java rename notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRemoteServiceTest.java => bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangServiceTest.java (60%) create mode 100644 bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangTestFactory.java rename {mail-service => bescheid-manager}/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension (100%) create mode 100644 bescheid-manager/src/test/resources/SD_answer.xml create mode 100644 bescheid-manager/src/test/resources/application-itcase.yml rename {mail-service => bescheid-manager}/src/test/resources/junit-platform.properties (100%) rename {mail-service => bescheid-manager}/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) create mode 100644 dependency-check-supressions.xml rename pluto-server/lombok.config => lombok.config (94%) delete mode 100644 mail-service/lombok.config delete mode 100644 mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachEventListener.java delete mode 100644 mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailMapper.java delete mode 100644 mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachService.java delete mode 100644 mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerTest.java delete mode 100644 mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailMapperTest.java delete mode 100644 mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailTestFactory.java delete mode 100644 mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachServiceTest.java create mode 100644 mongodb/docker-compose.yml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/pom.xml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProperties.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyApplication.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyConfiguration.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcService.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyService.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/DeleteOnCloseInputStream.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserver.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteService.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandler.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Absender.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Attachment.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessage.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapper.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdResponse.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Empfaenger.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-dev.yml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-local.yml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application.yml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/bspnachrichten-2.13.xsd create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/log4j2-local.xml create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcServiceITCase.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyServiceTest.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdResponseTestFactory.java rename pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchConfiguration.java => nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAbsenderTestFactory.java (50%) create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAttachmentMetadataTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcBayernIdMessageMetadataTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcEmpfaengerTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserverTest.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteServiceTest.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandlerTest.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AbsenderTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AttachmentTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapperTest.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageTestFactory.java rename pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandExecutedEventTestFactory.java => nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdRsponseTestFactory.java (77%) create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BspQuitungTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/EmpfaengerTestFactory.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/BayernIdResponse.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/GrpcBayernIdProxyTestClient.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdInitializer.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdSendStreamObserver.java create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockChunkedDataStreamer.java rename {pluto-server => nachrichten-bayernid-proxy/bayernid-proxy-impl}/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension (100%) create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/application-itcase.yml rename {pluto-server => nachrichten-bayernid-proxy/bayernid-proxy-impl}/src/test/resources/junit-platform.properties (100%) create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.pdf create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.txt rename {pluto-interface => nachrichten-bayernid-proxy/bayernid-proxy-interface}/pom.xml (53%) create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernidproxy.model.proto create mode 100644 nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernproxy.proto create mode 100644 nachrichten-bayernid-proxy/pom.xml create mode 100755 nachrichten-bayernid-proxy/run_helm_test.sh create mode 100644 nachrichten-bayernid-proxy/src/main/helm/.helmignore create mode 100644 nachrichten-bayernid-proxy/src/main/helm/Chart.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/_helpers.tpl create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/configmap_bindings_type.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/deployment.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/service.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/templates/service_account.yaml create mode 100644 nachrichten-bayernid-proxy/src/main/helm/values.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm-linter-values.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/configmap_bindings_type_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_actuator_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_bayernid_certificate_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_bindings_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_container_basic_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_container_other_values_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_container_security_context_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_defaults_labels_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_env_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_imagepull_secret_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_ozgcloud_base_values_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_resources_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_service_account_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_springProfile_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deployment_template_other_values_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/deyploment_general_value_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/service_account_test.yaml create mode 100644 nachrichten-bayernid-proxy/src/test/helm/service_test.yaml create mode 100644 nachrichten-manager/lombok.config rename {mail-service => nachrichten-manager}/pom.xml (55%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerProperties.java rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeRemoteService.java (81%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeService.java (94%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeTestFactory.java (90%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/common/errorhandling/FunctionalException.java (90%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/common/errorhandling/TechnicalException.java (84%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/common/grpc/NachrichtenCallContextAttachingInterceptor.java (87%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/EMailService.java (93%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/EmailGrpcService.java (90%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/MailRecipient.java (90%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/MailSendErrorEvent.java (92%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/MailSendRequest.java (91%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/MailSentEvent.java (92%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/email/MailService.java (92%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/AttachmentFile.java rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/BinaryFileService.java (91%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/FileId.java (89%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachNachrichtMapper.java rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/NotConfiguredException.java (73%) rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PersistPostfachMailService.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java (81%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/Postfach.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddressIdentifier.java rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachBadRequestException.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachBadRequestException.java (73%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachEventListener.java rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachException.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachException.java (70%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/PostfachGrpcService.java (67%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/PostfachMailSentEvent.java (87%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/PostfachMailSentFailedEvent.java (88%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMapper.java rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachMessageCode.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMessageCode.java (90%) rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMail.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java (87%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachRuntimeException.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRuntimeException.java (73%) rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/PostfachScheduler.java (75%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java rename {mail-service/src/main/java/de/itvsh/ozg/mail => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten}/postfach/SendPostfachNachrichtResponse.java (88%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/StringBasedIdentifier.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumProperties.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumService.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachricht.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtMapper.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerProperties.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteService.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/Absender.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachment.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentService.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapper.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java rename notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangMapper.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandler.java (53%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdProperties.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponse.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdServerException.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatus.java create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/Message.java (87%) rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/MessageAttachment.java (91%) rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/AttachmentService.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java (59%) rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/MockOsiPostfachConfiguration.java (92%) rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/MockOsiPostfachRestTemplate.java (92%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapper.java rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/OsiPostfachProperties.java (89%) rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachService.java => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteService.java (71%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessException.java rename {mail-service/src/main/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi}/PostfachConfiguration.java (81%) create mode 100644 nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/ReplyOption.java create mode 100644 nachrichten-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 nachrichten-manager/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl create mode 100644 nachrichten-manager/src/main/resources/bayernid/bspnachrichten-2.13.xsd rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeRemoteServiceTest.java (88%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeServiceTest.java (94%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/attributes/GrpcClientAttributeTestFactory.java (81%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/attributes/GrpcSetClientAttributeRequestTestFactory.java (82%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/EMailServiceTest.java (95%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/EmailGrpcServiceTest.java (96%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/GrpcNotificationRecipientsTestFactory.java (93%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/GrpcRecipientTestFactory.java (92%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/MailRecipientTestFactory.java (92%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/MailSendErrorEventTestFactory.java (91%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/MailSendRequestTestFactory.java (90%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/email/MailSentEventTestFactory.java (91%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachAddressTestFactory.java rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/GrpcPostfachMailTestFactory.java (73%) rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/GrpcResendPostfachMailRequestTestFactory.java (84%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSaveNachrichtDraftRequestTestFactory.java rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/GrpcSendPostfachMailRequestTestFactory.java (88%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachAddressTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/PostfachGrpcServiceTest.java (60%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMapperTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/PostfachSchedulerTest.java (92%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachTestFactory.java rename {mail-service/src/test/java/de/itvsh/ozg/mail => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten}/postfach/SendPostfachNachrichtResponseTestFactory.java (86%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumServiceTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteServiceTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentServiceTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapperTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandlerTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPropertiesITCase.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponseTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BspNachrichtTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/EmpfaengerTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSenderTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FreiTextTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/GrpcSendBayernIdMessageResponseTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/IdentifikationNachrichtTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatusTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenInhaltTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenKopfTypeTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/SendBspNachrichtNativeOutputTestFactory.java create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/ZuVorgangTypeTestFactory.java rename mail-service/src/test/java/de/itvsh/ozg/mail/postfach/AttachmentServiceTest.java => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java (71%) rename {mail-service/src/test/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi}/MessageAttachmentTestFactory.java (87%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageJsonReplyTestFactory.java rename {mail-service/src/test/java/de/itvsh/ozg/mail/postfach => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi}/MessageTestFactory.java (88%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapperTest.java rename mail-service/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceTest.java => nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceTest.java (65%) create mode 100644 nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessExceptionTestFactory.java create mode 100644 nachrichten-manager/src/test/resources/BspQuittung.xml create mode 100644 nachrichten-manager/src/test/resources/BspQuittungError.xml rename {pluto-utils => nachrichten-manager}/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension (100%) create mode 100644 nachrichten-manager/src/test/resources/bayernid.p12 rename {pluto-utils => nachrichten-manager}/src/test/resources/junit-platform.properties (100%) create mode 100644 nachrichten-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListener.java rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/NotificationManagerCallContextAttachingInterceptor.java (90%) create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListener.java rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/antragsteller/AntragstellerNotificationService.java (87%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/command/Command.java (88%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandBody.java (89%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandMapper.java (83%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandRemoteService.java (83%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandService.java (57%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/email/EmailRecipientMapper.java (83%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/email/EmailRemoteService.java (71%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/email/UserEmail.java (87%) create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddress.java create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddressIdentifier.java rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/postfach/PostfachNachricht.java (82%) create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachRemoteService.java create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachService.java create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/postfach/StringBasedIdentifier.java rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/user/Recipient.java (90%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/user/UserNotificationEventListener.java (71%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/user/UserNotificationService.java (62%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/user/UserRecipientMapper.java (86%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/user/UserRemoteService.java (70%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/Vorgang.java (84%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangId.java (87%) create mode 100644 notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangMapper.java rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangRemoteService.java (81%) rename notification-manager/src/main/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangService.java (91%) create mode 100644 notification-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListenerTest.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/NotificationManagerCallContextAttachingInterceptorTest.java (92%) create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListenerTest.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/antragsteller/AntragstellerNotificationServiceTest.java (82%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandMapperTest.java (70%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandRemoteServiceTest.java (90%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandServiceTest.java (88%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/command/CommandTestFactory.java (84%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/command/GrpcCreateCommandRequestTestFactory.java (82%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/email/EmailRecipientMapperTest.java (89%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/email/EmailRemoteServiceTest.java (65%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/email/GrpcEmailRecipientTestFactory.java (84%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/email/UserEmailTestFactory.java (71%) create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/postfach/GrpcPostfachAddressTestFactory.java create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachAddressTestFactory.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/postfach/PostfachNachrichtTestFactory.java (69%) create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachRemoteServiceTest.java create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachServiceTest.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/GrpcFindRecipientRequestTestFactory.java (85%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/GrpcUserRecipientTestFactory.java (89%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/RecipientTestFactory.java (88%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/UserNotificationEventListenerTest.java (71%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/UserNotificationServiceTest.java (63%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/user/UserRecipientMapperTest.java (93%) create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/user/UserRemoteServiceTest.java create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcServiceKontoTestFactory.java create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangHeadTestFactory.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/GrpcVorgangTestFactory.java (82%) create mode 100644 notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangMapperTest.java rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangRemoteServiceTest.java (85%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangServiceTest.java (94%) rename notification-manager/src/test/java/de/{itvsh/kop => ozgcloud}/notification/vorgang/VorgangTestFactory.java (89%) delete mode 100644 pluto-interface/lombok.config delete mode 100644 pluto-interface/src/main/protobuf/vorgangmodel.proto delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListener.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandService.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/command/StatusOrder.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFs.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagen.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgang.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentar.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContent.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationContent.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAlias.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserId.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImpl.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyRepository.java delete mode 100644 pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListener.java delete mode 100644 pluto-server/src/main/resources/application-dev.yml delete mode 100644 pluto-server/src/main/resources/application-e2e.yml delete mode 100644 pluto-server/src/main/resources/application-local.yml delete mode 100644 pluto-server/src/main/resources/application-prod.yml delete mode 100644 pluto-server/src/main/resources/application-test.yml delete mode 100644 pluto-server/src/main/resources/application-withdevdb.yml delete mode 100644 pluto-server/src/main/resources/banner.txt delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepositoryITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandRepositoryITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationIdMigrationITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangsITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFsITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagenITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgangITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentarITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommandsITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollectionITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContentITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationsContentITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAliasITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserIdITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationAttachmentTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationBinaryFileTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationDbTestUtils.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangHeaderTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationGridFSFileTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationIncomingFileTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationKommentarTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangAttachedItemTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationWiedervorlageTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationZustaendigeStelleTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchRequestTestFactory.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceITCase.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImplTest.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapperTest.java delete mode 100644 pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceITCase.java delete mode 100644 pluto-server/src/test/resources/application-itcase.yml delete mode 100644 pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapper.java delete mode 100644 pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapperTest.java delete mode 100644 pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapperTest.java delete mode 100644 pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectTestFactory.java delete mode 100644 pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcSubFormTestFactory.java create mode 100755 release-erstellen.sh create mode 100755 release-startdev.sh create mode 100755 run_helm_test.sh create mode 100644 src/main/helm/Chart.yaml create mode 100644 src/main/helm/README.md create mode 100644 src/main/helm/templates/_helpers.tpl create mode 100644 src/main/helm/templates/configmap_bindings_type.yaml create mode 100644 src/main/helm/templates/deployment.yaml create mode 100644 src/main/helm/templates/elasticsearch_cr.yaml create mode 100644 src/main/helm/templates/image-pull-secret.yaml create mode 100644 src/main/helm/templates/network_policy.yaml create mode 100644 src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role.yaml create mode 100644 src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role_binding.yaml create mode 100644 src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role.yaml create mode 100644 src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role_binding.yaml create mode 100644 src/main/helm/templates/rabbitmq_exchange.yaml create mode 100644 src/main/helm/templates/rabbitmq_permissions.yaml create mode 100644 src/main/helm/templates/rabbitmq_queue.yaml create mode 100644 src/main/helm/templates/rabbitmq_secret.yaml create mode 100644 src/main/helm/templates/rabbitmq_user.yaml create mode 100644 src/main/helm/templates/secret_ozgcloud_proxyapi.yaml create mode 100644 src/main/helm/templates/service.yaml create mode 100644 src/main/helm/templates/service_account.yaml create mode 100644 src/main/helm/templates/service_monitor.yaml create mode 100644 src/main/helm/templates/tests/test-service-connection.yaml create mode 100644 src/main/helm/values.yaml create mode 100644 src/test/helm-linter-values.yaml create mode 100644 src/test/helm/configmap_bindings_type_test.yaml create mode 100644 src/test/helm/deployment_63_chars_test.yaml create mode 100644 src/test/helm/deployment_bayernid_test.yaml create mode 100644 src/test/helm/deployment_bindings_test.yaml create mode 100644 src/test/helm/deployment_container_security_context_test.yaml create mode 100644 src/test/helm/deployment_defaults_labels_test.yaml create mode 100644 src/test/helm/deployment_env_test.yaml create mode 100644 src/test/helm/deployment_grpc_info_manager_address_test.yaml create mode 100644 src/test/helm/deployment_grpc_user_manager_address_test.yaml create mode 100644 src/test/helm/deployment_host_aliases_test.yaml create mode 100644 src/test/helm/deployment_imagepull_secret_test.yaml create mode 100644 src/test/helm/deployment_liveness_probe_test.yaml create mode 100644 src/test/helm/deployment_mongodb_test.yaml create mode 100644 src/test/helm/deployment_nachrichten_manager_address_test.yaml create mode 100644 src/test/helm/deployment_rabbitmq_test.yaml create mode 100644 src/test/helm/deployment_resources_test.yaml create mode 100644 src/test/helm/deployment_service_account_test.yaml create mode 100644 src/test/helm/deployment_springProfile_test.yaml create mode 100644 src/test/helm/deployment_test.yaml create mode 100644 src/test/helm/deployment_test_ozgcloud_base_values_test.yaml create mode 100644 src/test/helm/deployment_usermanager_url_test.yaml create mode 100644 src/test/helm/deployment_zufimanager_address_test.yaml create mode 100644 src/test/helm/elasticsearch_cr_test.yaml create mode 100644 src/test/helm/elasticsearch_deployment_test.yaml create mode 100644 src/test/helm/image_pull_secret_test.yaml create mode 100644 src/test/helm/network_policy_test.yaml create mode 100644 src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_binding_test.yaml create mode 100644 src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_test.yaml create mode 100644 src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_binding_test.yaml create mode 100644 src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_test.yaml create mode 100644 src/test/helm/rabbitmq_exchange_test.yaml create mode 100644 src/test/helm/rabbitmq_permissions_test.yaml create mode 100644 src/test/helm/rabbitmq_queue_test.yaml create mode 100644 src/test/helm/rabbitmq_user_test.yaml create mode 100644 src/test/helm/service_account_test.yaml create mode 100644 src/test/helm/service_monitor_test.yaml create mode 100644 src/test/helm/service_test.yaml create mode 100644 vorgang-manager-base/pom.xml create mode 100644 vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/LogRunner.java rename pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerApplication.java (59%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/command => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext}/CallContext.java (86%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang}/callcontext/CallContextAuthenticationToken.java (94%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang}/callcontext/CallContextHandleInterceptor.java (80%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang}/callcontext/CallContextUser.java (93%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang}/callcontext/CurrentUserService.java (96%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/command => vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext}/User.java (83%) create mode 100644 vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptor.java create mode 100644 vorgang-manager-base/src/main/resources/.empty rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/CallContextHandleInterceptorTest.java (94%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/CallContextTestFactory.java (66%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/CallContextUserTestFactory.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/CurrentUserServiceITCase.java (95%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/CurrentUserServiceTest.java (95%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/common => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang}/callcontext/TestCallContextAttachingInterceptor.java (75%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/command => vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext}/UserTestFactory.java (86%) create mode 100644 vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptorTest.java create mode 100644 vorgang-manager-base/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension create mode 100644 vorgang-manager-base/src/test/resources/junit-platform.properties create mode 100644 vorgang-manager-base/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 vorgang-manager-command/lombok.config create mode 100644 vorgang-manager-command/pom.xml rename {pluto-interface/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-command/src/main/java/de/ozgcloud}/command/Command.java (90%) rename {pluto-interface/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-command/src/main/java/de/ozgcloud}/command/CommandCreatedEvent.java (92%) create mode 100644 vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandExecutedEvent.java rename {pluto-interface/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-command/src/main/java/de/ozgcloud}/command/CommandFailedEvent.java (93%) rename mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachServerProcessException.java => vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokeFailedEvent.java (74%) rename pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandExecutedEvent.java => vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokedEvent.java (77%) rename {pluto-interface/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-command/src/main/java/de/ozgcloud}/command/CommandStatus.java (90%) create mode 100644 vorgang-manager-command/src/main/java/de/ozgcloud/command/RevokeCommandEvent.java rename {pluto-interface/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-command/src/main/java/de/ozgcloud}/command/VorgangCreatedEvent.java (89%) create mode 100644 vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandCreatedEventTestFactory.java create mode 100644 vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandTestFactory.java create mode 100644 vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java create mode 100644 vorgang-manager-interface/pom.xml create mode 100644 vorgang-manager-interface/src/main/protobuf/bescheid.model.proto create mode 100644 vorgang-manager-interface/src/main/protobuf/bescheid.proto rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/binaryfile.proto (81%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/callcontext.proto (87%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/clientattribute.model.proto (88%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/clientattribute.proto (90%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/command.model.proto (79%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/command.proto (86%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/common.model.proto (76%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/email.model.proto (88%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/email.proto (87%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/file.proto (88%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/filemodel.proto (86%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/forwarding.model.proto (89%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/forwarding.proto (85%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/postfach.model.proto (59%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/postfach.proto (78%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/route-forwarding.model.proto (82%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/route-forwarding.proto (87%) create mode 100644 vorgang-manager-interface/src/main/protobuf/statistic.model.proto create mode 100644 vorgang-manager-interface/src/main/protobuf/statistic.proto rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/system.model.proto (88%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/system.proto (88%) create mode 100644 vorgang-manager-interface/src/main/protobuf/vorgang.model.proto rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/vorgang.proto (86%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/vorgangattacheditem.model.proto (83%) rename {pluto-interface => vorgang-manager-interface}/src/main/protobuf/vorgangattacheditem.proto (90%) rename {pluto-server => vorgang-manager-server}/.mvn/wrapper/MavenWrapperDownloader.java (100%) rename {pluto-server => vorgang-manager-server}/.mvn/wrapper/maven-wrapper.jar (100%) rename {pluto-server => vorgang-manager-server}/.mvn/wrapper/maven-wrapper.properties (100%) create mode 100644 vorgang-manager-server/lombok.config rename {pluto-server => vorgang-manager-server}/mvnw (100%) rename {pluto-server => vorgang-manager-server}/mvnw.cmd (100%) rename {pluto-server => vorgang-manager-server}/pom.xml (56%) create mode 100755 vorgang-manager-server/run_local.sh rename {pluto-server => vorgang-manager-server}/sonar-project.properties (93%) create mode 100644 vorgang-manager-server/src/db/cleanup_vorgang.mongodb create mode 100644 vorgang-manager-server/src/license/eupl/header.txt create mode 100644 vorgang-manager-server/src/license/eupl/license.txt create mode 100644 vorgang-manager-server/src/license/licenses.properties create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerConfiguration.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangProcessorConfiguration.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemMapper.java (89%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemService.java (80%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItem.java (88%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemCreatedEvent.java (78%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemCustomRepository.java (83%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemCustomRepositoryImpl.java (58%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemDeletedEvent.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListener.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemMapper.java (82%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemRepository.java (64%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemService.java (66%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemUpdatedEvent.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttribute.java (95%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeAlreadyExistsException.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeHasValueConstraint.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeIdentificator.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeMap.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeMapper.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeNotExistingException.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeReadPermitted.java (85%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeRepository.java (94%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeService.java (93%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributesMap.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/clientattribute/GrpcClientAttributeService.java (80%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CommandBodyMapper.java (73%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandDeletionScheduler.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CommandEventListener.java (70%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CommandRepository.java (63%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CommandResponse.java (78%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CommandService.java (63%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/CreateCommandRequest.java (81%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/GrpcCommandMapper.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/GrpcCommandResponseMapper.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/GrpcCommandService.java (66%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/GrpcCreateCommandRequestMapper.java (82%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/Order.java (87%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistPostfachNachrichtByCommandService.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/command/PersistedCommand.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/converter/CustomConverters.java (89%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/converter/FileIdConverter.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/converter/ZonedDateTimeReadConverter.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/converter/ZonedDateTimeWriteConverter.java (92%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CollisionVerifier.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db}/CriteriaUtil.java (51%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/errorhandling/ExceptionHandler.java (95%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/errorhandling/FunctionalException.java (88%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/errorhandling/NotFoundException.java (89%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/errorhandling/SearchServiceUnavailableException.java (86%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/logging/RepositoryAspectPointcut.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/logging/RepositoryLoggingAspect.java (88%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributes.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFs.java rename pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollection.java => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItem.java (63%) rename pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangs.java => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem.java (59%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributes.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItem.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributes.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFs.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/migration/MigrationException.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/migration/MongockFailedEventListener.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/migration/MongockStartEventListener.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/migration/MongockSuccessEventListener.java (92%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/RenameUtil.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/EqualOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/ExistsOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessor.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOrEqualOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOrEqualOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParser.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/Operator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorBuilder.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorFactory.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnequalOperator.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnsupportedEntityException.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/IndexedVorgang.java (78%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/IndexedVorgangMapper.java (78%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchConfig.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/SearchEventListener.java (58%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/SearchIndexInitializer.java (88%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/SearchProperties.java (79%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/SearchRequest.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/search/SearchService.java (53%) rename pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepostitory.java => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepository.java (68%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImpl.java rename pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepostitory.java => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepository.java (79%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyRepository.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/common/security/PolicyService.java (86%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigService.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/BinaryFileRepository.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/EingangFilesRepository.java (96%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/FileId.java (89%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/FileIdMapper.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/FileService.java (77%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/GrpcBinaryFileService.java (85%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/GrpcFileService.java (81%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/GrpcOzgFileMapper.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/OzgFile.java (86%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/UploadStreamObserver.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/files/UploadedFilesReference.java (91%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryScheduler.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/ZufiRemoteService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/PostfachAddress.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKonto.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapper.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountByPath.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountResult.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountStatisticMapper.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/InvalidFieldPathException.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/Statistic.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticFilter.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGroupMethod.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGrpcService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticMapper.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticRepository.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangCountRequest.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticBadRequestException.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequest.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status}/StatusChangedEvent.java (85%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusEventListener.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusRepository.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusService.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/system/SystemStatusGrpcService.java (93%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/DeleteUserScheduler.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserProfileRemoteService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserService.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptor.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/AktenzeichenProvider.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/AktenzeichenProviderConfiguration.java (90%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/AktenzeichenProviderEA.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/Antragsteller.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/AntragstellerMapper.java (93%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/CustomVorgangHeaderRepository.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/DefaultAktenzeichenProvider.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/Eingang.java (93%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/EingangHeader.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/EingangHeaderMapper.java (75%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/EingangMapper.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/FilterByMapper.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/FilterCriteria.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/FilterCriteriaDefault.java (90%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQuery.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapper.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/FindVorgangRequest.java (85%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/FindVorgangRequestMapper.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/GrpcVorgangService.java (79%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/IncomingFile.java (88%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/IncomingFileGroup.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/IncomingFileGroupMapper.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/IncomingFileMapper.java (88%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/LabelProcessor.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilder.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/SetAktenzeichenCompletedEvent.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgagnQueryExpression.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/Vorgang.java (70%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangAssignedEvent.java (83%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangAuthorizationService.java (95%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEvent.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangEventListener.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangHeader.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderMapper.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderRepository.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderRepositoryImpl.java (72%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderService.java (76%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangRepository.java (62%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangService.java (55%) create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java create mode 100644 vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/VorgangWithEingangMapper.java (80%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/ZustaendigeStelle.java (78%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/ZustaendigeStelleMapper.java (93%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/Forwarding.java (94%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingEventListener.java (60%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingGrpcService.java (83%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingMapper.java (88%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingRepository.java (95%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingService.java (86%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/RedirectRequest.java (92%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/RedirectRequestMapper.java (85%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangForwardFailedEvent.java (85%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangForwardSuccessfullEvent.java (84%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangRedirectFailedEvent.java (87%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangRedirectedEvent.java (91%) rename {pluto-server/src/main/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/main/java/de/ozgcloud/vorgang}/vorgang/redirect/ZipBuilderService.java (87%) rename {pluto-server => vorgang-manager-server}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (65%) rename {pluto-server => vorgang-manager-server}/src/main/resources/META-INF/mime.types (100%) create mode 100644 vorgang-manager-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 vorgang-manager-server/src/main/resources/application-a12proc.yml create mode 100644 vorgang-manager-server/src/main/resources/application-bayern.yml create mode 100644 vorgang-manager-server/src/main/resources/application-dev.yml create mode 100644 vorgang-manager-server/src/main/resources/application-e2e.yml create mode 100644 vorgang-manager-server/src/main/resources/application-local.yml rename {pluto-server => vorgang-manager-server}/src/main/resources/application-oc.yml (100%) create mode 100644 vorgang-manager-server/src/main/resources/application-prod.yml rename {pluto-server => vorgang-manager-server}/src/main/resources/application-stage.yml (55%) create mode 100644 vorgang-manager-server/src/main/resources/application-test.yml create mode 100644 vorgang-manager-server/src/main/resources/application-withdevdb.yml rename {pluto-server => vorgang-manager-server}/src/main/resources/application.yml (53%) create mode 100644 vorgang-manager-server/src/main/resources/banner.txt create mode 100644 vorgang-manager-server/src/main/resources/elastic/settings.json rename {pluto-server => vorgang-manager-server}/src/main/resources/images/logo-ea-sh.png (100%) rename {pluto-server => vorgang-manager-server}/src/main/resources/images/logo-itvsh.png (100%) create mode 100644 vorgang-manager-server/src/main/resources/log4j2-local.xml rename {pluto-server => vorgang-manager-server}/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh (97%) rename {pluto-server => vorgang-manager-server}/src/main/resources/templates/mail/redirect.txt.ftlh (97%) rename {pluto-server/src/test/java/de/itvsh/ozg/mail => vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten}/attributes/ClientAttributeITCase.java (83%) rename {pluto-server/src/test/java/de/itvsh/ozg/mail => vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten}/postfach/PostfachEventListenerITCase.java (67%) rename {pluto-server/src/test/java/de/itvsh/ozg/mail => vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten}/postfach/PostfachMailITCase.java (68%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachServiceConfigurationITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/mail/postfach => vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi}/OsiPostfachApiTestCase.java (63%) rename pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceITCase.java => vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java (63%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/processor/ProcessorITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/DbInitializer.java (95%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/TestConfiguration.java (88%) rename pluto-server/src/test/java/de/itvsh/ozg/pluto/PlutoServerApplicationTests.java => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/VorgangManagerServerApplicationTests.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemMapperTest.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java (86%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java (86%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemServiceTest.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/GrpcVorgangAttachedItemTestFactory.java (85%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImplTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemEventListenerITCase.java (55%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemEventListenerTest.java (67%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemITCase.java (74%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemMapperTest.java (93%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepositoryITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemServiceTest.java (55%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/attached_item/VorgangAttachedItemTestFactory.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeHasValueValidatorTest.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeITCase.java (86%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeIdentificatorTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeMapperTest.java (94%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeReadPermittedTest.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeRepositoryITCase.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeServiceITCase.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeServiceTest.java (94%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributeTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/ClientAttributesMapTestFactory.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcClientAttributeServiceITCase.java (88%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcClientAttributeServiceTest.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcClientAttributeTestFactory.java (76%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java (81%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcSetClientAttributeRequestTestFactory.java (76%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java (87%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/AttachmentFileTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandCreatedEventTestFactory.java (78%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandDeletionSchedulerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandEventListenerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandExecutedEventTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandITCase.java (67%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRepositoryITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandResponseMapperTest.java (93%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandResponseTestFactory.java (83%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRevokedEventTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandServiceITCase.java (76%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandServiceTest.java (62%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CommandTestFactory.java (79%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/CreateCommandRequestTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcCallContextTestFactory.java (78%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcCommandMapperTest.java (91%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcCommandServiceTest.java (79%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcCreateCommandRequestMapperTest.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcCreateCommandRequestTestFactory.java (83%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/GrpcUserTestFactory.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/PersistPostfachMailByCommandServiceITCase.java (80%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/command/PersistPostfachMailByCommandServiceTest.java (64%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/converter/ZonedDateTimeReadConverterTest.java (93%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/converter/ZonedDateTimeWriteConverterTest.java (93%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CollisionVerifierTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db}/CriteriaUtilTest.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/errorhandling/ExceptionHandlerTest.java (96%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/errorhandling/FunctionalExceptionTest.java (92%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributesITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFsITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItemITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItemITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributesITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItemITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributesITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFsITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationDbTestUtils.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/migration/MigrationTestUtils.java (93%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameUtilITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessorTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParserTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorBuilderTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/IndexedVorgangMapperTest.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/IndexedVorgangTestFactory.java (80%) rename pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListenerTest.java => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchConfigTest.java (51%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchEventListenerTest.java (54%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchITCase.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchIndexEnabledInitializer.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchIndexInitializerITCase.java (83%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchInitializer.java (82%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchServiceTest.java (72%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImplTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/search/SearchVorgangRepositoryITCase.java (74%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/security/PolicyRepositoryITCase.java (77%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/common/security/PolicyServiceTest.java (94%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/GrpcGetSupportedOrganisationEinheitenResponseTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteServiceTest.java rename pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandEventListenerTest.java => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigServiceTest.java (64%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/BinaryFileITCase.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/BinaryFileRepositoryITCase.java (73%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/BinaryFileRepositoryTest.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/EingangFilesRepositoryITCase.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/FileITCase.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/FileServiceTest.java (61%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GridFsTestFactory.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcBinaryFileServiceTest.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcBinaryFilesRequestTestFactory.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcGetAttachmentsRequestTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcGetBinaryFileDataRequestTestFactory.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcGetRepresentationsRequestTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcOzgFileMapperTest.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcUploadBinaryFileMetaDataTestFactory.java (83%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcUploadBinaryFileRequestTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/GrpcUploadedFilesReferencesTestFactory.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/OzgFileTestFactory.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/UploadStreamObserverTest.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/files/UploadedFilesReferenceTestFactory.java (86%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/GrpcRegistrationResponseTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistrySchedulerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistryServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/ZufiRemoteServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcPostfachAddressTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcServiceKontoTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/PostfachAddressTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapperTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountPathRequestTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountResultTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountStatisticMapperTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticQueryTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticRequestTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResponseTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResultTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/OperatorTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticGrpcServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticMapperTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangCountRequestTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequestTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusServiceTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/system/SystemStatusGrpcServiceTest.java (95%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/DeleteUserSchedulerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserProfileRemoteServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserServiceTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptorTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/AktenzeichenProviderEATest.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/AktenzeichenServiceITCase.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/AntragstellerMapperTest.java (93%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/AntragstellerTestFactory.java (96%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/DefaultAktenzeichenProviderTest.java (92%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapperTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/EingangHeaderTestFactory.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/EingangMapperTest.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/EingangTestFactory.java (69%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/FilterByMapperTest.java (95%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/FilterCriteriaTestFactory.java (77%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapperTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/FindVorgangRequestMapperTest.java (83%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/FindVorgangRequestTestFactory.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcAntragstellerTestFactory.java (96%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcCreateVorgangRequestTestFactory.java (81%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcEingangHeaderTestFactory.java (81%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcEingangTestFactory.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcFilterByTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcFindVorgangRequestTestFactory.java (90%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcFinishCreationRequestTestFactory.java (85%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcIncomingFileGroupTestFactory.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcIncomingFileTestFactory.java (94%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcQueryTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangHeadTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangQueryExpressionTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceFindQueryITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcVorgangServiceTest.java (79%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcVorgangWithEingangTestFactory.java (81%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/GrpcZustaendigeStelleTestFactory.java (93%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/IncomingFileGroupMapperTest.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/IncomingFileGroupTestFactory.java (92%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/IncomingFileMapperTest.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/IncomingFileTestFactory.java (93%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/LabelProcessorTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilderTest.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangAuthorizationServiceTest.java (97%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEventTestFactory.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerITCase.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeadTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderRepositoryITCase.java (51%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderRepositoryImplITCase.java (64%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderRepositoryImplTest.java (94%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderServiceTest.java (65%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangHeaderTestFactory.java (88%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangITCase.java (62%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangRepositoryITCase.java (62%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangServiceTest.java (58%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangTestFactory.java (81%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/VorgangWithEingangMapperTest.java (76%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/ZustaendigeStelleMapperTest.java (95%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/ZustaendigeStelleTestFactory.java (66%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardVorgangITCase.java (62%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingEventListenerITCase.java (76%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingEventListenerTest.java (60%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingGrpcServiceTest.java (91%) create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingITCase.java rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingRepositoryITCase.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingServiceITCase.java (89%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingServiceTest.java (87%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ForwardingTestFactory.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java (79%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/RedirectRequestTestFactory.java (88%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangForwardFailedEventTestFactory.java (84%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/VorgangRedirectedEventTestFactory.java (91%) rename {pluto-server/src/test/java/de/itvsh/ozg/pluto => vorgang-manager-server/src/test/java/de/ozgcloud/vorgang}/vorgang/redirect/ZipBuilderServiceTest.java (91%) create mode 100644 vorgang-manager-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename {pluto-server => vorgang-manager-server}/src/test/resources/TestDoc.docx (100%) create mode 100644 vorgang-manager-server/src/test/resources/application-itcase.yml rename {pluto-server => vorgang-manager-server}/src/test/resources/application-with_db.yml (81%) create mode 100644 vorgang-manager-server/src/test/resources/bayernid.p12 create mode 100644 vorgang-manager-server/src/test/resources/bayernid/bsp-nachricht create mode 100644 vorgang-manager-server/src/test/resources/bayernid/test.txt create mode 100644 vorgang-manager-server/src/test/resources/junit-platform.properties rename {pluto-utils => vorgang-manager-utils}/pom.xml (66%) create mode 100644 vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtils.java rename {pluto-utils/src/main/java/de/itvsh/kop/pluto => vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang}/common/grpc/GrpcFormDataMapper.java (53%) create mode 100644 vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapper.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtilsTest.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapperTest.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataTestFactory.java rename {pluto-utils/src/test/java/de/itvsh/kop/pluto => vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang}/common/grpc/GrpcFormFieldTestFactory.java (72%) create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapperTest.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectTestFactory.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcPropertyTestFactory.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubFormTestFactory.java create mode 100644 vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubObjectTestFactory.java create mode 100644 vorgang-manager-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension create mode 100644 vorgang-manager-utils/src/test/resources/junit-platform.properties diff --git a/.helmignore b/.helmignore new file mode 100644 index 0000000..f7ccba7 --- /dev/null +++ b/.helmignore @@ -0,0 +1 @@ +unit-tests/ \ No newline at end of file diff --git a/README.md b/README.md index ac57b09..181fd1c 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# KOP VorgangManager + +## Configuration +### Create mongodb user + +db.createUser({user:"sh-kiel-pluto",pwd:"...",roles:[{role:"readWrite",database:"sh-kiel"}]}) diff --git a/bescheid-manager/pom.xml b/bescheid-manager/pom.xml new file mode 100644 index 0000000..00cc9ba --- /dev/null +++ b/bescheid-manager/pom.xml @@ -0,0 +1,135 @@ +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> + <relativePath /> + </parent> + + <groupId>de.ozgcloud.bescheid</groupId> + <artifactId>bescheid-manager</artifactId> + <name>OZG-Cloud Bescheid Manager</name> + <version>1.8.0</version> + + <properties> + <vorgang-manager.version>2.4.0</vorgang-manager.version> + <api-lib.version>0.5.0</api-lib.version> + </properties> + + <dependencies> + <!-- ozg-cloud --> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> + <version>${vorgang-manager.version}</version> + </dependency> + <dependency> + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>${vorgang-manager.version}</version> + </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> + <version>${vorgang-manager.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-lib</artifactId> + </dependency> + <dependency> + <groupId>de.ozgcloud.api-lib</groupId> + <artifactId>api-lib-core</artifactId> + <version>${api-lib.version}</version> + </dependency> + + + <!-- spring --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>net.devh</groupId> + <artifactId>grpc-client-spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>net.devh</groupId> + <artifactId>grpc-server-spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-freemarker</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webflux</artifactId> + </dependency> + <dependency> + <groupId>io.projectreactor.netty</groupId> + <artifactId>reactor-netty-http</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-core</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-configuration-processor</artifactId> + <optional>true</optional> + </dependency> + + + <dependency> + <groupId>com.fasterxml.jackson.datatype</groupId> + <artifactId>jackson-datatype-jsr310</artifactId> + </dependency> + + + <!--dev tools--> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct</artifactId> + </dependency> + + <!--TEST--> + <dependency> + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>${vorgang-manager.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/Bescheid.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/Bescheid.java new file mode 100644 index 0000000..a7c925e --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/Bescheid.java @@ -0,0 +1,56 @@ +/* + * 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; + +import java.io.File; +import java.util.Optional; + +import de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import de.ozgcloud.common.binaryfile.FileId; +import lombok.Builder; +import lombok.Getter; +import lombok.With; + +@Builder(toBuilder = true) +@Getter +public class Bescheid { + + private VorgangId vorgangId; + + private boolean genehmigt; + private UserId createdBy; + + private String bescheidFileName; + private File bescheidFile; + @With + private FileId bescheidFileId; + private String contentType; + private long size; + + @Builder.Default + private Optional<String> nachrichtText = Optional.empty(); + + private Vorgang.ServiceKonto serviceKonto; +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCallContextAttachingInterceptor.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCallContextAttachingInterceptor.java new file mode 100644 index 0000000..1a1e047 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCallContextAttachingInterceptor.java @@ -0,0 +1,84 @@ +/* + * 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; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; + +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +@Component("bescheidCallContextInterceptor") +public class BescheidCallContextAttachingInterceptor implements ClientInterceptor { + + public static final String BESCHEID_MANAGER_CLIENT_NAME = "OzgCloud_BescheidManager"; + + @Autowired + private CurrentUserService userService; + + // <A> = Request, <B> = Response + @Override + public <A, B> ClientCall<A, B> interceptCall(MethodDescriptor<A, B> method, CallOptions callOptions, Channel next) { + return new CallContextAttachingClientCall<>(next.newCall(method, callOptions)); + } + + final class CallContextAttachingClientCall<A, B> extends SimpleForwardingClientCall<A, B> { + + protected CallContextAttachingClientCall(ClientCall<A, B> delegate) { + super(delegate); + } + + @Override + public void start(Listener<B> responseListener, Metadata headers) { + headers.merge(buildCallContextMetadata()); + super.start(responseListener, headers); + } + + private Metadata buildCallContextMetadata() { + var metadata = new Metadata(); + + userService.getUser().getUserId().ifPresent(userId -> metadata.put(HEADER_KEY_USER_ID, userId.getBytes())); + metadata.put(HEADER_KEY_CLIENT_NAME, BESCHEID_MANAGER_CLIENT_NAME.getBytes()); + metadata.put(HEADER_KEY_REQUEST_ID, generateRequestId().getBytes()); + + return metadata; + } + + // TODO requestId für command handling uebertragen / erstellen + private String generateRequestId() { + return UUID.randomUUID().toString(); + } + + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCreatedEvent.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCreatedEvent.java new file mode 100644 index 0000000..57dfb1f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidCreatedEvent.java @@ -0,0 +1,34 @@ +/* + * 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; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; + +class BescheidCreatedEvent extends CommandExecutedEvent { + + public BescheidCreatedEvent(Command command) { + super(command.getId()); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java new file mode 100644 index 0000000..a1f45e3 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java @@ -0,0 +1,135 @@ +/* + * 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; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.stereotype.Component; + +import de.ozgcloud.bescheid.binaryfile.BinaryFileService; +import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; +import de.ozgcloud.bescheid.nachricht.NachrichtService; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Component +@RequiredArgsConstructor +class BescheidEventListener { + + public static final String ORDER = "CREATE_BESCHEID"; + + private static final String IS_CREATE_BESCHEID = "{T(de.ozgcloud.bescheid.BescheidEventListener).IS_CREATE_BESCHEID_COMMAND.test(event.getSource())}"; + + public static final Predicate<Command> IS_CREATE_BESCHEID_COMMAND = command -> command.getOrder().equals(ORDER); + + static final String VORGANG_ID_BODYKEY = "vorgangId"; + static final String BESCHEID_VOM_BODYKEY = "bescheidVom"; + static final String GENEHMIGT_BODYKEY = "genehmigt"; + + private static final String ERROR_MESSAGE = "Error on executing Create Bescheid Command."; + + private final BescheidService service; + private final BinaryFileService fileService; + private final NachrichtService nachrichtService; + + private final ApplicationEventPublisher eventPublisher; + private final CurrentUserService userService; + + @EventListener(condition = IS_CREATE_BESCHEID) + public void onCreateBescheidCommand(CommandCreatedEvent event) { + Command command = event.getSource(); + + doCreateBescheid(command); + } + + private void doCreateBescheid(Command command) { + SecurityContext prevContext = null; + try { + prevContext = userService.startSecurityContext(command); + doCreateBescheidBiz(command); + eventPublisher.publishEvent(new BescheidCreatedEvent(command)); + } catch (Exception e) { + LOG.error("Error on executing Create Bescheid Command. Command failed.", e); + eventPublisher.publishEvent(new CommandFailedEvent(command.getId(), buildErrorMessage(e))); + } finally { + userService.resetSecurityContext(prevContext); + } + } + + public void doCreateBescheidBiz(@NonNull Command command) { + var bescheid = service.createBescheid(createRequest(command)); + bescheid = fileService.uploadBescheidFile(bescheid); + + nachrichtService.createNachrichtDraft(bescheid); + } + + BescheidRequest createRequest(Command command) { + var eventBody = command.getBodyObject(); + var builder = BescheidRequest.builder(); + + builder.vorgangId(VorgangId.from(command.getVorgangId())); + Optional.ofNullable(eventBody.get(BESCHEID_VOM_BODYKEY)) + .map(String.class::cast).map(LocalDate::parse).ifPresent(builder::bescheidVom); + Optional.ofNullable(eventBody.get(GENEHMIGT_BODYKEY)) + .map(Object::toString).map(Boolean::valueOf) + .ifPresentOrElse(builder::genehmigt, () -> builder.genehmigt(true)); + builder.createFor(userService.getUserProfile()); + + return builder.build(); + } + + private String buildErrorMessage(Exception e) { + try { + StringBuilder sb = new StringBuilder(ERROR_MESSAGE); + + if (Objects.nonNull(e.getCause()) && StringUtils.isNotBlank(e.getCause().getMessage())) { + sb.append(" Cause: " + e.getCause().getMessage()); + } + + if (e instanceof TechnicalException techException) { + sb.append(" ExceptionId: " + techException); + } + + return sb.toString(); + } catch (Exception e2) { + LOG.error("Error in building Error Message (sick).", e2); + return ERROR_MESSAGE; + } + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java new file mode 100644 index 0000000..1f67418 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidGrpcService.java @@ -0,0 +1,53 @@ +/* + * 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; + +import de.ozgcloud.bescheid.BescheidServiceGrpc.BescheidServiceImplBase; +import io.grpc.stub.StreamObserver; +import lombok.RequiredArgsConstructor; +import net.devh.boot.grpc.server.service.GrpcService; + +@GrpcService +@RequiredArgsConstructor +class BescheidGrpcService extends BescheidServiceImplBase { + + private final GrpcBescheidMapper mapper; + + @Override + public void getBescheidDraft(GrpcGetBescheidDraftRequest request, StreamObserver<GrpcGetBescheidDraftResponse> responseObserver) { + // dummy implementation + // TODO OZG-5099 du real implementation - load Bescheid + var bescheid = Bescheid.builder().build(); + + responseObserver.onNext(buildResponse(bescheid)); + responseObserver.onCompleted(); + + } + + GrpcGetBescheidDraftResponse buildResponse(Bescheid bescheid) { + return GrpcGetBescheidDraftResponse.newBuilder() + .setBescheid(mapper.fromBescheid(bescheid)) + .build(); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRemoteService.java new file mode 100644 index 0000000..e1b827d --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRemoteService.java @@ -0,0 +1,31 @@ +/* + * 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; + +import de.ozgcloud.bescheid.vorgang.Vorgang; + +public interface BescheidRemoteService { + + Bescheid create(BescheidRequest request, Vorgang vorgang); +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRequest.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRequest.java new file mode 100644 index 0000000..f06f583 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidRequest.java @@ -0,0 +1,43 @@ +/* + * 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; + +import java.time.LocalDate; + +import de.ozgcloud.bescheid.common.callcontext.UserProfile; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class BescheidRequest { + + private VorgangId vorgangId; + + private LocalDate bescheidVom; + private boolean genehmigt; + + private UserProfile createFor; +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidService.java new file mode 100644 index 0000000..c55d2d8 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidService.java @@ -0,0 +1,77 @@ +/* + * 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; + +import java.util.Objects; + +import jakarta.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.bescheid.vorgang.VorgangService; +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.extern.log4j.Log4j2; + +@Service +@Log4j2 +class BescheidService { + + private static final String ERROR_MESSAGE_NO_SERVICE = "'CREATE_BESCHEID' Command received but no Bescheid Endpoint is configured."; + + @Autowired + private VorgangService vorgangService; + @Autowired(required = false) + private BescheidRemoteService remoteService; + + @PostConstruct + void logStatus() { + if (Objects.isNull(ERROR_MESSAGE_NO_SERVICE)) { + LOG.info("No BescheidRemoteService configured - Bescheid creation is not possible."); + } else { + LOG.info("Bescheid-Manager is configured."); + } + } + + public Bescheid createBescheid(BescheidRequest request) { + checkRemoteService(); + + return doCreateBescheid(request); + } + + private Bescheid doCreateBescheid(BescheidRequest request) { + var vorgang = vorgangService.getById(request.getVorgangId()); + return remoteService.create(request, vorgang) + .toBuilder().vorgangId(vorgang.getId()).serviceKonto(vorgang.getServiceKonto()) + .build(); + } + + private void checkRemoteService() { + if (Objects.isNull(remoteService)) { + LOG.error(ERROR_MESSAGE_NO_SERVICE); + throw new TechnicalException(ERROR_MESSAGE_NO_SERVICE); + } + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/GrpcBescheidMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/GrpcBescheidMapper.java new file mode 100644 index 0000000..3611436 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/GrpcBescheidMapper.java @@ -0,0 +1,59 @@ +/* + * 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; + +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface GrpcBescheidMapper { + + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "bescheidDocument", ignore = true) + @Mapping(target = "bescheidDocumentBytes", ignore = true) + @Mapping(target = "beschiedenAm", ignore = true) + @Mapping(target = "beschiedenAmBytes", ignore = true) + @Mapping(target = "nachrichtSubject", ignore = true) + @Mapping(target = "nachrichtSubjectBytes", ignore = true) + @Mapping(target = "nachrichtTextBytes", ignore = true) + @Mapping(target = "sendBy", ignore = true) + @Mapping(target = "sendByBytes", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "attachmentsList", ignore = true) + + @Mapping(target = "nachrichtText", source = "nachrichtText") + @Mapping(target = "bewilligt", source = "genehmigt") + GrpcBescheid fromBescheid(Bescheid bescheid); + + default String fromOptional(Optional<String> optionalString) { + return optionalString.orElse(StringUtils.EMPTY); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/UserId.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/UserId.java new file mode 100644 index 0000000..cda26df --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/UserId.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.bescheid; + +import java.util.Objects; + +import de.ozgcloud.common.datatype.StringBasedValue; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public class UserId extends StringBasedValue { + + UserId(String userId) { + super(userId); + } + + public static UserId from(String userId) { + if (Objects.nonNull(userId)) { + return new UserId(userId); + } + return null; + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileRemoteService.java new file mode 100644 index 0000000..ede39f9 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileRemoteService.java @@ -0,0 +1,123 @@ +/* + * 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.binaryfile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Service; + +import com.google.protobuf.ByteString; + +import de.ozgcloud.bescheid.Bescheid; +import de.ozgcloud.common.binaryfile.FileId; +import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils; +import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import io.grpc.stub.CallStreamObserver; +import io.grpc.stub.StreamObserver; +import lombok.NonNull; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class BinaryFileRemoteService { + + private static final String CALL_CONTEXT_CLIENT = "bescheid-manager"; + private static final String VORGANG_ATTACHMENT_FIELD = "bescheid"; + + @GrpcClient("vorgang-manager") + private BinaryFileServiceStub binaryFileRemoteStub; + + public FileId uploadBescheidFile(@NonNull Bescheid bescheid) { + try (var in = openFile(bescheid.getBescheidFile())) { + var resultFuture = GrpcFileUploadUtils.createSender(this::buildChunkRequest, in, + this::buildCallStreamObserver) + .withMetaData(buildMetaDataRequest(bescheid)) + .send(); + + return FileId.from(waitUntilFutureToComplete(resultFuture, in).getFileId()); + } catch (IOException e) { + throw new TechnicalException("Error on uploading file.", e); + } + } + + private InputStream openFile(File file) { + try { + return new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new TechnicalException("File to upload not found.", e); + } + } + + private GrpcUploadBinaryFileRequest buildMetaDataRequest(Bescheid bescheid) { + return GrpcUploadBinaryFileRequest.newBuilder() + .setMetadata(GrpcUploadBinaryFileMetaData.newBuilder() + // TODO remove context - check why needed! + .setContext(GrpcCallContext.newBuilder().setClient(CALL_CONTEXT_CLIENT).build()) + .setVorgangId(bescheid.getVorgangId().toString()) + .setField(VORGANG_ATTACHMENT_FIELD) + .setContentType(bescheid.getContentType()) + .setSize(bescheid.getBescheidFile().length()) + .setFileName(bescheid.getBescheidFileName()) + .build()) + .build(); + } + + private GrpcUploadBinaryFileRequest buildChunkRequest(byte[] bytes, Integer length) { + return GrpcUploadBinaryFileRequest.newBuilder().setFileContent((ByteString.copyFrom(bytes, 0, length))).build(); + } + + private CallStreamObserver<GrpcUploadBinaryFileRequest> buildCallStreamObserver( + StreamObserver<GrpcUploadBinaryFileResponse> responseObserver) { + return (CallStreamObserver<GrpcUploadBinaryFileRequest>) binaryFileRemoteStub.uploadBinaryFileAsStream(responseObserver); + } + + GrpcUploadBinaryFileResponse waitUntilFutureToComplete(FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> fileSender, + InputStream fileContentStream) { + try { + return fileSender.getResultFuture().get(10, TimeUnit.MINUTES); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + fileSender.cancelOnError(e); + throw new TechnicalException("Waiting for finishing upload was interrupted.", e); + } catch (ExecutionException | TimeoutException e) { + fileSender.cancelOnTimeout(); + throw new TechnicalException("Error / Timeout on uploading data.", e); + } finally { + IOUtils.closeQuietly(fileContentStream); + } + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileService.java new file mode 100644 index 0000000..07ef147 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/binaryfile/BinaryFileService.java @@ -0,0 +1,43 @@ +/* + * 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.binaryfile; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.bescheid.Bescheid; +import lombok.NonNull; + +@Service +public class BinaryFileService { + + @Autowired + private BinaryFileRemoteService remoteService; + + public Bescheid uploadBescheidFile(@NonNull Bescheid bescheid) { + var fileId = remoteService.uploadBescheidFile(bescheid); + + return bescheid.withBescheidFileId(fileId); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextAuthenticationToken.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextAuthenticationToken.java new file mode 100644 index 0000000..975d435 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextAuthenticationToken.java @@ -0,0 +1,64 @@ +/* + * 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.common.callcontext; + +import java.util.Collection; +import java.util.stream.Collectors; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public class CallContextAuthenticationToken extends AbstractAuthenticationToken { + + private final CallContextUser user; + + static CallContextAuthenticationToken authenticate(CallContextUser user) { + return new CallContextAuthenticationToken(user); + } + + private CallContextAuthenticationToken(CallContextUser user) { + super(user.getOrganisatorischeEinheitenIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet())); + this.user = user; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return user; + } + + @Override + public Collection<GrantedAuthority> getAuthorities() { + return user.getOrganisatorischeEinheitenIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toUnmodifiableSet()); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextUser.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextUser.java new file mode 100644 index 0000000..d180bf1 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CallContextUser.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.bescheid.common.callcontext; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Optional; + +import org.springframework.security.core.AuthenticatedPrincipal; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class CallContextUser implements AuthenticatedPrincipal, Serializable { + + private static final long serialVersionUID = 1L; + + private final String clientName; + + @Builder.Default + private final transient Optional<String> userId = Optional.empty(); + @Builder.Default + private final transient Optional<String> userName = Optional.empty(); + @Singular + private final Collection<String> organisatorischeEinheitenIds; + @Builder.Default + private final transient boolean organisationEinheitenIdCheckNecessary = false; + + @Override + public String getName() { + return clientName; + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserService.java new file mode 100644 index 0000000..458ea68 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserService.java @@ -0,0 +1,119 @@ +/* + * 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.common.callcontext; + +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import de.ozgcloud.apilib.user.OzgCloudUserId; +import de.ozgcloud.apilib.user.OzgCloudUserProfileService; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service("bescheid_currentUserService") +public class CurrentUserService { + + private final AuthenticationTrustResolver trustResolver; + private final Optional<OzgCloudUserProfileService> userProfileService; + private final UserProfileMapper mapper; + + public CallContextUser getUser() { + return findUser().orElseThrow(() -> new IllegalStateException("No authenticated User found")); + } + + public UserProfile getUserProfile() { + var service = userProfileService.orElseThrow(() -> new IllegalStateException("No connection to user-manager configured.")); + + return getUser().getUserId().map(OzgCloudUserId::from) + .map(service::getById) + .map(mapper::mapProfile).orElseThrow(() -> new TechnicalException("Unknown UserId or cannot load user profile.")); + } + + public Optional<CallContextUser> findUser() { + return findTrustedAuthentication() + .map(this::mapToCallContextUser) + // remove this filter as soon we have a trusted authentication + .filter(user -> StringUtils.isNotBlank(user.getClientName())); + } + + private CallContextUser mapToCallContextUser(Authentication auth) { + if (auth instanceof CallContextAuthenticationToken) { + return (CallContextUser) auth.getPrincipal(); + } else { + return CallContextUser.builder() + .clientName(auth.getName()) + .organisatorischeEinheitenIds( + auth.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toUnmodifiableSet())) + .build(); + } + } + + public Optional<Authentication> findAuthentication() { + return findTrustedAuthentication(); + } + + Optional<Authentication> findTrustedAuthentication() { + return Optional.ofNullable(SecurityContextHolder.getContext()) + .map(SecurityContext::getAuthentication) + .filter(auth -> !trustResolver.isAnonymous(auth)) + .filter(Authentication::isAuthenticated); + } + + public SecurityContext startSecurityContext(Command command) { + var prevContext = SecurityContextHolder.getContext(); + + SecurityContextHolder.clearContext(); + SecurityContextHolder.getContext().setAuthentication(CallContextAuthenticationToken.authenticate(createUser(command))); + + return prevContext; + } + + CallContextUser createUser(Command command) { + var builder = CallContextUser.builder() + .userId(Optional.ofNullable(command.getCreatedBy())) + .userName(Optional.ofNullable(command.getCreatedByName())) + .clientName("Alfa") // FIXME read client name from command + .organisationEinheitenIdCheckNecessary(false); + + return builder.build(); + } + + public void resetSecurityContext(SecurityContext context) { + SecurityContextHolder.clearContext(); + if (Objects.nonNull(context)) { + SecurityContextHolder.setContext(context); + } + } +} \ No newline at end of file diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfile.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfile.java new file mode 100644 index 0000000..0410ae5 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfile.java @@ -0,0 +1,38 @@ +/* + * 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.common.callcontext; + +import de.ozgcloud.bescheid.UserId; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class UserProfile { + + private UserId id; + private String firstName; + private String lastName; + private String email; +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileMapper.java new file mode 100644 index 0000000..e02f8c1 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileMapper.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.bescheid.common.callcontext; + +import org.mapstruct.Mapper; + +import de.ozgcloud.apilib.user.OzgCloudUserId; +import de.ozgcloud.apilib.user.OzgCloudUserProfile; +import de.ozgcloud.bescheid.UserId; + +@Mapper +public interface UserProfileMapper { + + UserProfile mapProfile(OzgCloudUserProfile userProfile); + + default UserId mapUserId(OzgCloudUserId id) { + return UserId.from(id.toString()); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileTestFactory.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileTestFactory.java new file mode 100644 index 0000000..cabb76f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/common/callcontext/UserProfileTestFactory.java @@ -0,0 +1,53 @@ +/* + * 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.common.callcontext; + +import java.util.UUID; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.bescheid.UserId; + +public class UserProfileTestFactory { + + private static final LoremIpsum LOREM_IPSUM = LoremIpsum.getInstance(); + + public static final UserId ID = UserId.from(UUID.randomUUID().toString()); + + public static final String FIRST_NAME = LOREM_IPSUM.getFirstName(); + public static final String LAST_NAME = LOREM_IPSUM.getLastName(); + public static final String EMAIL = "test-email@local"; + + public static UserProfile create() { + return createBuilder().build(); + } + + public static UserProfile.UserProfileBuilder createBuilder() { + return UserProfile.builder() + .id(ID) + .firstName(FIRST_NAME) + .lastName(LAST_NAME) + .email(EMAIL); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/dummy/DummyBescheidRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/dummy/DummyBescheidRemoteService.java new file mode 100644 index 0000000..2cf1edf --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/dummy/DummyBescheidRemoteService.java @@ -0,0 +1,57 @@ +/* + * 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.dummy; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.stereotype.Service; + +import com.google.common.net.MediaType; + +import de.ozgcloud.bescheid.Bescheid; +import de.ozgcloud.bescheid.BescheidRemoteService; +import de.ozgcloud.bescheid.BescheidRequest; +import de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.common.binaryfile.TempFileUtils; + +@Service +@ConditionalOnMissingBean(BescheidRemoteService.class) +class DummyBescheidRemoteService implements BescheidRemoteService { + + private static final String DUMMY_BESCHEID_FILE_NAME = "dummy-bescheid.pdf"; + private static final String DUMMY_BESCHEID_CONTENT_TYPE = MediaType.PDF.toString(); + + @Override + public Bescheid create(BescheidRequest request, Vorgang vorgang) { + var file = TempFileUtils.writeTmpFile(this.getClass().getClassLoader().getResourceAsStream(DUMMY_BESCHEID_FILE_NAME)); + + return Bescheid.builder() + .bescheidFile(file) + .bescheidFileName(DUMMY_BESCHEID_FILE_NAME) + .contentType(DUMMY_BESCHEID_CONTENT_TYPE) + .size(file.length()) + .createdBy(request.getCreateFor().getId()) + .build(); + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/Nachricht.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/Nachricht.java new file mode 100644 index 0000000..730ad8c --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/Nachricht.java @@ -0,0 +1,56 @@ +/* + * 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.nachricht; + +import java.time.ZonedDateTime; + +import de.ozgcloud.bescheid.UserId; +import de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import de.ozgcloud.common.binaryfile.FileId; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@Builder +public class Nachricht { + + private NachrichtId id; + private VorgangId vorgangId; + + @NonNull + private String subject; + @NonNull + private String mailBody; + + private FileId bescheidFileId; + + @NonNull + private UserId createdBy; + @Builder.Default + private ZonedDateTime createdAt = ZonedDateTime.now(); + + private Vorgang.PostfachAddress postfachAddress; +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtId.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtId.java new file mode 100644 index 0000000..281704f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtId.java @@ -0,0 +1,37 @@ +/* + * 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.nachricht; + +import de.ozgcloud.common.datatype.StringBasedValue; + +public class NachrichtId extends StringBasedValue { + + NachrichtId(String nachrichtId) { + super(nachrichtId); + } + + public static NachrichtId from(String nachrichtId) { + return new NachrichtId(nachrichtId); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtMapper.java new file mode 100644 index 0000000..bc03092 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtMapper.java @@ -0,0 +1,78 @@ +/* + * 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.nachricht; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.bescheid.UserId; +import de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.common.binaryfile.FileId; +import de.ozgcloud.nachrichten.postfach.GrpcPostfachNachricht; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, // + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, unmappedTargetPolicy = ReportingPolicy.ERROR, uses = { GrpcObjectMapper.class }) +public interface NachrichtMapper { + + @Mapping(target = "createdAtBytes", ignore = true) + @Mapping(target = "mergePostfachAddress", ignore = true) + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "idBytes", ignore = true) + @Mapping(target = "mailBodyBytes", ignore = true) + @Mapping(target = "replyOptionBytes", ignore = true) + @Mapping(target = "subjectBytes", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "allFields", ignore = true) + + @Mapping(target = "id", ignore = true) + @Mapping(target = "attachmentList", source = "bescheidFileId") + @Mapping(target = "replyOption", constant = "FORBIDDEN") + GrpcPostfachNachricht mapToGrpc(Nachricht nachricht); + + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeIdentifier", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "versionBytes", ignore = true) + @Mapping(target = "allFields", ignore = true) + GrpcPostfachAddress mapAddress(Vorgang.PostfachAddress address); + + default String mapToString(FileId fileId) { + return fileId.toString(); + } + + default String mapToString(UserId userId) { + return userId.toString(); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteService.java new file mode 100644 index 0000000..0578be2 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteService.java @@ -0,0 +1,57 @@ +/* + * 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.nachricht; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.nachrichten.postfach.GrpcSaveNachrichtDraftRequest; +import de.ozgcloud.nachrichten.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub; +import io.grpc.ClientInterceptor; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class NachrichtRemoteService { + + @GrpcClient("nachrichten-manager") + private PostfachServiceBlockingStub serviceStub; + + @Autowired + private NachrichtMapper mapper; + + @Autowired + private ClientInterceptor bescheidCallContextInterceptor; + + public void saveDraft(Nachricht nachricht) { + serviceStub.withInterceptors(bescheidCallContextInterceptor) + .saveNachrichtDraft(buildRequest(nachricht)); + } + + GrpcSaveNachrichtDraftRequest buildRequest(Nachricht nachricht) { + return GrpcSaveNachrichtDraftRequest.newBuilder() + .setVorgangId(nachricht.getVorgangId().toString()) + .setNachricht(mapper.mapToGrpc(nachricht)) + .build(); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtService.java new file mode 100644 index 0000000..74606a9 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/nachricht/NachrichtService.java @@ -0,0 +1,103 @@ +/* + * 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.nachricht; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Objects; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.bescheid.Bescheid; +import de.ozgcloud.bescheid.vorgang.Vorgang.PostfachAddress; +import de.ozgcloud.common.errorhandling.TechnicalException; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import lombok.extern.log4j.Log4j2; + +@Service +@Log4j2 +public class NachrichtService { + + @Autowired + private NachrichtRemoteService remoteService; + + @Autowired + private Configuration freemarkerCfg; + + static final String SUBJECT = "Ihr Antrag"; + + private static final String TEMPLATE_FILE = "bescheid.nachrichtTemplate.txt.ftlh"; + + public void createNachrichtDraft(Bescheid bescheid) { + buildNachricht(bescheid).ifPresentOrElse(remoteService::saveDraft, () -> LOG.warn("No ServiceKonto given on Vorgang.")); + } + + Optional<Nachricht> buildNachricht(Bescheid bescheid) { + return getAddress(bescheid).map(address -> Nachricht.builder() + .vorgangId(bescheid.getVorgangId()) + .postfachAddress(address) + .subject(SUBJECT) + .mailBody(buildMessage(bescheid)) + .createdBy(bescheid.getCreatedBy()) + .bescheidFileId(bescheid.getBescheidFileId()) + .build()); + } + + Optional<PostfachAddress> getAddress(Bescheid bescheid) { + var serviceKonto = bescheid.getServiceKonto(); + if (Objects.nonNull(serviceKonto)) { + return Optional.of(serviceKonto.getPostfachAddresses().get(0)); + } + return Optional.empty(); + } + + String buildMessage(Bescheid bescheid) { + return bescheid.getNachrichtText() + .orElseGet(() -> fillTemplate(TEMPLATE_FILE, bescheid)); + } + + String fillTemplate(String templateName, Object dataModel) { + try { + Template template = getTemplate(templateName); + StringWriter stringWriter = new StringWriter(); + template.process(dataModel, stringWriter); + return stringWriter.toString(); + + } catch (IOException | TemplateException e) { + throw new TechnicalException("Error filling template", e); + } + } + + Template getTemplate(String templateName) { + try { + return freemarkerCfg.getTemplate(templateName); + } catch (IOException e) { + throw new TechnicalException("Error loading mail template", e); + } + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java new file mode 100644 index 0000000..2e6e0ef --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java @@ -0,0 +1,245 @@ +/* + * 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.smartdocuments; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Optional; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.BodyExtractors; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; +import org.w3c.dom.Text; +import org.xml.sax.SAXException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import de.ozgcloud.bescheid.Bescheid; +import de.ozgcloud.bescheid.BescheidRemoteService; +import de.ozgcloud.bescheid.BescheidRequest; +import de.ozgcloud.bescheid.common.callcontext.UserProfile; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsBescheidRemoteService.SmartDocumentsResponse.SmartDocumentDocument; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsBescheidRemoteService.SmartDocumentsResponse.SmartDocumentFile; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsRequest.CustomerData; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsRequest.CustomerData.BescheidData; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsRequest.CustomerData.UserData; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsRequest.SmartDocument.Selection; +import de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.common.binaryfile.FileDataDeserializer; +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.log4j.Log4j2; +import reactor.core.publisher.Mono; + +@Log4j2 +@Service +@ConditionalOnProperty("ozgcloud.bescheid.smart-documents.url") +class SmartDocumentsBescheidRemoteService implements BescheidRemoteService { + + private static final String FILE_TYPE_PDF = "PDF"; + private static final String FILE_TYPE_XML = "XML"; + + @SuppressWarnings("deprecation") // SD requires forced UTF-8 encoding + private static final MediaType JSON_MEDIA_TYPE_FOR_SD = MediaType.APPLICATION_JSON_UTF8; + + @Autowired + @Qualifier("smartDocuments") + private WebClient smartDocumentsWebClient; + + @Autowired + private SmartDocumentsProperties properties; + + @Override + public Bescheid create(BescheidRequest request, Vorgang vorgang) { + var sdRequest = createRequest(request, vorgang); + LOG.debug(() -> buildLogRequest(sdRequest)); + + return smartDocumentsWebClient.post().accept(MediaType.APPLICATION_JSON) + .contentType(JSON_MEDIA_TYPE_FOR_SD) + .bodyValue(sdRequest) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, this::handleClientError) + .bodyToMono(SmartDocumentsResponse.class) + .map(response -> buildBescheid(request, response)) + .block(); + } + + Mono<Throwable> handleClientError(ClientResponse response) { + return response.body(BodyExtractors.toMono(String.class)) + .map(content -> new TechnicalException("Client-Error: " + content)); + } + + private String buildLogRequest(SmartDocumentsRequest request) { + try { + ObjectMapper oj = new ObjectMapper(); + return oj.writerWithDefaultPrettyPrinter().writeValueAsString(request); + } catch (Exception e) { + LOG.warn("Error writing request as json-string for logging.", e); + return "Error generating logging string"; + } + } + + Bescheid buildBescheid(BescheidRequest request, SmartDocumentsResponse smartDocumentsResponse) { + var smartDocumentsFile = getSmartDocumentsFile(smartDocumentsResponse); + + return Bescheid.builder() + .bescheidFile(smartDocumentsFile.getDocument().getData()) + .bescheidFileName(smartDocumentsFile.getFilename()) + .size(smartDocumentsFile.getDocument().getData().length()) + .contentType(MediaType.APPLICATION_PDF_VALUE) + .nachrichtText(getNachrichtText(smartDocumentsResponse)) + .genehmigt(request.isGenehmigt()) + .createdBy(request.getCreateFor().getId()) + .vorgangId(request.getVorgangId()) + .build(); + } + + private SmartDocumentFile getSmartDocumentsFile(SmartDocumentsResponse response) { + return getSmartDocumentsFile(response, FILE_TYPE_PDF) + .orElseThrow(() -> new IllegalStateException("No PDF File in SmartDocuments Response found.")); + } + + Optional<String> getNachrichtText(SmartDocumentsResponse response) { + return getXMLFile(response).flatMap(this::extractTextFormXmlFile); + } + + Optional<String> extractTextFormXmlFile(File xmlFile) { + var xPath = XPathFactory.newInstance().newXPath(); + try { + var document = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder().parse(xmlFile); + var expr = xPath.compile("/root/SmartDocument/Fields/NachrichtenText/text()"); + var text = (Text) expr.evaluate(document, XPathConstants.NODE); + + return Optional.of(text.getTextContent()); + } catch (XPathExpressionException | SAXException | IOException | ParserConfigurationException e) { + LOG.error("XML-Parsing error on extracting Nachricht-Text: {}", e.getMessage(), e); + } catch (ClassCastException e) { + LOG.error("Error on extraction Nachricht-Text. XPath return unexpected Type.", e); + } catch (RuntimeException e) { + LOG.error("Unexpected Error on extracting NachrichtText: {}", e.getMessage(), e); + } + return Optional.empty(); + } + + Optional<File> getXMLFile(SmartDocumentsResponse response) { + return getSmartDocumentsFile(response, FILE_TYPE_XML) + .map(SmartDocumentFile::getDocument) + .map(SmartDocumentDocument::getData); + } + + Optional<SmartDocumentFile> getSmartDocumentsFile(SmartDocumentsResponse response, String fileType) { + return response.getFile().stream() + .filter(file -> file.getOutputFormat().equals(fileType)) + .findFirst(); + } + + SmartDocumentsRequest createRequest(BescheidRequest request, Vorgang vorgang) { + return logRequest(SmartDocumentsRequest.builder() + .smartDocument(buildSDSection(vorgang)) + .customerData( + CustomerData.builder() + .vorgang(vorgang) + .userData(buildUserData(request.getCreateFor())) + .bescheid(BescheidData.builder().bescheidVom(request.getBescheidVom()).genehmigt(request.isGenehmigt()).build()) + .build()) + + .build()); + } + + private UserData buildUserData(UserProfile userProfile) { + return UserData.builder() + .firstName(userProfile.getFirstName()) + .lastName(userProfile.getLastName()) + .email(userProfile.getEmail()) + .build(); + } + + private SmartDocumentsRequest.SmartDocument buildSDSection(Vorgang vorgang) { + return SmartDocumentsRequest.SmartDocument.builder().selection(Selection.builder() + .templateGroup(properties.getTemplateGroup()) + .template(vorgang.getVorgangName()) + .build()) + .build(); + } + + private SmartDocumentsRequest logRequest(SmartDocumentsRequest request) { + LOG.debug(() -> { + var ojMapper = new ObjectMapper(); + try { + return ojMapper.writeValueAsString(request); + } catch (JsonProcessingException e) { + LOG.warn("Json Processing Exception on logging request.", e); + return request.toString(); + } + }); + + return request; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + static class SmartDocumentsResponse { + Collection<SmartDocumentFile> file; + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + static class SmartDocumentFile { + private String filename; + private SmartDocumentDocument document; + private String outputFormat; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + static class SmartDocumentDocument { + @JsonDeserialize(using = FileDataDeserializer.class) + private File data; + } + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsConfiguration.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsConfiguration.java new file mode 100644 index 0000000..bec4a85 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsConfiguration.java @@ -0,0 +1,76 @@ +/* + * 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.smartdocuments; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeFilterFunctions; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.ProxyProvider; + +@Configuration +@ConditionalOnProperty("ozgcloud.bescheid.smart-documents.url") +class SmartDocumentsConfiguration { + + @Autowired + private SmartDocumentsProperties properties; + + @Bean("smartDocuments") + WebClient smartDocumentsWebClient() { + ReactorClientHttpConnector connector = new ReactorClientHttpConnector(buildHttpClient()); + + return WebClient.builder() + .baseUrl(properties.getUrl()) + .filter(ExchangeFilterFunctions.basicAuthentication(properties.getBasicAuth().getUsername(), properties.getBasicAuth().getPassword())) + .clientConnector(connector) + .build(); + } + + private HttpClient buildHttpClient() { + if (properties.getProxy() != null) { + return createProxyHttpClient(); + } else { + return createNoProxyHttpClient(); + } + } + + private HttpClient createNoProxyHttpClient() { + return HttpClient.create(); + } + + private HttpClient createProxyHttpClient() { + return HttpClient.create() + .proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP) + .host(properties.getProxy().getHost()) + .port(properties.getProxy().getPort()) + .username(properties.getProxy().getUsername()) + .password(username -> properties.getProxy().getPassword())); + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsProperties.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsProperties.java new file mode 100644 index 0000000..213782c --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsProperties.java @@ -0,0 +1,111 @@ +/* + * 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.smartdocuments; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import org.apache.logging.log4j.core.config.plugins.validation.constraints.NotBlank; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.Getter; +import lombok.Setter; + +@ConditionalOnProperty("ozgcloud.bescheid.smart-documents.url") +@Validated +@Getter +@Setter +@Configuration +@ConfigurationProperties("ozgcloud.bescheid.smart-documents") +public class SmartDocumentsProperties { + + /** + * Location of the Smart Documents Server + */ + @NotBlank + private String url; + + /** + * Credential for basic auth to the Smart Documents Server + */ + @NotNull + @Valid + private UsernamePassword basicAuth; + + /** + * Smart Documents Template Group + */ + @NotBlank + private String templateGroup; + /** + * Smart Documents Template + */ + @NotBlank + private String template; + + /** + * Proxy Configuration if required. + */ + private ProxyConfiguration proxy; + + @Getter + @Setter + static class UsernamePassword { + /** + * Username for authentication + */ + @NotBlank + private String username; + /** + * Password for authentication + */ + @NotBlank + private String password; + } + + @Getter + @Setter + static class ProxyConfiguration { + /** + * Host Address of the proxy server with protocol + */ + @NotBlank + private String host; + /** + * Port Number of the proxy server + */ + private int port = 8080; + /** + * Username for Authentication for the proxy server + */ + private String username; + /** + * Username for Authentication for the proxy server + */ + private String password; + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsRequest.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsRequest.java new file mode 100644 index 0000000..27f5364 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsRequest.java @@ -0,0 +1,91 @@ +/* + * 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.smartdocuments; + +import java.time.LocalDate; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +import de.ozgcloud.bescheid.vorgang.Vorgang; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Builder +@Getter +@JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) +@ToString +class SmartDocumentsRequest { + + @Builder.Default + private CustomerData customerData = CustomerData.builder().build(); + @Builder.Default + private SmartDocument smartDocument = SmartDocument.builder().build(); + + @Builder + @Getter + static class CustomerData { + private Vorgang vorgang; + private BescheidData bescheid; + private UserData userData; + + @Builder + @Getter + static class BescheidData { + private LocalDate bescheidVom; + private boolean genehmigt; + } + + @Builder + @Getter + static class UserData { + private String firstName; + private String lastName; + private String email; + } + } + + @Builder + @Getter + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + static class SmartDocument { + + @Builder.Default + @JsonProperty("Selection") + private Selection selection = Selection.builder().build(); + + @Builder + @Getter + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + static class Selection { + @Builder.Default + private String templateGroup = "Kiel"; + @Builder.Default + private String template = "Halteverbot"; + } + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapper.java new file mode 100644 index 0000000..2084c41 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapper.java @@ -0,0 +1,71 @@ +/* + * 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.vorgang; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgang.GrpcEingang; +import de.ozgcloud.vorgang.vorgang.GrpcFormData; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, // + uses = { FormDataEntryMapper.class, GrpcObjectMapper.class }) +interface BescheidVorgangMapper { + + @Mapping(target = "serviceKonto", source = "header.serviceKonto") + @Mapping(target = "vorgangNummer", source = "nummer") + @Mapping(target = "vorgangName", source = "name") + Vorgang mapVorgang(GrpcVorgangWithEingang vorgang); + + @Mapping(target = "postfachAddress", ignore = true) + @Mapping(target = "postfachAddresses", source = "postfachAddressesList") + Vorgang.ServiceKonto mapServiceKonto(GrpcServiceKonto serviceKonto); + + Vorgang.PostfachAddress mapAddress(GrpcPostfachAddress address); + + VorgangId mapVorgangId(String vorgangId); + + Vorgang.Eingang mapEingang(GrpcEingang eingang); + + default Collection<FormDataEntry> mapFormData(GrpcFormData value) { + var result = new ArrayList<FormDataEntry>(); + var entryMapper = Mappers.getMapper(FormDataEntryMapper.class); + + result.addAll(value.getFieldList().stream().map(entryMapper::fromGrpc).toList()); + result.addAll(value.getFormList().stream().map(entryMapper::fromGrpc).toList()); + + return Collections.unmodifiableList(result); + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntry.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntry.java new file mode 100644 index 0000000..16c0414 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntry.java @@ -0,0 +1,86 @@ +/* + * 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.vorgang; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@JsonSerialize(using = FormDataEntrySerializer.class) +public interface FormDataEntry { + + String getName(); + @JsonIgnore + String getLabel(); + + @JsonIgnore + default boolean isSubForm() { + return false; + } + + @JsonIgnore + default boolean isFormEntry() { + return false; + } + + @Builder + @Getter + static class SubForm implements FormDataEntry { + + private String name; + @JsonIgnore + private String label; + + @Singular + private List<FormDataEntry> entries; + + @JsonIgnore + @Override + public boolean isSubForm() { + return true; + } + } + + @Builder + @Getter + static class FormField implements FormDataEntry { + + private String name; + @JsonIgnore + private String label; + + private Object value; + + @JsonIgnore + @Override + public boolean isFormEntry() { + return true; + } + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntryMapper.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntryMapper.java new file mode 100644 index 0000000..2a36897 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntryMapper.java @@ -0,0 +1,57 @@ +/* + * 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.vorgang; + +import java.util.List; +import java.util.stream.Stream; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.bescheid.vorgang.FormDataEntry.FormField; +import de.ozgcloud.bescheid.vorgang.FormDataEntry.SubForm; +import de.ozgcloud.vorgang.vorgang.GrpcFormField; +import de.ozgcloud.vorgang.vorgang.GrpcSubForm; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface FormDataEntryMapper { + + @Mapping(target = "entries", source = ".", qualifiedByName = "mapEntrys") + @Mapping(target = "entry", ignore = true) + @Mapping(target = "name", source = "title") + SubForm fromGrpc(GrpcSubForm subForm); + + FormField fromGrpc(GrpcFormField field); + + @Named("mapEntrys") + default List<FormDataEntry> mapEntrys(GrpcSubForm subForm) { + var fieldStream = subForm.getFieldList().stream().map(this::fromGrpc); + var subFormsStream = subForm.getSubFormList().stream().map(this::fromGrpc); + + return Stream.concat(fieldStream, subFormsStream).toList(); + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializer.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializer.java new file mode 100644 index 0000000..fe3bd2f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializer.java @@ -0,0 +1,104 @@ +/* + * 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.vorgang; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import de.ozgcloud.bescheid.vorgang.FormDataEntry.FormField; +import de.ozgcloud.bescheid.vorgang.FormDataEntry.SubForm; +import de.ozgcloud.common.errorhandling.TechnicalException; + +public class FormDataEntrySerializer extends StdSerializer<FormDataEntry> { + + public FormDataEntrySerializer() { + super(FormDataEntry.class); + } + + @Override + public void serialize(FormDataEntry value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + if (value.isFormEntry()) { + var formEntry = (FormField) value; + Optional.ofNullable(formEntry.getValue()).map(Object::toString).filter(StringUtils::isNoneBlank) + .ifPresent(val -> writeStringField(value.getName(), val, gen)); + } + if (value.isSubForm()) { + gen.writeFieldName(value.getName()); + gen.writeStartObject(); + var subForm = (SubForm) value; + + subForm.getEntries().forEach(entry -> writeObject(entry, gen)); + gen.writeEndObject(); + } + } + + private void writeStringField(String name, String value, JsonGenerator gen) { + try { + gen.writeStringField(name, value); + } catch (IOException e) { + throw new TechnicalException("Error writing string field in json.", e); + } + } + + static void writeObject(Object pojo, JsonGenerator jgen) { + try { + jgen.writeObject(pojo); + } catch (IOException e) { + throw new TechnicalException("Error on writing object to json.", e); + } + } +} + +class FormDataEntryListSerializer extends StdSerializer<List<FormDataEntry>> { + + public FormDataEntryListSerializer() { + super(List.class, true); + } + + @Override + public void serialize(List<FormDataEntry> value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeStartObject(); + + value.forEach(entry -> defaultSerializeValue(entry, gen, provider)); + gen.writeEndObject(); + } + + private void defaultSerializeValue(Object value, JsonGenerator jgen, SerializerProvider provider) { + try { + var serializer = provider.findValueSerializer(FormDataEntry.class); + serializer.serialize(value, jgen, provider); + } catch (IOException e) { + throw new TechnicalException("Error serializing value.", e); + } + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/Vorgang.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/Vorgang.java new file mode 100644 index 0000000..d10b0b9 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/Vorgang.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.bescheid.vorgang; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; +import lombok.ToString; + +@Builder +@Getter +@ToString +public class Vorgang { + + @JsonIgnore + private VorgangId id; + + private String vorgangName; + + private String vorgangNummer; + private String aktenzeichen; + + @JsonIgnore + @ToString.Exclude + private ServiceKonto serviceKonto; + @ToString.Exclude + private Eingang eingang; + + @Builder + @Getter + public static class ServiceKonto { + private String type; + @Singular + private List<PostfachAddress> postfachAddresses; + } + + @Builder + @Getter + public static class PostfachAddress { + private String version; + private int type; + private Map<String, Object> identifier; + } + + @Builder + @Getter + static class Eingang { + private Antragsteller antragsteller; + private ZustaendigeStelle zustaendigeStelle; + + @Singular("formData") + @JsonSerialize(using = FormDataEntryListSerializer.class) + private List<FormDataEntry> formData; + } + + @Builder + @Getter + @JsonInclude(Include.NON_EMPTY) + static class Antragsteller { + private String anrede; + private String nachname; + private String vorname; + private String geburtsdatum; + private String geburtsort; + private String geburtsname; + private String email; + private String telefon; + private String strasse; + private String hausnummer; + private String plz; + private String ort; + } + + @Builder + @Getter + static class ZustaendigeStelle { + private String organisationseinheitenId; + private String email; + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangId.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangId.java new file mode 100644 index 0000000..3603e7f --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangId.java @@ -0,0 +1,38 @@ +/* + * 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.vorgang; + +import de.ozgcloud.common.datatype.StringBasedValue; + +public class VorgangId extends StringBasedValue { + + VorgangId(String vorgangId) { + super(vorgangId); + } + + public static VorgangId from(String vorgangId) { + return new VorgangId(vorgangId); + } + +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteService.java new file mode 100644 index 0000000..147de6d --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteService.java @@ -0,0 +1,54 @@ +/* + * 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.vorgang; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import io.grpc.ClientInterceptor; +import lombok.NonNull; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service("bescheid_VorgangRemoteService") +class VorgangRemoteService { + + @GrpcClient("vorgang-manager") + private VorgangServiceBlockingStub vorgangServiceStub; + @Autowired + private BescheidVorgangMapper mapper; + + @Autowired + private ClientInterceptor bescheidCallContextInterceptor; + + public Vorgang getById(@NonNull VorgangId vorgangId) { + var request = GrpcFindVorgangWithEingangRequest.newBuilder().setId(vorgangId.toString()).build(); + var response = vorgangServiceStub + .withInterceptors(bescheidCallContextInterceptor) + .findVorgangWithEingang(request); + + return mapper.mapVorgang(response.getVorgangWithEingang()); + } +} diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangService.java new file mode 100644 index 0000000..a8d9c88 --- /dev/null +++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/vorgang/VorgangService.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.bescheid.vorgang; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import lombok.NonNull; + +@Service("bescheid_VorgangService") +public class VorgangService { + + @Autowired + public VorgangRemoteService remoteService; + + public Vorgang getById(@NonNull VorgangId id) { + return remoteService.getById(id); + } +} diff --git a/bescheid-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/bescheid-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..539db3d --- /dev/null +++ b/bescheid-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,8 @@ +net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration diff --git a/bescheid-manager/src/main/resources/dummy-bescheid.pdf b/bescheid-manager/src/main/resources/dummy-bescheid.pdf new file mode 100644 index 0000000000000000000000000000000000000000..38e37a52ebeddf42ace077231b0a015ece6ef7ea GIT binary patch literal 10120 zcmY!laB<T$)HCB!J-p=bp2OP?&*w5yFi^-(%Hp!I(f3KsOE1Y#Fjg>72-0`U%qdAN z(s#>AEJ<}qP0mkAwX@?YE-6Y)%;l<>liRzOi^))+<+shzYfg{eJ^MDvA>zZAbsMZX zB0A>U&wXIJZ=a?AhJa-=5+(LIx_>a?cW`Kzahznq$FxyVJi6&+5})=C{q9vS({?2- zDHU}3pm&tzDbMT128mN&XG{z+GOF5ob#KuzHr8k!FUiHXqLx_ZO<OiwJo?Vdm2Z6G z&;0m)YV+j#tN-~*Yqb?D<eYfxl~2s(@cAoO3T>T#rKaAkf^mI<=`XI-ycDQ|Q}a?l ze&hmq4a6`sGXu$jm|Uh90bqtB0H6V6s9<PpXkvjJ98ariYoxDEePL@XRr|x+c$1Fz zM%~`EHwqu|-<&r0h^LIdOmtb2dRUTmgyNA&x<8q7yeCd+aftl$L*t5~szU=?#nIco zo45Fi&s<^>Am-zp`CZiO#-_K-vs7!Boc<ObbSY=nQ&FAwGp&`6b2jd~`~6?_<1=S| z?t4D3_}$+0H%Aulc2;Tj5t!z|oZRT)fB2M?(~0bshRg*2n4A}9B6~kbI?bq;>EY?M z{q|Q@ob%!w1())qjFS5g0_&I__9Qy#tmkcKI{53Av^GcKwMD&84}090cxSnDjmXEN zhm$|fe!X>mj`JUdM|&4PY&@{>*d(?i|3yEZ+IZmXL^WUb=0#ygj($84@#69N{~8@X zyqqp2Pb|=pQ~7>Q@R60;XXT3lOCE3hC$HT1Z__5<1M)vlIRt1w=2`u4i`8C5U0Y@2 z(<iu><rMS%{Qu$+-vpUU$4mv3J1;yJ6|e5OaU#*_ncb9)r_ZMxzcc@TeAUA6xOipv zlbl5jdwlZ(B;_8dDyNtSiN)zpHlL^!AGc|4&1|2#zMIKUR6dDX+V6~?chXc}zjBI< zy8X^15q(MJ?Ths9E9X0#{$$sgYOs@`>eKxb{TE-cF3H_BO;e3qzF9;j#-Vn)&AB(~ z(la-A$V{{B>3(=p`w8cb&S{S=&NF{Dj{7XR`1^$0A8xv~os?^NdDOJ#7oXvoztZPk znQfYQ$MM?4i>y-m2PWr8JzGE9rqi%?=A{_TW$SwPPOO}km?rP^gwd#_oT1>|8OE}^ z&s|>F*KV{`5uUc`=#c_ly<qR2llI1@#o{-Qs`P$2GuQv(vs=&q_42A5H?5sjv(EAJ zW_>B=-wkOzTTkA}pS)eI`A*t9jkMRAPD`%6-u}C)de`o4c^}L2?p?XKuh2Pq_41{a zwU@0{7UmwFb#?Wt@O2S!;jvFwt<lhr4GP+GBQoU0hFPrlW=x$qFYUtXEpysZ8>Vz~ ze%P*ZBPs9$%N*Tv4$-bVZzRd)t<%Uatop-gsG#;?sb=A}t$~w_CkXsaTEr6H$eL2` z<aF}jY86%2pjp#d;$obyop81|dgS$4zmF<8_b+vSXiQt~?=xrd2Q{v2FO5l^9*K%s z0qaxpk4|ezKmQ@6TfVmC<(DmA&wX9ErK`wj?zFxHE2qw&^b{$t>rAXOE=>!)%yTjQ z)Zs@y(M$(h%DwZwi{la(u3uE+taSROPh^U%>C6l3{9ml_EOaTG`$l~E>2$UC)+Z;| z)knHrkmPyu!gmAXmANU=YU=MjIZ`{9o_luWQuMi~!e<Lzc5dFO8mJbXd*905@Ap$h z#e<@s{R%(%vn+pX^Znt}DGgp1#Xi?78O=zzrk;?Uzp&<MrNOnyljWAbnEAz@&F`G= z7i-shmX>oT8cJp!ED+AupJieB{m;KWEzj-Zo4)fO)|zisdj8rsmv7TvR}1@WbeG{% zVEu1u#U1`kl<Tw6z4OV!Jlt&T$}tfd?TP<AJHIGTnsMXO>IX_M&sVp3tTT#l`gnTI zOcC|v?$3OdSbTm}r~Yi)-qqzs3pMWvlx#~l@||5s_-{n4`KivrPn~PLD_hTbPFA?K zyCx*eWxW}T`w^D#CP$~Wty~f2n@*|tPh8`D>UE49Ux3n#BUS3NCcfQb5&h@Ye%r%g zCJIRlZl9Xs^x~bb$5{>!M$=^7%b|K#IDQx=DxWo($vNG4l7aQ?XPdQmUp2aP)jKp~ zYfEKq(+~ELwJob#*J*D|y>x%g4u#uAc`s}Gc051lbG@tb_}wMbe#}ZuJYBVB)1+x9 z?>$I3^zc0Qqg~P>)t|Y9C-ED<DgM@0Q*<-2W!k)xi;q5By!F!E+xMR4+~2gfeCex> zLle$sc15o<di>^W@R<ZgwJ%4jHcmg8T&r<H+3}0QgPf@5^DXNl`px?pmxt^un0>8d z?*#XtOE27#R^AZG3VWLJhimbi7{AxIgRX5c>MFao{i*0LuBodR&2ikeg0Dxa%5p`n zrdVF^i3`cK>+%<?SWXMu`Qm6?`iYmteBGQUZ)>0T<>T+&B*i0DY#M$yJb}BZHBqVc zgr8!Of$+Rdds+|rZV9T9%iZ0zSMjKr`qy*c)_LCC5p3#l;WIC%()0~mf=(>1ZrrnA z?vC$WHhP)67N{>*^^7}ncy)^MIo^Yw>EZ9Cw0eJ^%&pvhB6+5V^_Ft;&?%3vT{C&x zQoY^ByCDDiw|mbk-f+Kv`>wW)F>UYuljeIRD)*l6tjGw^QVvdC)YD<46n(3!W8SIf zw(5dLjyt8i7W_EisW4@k|HTHLIVmDi>v=+)*e7u`%k&<a7<5T$$xG2&EK4tD&pM$v z`I3dFzT^@fwaF)Ev(5a%6EyF*-8F_M6>KR^_e`>Kmp++nV3<4MlSn7$lnEmI@89mU zDLMb`-ebuMtLGQh`L3wMN9bKk^f8mu)=dh~o1*`-P5rN3<wim7Wo-W)ndW30`kveR zqQgvi;xiso)k|}IjrImEGuJ9v>vKJ^vxzmJmZ|u?Z$k{@_3vVjCW(mub-t%k?{{tr zzxh<pf7?Z0+<CRrf9KsB%~BqEFDJyznVB-nc<r`3bL`^R9eaN|wX%4A|Mj1>dpd6{ z2;9_|(QIrsW0T_%HuF0Lhu6J0C+(3ODY@~Hvw>sn-UniLu7)0%?6f?g@cIk~6(*&l z=XQx6nq+l$;*;4Y`Tg$vIqSWD_Fsu4gBgErKiNLX^?09b@;oMKk=mlwa$Ps%)%Q=g zndqa^pY`gKNql^W`;+w@dv@~QynI78`o!TNdBfB!6Sm2U*H5KJZ`x}&_vng)Tk^lA zewxP9e0};v<J4B;uo)Yf@>!Ewt6WsHLn0lQR2<?G)c&C<m^fvgM_|AMwyL*>w6)@` zHQPQP$=r3C<xyDtXW?bRX1lYWXo_*|v~2a>bRaT?`N)F0SKf=`S-;<VBL8LWdGmSu zCErXaJae!nVfBwMhS9FaCsi33H*e#zI&So4L(ZFiPg5J^vz(H*{`_$Yii!#hoN;hh z_A2eY`?8WV6ZcIB3=Dht)v_nm(roRu1cUsql0Q^$Fl;&+U8}SIIPdK{8}9IS-%TiN zzQ#NKPQf+a{GAU&&1DJ?E9bo^XRf$=;Z2*CR(e_UG2X+^gPYXv2$VNJX^T4LcF)y( z&+9fxbCngnyYC2;tX30|v{NlR#k+pTL+d;XkE3}-hqKH(RvLzBG5hR1_`dDk6^XP} zmD951iVm~z=}*;t@I3JD<|~Y9j;u;06*5;}u>JK@O|JF2bVYkroK~^j^7(=tabfWa zEkCCf_nh?Gd)MUkC)LY76IQFm>o#nCux{g%Q~uHkya@-dTXk=en5*g@a8W3IqF?LN zOCPq_t8RUxcjJrO=byDF=lxzLwsniiGY<AizQ3!hs@~g7xU;QXKV|d3O`%)Aruv?| zf8H)>^@<IKdyjv~oH^_1>!6J3>l3c2HLvkF&GGugv@aXvA4i>R|NhkK)V8#Uw`Rv! zW=aKDHJV1BIC1L3ucA#oF58bDpY&&kEZf@+XZd<$^=>>|BYSVt;nigo*ZAT$G8g?V z`*3UFNj}rEh#dCKvRld|_NBDP-+I_yR&k8a{mq93vhNmM%2<7yPfjZ~g?+NDN!gB! z_WFgN*57#8BHOp@$>OpX+Yg6Xo7`S_jZd{~!;&Y@|5_9-{k!^!Xnt7SqD!Ce$#_Lh zUl;x2e9|j^0qZ&24@+9l@v<z@NVWBNzA9qB2kQ(;Yn3+z7x;wBI&Lhy%;)yI=4@<e z$?iq97q!>5Uj2SkC?=xy`jl|3jcIkS3zOIG{9ShM!M;5=)5LXG7C(QKwp%RhM6_R@ zo`0pI*yqV-W!E_!@49u5S9?<b&xc1AK3UqHkY4|(vGiZXrQ}~T?aR;3Tfb3IXa1g> z2A>7?72ECoH=Eu362F&?{J%9j8=g1Mo8iG}scV~}q4YB*EX=P@dA~>St|c?R|L*eT z(`!Ec;dhVBlFc&dXSYTDstL2PTa#lZr*d=I${>pfF5#sDnymGj9!m?BiOgFf;<9&& z(zHX>OAVYgLq$}VZg|Ce>Y4XL8&k&>&sGM_ShP*#>`#N(zPqB0q1$qQmMDD<6L<4# zTo-j<M@_c(DTjjVI_H-$v=v(}UlV+BQu4J|Zzd#P6A|02Z};u4`Mtl#9$w(ipEJMa zk@fw5SGv-}JI>VpI578qwdv30mXqG3+3z!*^h9maH0JVi`<B%{*nUd!+lz^|?w>dB zuYP~pequfMF#-K~>2h~o7kk)QD&%fwln{Se++)dFCjIeOk6C-~$%Nc(Jd;m8`a1Im zPhPkF;YA^jt~4cuOjEn|IjY99Y{jPL4EA}~zKe+NdL*)Vy40jr!G%Ysbh+^9Y0mlA zCG%56TQF<-ZdXP2t}T|WTU8fi?x@Z9xp390{JiS#>Gt)UZj<`?+8-X2{je?b(}wF) z_FW46saP;wPlbK^Az^=6%eshr{kxvqrPMVR>#EwV+!l}?H^uWz%F9h>oXpIxzx(?1 z>8BhkxkqbKlO$cHHP%a3OmE!5GcS&<_Vj{c$t9D#3IsK@8Ee<?e`97_zxBnMT|%$2 zVgpWIS@_&^r{y`-9q+S>&rFN4KK&=@*Y0`wp`jt$@BcY`c;AJ-S^2UuRd=?o(c85& z{qnQ+ZRS>v_4f}lU1l#gli#~^+ky?12R<+TExW#d=bp1)XNzAAS$E&<`}MOkcAvG7 z=l<xO&7ybrP-M~CD&=poRriw8&hA(pwc%uh_5H#G;i7w7%Y%B^F3sQOH2+S<nQ*P# zB|&?SK0O-SV=2IDCFnS>Lt{o^o%W5hSC4N~5C8M-ZS}ISDWyjzi~oOS&EI!TKaQ*Z z&)+r5Kc6pN_vAzLeeEf=rjMQe>6SN$OnAPu_DIgQ)U;H|9Jbwy6DD2{cR17W<kp4H zcjn}@J+w$%-T!#GOu;cmW4;Hn4l*}vEFUajR^t0$ec(02Nybn<0oex&a#DPk>^NcN zYAVb(Bg!Fu$M@K+*L5v2uFCpF&iTqMzC6<1|N76#Usg4TT>tj>SoA&--+LvuFU~E$ zH;?DtUjD2b-iN1pU$6Np_jS&l$~6gQ(QOvTw7&1Vk!`59u6fC0u0QWDDV#iUfy-%K zt7*wk4sM&%&pa&EY*c$Cn*tB8&P+bX>Z^Ap{!DB0&I2w*2j_F&i<wZAs3tD7)4(;* zQ2a-X!p?$uK>;NTpYYDVx!_lZNYF}s<?c0q&Ifx>npU=IQ>J0`jnk9&g|5<=zT^{^ z=G*m?x2@d0(C72KChz%cX63U>Y!b}=%6z8YEbKtbmCS2PglG3&|4`;`_Wo<?<39yO zF4Oy8_is=1nQ=$g?pRZ1ZtRRqr^!~1np_W-e>q+K{wdcoUEz((%p^@GdYNWFO)^U~ zoNm%^OPg6YgVB5T&!g+yCvV^X`C3NA@6wDub$dT6wRg9+-WB()dv%j<|IhM<JBN1b zM`{22GiNPRT>VFO?-~3oyQc56{%*IY?|F!oVUyo4yOU?Gq@{dtQp-Nm#ADVyHRAB& z>zi-x7kLoMXv3r<{veXEk1If_!Ih!4Z;CRLjL-u<Mg^sYc!u>1XPK^WZHQoqV^DJV zTgiBi>%%k#W2QMCnLZq=oXWi%l^ML|2|k#@uzrb3bBKdb!%88CC2IbG&YW3Jy{Y$~ zm#}^QU4DP+e07(Vv#xK*k`fQ`{dj0q;by;zy-T-kJNme+`rp&JTdm7Owr>sHZ7X;7 ze(kMgUwT$^KKz!<^ZCT(OBJ(@DoNy+xg~IY;tjL8&D-1N$2|L-6i>_J%U^YlfBR`< zc`Z#);?S3$XO4tKGjwwwh+&w;6!F!Ik%fDKWox`n!)B4tmUAKu#j6;WaVZ2b++zw* zE3G_bJ=J-Y+E(c$Qu3Fl9uLhbF3{#ya#t5wm7hBC#MP}*{^_?3)7~4hoqu_=-q!5* z)Z|lzG21h~_4fqU)nA$)9zOl}m9zhJ*7Ier<h_1c?^|k*v!Uc<Dc0J;jc#X7Y{<N! zs(REl(>1#0nvCOtr%56*OmY{S9KK|V&1Jjp&v)|UFAn>SEWf5TY+(^Np#LO<U1@&w zvR^;>T>durY*qMV75;s@>I{p8Wx6I#bN?JoU`fAQbRqTOMjiQ6AD$)izwuMsy!dkc z9fPl1nb%4;$GU3oXMA!_|NGthHUWqC{RuBWb1!%G4N2D5=c2D~oYl@`9kV;WT<xt? z-t&q>iBpSv-*&nE^9~kkS!yYpd?IO6Pt7#P;~5g`^<$H-yi^SKKOpp6@r1KE|5=+W zpEk^3H|Cd;)B98~t$lk%MQgjTjm*P`0{rD4Kd^pE|7ZN^>;LJ@KC#~Wy4WYO&pWl> zDcA4Aj{e0v=Ch}U{%yVX=l`DR$L)^xo-W*1@VvkH+{!J_*q$B@$?>`OtUX<xO*lio zP4@QLH@aKI@1K4%y}B?pHf!3WU1wCqmo65Ye6nZv<gjeN^xUw<AGNhk5eZr>37rSH zdm4pV)*fug-RXG!x$%YtS2KRsNL}WXmf3hvQQGH*LSFL%UK2Bm{N~MO72TI6zS!=# zop)Al!6~-&HxlBWuA9PDq$(Y9F`jAW%GO`qS6Y<XfAsL~KbPAOedBrUDIJbWe`c2N z6g(<ZvrKn?&6(4G`OBWQYTw~F82tY1zCTY4zw!GfJy~0xxPS4&g9mfw?^Ri!T3M?e zUuB*B?d-~w57H9O;@=$hAFR`zf5v0`#5XzFRc>wPR%vf|p8R}r{u#F;Nnd|m(y>(g zd0k`ApX@2hUzop${;KV~zxZqVOY=pa8gI<~<#6QuNt;v0*3F5$G1>de>B4=n^Ox)M zxZbZ{DZFbF|E^c&TxVzh%bR+MJ@@6!zTOMHyUQLjzR+JkKfk$Z_pd8<9&h=NP1>HN zUvM`?_ohRgYHez3U&N|an`V9Po^F;GaVqMQ?k=6!Ysbohf3B}ln|=1PeXZ*y{g0oQ zoEO`+@#QfkcfrG(w<$#n&Yt(~pZXn}Yn$G@s{gd{SlNv1cH_4Nt7Ow|DPH6Yep_JY z`tWw+mgW|fm9k22ANYI9<gmM2FWB^}QaAkcIo7Mfs(M?qUWhkbRh`cJZiP`G?^MqB zcdooo_4!(IHPiImqN6^t`AV%yf@gRZm2TC3@!U7|ZB&`*l_#4%v1!+To%t%uGjU>@ z;2AaEy9LulG9^>rKb>be;m_HN_f__PZT5e_K7lpv#@EA7HXpzKa(#7HZFIWxkNoBD zB4UC>uS$1!KQ^BD#D8-AkJzIB>*d-f&6oRizg+!)_*Yr~{)%wBD+NV+-oIb?UG_x# z^#;#<GyXgmpM3fM;n>S{bMxQ)+WTHTZ|#M1{|-uS6}|nBtxN8=$eQ=+yC=>6qfz<F zdiJjy$x`v39=FTKMQgu*Ec=1uaeB;;rT=D_oD%Y5eqt%VC*bJ8B)&5;85TQE9E{|< z_vir&ySv4X?q&=2vobP|5}FRb?Ps=UkK<F}3-Eo?P;lc(fx+Q}l6-!F3I`90i1r8U zylok=VcPnS*%Pk3nszxbc51J5EPHaBJKyE}gNdK^EDQL|adA?XroXd<?!{MMqWqj= zcqC@Jsh!z#@Qk61bIv;Hvc3O)iSB;hWyO5O@tnc#FPGytp0~AU`F_CG`Q#?4s%3)5 z%6{y!uFrpKyzZxPp~nCH50{@^URU>X{dG_Nuw8$`>us;?Em}Bloxx3~b+g5rR{wjF zd+}Ow`WN9%QO+K6hf;rRJNfF4*``^x4tsJKUmp9Owq&+s>;8#9%__sMIaWzOauHtq zOYg3qQQIEAvvVcbf8KJd<C5QG^KZ|Jl~-*R?mX~UwA@kpN@nTgUH)JHXLKw#%uK%& zzLbB}yvP%7XUzUK+dV9dzukDC|3>&kwc@u1cJKdh`?-_BD=#>)?Zt@&T$^t^?pe8k zE%jY!VqeOn^(!|_lQ?M}8sVO&s2&pGe<on%A+|TlvqCI*j~!fn=%vd1%EEv3|3i%4 zuP9Jknfz62j;q*4-c8@7e%9;CB(D!nR9Ms&n%I_-IY;Zvq^Gm8M6WG4Gl8o(W#ThA z(Q87xpREs#aM#O<3re)reA>5qL*tX;_p1t|K4-tXA8Ijo&6WR7t;Q$#oOf}hPm<<c zxp9-n+J|SKO<Xwf#|hnq3nX}sFh6pz*rab|WFjN(%|5NmH1uj{QnrPSiImXw_Qewm zOa$aP`@@&5-5<5a?M|24EvAn}g@=DQq#pOE_n0WU+v(!OgKHNqyt}yZ#jYC;88#AK zU80Y!3WYzu?R0TQ&y|p{@N2PYak|z*!puoFQXFl^m@dvf^5MbMx{iw%E_mq3btx65 z#JpMgW|hd^#)=FZJ+@=bN#FM*J%8}vghPiAyVJ!AhStL$6Tf^pcK71Mh=LRcIo&Wz z`$pD_FS^>lwH)zntgsQ`?l)&mvJk7fW@{wZH?_OE-JPxN=-$Q|5<ExU+Kx@Ux!-?J zkh@DB!*e4$xqHoO-&;;ye19-Q!_3CWPUYAW&DFP(YAgh%tJ{ioxx2G5EnfWFAT?R= z%B$ltZ)H3AA0J3wIAe$9mhd}La@;-jyMqc@lZ`tJMct1nUHl;TD%mwhL5i#QaYAFl zg8GyamA-3j%oh(ZxbYk|GZI)Vc+jC^;(-d+)9*4Ygq-}>XTRN{)4`{8v8UDj`-2mk zzEo(4OmTPF{=LO5kds}Gw>^K-b7P6VMT-yqC^*V=p8fFS!Vuo>#smTNzKdM^Z{#L_ zZb|H0K8Ksf<?xB_9=1mrsXAenGX3shJ7cQ9zgx?*Vx{DPGa-vouZw?t^jk^MR6g+L zsT&#W%j#qN?&i&kuM~=vwmNc-<Jj@$bDgUkcFtIJ=GCdJQVyQS9x8IHdwP4q+7>&n z^YdrVR8vmjcyDoU`vd__A;I?yj~H9nJZ89@uoGGubl5}GQ!{A#qup&G6SMZXUg`=; zeA2&YpT{+28CTt(k_*ZXr_2eNWOC|fQno2aZs^{O#kZbv<U0Ii+;X9@>hFozjBu6M zDMn4V*Q~L0DO)VhxMYp8;T5ihJ`=n;mN32FpYmA$<Mu!ev-2w*_pkc6Zuhch@tdrh zrnyMHw0L@AUSHt*e5WXhulqFQluor~d`mjP8K~p2_SClOfJNP2l`EIYbXv&f&haXZ zPd?%&Qz-D2Jwq*c67!X9F@jxB4Gta7^2t9^;l7gHan<x$(LC<|a@f|zO2=N=ZCi52 zcZ%L)!&BK#Hp|X=cSf3jRq6?`6sx`{TzMyvi#@}pIV5`B#=_9e@~i#+94d4PHDB;7 zbxz+#_pd?MG{Ya;ddxSpdS}t681#RNPQ2wdkH;bl0>h1L+wNFQm38=~@$XG=_)Q5n zSIO1!vF_C`SILB>+qk{$N-^H|{n9Fq%X@mo#V*Rk_jLuCH)qZ53Nddgm~l=?^f=cn z=}I-lS1Wl~Uz~dH-WzDO?a^(6wS5d{b3M+M&N-(bx_*IG@Xgm8OG74zMTvi^;$LaF zm+yOLUv^Z8(vA&gPv`Um)hBc3^atlRe=ZJLr0d<gN?FrbZt3rfzMp?eF8R95#l&N6 zXpP?)_RO3|uT~_!3KXcH(xbgq)a~wF6ZunBL8~nP%{;-HQFC}zT+2JJ!mHB_ciFXN zvbvqn%F&5^G51ff=j(!pt0V)i`z(F6`St!a>c2%73dZcPTl9Hf&%%D$SFhyf$CvIF zUvoc1ZC3&Rs|CMZUDnF?OId!@;{LR1XVv*N%c`GE-5jv0kmaMrS9Q1KNYCd6Er0xE z7B;WgYcX@TbnLEUrnw*1y>1s^lxS0&<SX+)efGlsF9)nHF$nEbePa5s+V;_>-9l0) zSWcNL)apLUp0H2qyC1uq^v8Ece%I|Wt<V+<)p&SlyZ2FT0e$yg^ADU~rmgJtn0jAY zF#mA*>R;a!_OjmB)!N5cSR-uzVgqOXlJnCYlx5qEH-9*$)3LeWxB7#>ENXf(dk*~h z_$TQ2<>&EM=S%9Ye7|^Eeq*S7<45HSlZ*dYzPJ3p^Tf`T#kWizw@+}a<3IE}J<RG} zw#D7g=Xv+PQ(Rt{wtTf;wZH!yzd6tRm~Vg1zV_%r`jMHdW}Y~6<jl&M#>UUnzX<Eg z)lB^PTRevEF?XN1#PN^k9&eXV|LfoQQS*3k&-cRrkIx)bKk%dFG3RyRH_7eVvhC4t z``qOtA6a}p@zZ_A<YMFF@+U=X^c~boCb0E9eD?UwoX0OqEjMs3Pd&1nIbZzV+=}*( z`{eWgJaa5$zo++NLfEESe&=7!mHg9eD_%GMmVcrYKkvt<gZi6=%jNgXuB<xmT|Hw) z`ATJ*xMvdivClT_Tx)A(etYrJ#DbDc=la5x$M36K{t9^U>uqS?+qK@ZH}it|+l8+! zSTM14LvN0{blUs$_@vTbYvXn&bKgtf^L%g56VsH6p1FN~;p){z?|MYC^j)&0m8I3q zHc8uf%jT}tmOU2czIyf7-fQ2Z?6a<Z+j?m7kMp0mJXht{uAH{ZX43Jv7bo*izuvf` zxQfN#+lRble&!h&<}V8+pZD}!ypg`=?g=SR<wP}|0|z}VEbiV74ZBtsWWIf??ZWSI z^Bby#kH&rqzO~7A;a+pcs%`Q2t$9C$-oMMvH(^=RHy7XV{6p~%vi(^EC!{1WG44ya z<ut2iW5k}GxPY*>4|z3{Hr-A2xFZ?7B4wWcsU(5Jx>{~i7x;(;6dXvOdB(YE4f~3{ z#%@pA&*%hCNqIXXt4~XtpDUvLAN%Fxo#mkUYP8vG&^$G03ftV=!Vn}4Vsn`zrn5sT z3sUvn^7BeuQj3#|G7C!bi@;pJ#N1SUCr1#__Q_02ElMoO%+Cu>Ey_&e(s#>AOfOb2 z;R364a>}oW)-^RTR?syzFjg=$GB;PSv@nd-_bf@w$xL?4OV3GFFyPX6EKW|%D*>@U zRzaE0i3J|1nduoNAT3<_!6m7=VG0%o5R=_9b5e~IKy&XwTy}PF*IOW5?*m<pU}!;L zEkf+1vw6)10xj?Bxa2Q8w<xx#2swFuRxW(e@AaD@L0>b-aGE0fy?ys$Z+Y1^*xfc> zo#<1db$;pFWiPJs?`rbgHrG_{*u!_GC)o1liWVyQE?=JNnt%7YpUc7MvyWM7GjA)N zcl{!E?%2umMWrUr%=}7KAK7Zs^NYR~t~#`9m-Tm6+Z&!*fg+b2q@USbeYf+SqSEzU zCJ%Saepb5S59hsfcB6%*X9B+@B$RAri@z=15wp_i+4XG21GDPWPbOtX{f+#s(Aylc z(nOa@{m5?JPi+>~%FFlEJKPge=dw)BZ`zY=Tlsy>eFgc7`9DtVaj#2RHd8(ARKc^K zhM!uWPyTmG>Q2At`STN||2Z<pez!vLKat{NbL<c1cUt~`=JZrYH^H}}-~Ow2?RUEn z|LMMSlW)&$z5o9pFJJ7J8s@IKb1XmskCv(|5m5k7K>ER@NhP4v6jD^03Kn%rEKUU_ zE!^oSv#7YlIU}(Mlq!4@p=={VF8%P#l#-0%XmfLO1#=@K1ych91rQrV8<`p?n3<U= zn3xzV7+Y9^X|TAtIar;su`yVWiHR{6NZi!a3@mPGWS{_&Gc_|-h=n9DP(p;Hc?D3G z2;$NY$q&uT1TADy0HrdNWM^oA@U)wu0w@Sj<qeVK^Ycm+z#4+M^aG0WlY>)BqV)q@ z-1I|ID@tOKQ!|n-aG(Vwrl;x$Bo=`(h=~Gdl}%7;aeir0a%!=HAxLqMzHe$uW+Eup zfm~#2X{u*zU~Fk@ZeU<;VQ!*eVPdFfVPR=*W^8V5X=-E<tM6WvUs_;eqaUmvQk0li zTmUjWxl-RbSl=bJEHgPZ$lXcbQ=z1&G}X>d-#I_8BsH(3SiuNnIa0O*IR;dE*x2a9 z9a_w#kM24yg!2@Lavvx%yfagZqZPou196@6OF`j>WVs>8HORI*Czd4U<frR{f~!~o z<hCF#egA^gJjY~EK@|-#OFtqqN+GW_CkH|p#B%BTB<7`Sq@?P)xN4$A18mukjg7u@ zQEFmIevyrvtDBpFfhj0pjSLLTEDa3IO$-doObraojqJejno^pa3R7p|3{hid1d@lS zGjTI8Ff)T<O9KNlV~Dtsfq?-i!i-!E42+HKxFA+$=I6O2mZWO9SQ!}@85@`x85kNG zm>L*s8yKk@7^rI^g-1nEY8sb;f}shQ0URipnVK4#Dx@hu#VifX4Hdw$3VARw0|P@# z3^5~9GjuUaBNGF3F#{uW40RTUCPwJ$EDX(zF~p2bF~!U=?Xa-4FhSRAX<&$9ucfh> zDTX=|GbFc^6eVWnq!xkJtOaLQr79Sj=m+KJmneW!QV^HEXI@&qf*~l@K^zx_XayTL zQ%hG@Lo;J1Ge=8D7efmpQzv5=OJ`#XGb3X+LsK(5F2YJc$=4-6**POMIlH(tS3%$0 z&B)l$$k4>i)WX8e$=J}s#N5Ey$<)Zr)Xl)nz`y{M2#ZS+i%P&zYH4O{&ZVmA>hHz{ E02zuBVgLXD literal 0 HcmV?d00001 diff --git a/bescheid-manager/src/main/resources/templates/bescheid.nachrichtTemplate.txt.ftlh b/bescheid-manager/src/main/resources/templates/bescheid.nachrichtTemplate.txt.ftlh new file mode 100644 index 0000000..861bcc6 --- /dev/null +++ b/bescheid-manager/src/main/resources/templates/bescheid.nachrichtTemplate.txt.ftlh @@ -0,0 +1,8 @@ +Sehr geehrte/r Antragstellende/r, + +ihr Antrag wurde <#if genehmigt>genehmigt<#else>abgelehnt</#if>. + +Sie können innerhalb von vier Wochen Einspruch einlegen. + +Mit freundlichen Grüßen, +Ihre Verwaltung \ No newline at end of file diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java new file mode 100644 index 0000000..bf35de7 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java @@ -0,0 +1,69 @@ +/* + * 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; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEventTestFactory; +import de.ozgcloud.command.CommandTestFactory; + +@ITCase +class BescheidEventListenerITCase { + + @Autowired + private ApplicationEventPublisher publisher; + + @MockBean + private BescheidService service; + + @Nested + class TestCreateBescheid { + + private Command command = CommandTestFactory.createBuilder().order(BescheidEventListener.ORDER).build(); + + @Test + void shouldCallService() { + publisher.publishEvent(CommandCreatedEventTestFactory.withCommand(command)); + + verify(service).createBescheid(any()); + } + + @Test + void shouldNotReactOnOtherOrder() { + publisher.publishEvent(CommandCreatedEventTestFactory.withCommand(CommandTestFactory.createBuilder().order("OTHER").build())); + + verifyNoInteractions(service); + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerTest.java new file mode 100644 index 0000000..5d74569 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerTest.java @@ -0,0 +1,191 @@ +/* + * 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; + +import static de.ozgcloud.bescheid.BescheidEventListener.*; +import static de.ozgcloud.bescheid.BescheidRequestTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.core.context.SecurityContext; + +import de.ozgcloud.bescheid.binaryfile.BinaryFileService; +import de.ozgcloud.bescheid.common.callcontext.CurrentUserService; +import de.ozgcloud.bescheid.common.callcontext.UserProfile; +import de.ozgcloud.bescheid.common.callcontext.UserProfileTestFactory; +import de.ozgcloud.bescheid.nachricht.NachrichtService; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEventTestFactory; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandTestFactory; + +class BescheidEventListenerTest { + + @Spy + @InjectMocks + private BescheidEventListener listener; + + @Mock + private BescheidService service; + @Mock + private BinaryFileService fileService; + @Mock + private NachrichtService nachrichtService; + + @Mock + private ApplicationEventPublisher eventPublisher; + @Mock + private CurrentUserService userService; + + @Nested + class TestOnCreateBescheidCommand { + + private Command command = CommandTestFactory.createBuilder() + .bodyObject( + Map.of(VORGANG_ID_BODYKEY, VORGANG_ID.toString(), + BESCHEID_VOM_BODYKEY, BESCHEID_VOM_STRING, + GENEHMIGT_BODYKEY, GENEHMIGT)) + .build(); + + @Mock + private SecurityContext secContext; + + @Test + void shouldCreateBescheid() { + listener.onCreateBescheidCommand(CommandCreatedEventTestFactory.withCommand(command)); + + verify(listener).doCreateBescheidBiz(command); + } + + @Test + void shouldPublishErrorEventOnException() { + doThrow(new RuntimeException("ups")).when(listener).doCreateBescheidBiz(any()); + + listener.onCreateBescheidCommand(CommandCreatedEventTestFactory.withCommand(command)); + + verify(eventPublisher).publishEvent(any(CommandFailedEvent.class)); + } + + @Nested + class HandleSecurityContext { + + @BeforeEach + void init() { + when(userService.startSecurityContext(any())).thenReturn(secContext); + } + + @Test + void shouldStartSecurityContext() { + listener.onCreateBescheidCommand(CommandCreatedEventTestFactory.withCommand(command)); + + verify(userService).startSecurityContext(command); + } + + @Test + void shouldResetSecurityContext() { + listener.onCreateBescheidCommand(CommandCreatedEventTestFactory.withCommand(command)); + + verify(userService).resetSecurityContext(secContext); + } + + @Test + void shouldResetSecurityContextAfterException() { + doThrow(new RuntimeException("ups")).when(listener).doCreateBescheidBiz(any()); + + listener.onCreateBescheidCommand(CommandCreatedEventTestFactory.withCommand(command)); + + verify(userService).resetSecurityContext(secContext); + } + } + + @Nested + class CreateBescheidRequest { + @Test + void shouldContainUserProfile() { + UserProfile user = UserProfileTestFactory.create(); + when(userService.getUserProfile()).thenReturn(user); + + var request = listener.createRequest(command); + + assertThat(request.getCreateFor()).isSameAs(user); + } + } + + @Nested + class CreateBescheid { + + @Captor + private ArgumentCaptor<BescheidRequest> requestCaptor; + + private Bescheid bescheid = BescheidTestFactory.create(); + private Bescheid bescheidWithFileId = BescheidTestFactory.create(); + + @BeforeEach + void init() { + when(service.createBescheid(any())).thenReturn(bescheid); + when(fileService.uploadBescheidFile(any())).thenReturn(bescheidWithFileId); + when(userService.getUserProfile()).thenReturn(UserProfileTestFactory.create()); + } + + @Test + void shouldCreateBescheid() { + listener.doCreateBescheidBiz(command); + + verify(service).createBescheid(requestCaptor.capture()); + assertThat(requestCaptor.getValue()).usingRecursiveComparison() + .isEqualTo(BescheidRequestTestFactory.createBuilder() + .vorgangId(VorgangId.from(CommandTestFactory.VORGANG_ID)) + .build()); + } + + @Test + void shouldSaveFile() { + listener.doCreateBescheidBiz(command); + + verify(fileService).uploadBescheidFile(bescheid); + } + + @Test + void shouldSaveNachricht() { + listener.doCreateBescheidBiz(command); + + verify(nachrichtService).createNachrichtDraft(bescheidWithFileId); + } + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java new file mode 100644 index 0000000..c4b7693 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidGrpcServiceTest.java @@ -0,0 +1,103 @@ +/* + * 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; + +import static org.mockito.ArgumentMatchers.*; +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 BescheidGrpcServiceTest { + + @Spy + @InjectMocks + private BescheidGrpcService service; + + @Mock + private GrpcBescheidMapper mapper; + + @BeforeEach + void initMapperMock() { + when(mapper.fromBescheid(any())).thenReturn(GrpcBescheidTestFactory.create()); + } + + @Nested + class TestGetBescheidDraft { + + @Mock + private GrpcGetBescheidDraftRequest request; + @Mock + private StreamObserver<GrpcGetBescheidDraftResponse> responseObserver; + + private static final GrpcGetBescheidDraftResponse response = GrpcGetBescheidDraftResponse.newBuilder().build(); + + @BeforeEach + void initMocks() { + when(service.buildResponse(any())).thenReturn(response); + } + + @Test + void shouldBuildResponse() { + service.getBescheidDraft(request, responseObserver); + + verify(service).buildResponse(any()); + } + + @Test + void shouldCallNext() { + service.getBescheidDraft(request, responseObserver); + + verify(responseObserver).onNext(response); + } + + @Test + void shouldCallCompleted() { + service.getBescheidDraft(request, responseObserver); + + verify(responseObserver).onCompleted(); + } + + } + + @Nested + class TestBuildResponse { + + @Test + void shouldCallMapper() { + Bescheid bescheid = BescheidTestFactory.create(); + + service.buildResponse(bescheid); + + verify(mapper).fromBescheid(bescheid); + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidRequestTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidRequestTestFactory.java new file mode 100644 index 0000000..02d08d4 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidRequestTestFactory.java @@ -0,0 +1,51 @@ +/* + * 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; + +import java.time.LocalDate; + +import de.ozgcloud.bescheid.common.callcontext.UserProfileTestFactory; +import de.ozgcloud.bescheid.vorgang.VorgangId; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; + +public class BescheidRequestTestFactory { + + static final VorgangId VORGANG_ID = VorgangTestFactory.ID; + static final String BESCHEID_VOM_STRING = "2023-01-04"; + static final LocalDate BESCHEID_VOM = LocalDate.parse(BESCHEID_VOM_STRING); + static final boolean GENEHMIGT = true; + + public static BescheidRequest create() { + return createBuilder().build(); + } + + public static BescheidRequest.BescheidRequestBuilder createBuilder() { + return BescheidRequest.builder() + .vorgangId(VORGANG_ID) + .bescheidVom(BESCHEID_VOM) + .genehmigt(GENEHMIGT) + .createFor(UserProfileTestFactory.create()); + + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidServiceTest.java new file mode 100644 index 0000000..6c7505f --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidServiceTest.java @@ -0,0 +1,86 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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 de.ozgcloud.bescheid.vorgang.Vorgang; +import de.ozgcloud.bescheid.vorgang.VorgangService; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; + +class BescheidServiceTest { + + @InjectMocks + private BescheidService service; + + @Mock + private VorgangService vorgangService; + @Mock + private BescheidRemoteService remoteService; + + @Nested + class TestCreateBescheid { + + private Vorgang vorgang = VorgangTestFactory.create(); + private Bescheid bescheid = BescheidTestFactory.createBuilder().vorgangId(null).build(); + + @BeforeEach + void initMocks() { + when(vorgangService.getById(any())).thenReturn(vorgang); + when(remoteService.create(any(), any())).thenReturn(bescheid); + } + + @Test + void shouldLoadVorgang() { + service.createBescheid(BescheidRequestTestFactory.create()); + + verify(vorgangService).getById(VorgangTestFactory.ID); + } + + @Test + void shouldCreateBescheid() { + BescheidRequest request = BescheidRequestTestFactory.create(); + + service.createBescheid(request); + + verify(remoteService).create(request, vorgang); + } + + @Test + void shouldReturnCreatedBescheid() { + var result = service.createBescheid(BescheidRequestTestFactory.create()); + + assertThat(result).usingRecursiveComparison().isEqualTo(BescheidTestFactory.create()); + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestApplication.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestApplication.java new file mode 100644 index 0000000..2ecd853 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestApplication.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.bescheid; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; + +@SpringBootApplication +@ComponentScan({ "de.ozgcloud.*" }) +public class BescheidTestApplication { + + @Bean + AuthenticationTrustResolver trustResolver() { + return new AuthenticationTrustResolverImpl(); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestFactory.java new file mode 100644 index 0000000..f89f4ca --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/BescheidTestFactory.java @@ -0,0 +1,65 @@ +/* + * 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; + +import java.io.File; +import java.util.Optional; + +import org.springframework.http.MediaType; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.bescheid.common.callcontext.UserProfileTestFactory; +import de.ozgcloud.bescheid.vorgang.ServiceKontoTestFactory; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; +import de.ozgcloud.common.binaryfile.TempFileUtils; + +public class BescheidTestFactory { + + public static final UserId CREATED_BY = UserProfileTestFactory.ID; + public static final String FILE_NAME = "bescheid.pdf"; + + public static final byte[] TEST_BESCHEID = "testbescheid".getBytes(); + public static final File BESCHEID_FILE = TempFileUtils.writeTmpFile(TEST_BESCHEID); + + public static final String CONTENT_TYPE = MediaType.APPLICATION_PDF_VALUE; + public static final String NACHRICHT_TEXT = LoremIpsum.getInstance().getWords(5); + + public static Bescheid create() { + return createBuilder().build(); + } + + public static Bescheid.BescheidBuilder createBuilder() { + return Bescheid.builder() + .createdBy(CREATED_BY) + .vorgangId(VorgangTestFactory.ID) + .contentType(CONTENT_TYPE) + .bescheidFileName(FILE_NAME) + .bescheidFile(BESCHEID_FILE) + .nachrichtText(Optional.of(NACHRICHT_TEXT)) + .genehmigt(true) + .size(TEST_BESCHEID.length) + .serviceKonto(ServiceKontoTestFactory.create()); + } +} diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangMapperTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidMapperTest.java similarity index 72% rename from notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangMapperTest.java rename to bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidMapperTest.java index 467519b..d167ae1 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangMapperTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.bescheid; import static org.assertj.core.api.Assertions.*; @@ -29,18 +29,18 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; -class VorgangMapperTest { +class GrpcBescheidMapperTest { - private VorgangMapper mapper = Mappers.getMapper(VorgangMapper.class); + private GrpcBescheidMapper mapper = Mappers.getMapper(GrpcBescheidMapper.class); @Nested - class TestFromGrpc { + class TestFromBescheid { @Test - void shouldMapVorgang() { - var mapped = mapper.fromGrpc(GrpcVorgangTestFactory.create()); + void shouldMapAllFields() { + var result = mapper.fromBescheid(BescheidTestFactory.create()); - assertThat(mapped).usingRecursiveComparison().isEqualTo(VorgangTestFactory.create()); + assertThat(result).usingRecursiveComparison().isEqualTo(GrpcBescheidTestFactory.create()); } } diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidTestFactory.java new file mode 100644 index 0000000..ab0aba3 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/GrpcBescheidTestFactory.java @@ -0,0 +1,37 @@ +/* + * 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; + +class GrpcBescheidTestFactory { + + public static GrpcBescheid create() { + return createBuilder().build(); + } + + public static GrpcBescheid.Builder createBuilder() { + return GrpcBescheid.newBuilder() + .setBewilligt(true) + .setNachrichtText(BescheidTestFactory.NACHRICHT_TEXT); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserServiceTest.java similarity index 59% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsTest.java rename to bescheid-manager/src/test/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserServiceTest.java index cf88c10..745f6cd 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/common/callcontext/CurrentUserServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,31 +21,36 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.bescheid.common.callcontext; 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.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Spy; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.gridfs.GridFsTemplate; +import org.springframework.security.authentication.AuthenticationTrustResolver; -class M001_MigrateMailServiceAttachmentsToGridFsTest {// NOSONAR +import de.ozgcloud.command.CommandTestFactory; + +class CurrentUserServiceTest { - @Spy @InjectMocks - private M001_MigrateMailServiceAttachmentsToGridFs migrator = new M001_MigrateMailServiceAttachmentsToGridFs(); - @Mock - private MongoTemplate template; + private CurrentUserService service; @Mock - private GridFsTemplate gridFsTemplate; + private AuthenticationTrustResolver trustResolver; + + @DisplayName("Create user") + @Nested + class TestCreateUser { - @Test - void shouldConvertBytes() { - byte[] content = migrator.convertContent(MigrationBinaryFileTestFactory.createFile()); + // FIXME read client name from command + @Test + void shouldContainsClientName() { + var user = service.createUser(CommandTestFactory.create()); - assertThat(content).isEqualTo(MigrationIncomingFileTestFactory.CONTENT); + assertThat(user.getClientName()).isEqualTo("Alfa"); + } } -} \ No newline at end of file +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/GrpcPostfachNachrichtTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/GrpcPostfachNachrichtTestFactory.java new file mode 100644 index 0000000..9807e73 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/GrpcPostfachNachrichtTestFactory.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.bescheid.nachricht; + +import de.ozgcloud.nachrichten.postfach.GrpcPostfachNachricht; + +public class GrpcPostfachNachrichtTestFactory { + + public static final GrpcPostfachNachricht create() { + return createBuilder().build(); + } + + public static final GrpcPostfachNachricht.Builder createBuilder() { + return GrpcPostfachNachricht.newBuilder() + .setCreatedAt(NachrichtTestFactory.CREATED_AT.toString()) + .setMailBody(NachrichtTestFactory.MAIL_BODY) + .setSubject(NachrichtTestFactory.SUBJECT); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtMapperTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtMapperTest.java new file mode 100644 index 0000000..01cb5f9 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtMapperTest.java @@ -0,0 +1,71 @@ +/* + * 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.nachricht; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; + +class NachrichtMapperTest { + + @InjectMocks + private NachrichtMapper mapper = Mappers.getMapper(NachrichtMapper.class);; + + @Nested + class TestMapToGrpc { + @Test + void shouldMapNachricht() { + var mapped = mapper.mapToGrpc(NachrichtTestFactory.create()); + + assertThat(mapped).usingRecursiveComparison() + .ignoringFields("replyOption_", "memoizedHashCode") + .isEqualTo(GrpcPostfachNachrichtTestFactory.create()); + } + + @Test + void shouldIgnoreMissingFileId() { + var mapped = mapper.mapToGrpc(NachrichtTestFactory.createBuilder().bescheidFileId(null).build()); + + assertThat(mapped.getAttachmentList()).isEmpty(); + } + + @Test + void shouldSetReplyOption() { + var mapped = mapper.mapToGrpc(NachrichtTestFactory.create()); + + assertThat(mapped.getReplyOption()).isEqualTo("FORBIDDEN"); + } + + @Test + void shouldNotMapId() { + var mapped = mapper.mapToGrpc(NachrichtTestFactory.create()); + + assertThat(mapped.getId()).isEmpty(); + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteServiceTest.java new file mode 100644 index 0000000..c447e1a --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtRemoteServiceTest.java @@ -0,0 +1,82 @@ +/* + * 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.nachricht; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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 de.ozgcloud.bescheid.vorgang.VorgangTestFactory; +import de.ozgcloud.nachrichten.postfach.GrpcPostfachNachricht; + +class NachrichtRemoteServiceTest { + + @InjectMocks + private NachrichtRemoteService remoteService; + + @Mock + private NachrichtMapper mapper; + + @Nested + class TestSaveDarft { + @Nested + class BuildRequest { + private Nachricht nachricht = NachrichtTestFactory.create(); + private GrpcPostfachNachricht grpcNachricht = GrpcPostfachNachrichtTestFactory.create(); + + @BeforeEach + void initMocks() { + when(mapper.mapToGrpc(any())).thenReturn(grpcNachricht); + } + + @Test + void shouldCallMapper() { + remoteService.buildRequest(nachricht); + + verify(mapper).mapToGrpc(nachricht); + } + + @Test + void shouldSetNachricht() { + var request = remoteService.buildRequest(nachricht); + + assertThat(request.getNachricht()).isSameAs(grpcNachricht); + } + + @Test + void shouldSetVorgangId() { + var request = remoteService.buildRequest(nachricht); + + assertThat(request.getVorgangId()).isEqualTo(VorgangTestFactory.ID.toString()); + } + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceITCase.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceITCase.java new file mode 100644 index 0000000..29afe88 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceITCase.java @@ -0,0 +1,65 @@ +/* + * 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.nachricht; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.bescheid.BescheidTestFactory; + +@ITCase +class NachrichtServiceITCase { + + @Autowired + private NachrichtService service; + + @Nested + class TestBuildMessage { + @Test + void shouldBuildMessage() { + var message = service.buildMessage(BescheidTestFactory.create()); + + assertThat(message).isNotBlank(); + } + + @Test + void shouldBeGenehmigt() { + var message = service.buildMessage(BescheidTestFactory.createBuilder().genehmigt(true).build()); + + assertThat(message).contains("genehmigt").doesNotContain("abgelehnt"); + } + + @Test + void shouldBeAbgelehnt() { + var message = service.buildMessage(BescheidTestFactory.createBuilder().genehmigt(false).build()); + + assertThat(message).contains("abgelehnt").doesNotContain("genehmigt"); + } + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceTest.java new file mode 100644 index 0000000..ae7a417 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtServiceTest.java @@ -0,0 +1,121 @@ +/* + * 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.nachricht; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.bescheid.BescheidTestFactory; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; + +class NachrichtServiceTest { + + @Spy + @InjectMocks + private NachrichtService service; + + @Mock + private NachrichtRemoteService remoteService; + + @Nested + class TestCreateNachrichtDraft { + + private Nachricht nachricht = NachrichtTestFactory.create(); + + @Test + void shouldCallRemoteService() { + doReturn(Optional.of(nachricht)).when(service).buildNachricht(any()); + + service.createNachrichtDraft(BescheidTestFactory.create()); + + verify(remoteService).saveDraft(nachricht); + } + + @Nested + class BuildNachricht { + + @BeforeEach + void init() { + doReturn(NachrichtTestFactory.MAIL_BODY).when(service).buildMessage(any()); + } + + @Test + void shouldFillMailBody() { + var nachricht = service.buildNachricht(BescheidTestFactory.create()).get(); + + assertThat(nachricht.getMailBody()).isEqualTo(NachrichtTestFactory.MAIL_BODY); + } + + @Test + void shouldSetSubject() { + var nachricht = service.buildNachricht(BescheidTestFactory.create()).get(); + + assertThat(nachricht.getSubject()).isEqualTo(NachrichtService.SUBJECT); + } + + @Test + void shouldSetUser() { + var nachricht = service.buildNachricht(BescheidTestFactory.create()).get(); + + assertThat(nachricht.getCreatedBy()).isEqualTo(BescheidTestFactory.CREATED_BY); + } + + @Test + void shouldSetVorgangId() { + var nachricht = service.buildNachricht(BescheidTestFactory.create()).get(); + + assertThat(nachricht.getVorgangId()).isEqualTo(VorgangTestFactory.ID); + } + } + } + + @Nested + class TestBuildMessage { + @Test + void shouldUseTextFromBescheid() { + var message = service.buildMessage(BescheidTestFactory.create()); + + assertThat(message).isEqualTo(BescheidTestFactory.NACHRICHT_TEXT); + } + + @Test + void shouldUseDefaultTemplate() { + doReturn("FROM_TEMPLATE").when(service).fillTemplate(any(), any()); + + var message = service.buildMessage(BescheidTestFactory.createBuilder().nachrichtText(Optional.empty()).build()); + + assertThat(message).isEqualTo("FROM_TEMPLATE"); + } + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtTestFactory.java new file mode 100644 index 0000000..21dd7fd --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/nachricht/NachrichtTestFactory.java @@ -0,0 +1,55 @@ +/* + * 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.nachricht; + +import java.time.ZonedDateTime; +import java.util.UUID; + +import de.ozgcloud.bescheid.UserId; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; + +public class NachrichtTestFactory { + + public static final NachrichtId ID = NachrichtId.from(UUID.randomUUID().toString()); + + public static final String SUBJECT = "subject of message"; + public static final String MAIL_BODY = "Lorem ipsum"; + + public static final UserId CREATED_BY = UserId.from(UUID.randomUUID().toString()); + public static final ZonedDateTime CREATED_AT = ZonedDateTime.now().withNano(0); + + public static Nachricht create() { + return createBuilder().build(); + } + + public static Nachricht.NachrichtBuilder createBuilder() { + return Nachricht.builder() + .id(ID) + .vorgangId(VorgangTestFactory.ID) + .subject(SUBJECT) + .mailBody(MAIL_BODY) + .createdBy(CREATED_BY) + .createdAt(CREATED_AT); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceITCase.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceITCase.java new file mode 100644 index 0000000..452dd07 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceITCase.java @@ -0,0 +1,51 @@ +/* + * 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.smartdocuments; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.bescheid.BescheidRequestTestFactory; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; + +@Disabled +@ITCase +@ActiveProfiles({ "itcase", "local" }) +class SmartDocumentsBescheidRemoteServiceITCase { + + @Autowired + private SmartDocumentsBescheidRemoteService remoteService; + + @Test + void createBescheid() { + var bescheid = remoteService.create(BescheidRequestTestFactory.create(), VorgangTestFactory.create()); + + System.out.println(bescheid.getBescheidFileName()); + System.out.println(bescheid.getBescheidFile().getAbsolutePath()); + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceTest.java new file mode 100644 index 0000000..1ec9d4b --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteServiceTest.java @@ -0,0 +1,112 @@ +/* + * 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.smartdocuments; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.File; +import java.util.Optional; + +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 de.ozgcloud.bescheid.BescheidRequestTestFactory; +import de.ozgcloud.bescheid.BescheidTestFactory; +import de.ozgcloud.bescheid.common.callcontext.UserProfileTestFactory; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsRequest.CustomerData.UserData; +import de.ozgcloud.bescheid.vorgang.VorgangTestFactory; +import de.ozgcloud.common.binaryfile.TempFileUtils; +import de.ozgcloud.common.test.TestUtils; + +class SmartDocumentsBescheidRemoteServiceTest { + + @Spy + @InjectMocks + private SmartDocumentsBescheidRemoteService service; + + @Mock + private SmartDocumentsProperties properties; + + @Nested + class TestBuildBescheid { + + @Test + void shouldFillBescheid() { + var bescheid = service.buildBescheid(BescheidRequestTestFactory.create(), SmartDocumentsResponseTestFactory.create()); + + assertThat(bescheid).usingRecursiveComparison().ignoringFields("serviceKonto") + .isEqualTo(BescheidTestFactory.createBuilder().nachrichtText(Optional.empty()).build()); + } + } + + @Nested + class TestCreateRequest { + + @Test + void shouldFillUserData() { + var request = service.createRequest(BescheidRequestTestFactory.create(), VorgangTestFactory.create()); + + assertThat(request.getCustomerData().getUserData()).isNotNull() + .extracting(UserData::getEmail).isEqualTo(UserProfileTestFactory.EMAIL); + } + } + + @Nested + class TestGetNachrichtText { + private File xmlFile = TempFileUtils.writeTmpFile(TestUtils.loadFile("SD_answer.xml")); + + @Test + void shouldCallExtractText() { + doReturn(Optional.of(xmlFile)).when(service).getXMLFile(any()); + + service.getNachrichtText(SmartDocumentsResponseTestFactory.create()); + + verify(service).extractTextFormXmlFile(notNull()); + } + + @Nested + class ExtractingText { + + @Test + void shouldReturnText() { + var text = service.extractTextFormXmlFile(xmlFile); + + assertThat(text).isPresent().get().isNotNull(); + } + + @Test + void shouldHandleError() { + var text = service.extractTextFormXmlFile(null); + + assertThat(text).isEmpty(); + } + + } + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsResponseTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsResponseTestFactory.java new file mode 100644 index 0000000..b0b9010 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsResponseTestFactory.java @@ -0,0 +1,51 @@ +/* + * 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.smartdocuments; + +import java.util.List; + +import de.ozgcloud.bescheid.BescheidTestFactory; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsBescheidRemoteService.SmartDocumentsResponse; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsBescheidRemoteService.SmartDocumentsResponse.SmartDocumentDocument; +import de.ozgcloud.bescheid.smartdocuments.SmartDocumentsBescheidRemoteService.SmartDocumentsResponse.SmartDocumentFile; + +public class SmartDocumentsResponseTestFactory { + + static final String OUTPUT_FORMAT = "PDF"; + + static SmartDocumentsResponse create() { + return createBuilder().build(); + } + + static SmartDocumentsResponse.SmartDocumentsResponseBuilder createBuilder() { + return SmartDocumentsResponse.builder() + .file(List.of(SmartDocumentFile.builder() + .filename(BescheidTestFactory.FILE_NAME) + .outputFormat(OUTPUT_FORMAT) + .document(SmartDocumentDocument.builder() + .data(BescheidTestFactory.BESCHEID_FILE) + .build()) + .build())); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapperTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapperTest.java new file mode 100644 index 0000000..15315ae --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/BescheidVorgangMapperTest.java @@ -0,0 +1,54 @@ +/* + * 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.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; + +class BescheidVorgangMapperTest { + + @InjectMocks + private BescheidVorgangMapperImpl mapper; + + @Nested + class TestMapVorgang { + + @Test + void shouldMapEingang() { + var result = mapper.mapVorgang(GrpcVorgangWithEingangTestFactory.create()); + + assertThat(result.getEingang()).isNotNull(); + } + + @Test + void shouldMapVorgangId() { + var result = mapper.mapVorgang(GrpcVorgangWithEingangTestFactory.create()); + + assertThat(result.getId()).isEqualTo(VorgangTestFactory.ID); + } + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializerTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializerTest.java new file mode 100644 index 0000000..2edf705 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/FormDataEntrySerializerTest.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.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import de.ozgcloud.bescheid.vorgang.FormDataEntry.FormField; +import de.ozgcloud.bescheid.vorgang.FormDataEntry.SubForm; +import de.ozgcloud.bescheid.vorgang.Vorgang.Eingang; +import lombok.SneakyThrows; + +class FormDataEntrySerializerTest { + + private ObjectMapper mapper = new ObjectMapper(); + + @Test + void schouldSerializeFormDataWithSingleField() throws JsonProcessingException { + var eingang = Eingang.builder() + .formData(FormField.builder().name("name").value("Thea").build()) + .build(); + + var json = mapper.writeValueAsString(eingang); + + assertThat(json).contains("\"formData\":{\"name\":\"Thea\"}"); + } + + @Test + @SneakyThrows + void sohludSerializeFormDataWithSubForm() { + var eingang = Eingang.builder() + .formData(SubForm.builder().name("address") + .entry(FormField.builder().name("name").value("Thea").build()) + .build()) + .build(); + + var json = mapper.writeValueAsString(eingang); + + assertThat(json).contains("\"formData\":{\"address\":{\"name\":\"Thea\"}}"); + } + + @Test + @SneakyThrows + void shouldSerializeFormDataWithSubSubForm() { + var eingang = Eingang.builder() + .formData(SubForm.builder().name("address") + .entry(SubForm.builder().name("person") + .entry(FormField.builder().name("name").value("Thea").build()) + .build()) + .build()) + .build(); + + var json = mapper.writeValueAsString(eingang); + + assertThat(json).contains("\"formData\":{\"address\":{\"person\":{\"name\":\"Thea\"}}}"); + } + + @Test + @SneakyThrows + void shouldSerializeFormWithTwoFields() { + var eingang = Eingang.builder() + .formData(FormField.builder().name("firstname").value("Thea").build()) + .formData(FormField.builder().name("lastname").value("Test").build()) + .build(); + + var json = mapper.writeValueAsString(eingang); + + assertThat(json).contains("\"formData\":{\"firstname\":\"Thea\",\"lastname\":\"Test\"}"); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcEingangTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcEingangTestFactory.java new file mode 100644 index 0000000..c21e9c5 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcEingangTestFactory.java @@ -0,0 +1,37 @@ +/* + * 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.vorgang; + +import de.ozgcloud.vorgang.vorgang.GrpcEingang; + +public class GrpcEingangTestFactory { + + static GrpcEingang create() { + return createBuilder().build(); + } + + static GrpcEingang.Builder createBuilder() { + return GrpcEingang.newBuilder(); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcVorgangWithEingangTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcVorgangWithEingangTestFactory.java new file mode 100644 index 0000000..a19fee5 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/GrpcVorgangWithEingangTestFactory.java @@ -0,0 +1,49 @@ +/* + * 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.vorgang; + +import static de.ozgcloud.bescheid.vorgang.VorgangTestFactory.*; + +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangResponse; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; + +class GrpcVorgangWithEingangTestFactory { + + static GrpcVorgangWithEingang create() { + return createBuilder().build(); + } + + static GrpcVorgangWithEingang.Builder createBuilder() { + return GrpcVorgangWithEingang.newBuilder() + .setId(ID.toString()) + .setEingang(GrpcEingangTestFactory.create()); + } + + static GrpcFindVorgangWithEingangResponse createResponse() { + return GrpcFindVorgangWithEingangResponse.newBuilder() + .setVorgangWithEingang(create()) + .build(); + } + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/ServiceKontoTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/ServiceKontoTestFactory.java new file mode 100644 index 0000000..ea978d8 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/ServiceKontoTestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.vorgang; + +import de.ozgcloud.bescheid.vorgang.Vorgang.PostfachAddress; +import de.ozgcloud.bescheid.vorgang.Vorgang.ServiceKonto; + +public class ServiceKontoTestFactory { + + public static ServiceKonto create() { + return createBuilder().build(); + } + + public static ServiceKonto.ServiceKontoBuilder createBuilder() { + return ServiceKonto.builder() + .postfachAddress(PostfachAddress.builder().build()); + } +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteServiceTest.java new file mode 100644 index 0000000..94a4452 --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangRemoteServiceTest.java @@ -0,0 +1,94 @@ +/* + * 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.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; + +class VorgangRemoteServiceTest { + + @Spy + @InjectMocks + private VorgangRemoteService service; + + @Mock + private VorgangServiceBlockingStub serviceStub; + @Mock + private BescheidVorgangMapper mapper; + + @Nested + class TestGetById { + @Captor + private ArgumentCaptor<GrpcFindVorgangWithEingangRequest> requestCaptor; + + @BeforeEach + void prepareGrpc() { + when(serviceStub.withInterceptors(any())).thenReturn(serviceStub); + when(serviceStub.findVorgangWithEingang(any())).thenReturn(GrpcVorgangWithEingangTestFactory.createResponse()); + + } + + @BeforeEach + void init() { + when(mapper.mapVorgang(any())).thenReturn(VorgangTestFactory.create()); + } + + @Test + void shouldCallStubWithId() { + service.getById(VorgangTestFactory.ID); + + verify(serviceStub).findVorgangWithEingang(requestCaptor.capture()); + assertThat(requestCaptor.getValue()).extracting(GrpcFindVorgangWithEingangRequest::getId).isEqualTo(VorgangTestFactory.ID.toString()); + } + + @Test + void shouldCallMapper() { + service.getById(VorgangTestFactory.ID); + + verify(mapper).mapVorgang(any()); + } + + @Test + void shouldReturnVorgang() { + var vorgang = service.getById(VorgangTestFactory.ID); + + assertThat(vorgang).usingRecursiveComparison().isEqualTo(VorgangTestFactory.create()); + } + + } + +} diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRemoteServiceTest.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangServiceTest.java similarity index 60% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRemoteServiceTest.java rename to bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangServiceTest.java index 372ad9f..2dde114 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRemoteServiceTest.java +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,39 +21,49 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.bescheid.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import de.itvsh.kop.user.grpc.recipient.RecipientServiceGrpc.RecipientServiceBlockingStub; +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; -class UserRemoteServiceTest { +class VorgangServiceTest { @InjectMocks - private UserRemoteService remoteService; + private VorgangService service; @Mock - private RecipientServiceBlockingStub recipientService; - @Mock - private UserRecipientMapper mapper; + private VorgangRemoteService remoteService; @Nested - class TestRequestRecipients { + class TestGetById { + + private Vorgang vorgang = VorgangTestFactory.create(); + + @BeforeEach + void init() { + when(remoteService.getById(any())).thenReturn(vorgang); + } @Test - void shouldConvertCorrectly() { - when(recipientService.findRecipientByOrganisationsEinheitId(any())).thenReturn(GrpcFindRecipientRequestTestFactory.create()); - when(mapper.fromGrpc(any())).thenReturn(RecipientTestFactory.create()); + void shouldCallRemoteService() { + service.getById(VorgangTestFactory.ID); - var recipients = remoteService.getRecipients("id"); + verify(remoteService).getById(VorgangTestFactory.ID); + } + + @Test + void shouldReturnResult() { + var result = service.getById(VorgangTestFactory.ID); - assertThat(recipients.get(0)).usingRecursiveComparison().isEqualTo(RecipientTestFactory.create()); + assertThat(result).isEqualTo(vorgang); } } -} \ No newline at end of file + +} diff --git a/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangTestFactory.java b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangTestFactory.java new file mode 100644 index 0000000..333576e --- /dev/null +++ b/bescheid-manager/src/test/java/de/ozgcloud/bescheid/vorgang/VorgangTestFactory.java @@ -0,0 +1,45 @@ +/* + * 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.vorgang; + +import java.util.UUID; + +public class VorgangTestFactory { + + public static final VorgangId ID = VorgangId.from(UUID.randomUUID().toString()); + + public static Vorgang create() { + return createBuilder().build(); + } + + public static Vorgang.VorgangBuilder createBuilder() { + return Vorgang.builder() + .id(ID) + .serviceKonto(ServiceKontoTestFactory.create()) + .vorgangName("KFAS_LIVE_KI_10_Haltverbot_befristet") + .vorgangNummer("ABC-123-XY") + .aktenzeichen("DE-HÖÄ-003"); + } + +} diff --git a/mail-service/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/bescheid-manager/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 100% rename from mail-service/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to bescheid-manager/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension diff --git a/bescheid-manager/src/test/resources/SD_answer.xml b/bescheid-manager/src/test/resources/SD_answer.xml new file mode 100644 index 0000000..df9d905 --- /dev/null +++ b/bescheid-manager/src/test/resources/SD_answer.xml @@ -0,0 +1,399 @@ +<?xml version="1.0" encoding="UTF-8"?> +<root> + <SmartDocument Version="2.0"> + <Selection> + <TypistID>E53F295BC2794A6697155664D0F30880</TypistID> + <UserGroupID>88FC6F29D71C4BB096B71BC9B3C860F8</UserGroupID> + <AuthorID>E53F295BC2794A6697155664D0F30880</AuthorID> + <TemplateGroupID>94A1C1208DF0479CB58E3CFB0A6057BC</TemplateGroupID> + <Template>KFAS_LIVE_KI_10_Haltverbot_befristet</Template> + <TemplateID Timestamp="1704722931920">7ACEA5AE7C3642978ACCC48182EBCD6E</TemplateID> + <Blocks> + <Block VersionID="15DCCB4DFE1A414796EBA44352C7AAFF">CC2A9C0E14164B9A967CEE8DCD41B3B5</Block> + <Placeholders> + <Placeholder ID="125E766AF0424D4992F8F04C806F75EB">CC2A9C0E14164B9A967CEE8DCD41B3B5</Placeholder> + </Placeholders> + </Blocks> + </Selection> + <Variables/> + <QuestionAnswers> + <Question ID="07BE1279C0504852AEFBB264D165E139" + Description="Tagesdatum" + OriginalValue="2024-01-08"><![CDATA[08.01.2024]]></Question> + <Question ID="23BB945F7BA44321B09A0A984D541DD1" + Description="Tage Halteverbot" + ContentId="23BB945F7BA44321B09A0A984D541DD1" + IsFormatted="true" + ContentType="XML"> + <Records> + <Record> + <Field Name="71F5F35C4FD94982A1F8321A73E9B593"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="58F6E456AE1F4E13907D78E158BF4847" Description="Freitag"> + <Answer ID="313DC774D89E45D8864FC33983C95923" + Description="Nein" + IsFormatted="true" + ContentId="313DC774D89E45D8864FC33983C95923"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="B66C9D21D31A4293852EEDCAB57C593B"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="EF33891FF01A42B0BEFB1E78E3FC023D" Description="Samstag"> + <Answer ID="24CD7BEAB973475A998C7EAB9C4D1AE3" + Description="Nein" + IsFormatted="true" + ContentId="24CD7BEAB973475A998C7EAB9C4D1AE3"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="67082AAB675E457180A7014531C46CB3"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="60C6CD1F29084A26BEC493A862583AAB" Description="Montag"> + <Answer ID="13A1D81A4DB74AAEB2A6E684C575B768" + Description="Nein" + IsFormatted="true" + ContentId="13A1D81A4DB74AAEB2A6E684C575B768"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="3FD23F8F98EF459A95B50448DEDFF20E"> + <Value><![CDATA[ja]]></Value> + <QuestionAnswers> + <Question ID="C8BC6BFFE8BE4E6BBDC4CBCD34377DB2" Description="Mittwoch"> + <Answer ID="97B676CAC9B74D00B574F319B2D20BB5" + Description="Ja" + IsFormatted="true" + ContentId="97B676CAC9B74D00B574F319B2D20BB5"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="09658B4DA4BB4295822A42C0AA8FC2EC"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="39BF39565D4043078ABEEC9601A091E7" Description="Donnerstag"> + <Answer ID="8D4A19B4D3AF448FB720E9160E7A40D2" + Description="Nein" + IsFormatted="true" + ContentId="8D4A19B4D3AF448FB720E9160E7A40D2"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="975867EBE97547ACA6B8D85F1D8D39C8"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="03906ABB93494C6EB087D87C4C70217C" Description="Dienstag"> + <Answer ID="B9ACD0E74C6B41BEA700C9EB8FCFFC25" + Description="Nein" + IsFormatted="true" + ContentId="B9ACD0E74C6B41BEA700C9EB8FCFFC25"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="AF89873144744EDC9A1B78776F3D25F5"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="06349259221C4DEFBB4FE9FD33D76403" Description="Sonntag"> + <Answer ID="853ED74B536C4BD8AF95193450F18201" + Description="Nein" + IsFormatted="true" + ContentId="853ED74B536C4BD8AF95193450F18201"/> + </Question> + </QuestionAnswers> + </Field> + </Record> + </Records> + </Question> + <Question ID="28CB094DAD1A4604B08CE7C5D2177C03" Description="Beschilderung"> + <Answer ID="D2CA0BC90987429DA8CCF855C496DBAB" + Description="Ja" + IsFormatted="true" + ContentId="D2CA0BC90987429DA8CCF855C496DBAB"/> + </Question> + <Question ID="736372FDB0A2407CBBFB15DE71FD1450" + Description="Geschlecht Antragssteller"> + <Answer ID="4E80D616EB364F2EA9C567C1D7F8AED8" + Description="männlich" + IsFormatted="true" + ContentId="4E80D616EB364F2EA9C567C1D7F8AED8"/> + </Question> + <Question ID="97E309BDBDB548F48D162D289056B313" Description="Uhrzeit Halteverbot"> + <Answer ID="E45BE1342D5F43D59E21986C377DA1B0" + Description="ganztägig" + IsFormatted="true" + ContentId="E45BE1342D5F43D59E21986C377DA1B0"/> + </Question> + <Question ID="992F241A1DF4497A8B4568E69B9C567C" + Description="Vor Ort geltende Parkregelung"> + <Answer ID="7437DBBAAA6F468DBFAC138607C123FA" + Description="Parken am Seitenstreifen" + IsFormatted="true" + ContentId="7437DBBAAA6F468DBFAC138607C123FA"/> + </Question> + <Question ID="9BD81FB0E5FF4235A094BE3D21544615" + Description="Name Ansprechperson / Firma" + AlternativeParentID="736372FDB0A2407CBBFB15DE71FD1450"> + <Answer ID="CCD833A8C8C34E5D9564676CAFCF4DD8" + Description="männlich" + IsFormatted="true" + ContentId="CCD833A8C8C34E5D9564676CAFCF4DD8"/> + </Question> + <Question ID="9CE081D9122E43B1B778863AE32AB29F" Description="Protokoll"> + <Answer ID="C2E7328389584B33A0D4DB82D8FA2671" + Description="Ja" + IsFormatted="true" + ContentId="C2E7328389584B33A0D4DB82D8FA2671"/> + </Question> + <Question ID="B651AC699A4F4B768DC34DE87BBD578C" + Description="Gründe für Halteverbot" + ContentId="B651AC699A4F4B768DC34DE87BBD578C" + IsFormatted="true" + ContentType="XML"> + <Records> + <Record> + <Field Name="DE3D244EB8754929955FF571D374C635"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="35AECC80B19C426CAB60195F0839E968" Description="Container"> + <Answer ID="9034F5BDB3CE48429C95D7E8C5144E35" + Description="Nein" + IsFormatted="true" + ContentId="9034F5BDB3CE48429C95D7E8C5144E35"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="4EE22B7DF177414796C4458EDA2BDAAD"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="A167DD3CA6B14A459F350FFD725FD121" Description="Baufahrzeug"> + <Answer ID="D4D84D211E5640F4921BB280026B786C" + Description="Nein" + IsFormatted="true" + ContentId="D4D84D211E5640F4921BB280026B786C"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="D406E7038AD64786AC0E54C8033BAAB0"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="CB595FC6EC054D408FFCA67ACA1E33D6" Description="Materiallagerung"> + <Answer ID="A74A7B407B5B4681BF254948837912AC" + Description="Nein" + IsFormatted="true" + ContentId="A74A7B407B5B4681BF254948837912AC"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="2BBBB7D558014C4297747D4E841CBB93"> + <Value><![CDATA[ja]]></Value> + <QuestionAnswers> + <Question ID="38B11C2200034615B41F7DB88136B2C6" Description="Umzug"> + <Answer ID="D7B3F786760D48DBAEE9DC3A8F555EA8" + Description="Ja" + IsFormatted="true" + ContentId="D7B3F786760D48DBAEE9DC3A8F555EA8"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="6B173C517C4F48C7A8E212E6CF2ACF23"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="C67E6013B0554AEC9EDF897DD29794C3" Description="Hubsteiger / Kran"> + <Answer ID="FF2D2B532E3343228C59C072DCE783C1" + Description="Nein" + IsFormatted="true" + ContentId="FF2D2B532E3343228C59C072DCE783C1"/> + </Question> + </QuestionAnswers> + </Field> + <Field Name="AB9698E6B2EA4DAAB0A0F51E2B127F32"> + <Value><![CDATA[nein]]></Value> + <QuestionAnswers> + <Question ID="8356F526632542AEA6D30E41B4FF4872" Description="sonstiges"> + <Answer ID="A2776865599D44C28213EACCC0861BE5" + Description="Nein" + IsFormatted="true" + ContentId="A2776865599D44C28213EACCC0861BE5"/> + </Question> + </QuestionAnswers> + </Field> + </Record> + </Records> + </Question> + <Question ID="C7C9CCBF9633499EAB08D1BBB84BFD98" Description="Richtigkeit"> + <Answer ID="386B6CDC94D2498F9576ED949322491C" + Description="Ja" + IsFormatted="true" + ContentId="386B6CDC94D2498F9576ED949322491C"/> + </Question> + <Question ID="C7D1A20B17CD4C96BF55A2738B8A4631" Description="Kenntnisnahme"> + <Answer ID="27B4C15818DD4F3087EF6D4822EE1215" + Description="Ja" + IsFormatted="true" + ContentId="27B4C15818DD4F3087EF6D4822EE1215"/> + </Question> + </QuestionAnswers> + <Fields> + <Field ID="3C5C7920FB444A9DB2F5239339599BD7"/> + <Field ID="41237CC02584421A8D65990E7F78F833"><![CDATA[24]]></Field> + <Field ID="423CB6F4AEB54A44BC67F97626ADC06C"><![CDATA[christoph.steuber@kiel.de]]></Field> + <Field ID="442D48B946C64853B78DB99D9341AAC8"/> + <Field ID="4D4178B6F808409391990233D33BF54C"><![CDATA[21727]]></Field> + <Field ID="5AE5217E97F845B48D4274894BC2F043"/> + <Field ID="635CEB0B41DE44EFB2207122CCB8EE1D"><![CDATA[0431789456]]></Field> + <Field ID="6B06CD242FC64865BFC5B770BB03EAA4"><![CDATA[ESTORF]]></Field> + <Field ID="769E3AC926154741AABE870EB802E2AD"/> + <Field ID="7AF097E4E741455685CD543ABB7CE337"><![CDATA[OSTERBERG]]></Field> + <Field ID="8CA72E11F95F4352AE6FB8001BE79508"><![CDATA[06.12.2023]]></Field> + <Field ID="8D38662ADBF2408B8C8DDB5294A5A5A9"><![CDATA[Fleet]]></Field> + <Field ID="CA36A227CFEC4B89A40CA8B0CF4460C0"><![CDATA[9]]></Field> + <Field ID="CC330D642D7D465FA611D029F6A06344"/> + <Field ID="D316B8AE41A3496495C058CCB3766F3A"><![CDATA[CHRISTOPH ALÄXANDER]]></Field> + <Field ID="DB270EC247D5476A9D8BFA008E872D7D"><![CDATA[Kiel]]></Field> + <Field ID="DE7F7E00C8C246AEA9FFDF7F89E2FB03"><![CDATA[06.12.2023]]></Field> + <Field ID="F1826BE2F3D04E508F6401E8AA1D08C1"><![CDATA[10]]></Field> + <Field ID="FEC37A441C9D46189533DBD9CFD0E0E8"><![CDATA[STEUBER]]></Field> + <Field ID="FECCC52ABB614390BAE2577AD8C44262"><![CDATA[24103]]></Field> + <Field ID="root/CustomerData/Dateiname"><![CDATA[Fleet_9-Verk-AO_01-08_06.12.2023-06.12.2023]]></Field> + <NachrichtenText>Sehr geehrte/r Antragstellende, + +anliegend erhalten Sie die verkehrsrechtliche Anordnung für die Aufstellung der von Ihnen beantragten Beschilderung. Die Prüfung der Straßenverkehrsbehörde bezieht sich nur auf die Vollständigkeit des Antrages und die Plausibilität der Angaben. Die richtige Auswahl der aufzustellenden Verkehrszeichen oder Überschneidung mit anderen Anträgen wurde dabei nicht geprüft. + +BITTE DRINGEND BEACHTEN +Der Antrag einer mobilen Haltverbotszone ist MINDESTENS 1 Woche vor Aufstellung der Beschilderung zu stellen. Des Weiteren gilt die Beschilderung erst als angeordnet, wenn die Antragstellenden das von der Straßenverkehrsbehörde unterschriebene Anmeldeformular zurückerhalten haben (Fax, E-Mail, Post). Vorab sind keine Schilder aufzustellen!!! +</NachrichtenText> + </Fields> + <DocumentProperties> + <Guid>7ACEA5AE7C3642978ACCC48182EBCD6E</Guid> + <BuiltIn> + <creator>Pascal Sauermann</creator> + </BuiltIn> + <Extended/> + <Custom> + <Author name="Author" + type="lpwstr" + property="true" + variable="false" + xml="false">psa</Author> + <Typist name="Typist" + type="lpwstr" + property="true" + variable="false" + xml="false">psa</Typist> + <TemplateId name="TemplateId" + type="lpwstr" + property="true" + variable="false" + xml="false">7ACEA5AE7C3642978ACCC48182EBCD6E</TemplateId> + <Template name="Template" + type="lpwstr" + property="true" + variable="false" + xml="false">KFAS_LIVE_KI_10_Haltverbot_befristet</Template> + </Custom> + </DocumentProperties> + </SmartDocument> + <CustomerData> + <bescheid> + <bescheidVom/> + <genehmigt>true</genehmigt> + </bescheid> + <userData> + <firstName>Tobias</firstName> + <lastName>Bruns</lastName> + <email>tobias.bruns@external.mgm-tp.com</email> + </userData> + <vorgang> + <vorgangName>KFAS_LIVE_KI_10_Haltverbot_befristet</vorgangName> + <serviceKonto> + <type>OSI</type> + <postfachAddresses> + <item> + <identifier> + <postfachId>76f1ae54-1cf1-4ae1-c0b4-08d950d6cfc0</postfachId> + </identifier> + <type>1</type> + <version>1.0</version> + </item> + </postfachAddresses> + </serviceKonto> + <eingang> + <zustaendigeStelle> + <organisationseinheitenId>268084622</organisationseinheitenId> + <email/> + </zustaendigeStelle> + <antragsteller> + <vorname>CHRISTOPH ALÄXANDER</vorname> + <nachname>STEUBER</nachname> + </antragsteller> + <formData> + <Stammdaten__Antragstellende_Person_> + <Adresse_Kiel_vorbefüllt_mit_Kontaktdaten> + <AS_E-Mail>christoph.steuber@kiel.de</AS_E-Mail> + <Postleitzahl>21727</Postleitzahl> + <AS_Telefon>0431789456</AS_Telefon> + <Wohnort>ESTORF</Wohnort> + <Straße>OSTERBERG</Straße> + <Hausnummer>24</Hausnummer> + </Adresse_Kiel_vorbefüllt_mit_Kontaktdaten> + <Angabe_zur_Person__Firma>männlich</Angabe_zur_Person__Firma> + <Verantwortliche_Person_für_die_Aufstellung_der_Beschilderung/> + <AS_Name1> + <AS_Name1> + <AS_Vorname>CHRISTOPH ALÄXANDER</AS_Vorname> + <AS_Name>STEUBER</AS_Name> + </AS_Name1> + </AS_Name1> + </Stammdaten__Antragstellende_Person_> + <Antrag_abschließen> + <Ich_bestätige__dass_die_Beschilderung_entsprechend_den_wichtigen_Hinweisen_durchgeführt_wird>ja</Ich_bestätige__dass_die_Beschilderung_entsprechend_den_wichtigen_Hinweisen_durchgeführt_wird> + <Hiermit_bestätige_ich_die_Kenntnisnahme_des_Vorgehens_bei_parkenden_KFZ>ja</Hiermit_bestätige_ich_die_Kenntnisnahme_des_Vorgehens_bei_parkenden_KFZ> + <Ich_bestätige_hiermit__dass_ein_Protokoll_entsprechend_den_wichtigen_Hinweisen_erstellt_wird>ja</Ich_bestätige_hiermit__dass_ein_Protokoll_entsprechend_den_wichtigen_Hinweisen_erstellt_wird> + <Hiermit_bestätige_ich_die_Richtigkeit_der_gemachten_Angaben>ja</Hiermit_bestätige_ich_die_Richtigkeit_der_gemachten_Angaben> + </Antrag_abschließen> + <Angaben_zur_Parkregelung_und_zur_Beschilderung> + <Länge_der_Fläche_in_Metern>10</Länge_der_Fläche_in_Metern> + <Ort_des_Haltverbotes> + <Postleitzahl>24103</Postleitzahl> + <Wohnort>Kiel</Wohnort> + <Straße>Fleet</Straße> + <Hausnummer>9</Hausnummer> + </Ort_des_Haltverbotes> + <Beginn_des_Haltverbotes>06.12.2023</Beginn_des_Haltverbotes> + <Gründe> + <Container>nein</Container> + <Baufahrzeug>nein</Baufahrzeug> + <Materiallagerung>nein</Materiallagerung> + <Umzug>ja</Umzug> + <Hubsteiger__Kran>nein</Hubsteiger__Kran> + <Sonstiges>nein</Sonstiges> + </Gründe> + <Uhrzeit> + <ganztägig>ja</ganztägig> + </Uhrzeit> + <Vor_Ort_geltende_Parkregelung>Parken am Seitenstreifen</Vor_Ort_geltende_Parkregelung> + <Objektgruppe_Hinweis_kein_Abschleppen_möglich/> + <Tage_Haltverbot> + <Freitag>nein</Freitag> + <Samstag>nein</Samstag> + <Montag>nein</Montag> + <Mittwoch>ja</Mittwoch> + <Donnerstag>nein</Donnerstag> + <Dienstag>nein</Dienstag> + <Sonntag>nein</Sonntag> + </Tage_Haltverbot> + <Ende_des_Haltverbotes>06.12.2023</Ende_des_Haltverbotes> + </Angaben_zur_Parkregelung_und_zur_Beschilderung> + <Informationen_und_Hinweise_zu_erforderlichen_Unterlagen/> + </formData> + </eingang> + <vorgangNummer>KFAS_LIVE_KI_10_Haltverbot_befristet-GZpJckhu</vorgangNummer> + <aktenzeichen/> + </vorgang> + <Dateiname>Fleet_9-Verk-AO_01-08_06.12.2023-06.12.2023</Dateiname> + <Dateiname>Fleet_9-Verk-AO_01-08_06.12.2023-06.12.2023</Dateiname> + </CustomerData> +</root> \ No newline at end of file diff --git a/bescheid-manager/src/test/resources/application-itcase.yml b/bescheid-manager/src/test/resources/application-itcase.yml new file mode 100644 index 0000000..c1a93ef --- /dev/null +++ b/bescheid-manager/src/test/resources/application-itcase.yml @@ -0,0 +1,16 @@ +logging: + level: + ROOT: WARN, + '[org.springframework]': ERROR + '[de.ozgcloud]': WARN + config: classpath:log4j2-local.xml + +ozgcloud: + bescheid: + smart-documents: + url: https://demo-de.smartdocuments.com/wsxmldeposit/deposit/unattended + basicAuth: + username: + password: + templateGroup: Kiel + template: Halteverbot diff --git a/mail-service/src/test/resources/junit-platform.properties b/bescheid-manager/src/test/resources/junit-platform.properties similarity index 100% rename from mail-service/src/test/resources/junit-platform.properties rename to bescheid-manager/src/test/resources/junit-platform.properties diff --git a/mail-service/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bescheid-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from mail-service/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to bescheid-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/dependency-check-supressions.xml b/dependency-check-supressions.xml new file mode 100644 index 0000000..db1350f --- /dev/null +++ b/dependency-check-supressions.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd"> + <suppress> + <vulnerabilityName>CVE-DUMMY</vulnerabilityName> + </suppress> +</suppressions> \ No newline at end of file diff --git a/pluto-server/lombok.config b/lombok.config similarity index 94% rename from pluto-server/lombok.config rename to lombok.config index d07dd9b..81661f0 100644 --- a/pluto-server/lombok.config +++ b/lombok.config @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# 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 diff --git a/mail-service/lombok.config b/mail-service/lombok.config deleted file mode 100644 index e2cecc9..0000000 --- a/mail-service/lombok.config +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2022 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. - -lombok.log.fieldName=LOG -lombok.log.slf4j.flagUsage = ERROR -lombok.log.log4j.flagUsage = ERROR -lombok.data.flagUsage = ERROR -lombok.nonNull.exceptionType = IllegalArgumentException -lombok.addLombokGeneratedAnnotation = true diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachEventListener.java b/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachEventListener.java deleted file mode 100644 index b0350dc..0000000 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachEventListener.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Predicate; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Component; - -import de.itvsh.ozg.mail.postfach.Message.ReplyOption; -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; -import lombok.extern.log4j.Log4j2; - -@Component -@Log4j2 -public class PostfachEventListener { - - private static final String IS_SEND_POSTFACH_NACHRICHT_COMMAND = "{T(de.itvsh.ozg.mail.postfach.PostfachEventListener).IS_SEND_POSTFACH_NACHRICHT.test(event.getSource())}"; - - public static final Predicate<Command> IS_SEND_POSTFACH_NACHRICHT = command -> command.getOrder().equals("SEND_POSTFACH_NACHRICHT"); - - @Autowired - private PostfachService service; - - @EventListener(condition = IS_SEND_POSTFACH_NACHRICHT_COMMAND) - public void sendPostfachNachricht(CommandCreatedEvent event) { - var command = event.getSource(); - try { - service.sendMail(command.getId(), command.getCreatedBy(), buildNachricht(command, command.getBodyObject())); - } catch (RuntimeException e) { - service.publishMailSentFailedEvent(command.getId(), "Error on sending Postfach Nachricht: " + e.getMessage()); - LOG.error("Error on sending Postfach Nachricht.", e); - } - - } - - private PostfachMail buildNachricht(Command command, Map<String, Object> commandBody) { - return PostfachMail.builder() - .vorgangId(command.getRelationId()) - .postfachId(getStringValue(commandBody, PostfachMail.FIELD_POSTFACH_ID)) - .replyOption(ReplyOption.valueOf(getStringValue(commandBody, PostfachMail.FIELD_REPLY_OPTION))) - .createdBy(command.getCreatedBy()) - .direction(Direction.OUT) - .subject(getStringValue(commandBody, PostfachMail.FIELD_SUBJECT)) - .mailBody(getStringValue(commandBody, PostfachMail.FIELD_MAIL_BODY)) - .attachments(getStringListValue(commandBody, PostfachMail.FIELD_ATTACHMENTS)) - .build(); - } - - private String getStringValue(Map<String, Object> commandBody, String fieldName) { - return Optional.ofNullable( - commandBody.get(fieldName)).map(Object::toString).orElse(null); - } - - List<String> getStringListValue(Map<String, Object> commandBody, String fieldName) { - return Optional.ofNullable(commandBody.get(fieldName)) - .filter(Objects::nonNull) - .map(this::mapObjectToList) - .orElse(Collections.emptyList()); - } - - private List<String> mapObjectToList(Object object) { - if (object instanceof Collection<?> objects) { - return objects.stream().map(Objects::toString).toList(); - } else { - return List.of(object.toString()); - } - } -} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailMapper.java b/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailMapper.java deleted file mode 100644 index cc8232e..0000000 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailMapper.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import java.time.ZonedDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.MappingConstants; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ValueMapping; -import org.springframework.beans.factory.annotation.Autowired; - -import de.itvsh.ozg.mail.postfach.Message.ReplyOption; -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; - -@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) -public abstract class PostfachMailMapper { - - @Autowired - private AttachmentService attachmentService; - - @Mapping(target = "attachment", ignore = true) - @Mapping(target = "messageId", ignore = true) - - @Mapping(target = "isHtml", constant = "false") - @Mapping(target = "rechtsverbindlich", constant = "false") - @Mapping(target = "eidasLevel", constant = "MEDIUM") - public abstract Message toOsiMessage(PostfachMail mail); - - List<MessageAttachment> map(List<String> attachedFileIds) { - return attachedFileIds.stream().map(FileId::from).map(fileId -> attachmentService.getMessageAttachment(fileId)).toList(); - } - - @Mapping(target = "attachments", source = "attachmentList") - @Mapping(target = "createdAt", ignore = true) - @Mapping(target = "createdBy", ignore = true) - @Mapping(target = "direction", ignore = true) - @Mapping(target = "messageId", ignore = true) - @Mapping(target = "sentAt", ignore = true) - @Mapping(target = "sentSuccessful", ignore = true) - - @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) - @ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL) - public abstract PostfachMail fromGrpcMail(GrpcPostfachMail grpcMail); - - @SuppressWarnings("unchecked") - public GrpcPostfachMail fromMap(Map<String, Object> mailMap) { - return GrpcPostfachMail.newBuilder() - .setId((String) mailMap.get(PostfachMail.FIELD_ID)) - .setVorgangId((String) mailMap.get(PostfachMail.FIELD_VORGANG_ID)) - .setPostfachId((String) mailMap.get(PostfachMail.FIELD_POSTFACH_ID)) - .setCreatedAt((String) mailMap.get(PostfachMail.FIELD_CREATED_AT)) - .setCreatedBy((String) mailMap.getOrDefault(PostfachMail.FIELD_CREATED_BY, StringUtils.EMPTY)) - .setSentAt((String) mailMap.getOrDefault(PostfachMail.FIELD_SENT_AT, StringUtils.EMPTY)) - .setSentSuccessful((Boolean) mailMap.getOrDefault(PostfachMail.FIELD_SENT_SUCCESSFUL, false)) - .setMessageCode((String) mailMap.getOrDefault(PostfachMail.FIELD_MESSAGE_CODE, StringUtils.EMPTY)) - .setDirection(GrpcDirection.valueOf(((String) mailMap.get(PostfachMail.FIELD_DIRECTION)))) - .setSubject((String) mailMap.get(PostfachMail.FIELD_SUBJECT)) - .setMailBody((String) mailMap.get(PostfachMail.FIELD_MAIL_BODY)) - .setReplyOption(((String) mailMap.get(PostfachMail.FIELD_REPLY_OPTION))) - .addAllAttachment((Iterable<String>) mailMap.getOrDefault(PostfachMail.FIELD_ATTACHMENTS, Collections.emptyList())) - .build(); - } - - @Mapping(target = "createdBy", ignore = true) - @Mapping(target = "id", ignore = true) - @Mapping(target = "messageCode", ignore = true) - @Mapping(target = "sentAt", ignore = true) - @Mapping(target = "sentSuccessful", ignore = true) - @Mapping(target = "createdAt", expression = "java(java.time.ZonedDateTime.now())") - @Mapping(target = "direction", constant = "IN") - @Mapping(target = "attachments", expression = "java(persistAttachements(message.getVorgangId() ,message.getAttachments()))") - public abstract PostfachMail toMail(Message message); - - List<String> persistAttachements(String vorgangId, List<MessageAttachment> attachments) { - return attachments.stream().map(attachment -> attachmentService.persistAttachment(vorgangId, attachment)).toList(); - } - - @SuppressWarnings("unchecked") - PostfachMail fromMapToPostfachMail(Map<String, Object> mailMap) { - return PostfachMail.builder() - .id((String) mailMap.get(PostfachMail.FIELD_ID)) - .vorgangId((String) mailMap.get(PostfachMail.FIELD_VORGANG_ID)) - .postfachId((String) mailMap.get(PostfachMail.FIELD_POSTFACH_ID)) - .messageId((String) mailMap.get(PostfachMail.FIELD_MESSAGE_ID)) - .createdAt(ZonedDateTime.parse((String) mailMap.get(PostfachMail.FIELD_CREATED_AT))) - .createdBy((String) mailMap.get(PostfachMail.FIELD_CREATED_BY)) - .sentAt(ZonedDateTime.parse((String) mailMap.get(PostfachMail.FIELD_SENT_AT))) - .sentSuccessful((Boolean) mailMap.get(PostfachMail.FIELD_SENT_SUCCESSFUL)) - .messageCode((String) mailMap.get(PostfachMail.FIELD_MESSAGE_CODE)) - .direction(Direction.valueOf((String) mailMap.get(PostfachMail.FIELD_DIRECTION))) - .subject((String) mailMap.get(PostfachMail.FIELD_SUBJECT)) - .mailBody((String) mailMap.get(PostfachMail.FIELD_MAIL_BODY)) - .replyOption(ReplyOption.valueOf((String) mailMap.get(PostfachMail.FIELD_REPLY_OPTION))) - .attachments((List<String>) mailMap.getOrDefault(PostfachMail.FIELD_ATTACHMENTS, Collections.emptyList())) - .build(); - } -} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachService.java b/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachService.java deleted file mode 100644 index 40c54dd..0000000 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachService.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import java.time.ZonedDateTime; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import de.itvsh.ozg.mail.attributes.ClientAttributeService; -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; -import lombok.NonNull; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@Service -@Validated -class PostfachService { - - @Autowired - private OsiPostfachService osiPostfachService; - @Autowired - private PostfachMailMapper mapper; - - @Autowired - private PersistPostfachMailService persistingService; - @Autowired - private ClientAttributeService clientAttributeService; - - @Autowired - private ApplicationEventPublisher publisher; - - public void sendMail(String commandId, String userId, @Valid PostfachMail mail) { - var sendResponse = handleSendMail(commandId, mail); - persistSentMail(userId, addMailSentInformation(mail, sendResponse)); - } - - PostfachMail addMailSentInformation(PostfachMail mail, SendPostfachNachrichtResponse sendResponse) { - return mail.toBuilder().sentAt(ZonedDateTime.now()).sentSuccessful(sendResponse.isSentSuccessful()) - .messageCode(sendResponse.getMessageCode().getMessageCode()) - .build(); - } - - void persistSentMail(@NonNull String userId, PostfachMail mail) { - persistingService.persistMail(Optional.of(userId), mail.toBuilder() - .direction(Direction.OUT) - .createdAt(ZonedDateTime.now().withNano(0)).createdBy(userId) - .build()); - - clientAttributeService.setHasPostfachNachricht(mail.getVorgangId()); - } - - public Optional<Map<String, Object>> findById(String nachrichtId) { - return persistingService.findById(nachrichtId); - } - - public Stream<Map<String, Object>> findByVorgang(String vorgangId) { - return persistingService.findByVorgangAsMap(vorgangId); - } - - public void fetchAndPersistReplies() { - osiPostfachService.getAllMessages().map(mapper::toMail).forEach(this::persistMail); - } - - private void persistMail(PostfachMail mail) { - persistingService.persistMail(Optional.empty(), mail); - - clientAttributeService.setHasNewPostfachNachricht(mail.getVorgangId()); - - osiPostfachService.deleteMessage(mail.getMessageId()); - } - - public void resendMail(String commandId, String postfachMailId) { - PostfachMail mail = mapper.fromMapToPostfachMail(persistingService.getById(postfachMailId)); - - var sendResponse = handleSendMail(commandId, mail); - patchMail(mail.getId(), createResendPatchMap(sendResponse)); - } - - SendPostfachNachrichtResponse handleSendMail(String commandId, PostfachMail mail) { - try { - doSendMail(mail); - - publishMailSentEvent(commandId); - return buildSendNachrichtResponse(true, OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); - } catch (OsiPostfachServerProcessException e) { - return proceedwithWarnException(commandId, e); - - } catch (OsiPostfachException e) { - return proceedWithErrorException(commandId, e); - } - } - - SendPostfachNachrichtResponse proceedwithWarnException(String commandId, OsiPostfachServerProcessException e) { - LOG.warn(e.getMessage(), e); - return proceedWithException(commandId, e); - } - - SendPostfachNachrichtResponse proceedWithErrorException(String commandId, OsiPostfachException e) { - LOG.error(e.getMessage(), e); - return proceedWithException(commandId, e); - } - - private SendPostfachNachrichtResponse proceedWithException(String commandId, OsiPostfachException e) { - publishMailSentFailedEvent(commandId, e.getMessage()); - return buildSendNachrichtResponse(false, e.getMessageCode()); - - } - - void doSendMail(PostfachMail mail) { - osiPostfachService.sendMessage(mapper.toOsiMessage(mail)); - } - - private void publishMailSentEvent(String commandId) { - publisher.publishEvent(new PostfachMailSentEvent(commandId)); - } - - public void publishMailSentFailedEvent(String commandId, String message) { - publisher.publishEvent(new PostfachMailSentFailedEvent(commandId, message)); - } - - private SendPostfachNachrichtResponse buildSendNachrichtResponse(boolean sentSuccesful, OsiPostfachMessageCode messageCode) { - return SendPostfachNachrichtResponse.builder().sentSuccessful(sentSuccesful).messageCode(messageCode).build(); - } - - Map<String, Object> createResendPatchMap(SendPostfachNachrichtResponse sendResponse) { - return Map.of(PostfachMail.FIELD_SENT_AT, ZonedDateTime.now().withNano(0).toString(), - PostfachMail.FIELD_SENT_SUCCESSFUL, sendResponse.isSentSuccessful(), - PostfachMail.FIELD_MESSAGE_CODE, sendResponse.getMessageCode().getMessageCode()); - } - - private void patchMail(String postfachMailId, Map<String, Object> propertyMap) { - persistingService.patch(postfachMailId, propertyMap); - } - - public boolean isPostfachConfigured() { - return osiPostfachService.isConfigured(); - } - -} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerTest.java b/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerTest.java deleted file mode 100644 index 126e9a5..0000000 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; - -class PostfachEventListenerTest { - - @InjectMocks - private PostfachEventListener listener; - - @Mock - private PostfachService service; - @Mock - private Command command; - - @Captor - private ArgumentCaptor<PostfachMail> nachrichtCaptor; - - @DisplayName("Send postfach nachricht") - @Nested - class TestSendPostfachNachricht { - - private static final String COMMAND_ID = UUID.randomUUID().toString(); - private static final String USER_ID = PostfachMailTestFactory.CREATED_BY; - - @BeforeEach - void mockCommand() { - when(command.getId()).thenReturn(COMMAND_ID); - when(command.getCreatedBy()).thenReturn(USER_ID); - when(command.getRelationId()).thenReturn(MessageTestFactory.VORGANG_ID); - when(command.getBodyObject()).thenReturn(buildCommandBody()); - } - - @Test - void shouldCallService() { - listener.sendPostfachNachricht(new CommandCreatedEvent(command)); - - verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); - - assertThat(nachrichtCaptor.getValue()) - .usingRecursiveComparison().ignoringFields("id", "createdAt", "messageCode", "messageId", "sentAt", "sentSuccessful") - .isEqualTo(PostfachMailTestFactory.createBuilder().direction(Direction.OUT) - .build()); - } - - private Map<String, Object> buildCommandBody() { - return Map.of( - PostfachMail.FIELD_VORGANG_ID, "fake", - PostfachMail.FIELD_POSTFACH_ID, MessageTestFactory.POSTFACH_ID, - PostfachMail.FIELD_SUBJECT, MessageTestFactory.SUBJECT, - PostfachMail.FIELD_MAIL_BODY, MessageTestFactory.MAIL_BODY, - PostfachMail.FIELD_REPLY_OPTION, MessageTestFactory.REPLY_OPTION.name(), - PostfachMail.FIELD_ATTACHMENTS, PostfachMailTestFactory.ATTACHMENTS); - } - } - - @DisplayName("Get string list value") - @Nested - class TestGetStringListValue { - - @Test - void shouldReturnMultipleValuesFieldAsStringList() { - var commandBodyMap = new HashMap<String, Object>(); - commandBodyMap.put(PostfachMail.FIELD_ATTACHMENTS, List.of("1", "2")); - - var list = listener.getStringListValue(commandBodyMap, PostfachMail.FIELD_ATTACHMENTS); - - assertThat(list).contains("1").contains("2"); - } - - @Test - void shouldReturnSingleValueFieldAsStringList() { - var commandBodyMap = new HashMap<String, Object>(); - commandBodyMap.put(PostfachMail.FIELD_ATTACHMENTS, List.of("1", "2")); - - var list = listener.getStringListValue(commandBodyMap, PostfachMail.FIELD_ATTACHMENTS); - - assertThat(list).contains("1").contains("2"); - } - - @Test - void shouldReturnEmptyFieldValueAsEmptyCollection() { - var commandBodyMap = new HashMap<String, Object>(); - commandBodyMap.put(PostfachMail.FIELD_ATTACHMENTS, Collections.emptyList()); - - var list = listener.getStringListValue(commandBodyMap, PostfachMail.FIELD_ATTACHMENTS); - - assertThat(list).isEmpty(); - } - - @Test - void shouldReturnEmptyFieldAsEmptyCollection() { - var commandBodyMap = new HashMap<String, Object>(); - - var list = listener.getStringListValue(commandBodyMap, PostfachMail.FIELD_ATTACHMENTS); - - assertThat(list).isEmpty(); - } - } -} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailMapperTest.java b/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailMapperTest.java deleted file mode 100644 index 32485d0..0000000 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailMapperTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; - -class PostfachMailMapperTest { - - @InjectMocks - private PostfachMailMapper mapper = Mappers.getMapper(PostfachMailMapper.class); - @Mock - private AttachmentService attachmentService; - - @Nested - class TestFromMap { - @Test - void shouldFillGrpcMail() { - var grpcMail = mapper.fromMap(PostfachMailTestFactory.asMap()); - - assertThat(grpcMail).usingRecursiveComparison().isEqualTo(GrpcPostfachMailTestFactory.create()); - } - - @Test - void shouldIgnoreSentSuccessful() { - var grpcMail = mapper.fromMap(getMapWithoutProperty(PostfachMail.FIELD_SENT_SUCCESSFUL)); - - assertThat(grpcMail.getSentSuccessful()).isFalse(); - } - - @Test - void shouldIgnoreSentAt() { - var grpcMail = mapper.fromMap(getMapWithoutProperty(PostfachMail.FIELD_SENT_AT)); - - assertThat(grpcMail.getSentAt()).isEmpty(); - } - - private Map<String, Object> getMapWithoutProperty(String entryKey) { - Map<String, Object> map = PostfachMailTestFactory.asMap(); - map.remove(entryKey); - return map; - } - } - - @Nested - class TestToMail { - @Test - void shouldSetDirection() { - var mail = mapper.toMail(MessageTestFactory.create()); - - assertThat(mail.getDirection()).isEqualTo(Direction.IN); - } - - @Test - void shouldSetCreatedAt() { - var mail = mapper.toMail(MessageTestFactory.create()); - - assertThat(mail.getCreatedAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); - } - - @Test - void shouldIgnoreSentInformation() { - var mail = mapper.toMail(MessageTestFactory.create()); - - assertThat(mail.getSentAt()).isNull(); - assertThat(mail.getSentSuccessful()).isNull(); - } - - @Test - void shouldPersistAttachment() { - mapper.toMail(MessageTestFactory.create()); - - verify(attachmentService).persistAttachment(MessageTestFactory.VORGANG_ID, MessageTestFactory.ATTACHMENTS.get(0)); - } - } - - @Nested - class TestFromMapToPostfachMail { - - @Test - void shouldMap() { - var mail = mapper.fromMapToPostfachMail(PostfachMailTestFactory.asMap()); - - assertThat(mail).usingRecursiveComparison().isEqualTo(PostfachMailTestFactory.create()); - } - } - - @Nested - class TestToOsiMessage { - - @Test - void shouldCallAttachmentService() { - var fileId = FileId.from("42"); - - mapper.toOsiMessage(PostfachMailTestFactory.createBuilder().attachments(List.of(fileId.toString())).build()); - - verify(attachmentService).getMessageAttachment(fileId); - } - - @Test - void shouldMap() { - var message = mapper.toOsiMessage(PostfachMailTestFactory.create()); - - assertThat(message.getSubject()).isEqualTo(MessageTestFactory.SUBJECT); - assertThat(message.getAttachments()).hasSize(1); - } - } -} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailTestFactory.java b/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailTestFactory.java deleted file mode 100644 index 4ec37e0..0000000 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailTestFactory.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import static de.itvsh.ozg.mail.postfach.MessageTestFactory.*; - -import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; - -public class PostfachMailTestFactory { - - public static final String ID = UUID.randomUUID().toString(); - public static final String CREATED_AT_STR = "2020-04-01T10:30:10Z"; - public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); - public static final String CREATED_BY = UUID.randomUUID().toString(); - - public static final String SENT_AT_STR = "2020-04-01T11:30:10Z"; - public static final ZonedDateTime SENT_AT = ZonedDateTime.parse(SENT_AT_STR); - public static final boolean SENT_SUCCESSFUL = true; - public static final String MESSAGE_CODE = OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE.getMessageCode(); - - public static PostfachMail.Direction DIRECTION = Direction.IN; - public static final List<String> ATTACHMENTS = List.of("21"); - - public static PostfachMail create() { - return createBuilder().build(); - } - - public static PostfachMail.PostfachMailBuilder createBuilder() { - return PostfachMail.builder() - .id(ID) - .postfachId(POSTFACH_ID) - .messageId(MESSAGE_ID) - .vorgangId(VORGANG_ID) - .direction(DIRECTION) - .createdAt(CREATED_AT) - .createdBy(CREATED_BY) - .sentAt(SENT_AT) - .sentSuccessful(SENT_SUCCESSFUL) - .messageCode(MESSAGE_CODE) - .replyOption(REPLY_OPTION) - .subject(SUBJECT) - .mailBody(MAIL_BODY) - .attachments(ATTACHMENTS); - } - - public static Map<String, Object> asMap() { - HashMap<String, Object> map = new HashMap<>(); - map.put(PostfachMail.FIELD_ID, ID); - map.put(PostfachMail.FIELD_POSTFACH_ID, POSTFACH_ID); - map.put(PostfachMail.FIELD_MESSAGE_ID, MESSAGE_ID); - map.put(PostfachMail.FIELD_VORGANG_ID, VORGANG_ID); - map.put(PostfachMail.FIELD_DIRECTION, DIRECTION.name()); - map.put(PostfachMail.FIELD_CREATED_AT, CREATED_AT_STR); - map.put(PostfachMail.FIELD_CREATED_BY, CREATED_BY); - map.put(PostfachMail.FIELD_SENT_AT, SENT_AT_STR); - map.put(PostfachMail.FIELD_SENT_SUCCESSFUL, SENT_SUCCESSFUL); - map.put(PostfachMail.FIELD_MESSAGE_CODE, MESSAGE_CODE); - map.put(PostfachMail.FIELD_REPLY_OPTION, REPLY_OPTION.name()); - map.put(PostfachMail.FIELD_SUBJECT, SUBJECT); - map.put(PostfachMail.FIELD_MAIL_BODY, MAIL_BODY); - map.put(PostfachMail.FIELD_ATTACHMENTS, ATTACHMENTS); - return map; - } -} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachServiceTest.java b/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachServiceTest.java deleted file mode 100644 index e9a48d5..0000000 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachServiceTest.java +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.mail.postfach; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Stream; - -import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.springframework.boot.logging.LogLevel; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.ozg.mail.attributes.ClientAttributeService; -import de.itvsh.ozg.mail.postfach.PostfachMail.Direction; -import nl.altindag.log.LogCaptor; - -class PostfachServiceTest { - - @Spy - @InjectMocks - private PostfachService service; - @Mock - private OsiPostfachService osiPostfachService; - - @Mock - private PersistPostfachMailService persistingService; - @Spy - private PostfachMailMapper mapper = Mappers.getMapper(PostfachMailMapper.class); - - @Mock - private ClientAttributeService clientAttributeService; - - @Mock - private AttachmentService attachmentService; - - @Mock - private ApplicationEventPublisher publisher; - - @Nested - class TestSendMail { - - static final String COMMAND_ID = UUID.randomUUID().toString(); - static final String USER_ID = UUID.randomUUID().toString(); - - @BeforeEach - void init() { - ReflectionTestUtils.setField(mapper, "attachmentService", attachmentService); - } - - @Test - void shouldCallDoSendMail() { - var mail = PostfachMailTestFactory.create(); - - service.sendMail(COMMAND_ID, USER_ID, mail); - - verify(service).doSendMail(mail); - } - - @Test - void shouldCallPersistSentMail() { - var mail = PostfachMailTestFactory.create(); - doReturn(mail).when(service).addMailSentInformation(any(PostfachMail.class), any(SendPostfachNachrichtResponse.class)); - - service.sendMail(COMMAND_ID, USER_ID, PostfachMailTestFactory.create()); - - verify(service).persistSentMail(USER_ID, mail); - } - - @Test - void shouldAddMailSentInformation() { - var postfachMail = service.addMailSentInformation(PostfachMailTestFactory.createBuilder().sentAt(null).sentSuccessful(null).build(), - SendPostfachNachrichtResponseTestFactory.create()); - - assertThat(postfachMail.getSentAt()).isNotNull(); - assertThat(postfachMail.getSentSuccessful()).isEqualTo(SendPostfachNachrichtResponseTestFactory.SENT_SUCCESSFUL); - assertThat(postfachMail.getMessageCode()).isEqualTo(SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); - } - - @Test - void shouldHandleSendMail() { - var mail = PostfachMailTestFactory.create(); - service.sendMail(COMMAND_ID, USER_ID, mail); - - verify(service).handleSendMail(COMMAND_ID, mail); - } - - @Nested - class TestPersistSentMail { - - @Captor - private ArgumentCaptor<PostfachMail> mailCaptor; - - @Test - void shouldCallPersistingService() { - var mail = PostfachMailTestFactory.create(); - - service.persistSentMail(USER_ID, mail); - - verify(persistingService).persistMail(any(), notNull()); - } - - @Test - void shouldSetDirectionToIN() { - service.persistSentMail(USER_ID, PostfachMailTestFactory.createBuilder().direction(null).build()); - - verify(persistingService).persistMail(any(), mailCaptor.capture()); - assertThat(mailCaptor.getValue().getDirection()).isEqualTo(Direction.OUT); - } - - @Test - void shouldSetCreatedAt() { - service.persistSentMail(USER_ID, PostfachMailTestFactory.createBuilder().createdAt(null).build()); - - verify(persistingService).persistMail(any(), mailCaptor.capture()); - assertThat(mailCaptor.getValue().getCreatedAt()).isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); - } - - @Test - void shouldSetCreatedBy() { - service.persistSentMail(USER_ID, PostfachMailTestFactory.createBuilder().createdBy(null).build()); - - verify(persistingService).persistMail(any(), mailCaptor.capture()); - assertThat(mailCaptor.getValue().getCreatedBy()).isEqualTo(USER_ID); - } - - @Test - void shouldSetUserId() { - var mail = PostfachMailTestFactory.create(); - - service.persistSentMail(USER_ID, mail); - - verify(persistingService).persistMail(eq(Optional.of(USER_ID)), any()); - } - - @Test - void shouldSetClientAttribute() { - service.persistSentMail(USER_ID, PostfachMailTestFactory.create()); - - verify(clientAttributeService).setHasPostfachNachricht(MessageTestFactory.VORGANG_ID); - } - } - } - - @Nested - class TestFindById { - @Test - void shouldCallPersistingService() { - service.findById(PostfachMailTestFactory.ID); - - verify(persistingService).findById(PostfachMailTestFactory.ID); - } - } - - @Nested - class TestFindByVorgang { - - private static final String VORGANG_ID = UUID.randomUUID().toString(); - - @Test - void shouldCallPersistingService() { - service.findByVorgang(VORGANG_ID); - - verify(persistingService).findByVorgangAsMap(VORGANG_ID); - } - } - - @Nested - class TestFetchAndPersistReplies { - - private static final Message message = MessageTestFactory.create(); - - @BeforeEach - void initTest() { - when(osiPostfachService.getAllMessages()).thenReturn(Stream.of(message)); - ReflectionTestUtils.setField(mapper, "attachmentService", attachmentService); - } - - @Test - void shouldCallGetAllMessages() { - service.fetchAndPersistReplies(); - - verify(osiPostfachService).getAllMessages(); - } - - @Test - void shouldCallMapper() { - service.fetchAndPersistReplies(); - - verify(mapper).toMail(message); - } - - @Test - void shouldCallPersistingService() { - service.fetchAndPersistReplies(); - - verify(persistingService).persistMail(eq(Optional.empty()), any()); - } - - @Test - void shouldCallDelete() { - service.fetchAndPersistReplies(); - - verify(osiPostfachService).deleteMessage(MessageTestFactory.MESSAGE_ID); - } - - @Test - void shouldCallClientAttributeService() { - service.fetchAndPersistReplies(); - - verify(clientAttributeService).setHasNewPostfachNachricht(MessageTestFactory.VORGANG_ID); - } - } - - @Nested - class TestResendPostfachMail { - - static final String COMMAND_ID = UUID.randomUUID().toString(); - static final PostfachMail mail = PostfachMailTestFactory.create(); - - @BeforeEach - void mockService() { - when(persistingService.getById(anyString())).thenReturn(PostfachMailTestFactory.asMap()); - doReturn(mail).when(mapper).fromMapToPostfachMail(anyMap()); - ReflectionTestUtils.setField(mapper, "attachmentService", attachmentService); - } - - @Test - void shouldCallPersistingServiceGetById() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(persistingService).getById(PostfachMailTestFactory.ID); - } - - @Test - void shouldMapFromMapToPostfachMail() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(mapper).fromMapToPostfachMail(PostfachMailTestFactory.asMap()); - } - - @Test - void shouldSendMail() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(osiPostfachService).sendMessage(any(Message.class)); - } - - @Test - void shouldCallMapper() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(mapper).toOsiMessage(mail); - } - - @Test - void shouldPatchMail() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(persistingService).patch(anyString(), anyMap()); - } - - @Test - void shouldHandleSentMail() { - service.resendMail(COMMAND_ID, PostfachMailTestFactory.ID); - - verify(service).handleSendMail(COMMAND_ID, mail); - } - } - - @Nested - class TestCreateResendPatchMap { - - @Test - void shouldContainsSentAt() { - var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); - - assertThat(map).containsKey(PostfachMail.FIELD_SENT_AT); - assertThat(ZonedDateTime.parse(map.get(PostfachMail.FIELD_SENT_AT).toString())).isCloseTo(ZonedDateTime.now(), - within(2, ChronoUnit.SECONDS)); - } - - @Test - void shouldContainsSentSuccessful() { - var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); - - assertThat(map).containsEntry(PostfachMail.FIELD_SENT_SUCCESSFUL, true); - } - - @Test - void shouldContainsMessageCode() { - var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); - - assertThat(map).containsEntry(PostfachMail.FIELD_MESSAGE_CODE, SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); - } - } - - @DisplayName("Handle send mail") - @Nested - class TestHandleSendMail { - - final String COMMAND_ID = UUID.randomUUID().toString(); - final PostfachMail mail = PostfachMailTestFactory.create(); - - @BeforeEach - void initTest() { - ReflectionTestUtils.setField(mapper, "attachmentService", attachmentService); - } - - @Test - void shouldDoSendMail() { - service.handleSendMail(COMMAND_ID, mail); - - verify(service).doSendMail(mail); - } - - @Nested - class TestSentSuccess { - - @Captor - private ArgumentCaptor<PostfachMailSentEvent> eventCaptor; - - @Test - void shouldDoSendMail() { - service.handleSendMail(COMMAND_ID, mail); - - verify(service).doSendMail(mail); - } - - @Test - void shouldPublishEvent() { - service.handleSendMail(COMMAND_ID, mail); - - verify(publisher).publishEvent(eventCaptor.capture()); - assertThat(eventCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); - } - - @Test - void shouldReturnResponse() { - var response = service.handleSendMail(COMMAND_ID, mail); - - assertThat(response.isSentSuccessful()).isTrue(); - assertThat(response.getMessageCode()).isEqualTo(OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); - } - } - - @DisplayName("receive") - @Nested - class TestSentFailed { - - @Captor - private ArgumentCaptor<PostfachMailSentFailedEvent> eventFailedCaptor; - - @DisplayName("OsiPostfachException") - @Nested - class TestOnOsiPostfachException { - - private final static String MESSAGE = "Osi Postfach throws an exception."; - - @BeforeEach - void mockService() { - doThrow(new OsiPostfachException(MESSAGE, OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE)).when(osiPostfachService) - .sendMessage(any()); - } - - @Test - void shouldPublishEvent() { - service.handleSendMail(COMMAND_ID, mail); - - verify(publisher).publishEvent(eventFailedCaptor.capture()); - assertThat(eventFailedCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); - assertThat(eventFailedCaptor.getValue().getErrorMessage()).isEqualTo(MESSAGE); - } - - @Test - void shouldLogError() { - var logCaptor = LogCaptor.forClass(PostfachService.class); - - service.handleSendMail(COMMAND_ID, mail); - - verify(service).proceedWithErrorException(eq(COMMAND_ID), any(OsiPostfachException.class)); - assertThat(logCaptor.getLogEvents().get(0).getLevel()).isEqualTo(LogLevel.ERROR.name()); - assertThat(logCaptor.getLogEvents().get(0).getMessage()).isEqualTo(MESSAGE); - } - - @Test - void shouldReturnResponse() { - var response = service.handleSendMail(COMMAND_ID, mail); - - assertThat(response.isSentSuccessful()).isFalse(); - assertThat(response.getMessageCode()).isEqualTo(OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); - } - } - - @DisplayName("OsiPostfachServerProcessException") - @Nested - class TestOsiPostfachServerProcessException { - - private final static String MESSAGE = "Osi-Postfach server returned false"; - - @Mock - private Logger logger; - - @BeforeEach - void mockService() { - doThrow(new OsiPostfachServerProcessException()).when(osiPostfachService).sendMessage(any()); - } - - @Test - void shouldPublishEvent() { - service.handleSendMail(COMMAND_ID, mail); - - verify(publisher).publishEvent(eventFailedCaptor.capture()); - assertThat(eventFailedCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); - assertThat(eventFailedCaptor.getValue().getErrorMessage()).isEqualTo(MESSAGE); - } - - @Test - void shouldLogWarning() { - var logCaptor = LogCaptor.forClass(PostfachService.class); - - service.handleSendMail(COMMAND_ID, mail); - - verify(service).proceedwithWarnException(eq(COMMAND_ID), any(OsiPostfachServerProcessException.class)); - assertThat(logCaptor.getLogEvents().get(0).getLevel()).isEqualTo(LogLevel.WARN.name()); - assertThat(logCaptor.getLogEvents().get(0).getMessage()).isEqualTo(MESSAGE); - } - - @Test - void shouldReturnResponse() { - var response = service.handleSendMail(COMMAND_ID, mail); - - assertThat(response.isSentSuccessful()).isFalse(); - assertThat(response.getMessageCode()).isEqualTo(OsiPostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); - } - } - } - - } - - @Nested - class TestDoSendMail { - @Captor - private ArgumentCaptor<Message> messageCaptor; - - @BeforeEach - void initTest() { - ReflectionTestUtils.setField(mapper, "attachmentService", attachmentService); - when(attachmentService.getMessageAttachment(any())).thenReturn(MessageAttachmentTestFactory.create()); - } - - @Test - void shouldCallOsiPostfachService() { - service.doSendMail(PostfachMailTestFactory.create()); - - verify(osiPostfachService).sendMessage(any()); - } - - @Test - void shouldSendFilledMessage() { - var expected = MessageTestFactory.createBuilder() - .messageId(null) - .vorgangId(MessageTestFactory.VORGANG_ID) - .rechtsverbindlich(false) - .build(); - - service.doSendMail(PostfachMailTestFactory.create()); - - verify(osiPostfachService).sendMessage(messageCaptor.capture()); - assertThat(messageCaptor.getValue()).usingRecursiveComparison().isEqualTo(expected); - - } - } - - @Nested - class TestIsPostfachConfigured { - - @Test - void shouldCallOsiPostfachService() { - service.isPostfachConfigured(); - - verify(osiPostfachService).isConfigured(); - } - } -} \ No newline at end of file diff --git a/mongodb/docker-compose.yml b/mongodb/docker-compose.yml new file mode 100644 index 0000000..1c8da77 --- /dev/null +++ b/mongodb/docker-compose.yml @@ -0,0 +1,30 @@ +# +# 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. +# + +version: "2.1" +services: + mongo: + image: mongo:4 + ports: + - 27017:27017 diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/pom.xml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/pom.xml new file mode 100644 index 0000000..3ca593d --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/pom.xml @@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>nachrichten-bayernid-proxy</artifactId> + <version>0.1.0</version> + <relativePath>../</relativePath> + </parent> + + <artifactId>bayernid-proxy-impl</artifactId> + <name>OZG Cloud BayernID Proxy Implementation</name> + + <properties> + <jaxb-maven-plugin.version>4.0.0</jaxb-maven-plugin.version> + + <spring-boot.build-image.imageName>docker.ozg-sh.de/bayernid-proxy:build-latest</spring-boot.build-image.imageName> + </properties> + + <dependencies> + <dependency> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>bayernid-proxy-interface</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Spring --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.ws</groupId> + <artifactId>spring-ws-core</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-oxm</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.ws</groupId> + <artifactId>spring-xml</artifactId> + </dependency> + + <!-- commons --> + <dependency> + <groupId>org.apache.httpcomponents.client5</groupId> + <artifactId>httpclient5</artifactId> + </dependency> + + <!-- grpc --> + <dependency> + <groupId>net.devh</groupId> + <artifactId>grpc-server-spring-boot-starter</artifactId> + </dependency> + + <!-- aspectJ --> + <dependency> + <groupId>org.aspectj</groupId> + <artifactId>aspectjweaver</artifactId> + </dependency> + <dependency> + <groupId>org.aspectj</groupId> + <artifactId>aspectjrt</artifactId> + </dependency> + + <!-- Tools --> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-runtime</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-xml</artifactId> + </dependency> + + <!-- Dev --> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + <scope>provided</scope> + </dependency> + + <!-- Test --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.wiremock</groupId> + <artifactId>wiremock</artifactId> + <version>${wiremock.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>net.devh</groupId> + <artifactId>grpc-client-spring-boot-starter</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <finalName>${project.artifactId}</finalName> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.jvnet.jaxb</groupId> + <artifactId>jaxb-maven-plugin</artifactId> + <version>${jaxb-maven-plugin.version}</version> + <configuration> + <schemas> + <schema> + <fileset> + <directory>${basedir}/src/main/resources/bayernid</directory> + <includes> + <include>*.wsdl</include> + </includes> + </fileset> + </schema> + <schema> + <fileset> + <directory>${basedir}/src/main/resources/bayernid</directory> + <includes> + <include>*.xsd</include> + </includes> + </fileset> + </schema> + </schemas> + <episode>false</episode> + </configuration> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProperties.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProperties.java new file mode 100644 index 0000000..4fe6e1a --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProperties.java @@ -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. + */ +package de.ozgcloud.nachrichten.postfach.bayernid.proxy; + +import jakarta.validation.constraints.NotBlank; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Validated +@Configuration +@ConfigurationProperties(prefix = "ozgcloud.bayernid") +public class BayernIdProperties { + + @NotBlank + private String server; + + private boolean useSsl = true; +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyApplication.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyApplication.java new file mode 100644 index 0000000..6b47fed --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyApplication.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import java.util.TimeZone; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableAsync; + +@SpringBootApplication +@EnableAsync(proxyTargetClass = true) +@EnableAspectJAutoProxy(proxyTargetClass = true) +public class BayernIdProxyApplication { + + public static void main(String[] args) { + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + SpringApplication.run(BayernIdProxyApplication.class, args); + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyConfiguration.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyConfiguration.java new file mode 100644 index 0000000..1705b37 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyConfiguration.java @@ -0,0 +1,88 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.socket.ConnectionSocketFactory; +import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.core5.http.config.RegistryBuilder; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; +import org.springframework.ws.transport.http.HttpComponents5MessageSender; + +import akdb.bsp.postkorb.komm.webservice.ObjectFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.akdb.BayernIdRemoteService; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +class BayernIdProxyConfiguration { + + private final SslBundles sslBundles; + private final BayernIdProperties properties; + + @Bean + Jaxb2Marshaller createJaxb2Marshaller() { + var marshaller = new Jaxb2Marshaller(); + marshaller.setContextPaths("akdb.bsp.postkorb.komm.webservice", "de.akdb.egov.bsp.nachrichten"); + return marshaller; + } + + @Bean + BayernIdRemoteService soapHttpClient(BayernIdMessageMapper messageMapper, Jaxb2Marshaller marshaller) { + var bayernIdRemoteService = new BayernIdRemoteService(messageMapper, new ObjectFactory()); + bayernIdRemoteService.setMarshaller(marshaller); + bayernIdRemoteService.setUnmarshaller(marshaller); + bayernIdRemoteService.setDefaultUri(properties.getServer()); + bayernIdRemoteService.setMessageSender(createMessageSender()); + return bayernIdRemoteService; + } + + HttpComponents5MessageSender createMessageSender() { + var httpClient = HttpClientBuilder.create() + .setConnectionManager(createConnectionManager()) + .addRequestInterceptorFirst(new HttpComponents5MessageSender.RemoveSoapHeadersInterceptor()) + .build(); + return new HttpComponents5MessageSender(httpClient); + } + + private HttpClientConnectionManager createConnectionManager() { + var socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()); + if (properties.isUseSsl()) { + socketFactoryRegistry.register("https", createSslConnectionSocketFactory()); + } + return new BasicHttpClientConnectionManager(socketFactoryRegistry.build()); + } + + private SSLConnectionSocketFactory createSslConnectionSocketFactory() { + return new SSLConnectionSocketFactory(sslBundles.getBundle("bayern-id-ca").createSslContext()); + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcService.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcService.java new file mode 100644 index 0000000..b925280 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcService.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.BayernIdProxyServiceGrpc.BayernIdProxyServiceImplBase; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import io.grpc.stub.StreamObserver; +import lombok.RequiredArgsConstructor; +import net.devh.boot.grpc.server.service.GrpcService; + +@GrpcService +@RequiredArgsConstructor +public class BayernIdProxyGrpcService extends BayernIdProxyServiceImplBase { + + private final BayernIdProxyService proxyService; + private final BayernIdMessageMapper messageMapper; + + @Override + public StreamObserver<GrpcSendBayernIdMessageRequest> sendMessageAsStream(StreamObserver<GrpcSendBayernIdMessageResponse> responseObserver) { + return new UploadStreamObserver(responseObserver, proxyService, messageMapper); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyService.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyService.java new file mode 100644 index 0000000..1a760fd --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyService.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.akdb.BayernIdRemoteService; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class BayernIdProxyService { + + private final BayernIdRemoteService bayernIdRemoteService; + + public BayernIdResponse sendPostfachNachricht(BayernIdMessage message) { + return bayernIdRemoteService.sendPostfachNachricht(message); + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/DeleteOnCloseInputStream.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/DeleteOnCloseInputStream.java new file mode 100644 index 0000000..fa543be --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/DeleteOnCloseInputStream.java @@ -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. + */ +package de.ozgcloud.nachrichten.postfach.bayernid.proxy; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; + +public class DeleteOnCloseInputStream extends FileInputStream { + + private final File file; + + public DeleteOnCloseInputStream(File file) throws FileNotFoundException { + super(file); + this.file = file; + } + + @Override + public void close() throws IOException { + super.close(); + Files.deleteIfExists(file.toPath()); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserver.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserver.java new file mode 100644 index 0000000..e223ae4 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserver.java @@ -0,0 +1,153 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import static java.util.Objects.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.atomic.AtomicReference; + +import com.google.protobuf.ByteString; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.Attachment; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage.BayernIdMessageBuilder; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import io.grpc.stub.StreamObserver; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@RequiredArgsConstructor +public class UploadStreamObserver implements StreamObserver<GrpcSendBayernIdMessageRequest> { + + static final String ATTACHMENT_FILE_SUFFIX = ".ozg-cloud.tmp"; + + private final StreamObserver<GrpcSendBayernIdMessageResponse> responseObserver; + private final BayernIdProxyService proxyService; + private final BayernIdMessageMapper messageMapper; + + private final AtomicReference<BayernIdMessageBuilder> messageBuilder = new AtomicReference<>(); + private OutputStream attachmentWriter; + + @Override + public synchronized void onNext(GrpcSendBayernIdMessageRequest sendRequest) { + if (sendRequest.hasMessageMetadata()) { + readMessageMetadata(sendRequest.getMessageMetadata()); + return; + } + readAttachments(sendRequest.getAttachments()); + } + + void readMessageMetadata(GrpcBayernIdMessageMetadata sendRequest) { + messageBuilder.set(messageMapper.toBayernIdMessage(sendRequest)); + } + + void readAttachments(GrpcAttachments attachments) { + if (attachments.hasAttachmentMetadata()) { + addDataContainer(attachments.getAttachmentMetadata()); + return; + } + writeAttachment(attachments.getContent()); + } + + void addDataContainer(GrpcAttachmentMetadata attachmentMetadata) { + messageBuilder.get().attachment(buildAttachment(attachmentMetadata)); + } + + Attachment buildAttachment(GrpcAttachmentMetadata attachmentMetadata) { + var attachmentFile = createTemporallyFile(attachmentMetadata.getFileName()); + return Attachment.builder() + .name(attachmentMetadata.getFileName()) + .type(attachmentMetadata.getFileType()) + .content(attachmentFile) + .build(); + } + + InputStream createTemporallyFile(String fileName) { + try { + closeTemporallyWriter(); + var tempFilePath = createFile(fileName); + attachmentWriter = newOutputStream(tempFilePath); + return newInputStream(tempFilePath); + } catch (IOException e) { + throw new TechnicalException("Can not create temporary file for attachment " + fileName, e); + } + } + + Path createFile(String fileName) throws IOException { + var tmpFile = Files.createTempFile(fileName, ATTACHMENT_FILE_SUFFIX); + tmpFile.toFile().deleteOnExit(); + return tmpFile; + } + + OutputStream newOutputStream(Path filePath) throws IOException { + return Files.newOutputStream(filePath); + } + + InputStream newInputStream(Path filePath) throws IOException { + return new DeleteOnCloseInputStream(filePath.toFile()); + } + + void closeTemporallyWriter() { + try { + if (nonNull(attachmentWriter)) { + attachmentWriter.close(); + } + } catch (IOException e) { + throw new TechnicalException("Can not close attachment file", e); + } + } + + void writeAttachment(ByteString content) { + try { + attachmentWriter.write(content.toByteArray()); + attachmentWriter.flush(); + } catch (IOException e) { + throw new TechnicalException("Can not save attachment content", e); + } + } + + @Override + public void onError(Throwable t) { + closeTemporallyWriter(); + throw new TechnicalException("Error while sending postfach message", t); + } + + @Override + public void onCompleted() { + closeTemporallyWriter(); + try { + var bayernIdResponse = proxyService.sendPostfachNachricht(messageBuilder.get().build()); + responseObserver.onNext(messageMapper.fromBayernIdResponse(bayernIdResponse)); + responseObserver.onCompleted(); + } catch (Exception e) { + throw new TechnicalException("Error while sending postfach message", e); + } + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteService.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteService.java new file mode 100644 index 0000000..9446a6a --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteService.java @@ -0,0 +1,91 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.akdb; + +import java.io.IOException; + +import jakarta.xml.bind.JAXBElement; + +import org.springframework.ws.client.core.support.WebServiceGatewaySupport; +import org.springframework.xml.transform.StringResult; +import org.springframework.xml.transform.StringSource; + +import akdb.bsp.postkorb.komm.webservice.ObjectFactory; +import akdb.bsp.postkorb.komm.webservice.SendBspNachrichtNative; +import akdb.bsp.postkorb.komm.webservice.SendBspNachrichtNativeOutput; +import de.akdb.egov.bsp.nachrichten.BspNachricht; +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class BayernIdRemoteService extends WebServiceGatewaySupport { + + private final BayernIdMessageMapper messageMapper; + private final ObjectFactory objectFactory; + + public BayernIdResponse sendPostfachNachricht(BayernIdMessage message) { + var sendNachricht = createSendNachricht(message); + var sendBspNachrichtResponse = sendBspNachricht(sendNachricht); + var bspQuittung = createBspQuitung(sendBspNachrichtResponse); + return messageMapper.toBayernIdResponse(bspQuittung); + } + + SendBspNachrichtNative createSendNachricht(BayernIdMessage message) { + var bspNachricht = messageMapper.toBspNachricht(message); + var sendBspNachricht = new SendBspNachrichtNative(); + sendBspNachricht.setBspNachricht(buildBspNachrichtXml(bspNachricht)); + return sendBspNachricht; + } + + String buildBspNachrichtXml(BspNachricht message) { + try { + var result = new StringResult(); + getMarshaller().marshal(message, result); + return result.toString(); + } catch (IOException e) { + throw new TechnicalException("Error while marshalling BspNachricht", e); + } + } + + SendBspNachrichtNativeOutput sendBspNachricht(SendBspNachrichtNative request) { + return send(objectFactory.createSendBspNachrichtNative(request)).getValue(); + } + + @SuppressWarnings("unchecked") + JAXBElement<SendBspNachrichtNativeOutput> send(JAXBElement<SendBspNachrichtNative> jaxbSendBspNachrichtNative) { + return (JAXBElement<SendBspNachrichtNativeOutput>) getWebServiceTemplate().marshalSendAndReceive(jaxbSendBspNachrichtNative); + } + BspQuittung createBspQuitung(SendBspNachrichtNativeOutput bspNachrichtResponse) { + try { + return (BspQuittung) getUnmarshaller().unmarshal(new StringSource(bspNachrichtResponse.getBspQuittung())); + } catch (IOException e) { + throw new TechnicalException("Error while unmarshalling BspQuittung", e); + } + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandler.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandler.java new file mode 100644 index 0000000..fba0b8d --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandler.java @@ -0,0 +1,74 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.errorhandling; + +import java.util.UUID; + +import de.ozgcloud.common.errorhandling.ExceptionUtil; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.common.grpc.GrpcUtil; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.StatusException; +import lombok.extern.log4j.Log4j2; +import net.devh.boot.grpc.server.advice.GrpcAdvice; +import net.devh.boot.grpc.server.advice.GrpcExceptionHandler; + +@GrpcAdvice +@Log4j2 +public class ExceptionHandler { + + static final String KEY_EXCEPTION_ID = "EXCEPTION_ID"; + + @GrpcExceptionHandler + public StatusException handleTechnicalException(TechnicalException e) { + LOG.error("Technical exception occurred", e); + return createStatusException(buildInternalStatus(e), buildMetadata(e.getExceptionId())); + } + + @GrpcExceptionHandler + public StatusException handleRuntimeException(RuntimeException e) { + var exceptionId = createExceptionId(); + LOG.error(ExceptionUtil.formatMessageWithExceptionId("gRPC internal exception.",exceptionId), e); + return createStatusException(buildInternalStatus(e), buildMetadata(exceptionId)); + } + + Status buildInternalStatus(RuntimeException e) { + return Status.INTERNAL.withDescription(e.getMessage()).withCause(e.getCause()); + } + + String createExceptionId() { + return UUID.randomUUID().toString(); + } + + Metadata buildMetadata(String exceptionId) { + var metadata = new Metadata(); + metadata.put(GrpcUtil.keyOfString(KEY_EXCEPTION_ID), exceptionId); + return metadata; + } + + StatusException createStatusException(Status status, Metadata metadata) { + return new StatusException(status, metadata); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Absender.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Absender.java new file mode 100644 index 0000000..e5cbd91 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Absender.java @@ -0,0 +1,42 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class Absender { + + private String postkorbId; + private String name; + private String anschrift; + private String email; + private String telefon; + private String hyperlink; + private String dienst; + private String mandant; + private String gemeindeschluessel; +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Attachment.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Attachment.java new file mode 100644 index 0000000..4c144a4 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Attachment.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import java.io.InputStream; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class Attachment { + + private String name; + private String type; + private InputStream content; + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessage.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessage.java new file mode 100644 index 0000000..71328dd --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessage.java @@ -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. + */ +package de.ozgcloud.nachrichten.postfach.bayernid.proxy.message; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class BayernIdMessage { + + private String messageId; + private String createdAt; + private String vorgangId; + private Absender absender; + private Empfaenger empfaenger; + private String subject; + private String storkQaaLevel; + private String text; + @Singular + private List<Attachment> attachments; +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapper.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapper.java new file mode 100644 index 0000000..0e7a748 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapper.java @@ -0,0 +1,115 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import java.io.IOException; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; + +import de.akdb.egov.bsp.nachrichten.AbsenderType; +import de.akdb.egov.bsp.nachrichten.BspNachricht; +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.akdb.egov.bsp.nachrichten.DataContainerType; +import de.akdb.egov.bsp.nachrichten.SchluesseltabelleType; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAbsender; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage.BayernIdMessageBuilder; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface BayernIdMessageMapper { + + String TABELLE_NUMMER_TEXT_ENCODING = "9004"; + String TABELLE_NUMMER_MIME_TYPE = "9005"; + String TABELLE_NUMMER_GEMEINDE_SCHLUESSEL = "36"; + String TEXT_ENCODING_PLAIN_TEXT = "text/plain"; + + @Mapping(target = "attachments", ignore = true) + BayernIdMessageBuilder toBayernIdMessage(GrpcBayernIdMessageMetadata grpcMessage); + + @Mapping(target = "gemeindeschluessel.tabelle", constant = TABELLE_NUMMER_GEMEINDE_SCHLUESSEL) + @Mapping(target = "gemeindeschluessel.schluessel", source = "gemeindeschluessel") + AbsenderType toAbsenderType(GrpcAbsender absender); + + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "statusBytes", ignore = true) + @Mapping(target = "messageBytes", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "clearField", ignore = true) + GrpcSendBayernIdMessageResponse fromBayernIdResponse(BayernIdResponse message); + + @Mapping(target = "nachrichtenKopf.identifikationNachricht.nachrichtenId", source = "messageId") + @Mapping(target = "nachrichtenKopf.identifikationNachricht.erstellungszeitpunkt", source = "createdAt") + @Mapping(target = "nachrichtenKopf.empfaenger.postkorbId", source = "empfaenger.postkorbId") + @Mapping(target = "nachrichtenKopf.empfaenger.name", source = "empfaenger.name") + @Mapping(target = "nachrichtenKopf.empfaenger.anschrift", source = "empfaenger.anschrift") + @Mapping(target = "nachrichtenKopf.absender", source = "absender") + @Mapping(target = "nachrichtenInhalt.betreff", source = "subject") + @Mapping(target = "nachrichtenInhalt.storkQaaLevel", source = "storkQaaLevel") + @Mapping(target = "nachrichtenInhalt.zuVorgang.vorgangsId", source = "vorgangId") + @Mapping(target = "nachrichtenInhalt.freiText.encoding.schluessel", constant = TEXT_ENCODING_PLAIN_TEXT) + @Mapping(target = "nachrichtenInhalt.freiText.encoding.tabelle", constant = TABELLE_NUMMER_TEXT_ENCODING) + @Mapping(target = "nachrichtenInhalt.freiText.text", source = "text") + @Mapping(target = "nachrichtenInhalt.dataContainer", source = "attachments") + BspNachricht toBspNachricht(BayernIdMessage message); + + @Mapping(target = "gemeindeschluessel.tabelle", constant = TABELLE_NUMMER_GEMEINDE_SCHLUESSEL) + @Mapping(target = "gemeindeschluessel.schluessel", source = "gemeindeschluessel") + AbsenderType toAbsenderType(Absender absender); + + default DataContainerType toDataContainerType(Attachment attachment) { + var dataContainer = new DataContainerType(); + dataContainer.setFileType(toSchluesseltabelleType(attachment)); + dataContainer.setFileName(attachment.getName()); + try { + var content = attachment.getContent(); + try { + dataContainer.setInhalt(content.readAllBytes()); + } finally { + content.close(); + } + } catch (IOException e) { + throw new TechnicalException("Error reading attachment content", e); + } + return dataContainer; + } + + default SchluesseltabelleType toSchluesseltabelleType(Attachment attachment) { + var schluesseltabelle = new SchluesseltabelleType(); + schluesseltabelle.setSchluessel(attachment.getType()); + schluesseltabelle.setTabelle(TABELLE_NUMMER_MIME_TYPE); + return schluesseltabelle; + } + + @Mapping(target = "status", source = "ergebnisStatus.schluessel") + @Mapping(target = "message", source = "ergaenzendeHinweise") + @Mapping(target = "success", source = "annahmeErfolgreich") + BayernIdResponse toBayernIdResponse(BspQuittung quittung); +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdResponse.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdResponse.java new file mode 100644 index 0000000..f7b17f2 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdResponse.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class BayernIdResponse { + + private boolean success; + private String status; + private String message; + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Empfaenger.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Empfaenger.java new file mode 100644 index 0000000..6cfd6fb --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/Empfaenger.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.nachrichten.postfach.bayernid.proxy.message; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class Empfaenger { + + private String postkorbId; + private String name; + private String anschrift; +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..31f436d --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,14 @@ +net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcHealthServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-dev.yml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-dev.yml new file mode 100644 index 0000000..df2f1cc --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-dev.yml @@ -0,0 +1,5 @@ +ozgcloud: + bayernid: + proxy: + server: "https://infra-pre-id.bayernportal.de/bspx-postkorb-okkomm-ws/bspservices/postkorbkomm" + postkorbId: "28721c6f-b78f-4d5c-a048-19fd2fc429d2" diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-local.yml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-local.yml new file mode 100644 index 0000000..f048bc1 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application-local.yml @@ -0,0 +1,11 @@ +logging: + config: classpath:log4j2-local.xml + +server: + port: 9097 +management: + server.port: 9098 + +grpc: + server: + port: 9099 diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application.yml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application.yml new file mode 100644 index 0000000..69790c2 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/application.yml @@ -0,0 +1,29 @@ +logging: + level: + ROOT: WARN + '[de.ozgcloud]': INFO + config: classpath:log4j2-local.xml + + +management: + server: + port: 8081 + health: + livenessState: + enabled: true + readinessState: + enabled: true + endpoint: + health: + group: + exploratory: + include: livenessState,readinessState,ping + show-details: always + probes: + enabled: true + prometheus: + enabled: true + endpoints: + web: + exposure: + include: "*" diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl new file mode 100644 index 0000000..a2df760 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<definitions name="PostkorbKommService" + xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:bsp="http://akdb.de/portal/gehaltsabrechnungen-bspnachricht" + xmlns:tns="urn:akdb:bsp:postkorb:komm:webservice" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="urn:akdb:bsp:postkorb:komm:webservice"> + <types> + <xs:schema + targetNamespace='urn:akdb:bsp:postkorb:komm:webservice' version='1.1' + xmlns:tns='urn:akdb:bsp:postkorb:komm:webservice' + xmlns:xs='http://www.w3.org/2001/XMLSchema'> + <xs:element name='sendBspNachricht' + type='tns:sendBspNachricht' /> + <xs:complexType name='sendBspNachricht'> + <xs:sequence> + <xs:element minOccurs='1' name='okKommBspNachrichtInput' + type='xs:base64Binary' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtOutput' + type='tns:sendBspNachrichtOutput' /> + <xs:complexType name='sendBspNachrichtOutput'> + <xs:sequence> + <xs:element minOccurs='1' + name='okKommBspNachrichtOutput' type='xs:base64Binary' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtNative' + type='tns:sendBspNachrichtNative' /> + <xs:complexType name='sendBspNachrichtNative'> + <xs:sequence> + <xs:element minOccurs='1' name='bspNachricht' + type='xs:string' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtNativeOutput' + type='tns:sendBspNachrichtNativeOutput' /> + <xs:complexType name='sendBspNachrichtNativeOutput'> + <xs:sequence> + <xs:element minOccurs='1' name='bspQuittung' + type='xs:string' /> + </xs:sequence> + </xs:complexType> + </xs:schema> + </types> + <message name='PostkorbKommService_sendBspNachrichtInput'> + <part element='tns:sendBspNachricht' + name='okKommBspNachrichtInput'></part> + </message> + <message name='PostkorbKommService_sendBspNachrichtOutput'> + <part element='tns:sendBspNachrichtOutput' + name='sendBspNachrichtOutput'></part> + </message> + <message name='PostkorbKommService_sendBspNachrichtNativeInput'> + <part element='tns:sendBspNachrichtNative' + name='sendBspNachrichtNative'></part> + </message> + <message + name='PostkorbKommService_sendBspNachrichtNativeOutput'> + <part element='tns:sendBspNachrichtNativeOutput' + name='bspQuittung'></part> + </message> + <portType name='PostkorbKommPortType'> + <operation name='sendBspNachricht'> + <input message='tns:PostkorbKommService_sendBspNachrichtInput'></input> + <output + message='tns:PostkorbKommService_sendBspNachrichtOutput'></output> + </operation> + <operation name='sendBspNachrichtNative'> + <input + message='tns:PostkorbKommService_sendBspNachrichtNativeInput'></input> + <output + message='tns:PostkorbKommService_sendBspNachrichtNativeOutput'></output> + </operation> + </portType> + <binding name="PostkorbKommBinding" + type="tns:PostkorbKommPortType"> + <soap:binding style="document" + transport="http://schemas.xmlsoap.org/soap/http" /> + <operation name='sendBspNachricht'> + <soap:operation soapAction='' /> + <input> + <soap:body use='literal' /> + </input> + <output> + <soap:body use="literal" /> + </output> + </operation> + <operation name='sendBspNachrichtNative'> + <soap:operation soapAction='' /> + <input> + <soap:body use='literal' /> + </input> + <output> + <soap:body use="literal" /> + </output> + </operation> + </binding> + <service name="PostkorbKommService"> + <port name="PostkorbKommPort" binding="tns:PostkorbKommBinding"> + <!-- <soap:address location="${web-services-base- url}/bspservices/postkorbkomm" + /> --> + <soap:address location="http://localhost:8080/bspx-postkorb-okkomm-ws/bspservices/postkorbkomm" /> + </port> + </service> +</definitions> diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/bspnachrichten-2.13.xsd b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/bspnachrichten-2.13.xsd new file mode 100644 index 0000000..23b0e24 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/bayernid/bspnachrichten-2.13.xsd @@ -0,0 +1,343 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Service- und Portalplattform + AKDB München, Geschäftsfeld eGovernment + + Copyright (c) AKDB + +--> +<xsd:schema targetNamespace="http://www.akdb.de/egov/bsp/nachrichten" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:bsp="http://www.akdb.de/egov/bsp/nachrichten" + elementFormDefault="qualified"> + + <xsd:element name="BspNachricht"> + <xsd:annotation> + <xsd:appinfo> + <title>Nachricht für die Kommunikation zwischen Bürgerservice-Portal + und externen Fachverfahren</title> + </xsd:appinfo> + <xsd:documentation>Einheitliches Nachrichtenschema für die + Kommunikation zwischen Bürgerservice-Portal und externem Verfahren. + Nachrichten vom Bürgerservice-Portal an den Postkorb eines + Verfahrens + oder Nachrichten von den Verfahren an das Bürgerservice-Portal müssen + gemäß diesem Schema aufgebaut sein. + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="NachrichtenKopf" type="bsp:NachrichtenKopfType"/> + <xsd:element name="NachrichtenInhalt" type="bsp:NachrichtenInhaltType"/> + </xsd:sequence> + <xsd:attribute name="version" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet die + Nachrichten-Version, z. B. "1.0", "1.1".</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.1"/> + <xsd:enumeration value="1.2"/> + <xsd:enumeration value="1.3"/> + <xsd:enumeration value="1.4"/> + <xsd:enumeration value="1.5"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="fassung" use="required" > + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet das Datum, an dem + die diesen Schemata im Status final produziert wurde. Format: + YYYY-MM-DD.</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="2017-03-15"/> + <xsd:enumeration value="2018-04-01"/> + <xsd:enumeration value="2018-11-01"/> + <xsd:enumeration value="2019-06-28"/> + <xsd:enumeration value="2020-03-15"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="produkt" type="xsd:string" use="optional"> + <xsd:annotation> + <xsd:documentation>In diesem Attribut ist der Name des Produktes + (der Software) einzutragen, mit dem diese Nachricht erstellt + worden ist. z.B. BSP, PWS</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="produkthersteller" type="xsd:string" use="optional"/> + <xsd:attribute name="produktversion" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="BspQuittung"> + <xsd:annotation> + <xsd:appinfo> + <title>Quittung über den Empfang einer BSO-Nachricht</title> + </xsd:appinfo> + <xsd:documentation>Zu einer empfangenen BSP-Nachricht wird eine + Quittung geliefert, die bestätigt, dass die Nachricht übernommen wurde + oder aufgrund eines technischen oder fachlichen Fehlers abgewiesen wurde. + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="AnnahmeErfolgreich" type="xsd:boolean" minOccurs="1" maxOccurs="1"/> + <xsd:element name="ErgebnisStatus" type="bsp:SchluesseltabelleType" minOccurs="1" maxOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9006 (0 (erfolgreich angenommen), 99 (sonstiger technischer Fehler), ...)</xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="ErgaenzendeHinweise" type="xsd:string" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + <xsd:attribute name="version" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet die + Nachrichten-Version, z. B. "1.0", "1.1".</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.1"/> + <xsd:enumeration value="1.2"/> + <xsd:enumeration value="1.3"/> + <xsd:enumeration value="1.4"/> + <xsd:enumeration value="1.5"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="fassung" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet das Datum, an dem + die diesen Schemata im Status final produziert wurde. Format: + YYYY-MM-DD.</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="2017-03-15"/> + <xsd:enumeration value="2018-04-01"/> + <xsd:enumeration value="2018-11-01"/> + <xsd:enumeration value="2019-06-28"/> + <xsd:enumeration value="2020-03-15"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="produkt" type="xsd:string" use="optional"> + <xsd:annotation> + <xsd:documentation>In diesem Attribut ist der Name des Produktes + (der Software) einzutragen, mit dem diese Nachricht erstellt + worden ist. z.B. BSP, PWS</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="produkthersteller" type="xsd:string" use="optional"/> + <xsd:attribute name="produktversion" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="NachrichtenKopfType"> + <xsd:sequence> + <xsd:element name="Identifikation.Nachricht" type="bsp:Identifikation.NachrichtType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Anwenderkennung" type="xsd:string" minOccurs="0"> + <xsd:annotation> + <xsd:documentation> Die Anwenderkennung stellt Informationen über die absendende Person + zur Verfügung und dient der Protokollierung. + Anhand dieser Kennung kann die absendende Person identifiziert werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Absender" type="bsp:AbsenderType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Empfaenger" type="bsp:EmpfaengerType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="AntwortAuf" type="xsd:string" maxOccurs="1" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Eine Nachricht kann mit einer exisiterenden + Nachricht in Beziehung gebracht werden als Antwortnachricht oder + weitergeleitete Nachricht. Der Bezug erfolgt hierbei über die + NachrichtenId. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="WeiterleitungZu" type="xsd:string" minOccurs="0"/> + <xsd:element name="lesebestaetigungAntwortAdresse" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="Identifikation.NachrichtType"> + <xsd:sequence> + <xsd:element name="Ereignis" type="bsp:SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9001, Schluessel: BspNachricht + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Erstellungszeitpunkt" type="xsd:dateTime" maxOccurs="1" minOccurs="1"/> + <xsd:element name="NachrichtenId" type="xsd:string" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>eine beliebige, eindeutige ID, die durch den + erstellenden Client generiert wird. Zusammen mit + Erstellungszeitpunkt und Absender kann eine Nachricht bsp-global + eindeutig identifiziert werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="AbsenderType"> + <xsd:sequence> + <xsd:element name="PostkorbId" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Verfahren" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Dienst" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Mandant" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Gemeindeschluessel" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Der amtliche Gemeindeschlüssel (AGS). + Als Tabellennummer ist hier die 36 (OSCI-XMeld-Schlüsseltabelle "Amtlicher Gemeindeschluessel") zu verwenden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Name" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Anschrift" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Email" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Telefon" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Hyperlink" type="xsd:string" maxOccurs="1" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="EmpfaengerType"> + <xsd:sequence> + <xsd:element name="PostkorbId" type="xsd:string" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Verfahren" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Dienst" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Mandant" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Gemeindeschluessel" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Der amtliche Gemeindeschlüssel (AGS). + Als Tabellennummer ist hier die 36 (OSCI-XMeld-Schlüsseltabelle "Amtlicher Gemeindeschluessel") zu verwenden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Name" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Anschrift" type="xsd:string" maxOccurs="1" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="NachrichtenInhaltType"> + <xsd:sequence> + <xsd:element name="Betreff" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Kategorie" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9002 (KAT_STATUS, KAT_INFOBSP, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:choice minOccurs="0"> + <xsd:element name="StorkQaaLevel" type="bsp:StorkQaaLevel"/> + <xsd:element name="NpaGescheutzt" type="xsd:boolean" > + <!-- deprecated, wird durch StorkQaaLevel="STORK-QAA-Level-1" ersetzt --> + <xsd:annotation> + <xsd:documentation> + Diese Nachricht kann im BüsP-Postkorb nur nach + vorheriger Anmeldung mit dem nPA gelesen werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:choice> + <xsd:element name="ZuVorgang" type="bsp:ZuVorgangType" minOccurs="0"/> + <xsd:element name="FreiText" type="bsp:FreiTextType"/> + <xsd:element name="DataContainer" type="bsp:DataContainerType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ZuVorgangType"> + <xsd:annotation> + <xsd:documentation>VorgangsName oder VorgangsId müssen angegeben + werden. Es können auch beide angegeben werden.</xsd:documentation> + </xsd:annotation> + <xsd:sequence minOccurs="0"> + <xsd:element name="VorgangsName" type="xsd:string"/> + <xsd:element name="VorgangsId" type="xsd:string"/> + <xsd:element name="VorgangStatus" type="bsp:SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9003 (ST_ERHALTEN, ST_GELESEN,...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="FreiTextType"> + <xsd:sequence> + <xsd:element name="Encoding" type="bsp:SchluesseltabelleType" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9004 (text/plain, text/html, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Text" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation> + Wenn als Encoding text/plain festgelegt ist, so wird die Zeichensequenz "\n" als ein Zeilenvorschub interpretiert. + Das Backslash-Zeichen (\) wird mit einem weiteren Backslash-Zeichen entwertet. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="DataContainerType"> + <xsd:sequence minOccurs="0"> + <xsd:element name="Inhalt" type="xsd:base64Binary" maxOccurs="1" minOccurs="1"/> + <xsd:element name="FileName" maxOccurs="1" minOccurs="0"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:maxLength value="255"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:element> + <xsd:element name="FileType" type="bsp:SchluesseltabelleType" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9005 (application/pdf, text/html, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Dieser Datentyp wird für Schlüsselwerte benötigt. + Mit dem Datentyp SchluesseltabelleType übermittelt man den Schlüssel + und die Nummer der Tabelle, in der das Schlüssel-Wert Paar definiert + worden ist. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="Tabelle" type="xsd:string"/> + <xsd:element name="Schluessel" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="StorkQaaLevel"> + <xsd:restriction base="xsd:string"> + <!-- since version 1.2 - deprecated --> + <xsd:enumeration value="LEVEL_1"/> + <xsd:enumeration value="LEVEL_2"/> + <xsd:enumeration value="LEVEL_3"/> + <xsd:enumeration value="LEVEL_4"/> + <!-- since version 1.3 --> + <xsd:enumeration value="STORK-QAA-Level-1"/> + <xsd:enumeration value="STORK-QAA-Level-2"/> + <xsd:enumeration value="STORK-QAA-Level-3"/> + <xsd:enumeration value="STORK-QAA-Level-4"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="NonEmptyString"> + <xsd:restriction base="xsd:string"> + <xsd:minLength value="1"/> + </xsd:restriction> + </xsd:simpleType> +</xsd:schema> + + diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/log4j2-local.xml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/log4j2-local.xml new file mode 100644 index 0000000..5d7001e --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/main/resources/log4j2-local.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <Appenders> + <Console name="CONSOLE" target="SYSTEM_OUT"> + <PatternLayout pattern="[%-5level] %c{1.} %msg%n"/> + </Console> + </Appenders> + + <Loggers> + <Root level="WARN"> + <appender-ref ref="CONSOLE" /> + </Root> + </Loggers> +</configuration> \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcServiceITCase.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcServiceITCase.java new file mode 100644 index 0000000..8f9468c --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyGrpcServiceITCase.java @@ -0,0 +1,170 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import static org.assertj.core.api.Assertions.*; + +import java.io.InputStream; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; +import com.github.tomakehurst.wiremock.junit5.WireMockTest; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.akdb.BayernIdRemoteService; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.mock.GrpcBayernIdProxyTestClient; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.mock.MockBayernIdInitializer; +import io.grpc.StatusRuntimeException; +import lombok.SneakyThrows; +import net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration; +import net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration; +import net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration; +import net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration; +import net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration; +import net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@SpringBootTest(classes = BayernIdProxyApplication.class, properties = { + "grpc.server.inProcessName=test", + "grpc.client.inProcess.address=in-process:test", + "ozgcloud.bayernid.server: http://bayern-id", + "ozgcloud.bayernid.useSsl: false" +}) +@SpringJUnitConfig(classes = BayernIdProxyGrpcServiceITCase.TestConfig.class) +@DirtiesContext +@WireMockTest +@ITCase +class BayernIdProxyGrpcServiceITCase { + + @Autowired + private BayernIdProxyGrpcService service; + @Autowired + private BayernIdRemoteService bayernIdRemoteService; + + @GrpcClient("inProcess") + private BayernIdProxyServiceGrpc.BayernIdProxyServiceStub serviceStub; + + private MockBayernIdInitializer bayernIdInitializer; + + @Value("classpath:test.pdf") + private Resource pdfResource; + @Value("classpath:test.txt") + private Resource txtResource; + + private String pdfName = "test.pdf"; + private String txtName = "test.txt"; + + private GrpcBayernIdProxyTestClient grpcTestClient; + + @BeforeEach + void setup(WireMockRuntimeInfo wmRuntimeInfo) { + bayernIdRemoteService.setDefaultUri("http://localhost:" + wmRuntimeInfo.getHttpPort()); + bayernIdInitializer = new MockBayernIdInitializer(wmRuntimeInfo); + grpcTestClient = new GrpcBayernIdProxyTestClient(serviceStub); + } + + @Test + @SneakyThrows + void shouldSendMessage() { + bayernIdInitializer.createResponseOk(); + + var bayernIdResponse = grpcTestClient.sendMessage(GrpcBayernIdMessageMetadataTestFactory.create(), createAttachmentIterator()); + + assertThat(bayernIdResponse.isSuccess()).isTrue(); + assertThat(bayernIdResponse.getStatus()).isEqualTo("0"); + } + + @SneakyThrows + @Test + void shouldReceiveErrorResponse() { + bayernIdInitializer.createResponseError(); + + var bayernIdResponse = grpcTestClient.sendMessage(GrpcBayernIdMessageMetadataTestFactory.create(), createAttachmentIterator()); + + assertThat(bayernIdResponse.isSuccess()).isFalse(); + assertThat(bayernIdResponse.getStatus()).isEqualTo("31"); + assertThat(bayernIdResponse.getMessage()).isEqualTo("Unzulässiger Nachrichteninhalt"); + } + + @Test + void shouldPassException() { + bayernIdInitializer.createResponseWithException(); + + try { + grpcTestClient.sendMessage(GrpcBayernIdMessageMetadataTestFactory.create(), createAttachmentIterator()); + } catch (ExecutionException e) { + assertException(e.getMessage(), e.getCause()); + } + } + + @Test + void shouldPass500Response() { + bayernIdInitializer.create500Response(); + + try { + grpcTestClient.sendMessage(GrpcBayernIdMessageMetadataTestFactory.create(), createAttachmentIterator()); + } catch (ExecutionException e) { + assertException(e.getMessage(), e.getCause()); + } + } + + private void assertException(String exceptionMessage, Throwable cause) { + assertThat(cause).isInstanceOf(StatusRuntimeException.class); + assertThat(exceptionMessage).contains("(ExceptionId:"); + } + + + @SneakyThrows + Set<Pair<GrpcAttachmentMetadata, InputStream>> createAttachmentIterator() { + return Set.of( + Pair.of(GrpcAttachmentMetadata.newBuilder().setFileName(txtName).setFileType("text/plain").build(), txtResource.getInputStream()), + Pair.of(GrpcAttachmentMetadata.newBuilder().setFileName(pdfName).setFileType("application/pdf").build(), pdfResource.getInputStream()) + ); + } + + @Configuration + @ImportAutoConfiguration({ + GrpcClientAutoConfiguration.class, + GrpcClientHealthAutoConfiguration.class, + GrpcClientMetricAutoConfiguration.class, + GrpcClientSecurityAutoConfiguration.class, + GrpcClientTraceAutoConfiguration.class, + GrpcDiscoveryClientAutoConfiguration.class + }) + static class TestConfig { + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyServiceTest.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyServiceTest.java new file mode 100644 index 0000000..2bda292 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdProxyServiceTest.java @@ -0,0 +1,68 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.akdb.BayernIdRemoteService; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse; + +class BayernIdProxyServiceTest { + + @InjectMocks + private BayernIdProxyService service; + + @Mock + private BayernIdRemoteService remoteService; + @Mock + private BayernIdMessage message; + @Mock + private BayernIdResponse bayernIdResponse; + + @Test + void shouldCallRemoteService() { + sendMessage(); + + verify(remoteService).sendPostfachNachricht(message); + } + + @Test + void shouldReturnBayernIdResponse() { + when(remoteService.sendPostfachNachricht(any())).thenReturn(bayernIdResponse); + + var result = sendMessage(); + + assertThat(result).isEqualTo(bayernIdResponse); + } + + private BayernIdResponse sendMessage() { + return service.sendPostfachNachricht(message); + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdResponseTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdResponseTestFactory.java new file mode 100644 index 0000000..09b4146 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/BayernIdResponseTestFactory.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.nachrichten.postfach.bayernid.proxy; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse.BayernIdResponseBuilder; + +public class BayernIdResponseTestFactory { + + public static final String STATUS = "OK"; + public static final String MESSAGE = "Message sent successfully"; + + public static BayernIdResponse create() { + return createBuilder().build(); + } + + public static BayernIdResponseBuilder createBuilder() { + return BayernIdResponse.builder() + .success(true) + .status(STATUS) + .message(MESSAGE); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchConfiguration.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAbsenderTestFactory.java similarity index 50% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchConfiguration.java rename to nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAbsenderTestFactory.java index 3d9400f..a955fd2 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchConfiguration.java +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAbsenderTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,34 +21,32 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.nachrichten.postfach.bayernid.proxy; -import javax.validation.Valid; +public class GrpcAbsenderTestFactory { -import org.apache.http.Header; -import org.apache.http.message.BasicHeader; -import org.elasticsearch.client.RestClientBuilder; -import org.elasticsearch.client.RestHighLevelClient; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; + public static final String NAME = "Musterstadt Stadtverwaltung"; + public static final String ANSCHRIFT = "Musterstraße 1"; + public static final String EMAIL = "example@mail.loc"; + public static final String TELEFON = "0456123456789"; + public static final String HYPERLINK = "http://some.link"; + public static final String MANDANT = "Musterstadt"; + public static final String DIENST = "Stadtverwaltung"; + public static final String GEMEINDE_SCHLUESSEL = "123456789"; -@Configuration -class SearchConfiguration { - - @Autowired - @Valid - private SearchProperties properties; - - private static final Header[] COMPATIBILITY_HEADERS = new Header[] { - new BasicHeader("Accept", "application/vnd.elasticsearch+json;compatible-with=7"), - new BasicHeader("Content-Type", "application/vnd.elasticsearch+json;compatible-with=7") - }; - - @Bean - RestHighLevelClient restHighLevelClient(RestClientBuilder client) { - client.setDefaultHeaders(COMPATIBILITY_HEADERS); - return new RestHighLevelClient(client); + public static GrpcAbsender create() { + return createBuilder().build(); } + public static GrpcAbsender.Builder createBuilder() { + return GrpcAbsender.newBuilder() + .setName(NAME) + .setAnschrift(ANSCHRIFT) + .setEmail(EMAIL) + .setTelefon(TELEFON) + .setHyperlink(HYPERLINK) + .setMandant(MANDANT) + .setDienst(DIENST) + .setGemeindeschluessel(GEMEINDE_SCHLUESSEL); + } } diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAttachmentMetadataTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAttachmentMetadataTestFactory.java new file mode 100644 index 0000000..6972e7a --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcAttachmentMetadataTestFactory.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.nachrichten.postfach.bayernid.proxy; + +public class GrpcAttachmentMetadataTestFactory { + + public static final String FILE_TYPE = "plain/text"; + public static final String FILE_NAME = "test.txt"; + + public static GrpcAttachmentMetadata create() { + return createBuilder().build(); + } + + public static GrpcAttachmentMetadata.Builder createBuilder() { + return GrpcAttachmentMetadata.newBuilder() + .setFileType(FILE_TYPE) + .setFileName(FILE_NAME); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcBayernIdMessageMetadataTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcBayernIdMessageMetadataTestFactory.java new file mode 100644 index 0000000..854a5c1 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcBayernIdMessageMetadataTestFactory.java @@ -0,0 +1,64 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import java.time.ZonedDateTime; +import java.util.GregorianCalendar; +import java.util.UUID; + +import javax.xml.datatype.DatatypeFactory; + +import lombok.SneakyThrows; + +public class GrpcBayernIdMessageMetadataTestFactory { + + public static final String MESSAGE_ID = "messageId"; + public static final ZonedDateTime CREATED_AT = ZonedDateTime.now(); + public static final String CREATED_AT_STRING = convertZoneDDateTime(CREATED_AT); + public static final String STORK_QAA_LEVEL = "LEVEL_1"; + public static final String SUBJECT = "subject"; + public static final String VORGANG_ID = UUID.randomUUID().toString(); + public static final String MESSAGE_TEXT = "some completely random text"; + + public static GrpcBayernIdMessageMetadata create() { + return createBuilder().build(); + } + + public static GrpcBayernIdMessageMetadata.Builder createBuilder() { + return GrpcBayernIdMessageMetadata.newBuilder() + .setMessageId(MESSAGE_ID) + .setCreatedAt(convertZoneDDateTime(CREATED_AT)) + .setAbsender(GrpcAbsenderTestFactory.create()) + .setEmpfaenger(GrpcEmpfaengerTestFactory.create()) + .setSubject(SUBJECT) + .setStorkQaaLevel(STORK_QAA_LEVEL) + .setVorgangId(VORGANG_ID) + .setText(MESSAGE_TEXT); + } + + @SneakyThrows + public static String convertZoneDDateTime(ZonedDateTime dateTime) { + return DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar.from(dateTime)).toString(); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcEmpfaengerTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcEmpfaengerTestFactory.java new file mode 100644 index 0000000..5a0df82 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/GrpcEmpfaengerTestFactory.java @@ -0,0 +1,42 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +public class GrpcEmpfaengerTestFactory { + + public static final String POSTFACH_ID = "postfach-id-1"; + public static final String NAME = "Max Empfaenger"; + public static final String ANSCHRIFT = "anschrift"; + + public static GrpcEmpfaenger create() { + return createBuilder().build(); + } + + public static GrpcEmpfaenger.Builder createBuilder() { + return GrpcEmpfaenger.newBuilder() + .setPostkorbId(POSTFACH_ID) + .setName(NAME) + .setAnschrift(ANSCHRIFT); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserverTest.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserverTest.java new file mode 100644 index 0000000..d6efd88 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/UploadStreamObserverTest.java @@ -0,0 +1,404 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Path; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import com.google.protobuf.ByteString; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.Attachment; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage.BayernIdMessageBuilder; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageTestFactory; +import io.grpc.stub.StreamObserver; +import lombok.SneakyThrows; + +class UploadStreamObserverTest { + + @Spy + @InjectMocks + private UploadStreamObserver uploadStreamObserver; + + @Mock + private StreamObserver<GrpcSendBayernIdMessageResponse> responseObserver; + @Mock + private BayernIdProxyService proxyService; + @Mock + private BayernIdMessageMapper messageMapper; + @Mock + private BayernIdMessageBuilder bayernIdMessageBuilder; + @Mock + private AtomicReference<BayernIdMessageBuilder> messageBuilderAtomicReference; + + @Nested + class TestOnNext { + + @Test + void shouldCallReadMetadata() { + var messageMetadata = GrpcBayernIdMessageMetadataTestFactory.create(); + var sendRequest = GrpcSendBayernIdMessageRequest.newBuilder().setMessageMetadata(messageMetadata).build(); + + uploadStreamObserver.onNext(sendRequest); + + verify(uploadStreamObserver).readMessageMetadata(messageMetadata); + verify(uploadStreamObserver, never()).readAttachments(any()); + } + + @Test + void shouldCallReadAttachment() { + var attachments = GrpcAttachments.newBuilder().setAttachmentMetadata(GrpcAttachmentMetadataTestFactory.create()).build(); + var sendRequest = GrpcSendBayernIdMessageRequest.newBuilder().setAttachments(attachments).build(); + doNothing().when(uploadStreamObserver).readAttachments(any()); + + uploadStreamObserver.onNext(sendRequest); + + verify(uploadStreamObserver).readAttachments(attachments); + verify(uploadStreamObserver, never()).readMessageMetadata(any()); + } + } + + @Nested + class TestReadMessageMetadata { + + private GrpcBayernIdMessageMetadata messageMetadata = GrpcBayernIdMessageMetadataTestFactory.create(); + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(uploadStreamObserver, "messageBuilder", messageBuilderAtomicReference); + } + + @Test + void shouldCallMessageMapper() { + uploadStreamObserver.readMessageMetadata(messageMetadata); + + verify(messageMapper).toBayernIdMessage(messageMetadata); + } + + @Test + void shouldSetMessageBuilder() { + when(messageMapper.toBayernIdMessage(any())).thenReturn(bayernIdMessageBuilder); + + uploadStreamObserver.readMessageMetadata(messageMetadata); + + verify(messageBuilderAtomicReference).set(bayernIdMessageBuilder); + } + + } + + @Nested + class TestReadAttachments { + + @Test + void shouldCallAddContainer() { + var attachmentMetadata = GrpcAttachmentMetadataTestFactory.create(); + doNothing().when(uploadStreamObserver).addDataContainer(any()); + + uploadStreamObserver.readAttachments(GrpcAttachments.newBuilder().setAttachmentMetadata(attachmentMetadata).build()); + + verify(uploadStreamObserver).addDataContainer(attachmentMetadata); + verify(uploadStreamObserver, never()).writeAttachment(any()); + } + + @Test + void shouldCallWriteAttachment() { + var content = ByteString.copyFromUtf8("attachment"); + var attachment = GrpcAttachments.newBuilder().setContent(content).build(); + doNothing().when(uploadStreamObserver).writeAttachment(any()); + + uploadStreamObserver.readAttachments(attachment); + + verify(uploadStreamObserver).writeAttachment(content); + verify(uploadStreamObserver, never()).addDataContainer(any()); + } + + @Nested + class TestAddDataContainer { + + private GrpcAttachmentMetadata grpcAttachmentMetadata = GrpcAttachmentMetadataTestFactory.create(); + + @Mock + private Attachment attachment; + + @Mock + private AtomicReference<BayernIdMessageBuilder> atomicMessageBuilder; + + @BeforeEach + void setup() { + when(atomicMessageBuilder.get()).thenReturn(bayernIdMessageBuilder); + ReflectionTestUtils.setField(uploadStreamObserver, "messageBuilder", atomicMessageBuilder); + } + + @Test + void shouldCallBuildAttachment() { + uploadStreamObserver.addDataContainer(grpcAttachmentMetadata); + + verify(uploadStreamObserver).buildAttachment(grpcAttachmentMetadata); + } + + @Test + void shouldAddAttachment() { + doReturn(attachment).when(uploadStreamObserver).buildAttachment(any()); + + uploadStreamObserver.addDataContainer(grpcAttachmentMetadata); + + verify(bayernIdMessageBuilder).attachment(attachment); + } + } + + @Nested + class TestBuildAttachment { + + private GrpcAttachmentMetadata grpcAttachmentMetadata = GrpcAttachmentMetadataTestFactory.create(); + + @Mock + private InputStream tmpFileInputStream; + + @BeforeEach + void setup() { + doReturn(tmpFileInputStream).when(uploadStreamObserver).createTemporallyFile(any()); + } + + @Test + void shouldCallCreateTemporallyFile() { + uploadStreamObserver.buildAttachment(grpcAttachmentMetadata); + + verify(uploadStreamObserver).createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + } + + @Test + void shouldSetTemporallyFile() { + var result = uploadStreamObserver.buildAttachment(grpcAttachmentMetadata); + + assertThat(result.getContent()).isEqualTo(tmpFileInputStream); + } + + @Test + void shouldSetAttachmentName() { + var result = uploadStreamObserver.buildAttachment(grpcAttachmentMetadata); + + assertThat(result.getName()).isEqualTo(GrpcAttachmentMetadataTestFactory.FILE_NAME); + } + + @Test + void shouldSetAttachmentType() { + var result = uploadStreamObserver.buildAttachment(grpcAttachmentMetadata); + + assertThat(result.getType()).isEqualTo(GrpcAttachmentMetadataTestFactory.FILE_TYPE); + } + } + + @Nested + class TestCreateTemporallyFile { + + @Mock + private OutputStream attachmentWriter; + @Mock + private InputStream tmpFileInputStream; + + private Path tempFilePath = Path.of("tempFile"); + + @Test + void shouldCallCloseTemporallyFile() { + + uploadStreamObserver.createTemporallyFile("test.txt"); + + verify(uploadStreamObserver).closeTemporallyWriter(); + } + + @SneakyThrows + @Test + void shouldCallCreateFile() { + uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + + verify(uploadStreamObserver).createFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + } + + @SneakyThrows + @Test + void shouldCallNewOutputStream() { + doReturn(tempFilePath).when(uploadStreamObserver).createFile(any()); + + uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + + verify(uploadStreamObserver).newOutputStream(tempFilePath); + } + + @SneakyThrows + @Test + void shouldInitializeOutputWriter() { + doReturn(attachmentWriter).when(uploadStreamObserver).newOutputStream(any()); + + uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + + assertThat(getAttachmentWriter()).isEqualTo(attachmentWriter); + } + + @SneakyThrows + @Test + void shouldCallNewInputStream() { + doReturn(tempFilePath).when(uploadStreamObserver).createFile(any()); + + uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + + verify(uploadStreamObserver).newInputStream(tempFilePath); + } + + @SneakyThrows + @Test + void shouldReturnInputStream() { + doReturn(tmpFileInputStream).when(uploadStreamObserver).newInputStream(any()); + + var result = uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME); + + assertThat(result).isEqualTo(tmpFileInputStream); + } + + @SneakyThrows + @Test + void shouldThrowException() { + doThrow(new IOException()).when(uploadStreamObserver).createFile(any()); + + assertThrows(TechnicalException.class, () -> uploadStreamObserver.createTemporallyFile(GrpcAttachmentMetadataTestFactory.FILE_NAME)); + } + + private OutputStream getAttachmentWriter() { + return (OutputStream) ReflectionTestUtils.getField(uploadStreamObserver, "attachmentWriter"); + } + } + } + + @Nested + class TestOnError { + + @Test + void shouldCallCloseTemporallyWriter() { + try { + uploadStreamObserver.onError(new RuntimeException()); + } catch (TechnicalException e) { + // expected + } + + verify(uploadStreamObserver).closeTemporallyWriter(); + } + + @Test + void shouldTrowTechnicalException() { + var cause = new RuntimeException(); + + var thrownException = assertThrows(TechnicalException.class, () -> uploadStreamObserver.onError(cause)); + + assertThat(thrownException.getCause()).isEqualTo(cause); + } + } + + @Nested + class TestOnComplete { + + @BeforeEach + void setup() { + when(messageBuilderAtomicReference.get()).thenReturn(bayernIdMessageBuilder); + ReflectionTestUtils.setField(uploadStreamObserver, "messageBuilder", messageBuilderAtomicReference); + } + + @Test + void shouldCallCloseTemporallyWriter() { + uploadStreamObserver.onCompleted(); + + verify(uploadStreamObserver).closeTemporallyWriter(); + } + + @Test + void shouldCallSendBayernIdMessage() { + var bayernIdMessage = BayernIdMessageTestFactory.create(); + when(bayernIdMessageBuilder.build()).thenReturn(bayernIdMessage); + + uploadStreamObserver.onCompleted(); + + verify(proxyService).sendPostfachNachricht(bayernIdMessage); + } + + @Test + void shouldCallMessageMapper() { + var bayernIdResponse = BayernIdResponseTestFactory.create(); + when(proxyService.sendPostfachNachricht(any())).thenReturn(bayernIdResponse); + + uploadStreamObserver.onCompleted(); + + verify(messageMapper).fromBayernIdResponse(bayernIdResponse); + } + + @Test + void shouldCallResponseObserver() { + var grpcSendResponse = GrpcSendBayernIdMessageResponse.newBuilder().build(); + when(messageMapper.fromBayernIdResponse(any())).thenReturn(grpcSendResponse); + + uploadStreamObserver.onCompleted(); + + verify(responseObserver).onNext(grpcSendResponse); + } + + @Test + void shouldCallSendResponse() { + uploadStreamObserver.onCompleted(); + + verify(responseObserver).onNext(any()); + } + + @Test + void shouldCallComplete() { + uploadStreamObserver.onCompleted(); + + verify(responseObserver).onCompleted(); + } + + @Test + void shouldThrowTechnicalException() { + var cause = new RuntimeException(); + + doThrow(cause).when(proxyService).sendPostfachNachricht(any()); + + var receivedException = assertThrows(TechnicalException.class, () -> uploadStreamObserver.onCompleted()); + assertThat(receivedException.getCause()).isEqualTo(cause); + } + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteServiceTest.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteServiceTest.java new file mode 100644 index 0000000..9d257bd --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/akdb/BayernIdRemoteServiceTest.java @@ -0,0 +1,233 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.akdb; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import jakarta.xml.bind.JAXBElement; + +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 org.springframework.ws.client.core.WebServiceTemplate; + +import akdb.bsp.postkorb.komm.webservice.ObjectFactory; +import akdb.bsp.postkorb.komm.webservice.SendBspNachrichtNative; +import akdb.bsp.postkorb.komm.webservice.SendBspNachrichtNativeOutput; +import de.akdb.egov.bsp.nachrichten.BspNachricht; +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessageMapper; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdResponse; + +class BayernIdRemoteServiceTest { + + @Spy + @InjectMocks + private BayernIdRemoteService service; + + @Mock + private BayernIdMessageMapper messageMapper; + @Mock + private ObjectFactory objectFactory; + + @Nested + class TestSendPostfachNachricht { + + @Mock + private SendBspNachrichtNative sendNachricht; + @Mock + private SendBspNachrichtNativeOutput sendBspNachrichtResponse; + @Mock + private BspQuittung bspQuittung; + @Mock + private JAXBElement<SendBspNachrichtNativeOutput> jaxbSendBspNachrichtNativeOutput; + @Mock + private BayernIdResponse response; + @Mock + private BayernIdMessage message; + + @BeforeEach + void setup(){ + doReturn(bspQuittung).when(service).createBspQuitung(any()); + doReturn(sendNachricht).when(service).createSendNachricht(any()); + } + + @Test + void shouldCallCreateSendNachricht() { + doReturn(jaxbSendBspNachrichtNativeOutput).when(service).send(any()); + + sendMessage(); + + verify(service).createSendNachricht(message); + } + + @Test + void shouldCallSendBspNachricht() { + doReturn(jaxbSendBspNachrichtNativeOutput).when(service).send(any()); + + sendMessage(); + + verify(service).sendBspNachricht(sendNachricht); + } + + @Test + void shouldCallCreateBspQuitung() { + doReturn(sendBspNachrichtResponse).when(service).sendBspNachricht(any()); + + sendMessage(); + + verify(service).createBspQuitung(sendBspNachrichtResponse); + } + + @Test + void shouldCallMessageMapper() { + doReturn(sendBspNachrichtResponse).when(service).sendBspNachricht(any()); + + sendMessage(); + + verify(messageMapper).toBayernIdResponse(bspQuittung); + } + + @Test + void shouldReturnResponse() { + doReturn(response).when(messageMapper).toBayernIdResponse(bspQuittung); + doReturn(sendBspNachrichtResponse).when(service).sendBspNachricht(any()); + + var result = sendMessage(); + + assertThat(result).isEqualTo(response); + } + + private BayernIdResponse sendMessage() { + return service.sendPostfachNachricht(message); + } + + } + + @Nested + class TestCreateSendNachricht { + + private static final String RESULT_STRING = "result"; + + @Mock + private BayernIdMessage message; + @Mock + private BspNachricht bspNachricht; + + @BeforeEach + void setup() { + doReturn(RESULT_STRING).when(service).buildBspNachrichtXml(any()); + } + + @Test + void shouldCallMessageMapper() { + service.createSendNachricht(message); + + verify(messageMapper).toBspNachricht(message); + } + + @Test + void shouldCallBuildBspNachrichtXml() { + when(messageMapper.toBspNachricht(any())).thenReturn(bspNachricht); + + service.createSendNachricht(message); + + verify(service).buildBspNachrichtXml(bspNachricht); + } + + @Test + void shouldSetBspNachricht() { + var result = service.createSendNachricht(message); + + assertThat(result.getBspNachricht()).isEqualTo(RESULT_STRING); + } + } + + @Nested + class TestSendBspNachricht { + + @Mock + private SendBspNachrichtNative sendBspNachrichtRequest; + @Mock + private JAXBElement<SendBspNachrichtNative> jaxbSendBspNachrichtNative; + @Mock + private JAXBElement<SendBspNachrichtNativeOutput> jaxbSendBspNachrichtNativeOutput; + @Mock + private SendBspNachrichtNativeOutput response; + + @BeforeEach + void setup() { + doReturn(jaxbSendBspNachrichtNativeOutput).when(service).send(any()); + when(jaxbSendBspNachrichtNativeOutput.getValue()).thenReturn(response); + } + + @Test + void shouldCallMarshaller() { + service.sendBspNachricht(sendBspNachrichtRequest); + + verify(objectFactory).createSendBspNachrichtNative(sendBspNachrichtRequest); + } + + @Test + void shouldReturnValue() { + var sendBspNachrichtNativeOutput = service.sendBspNachricht(sendBspNachrichtRequest); + + assertThat(sendBspNachrichtNativeOutput).isEqualTo(response); + } + + @Test + void shouldCallSend() { + when(objectFactory.createSendBspNachrichtNative(any())).thenReturn(jaxbSendBspNachrichtNative); + + service.sendBspNachricht(sendBspNachrichtRequest); + + verify(service).send(jaxbSendBspNachrichtNative); + } + + } + + @Nested + class TestSend { + + @Mock + private JAXBElement<SendBspNachrichtNative> jaxbSendBspNachrichtNative; + @Mock + private WebServiceTemplate webServiceTemplate; + + @Test + void shouldCallMarshalSendAndReceive() { + doReturn(webServiceTemplate).when(service).getWebServiceTemplate(); + + service.send(jaxbSendBspNachrichtNative); + + verify(webServiceTemplate).marshalSendAndReceive(jaxbSendBspNachrichtNative); + } + + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandlerTest.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandlerTest.java new file mode 100644 index 0000000..ad74aec --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/errorhandling/ExceptionHandlerTest.java @@ -0,0 +1,195 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.errorhandling; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +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 de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.common.grpc.GrpcUtil; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.Status.Code; +import io.grpc.StatusException; + +class ExceptionHandlerTest { + + @Spy + @InjectMocks + private ExceptionHandler exceptionHandler; + + @Nested + class TestHandleTechnicalException { + + private static final TechnicalException EXCEPTION = new TechnicalException("Test"); + + @Mock + private Metadata metadata; + @Mock + private StatusException statusException; + + @Test + void shouldCallBuildInternalStatus() { + exceptionHandler.handleTechnicalException(EXCEPTION); + + verify(exceptionHandler).buildInternalStatus(EXCEPTION); + } + + @Test + void shouldCallBuildMetadata() { + exceptionHandler.handleTechnicalException(EXCEPTION); + + verify(exceptionHandler).buildMetadata(EXCEPTION.getExceptionId()); + } + + @Test + void shouldCallCreateStatusException() { + var status = Status.INTERNAL; + doReturn(status).when(exceptionHandler).buildInternalStatus(any()); + doReturn(metadata).when(exceptionHandler).buildMetadata(any()); + + exceptionHandler.handleTechnicalException(EXCEPTION); + + verify(exceptionHandler).createStatusException(status, metadata); + } + + @Test + void shouldReturnStatusException() { + doReturn(statusException).when(exceptionHandler).createStatusException(any(), any()); + + var result = exceptionHandler.handleTechnicalException(EXCEPTION); + + assertThat(result).isEqualTo(statusException); + } + } + + @Nested + class TestHandleRuntimeException { + + private static final RuntimeException EXCEPTION = new RuntimeException("Test"); + + @Mock + private Metadata metadata; + @Mock + private StatusException statusException; + + @Test + void shouldCallBuildInternalStatus() { + exceptionHandler.handleRuntimeException(EXCEPTION); + + verify(exceptionHandler).buildInternalStatus(EXCEPTION); + } + + @Test + void shouldCallCreateExceptionId() { + exceptionHandler.handleRuntimeException(EXCEPTION); + + verify(exceptionHandler).createExceptionId(); + } + + @Test + void shouldCallBuildMetadata() { + var exceptionId = "42"; + doReturn(exceptionId).when(exceptionHandler).createExceptionId(); + + exceptionHandler.handleRuntimeException(EXCEPTION); + + verify(exceptionHandler).buildMetadata(exceptionId); + } + + @Test + void shouldCallCreateStatusException() { + var status = Status.INTERNAL; + doReturn(status).when(exceptionHandler).buildInternalStatus(any()); + doReturn(metadata).when(exceptionHandler).buildMetadata(any()); + + exceptionHandler.handleRuntimeException(EXCEPTION); + + verify(exceptionHandler).createStatusException(status, metadata); + } + + @Test + void shouldReturnStatusException() { + doReturn(statusException).when(exceptionHandler).createStatusException(any(), any()); + + var result = exceptionHandler.handleRuntimeException(EXCEPTION); + + assertThat(result).isEqualTo(statusException); + } + } + + @Nested + class TestBuildInternalStatus { + + private static final Exception CAUSE = new Exception("Cause"); + private static final RuntimeException EXCEPTION = new RuntimeException("Test", CAUSE); + + @Test + void shouldSetInternalStatusCode() { + var result = exceptionHandler.buildInternalStatus(EXCEPTION); + + assertThat(result.getCode()).isEqualTo(Code.INTERNAL); + } + + @Test + void shouldSetDescription() { + var result = exceptionHandler.buildInternalStatus(EXCEPTION); + + assertThat(result.getDescription()).isEqualTo(EXCEPTION.getMessage()); + } + + @Test + void shouldSetCause() { + var result = exceptionHandler.buildInternalStatus(EXCEPTION); + + assertThat(result.getCause()).isEqualTo(CAUSE); + } + } + + @Nested + class TestBuildMetadata { + + private static final String EXCEPTION_ID = "42"; + @Test + void shouldSetExceptionIdKey() { + var result = exceptionHandler.buildMetadata(EXCEPTION_ID); + + assertThat(result.keys()).containsOnly(ExceptionHandler.KEY_EXCEPTION_ID.toLowerCase()); + } + + @Test + void shouldSetExceptionIdValue() { + var result = exceptionHandler.buildMetadata(EXCEPTION_ID); + + assertThat(result.get(GrpcUtil.keyOfString(ExceptionHandler.KEY_EXCEPTION_ID))).isEqualTo(EXCEPTION_ID); + } + + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AbsenderTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AbsenderTestFactory.java new file mode 100644 index 0000000..31164b3 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AbsenderTestFactory.java @@ -0,0 +1,56 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.Absender.AbsenderBuilder; + +public class AbsenderTestFactory { + + public static final String ABSENDER_POSTKORB_ID = "absenderPostkorbId"; + public static final String NAME = "Musterstadt Stadtverwaltung"; + public static final String ANSCHRIFT = "Musterstraße 1"; + public static final String EMAIL = "mail@exam.ple"; + public static final String TELEFON = "0456123456789"; + public static final String HYPERLINK = "http://some.link"; + public static final String MANDANT = "Musterstadt"; + public static final String DIENST = "Stadtverwaltung"; + public static final String GEMEINDE_SCHLUESSEL = "123456789"; + + public static Absender create() { + return createBuilder().build(); + } + + public static AbsenderBuilder createBuilder() { + return Absender.builder() + .postkorbId(ABSENDER_POSTKORB_ID) + .name(NAME) + .anschrift(ANSCHRIFT) + .email(EMAIL) + .telefon(TELEFON) + .hyperlink(HYPERLINK) + .mandant(MANDANT) + .dienst(DIENST) + .gemeindeschluessel(GEMEINDE_SCHLUESSEL); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AttachmentTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AttachmentTestFactory.java new file mode 100644 index 0000000..bc3f4fd --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/AttachmentTestFactory.java @@ -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. + */ +package de.ozgcloud.nachrichten.postfach.bayernid.proxy.message; + +import java.io.ByteArrayInputStream; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.Attachment.AttachmentBuilder; + +public class AttachmentTestFactory { + + public static final String FILE_NAME = "test.txt"; + public static final String TYPE = "plain/text"; + public static final byte[] CONTENT = "test".getBytes(); + + public static Attachment create() { + return createBuilder().build(); + } + + public static AttachmentBuilder createBuilder() { + return Attachment.builder() + .name(FILE_NAME) + .type(TYPE) + .content(new ByteArrayInputStream(CONTENT)); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapperTest.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapperTest.java new file mode 100644 index 0000000..f807b82 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageMapperTest.java @@ -0,0 +1,506 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.ByteArrayInputStream; +import java.util.List; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.Mockito; +import org.testcontainers.shaded.org.apache.commons.io.IOUtils; + +import de.akdb.egov.bsp.nachrichten.BspNachricht; +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.akdb.egov.bsp.nachrichten.DataContainerType; +import de.akdb.egov.bsp.nachrichten.FreiTextType; +import de.akdb.egov.bsp.nachrichten.NachrichtenInhaltType; +import de.akdb.egov.bsp.nachrichten.NachrichtenKopfType; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.BayernIdResponseTestFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAbsenderTestFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadataTestFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcEmpfaengerTestFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import lombok.SneakyThrows; + +class BayernIdMessageMapperTest { + + private BayernIdMessageMapper mapper = Mappers.getMapper(BayernIdMessageMapper.class); + + @Nested + class ToBayernIdMessage { + + private static final GrpcBayernIdMessageMetadata MESSAGE_METADATA = GrpcBayernIdMessageMetadataTestFactory.create(); + + @Test + void shouldSetMessageId() { + var result = mapToBayernIdMessage(); + + assertThat(result.getMessageId()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.MESSAGE_ID); + } + + @Test + void shouldSetCreatedAt() { + var result = mapToBayernIdMessage(); + + assertThat(result.getCreatedAt()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.CREATED_AT_STRING); + } + + @Test + void shouldSetSubject() { + var result = mapToBayernIdMessage(); + + assertThat(result.getSubject()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.SUBJECT); + } + + @Test + void shoulSetStorkQaaLevel() { + var result = mapToBayernIdMessage(); + + assertThat(result.getStorkQaaLevel()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.STORK_QAA_LEVEL); + } + + @Test + void shouldSetVorgangId() { + var result = mapToBayernIdMessage(); + + assertThat(result.getVorgangId()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.VORGANG_ID); + } + + @Test + void shouldSetText() { + var result = mapToBayernIdMessage(); + + assertThat(result.getText()).isEqualTo(GrpcBayernIdMessageMetadataTestFactory.MESSAGE_TEXT); + } + + @Nested + class TestSetAbsender { + + @Test + void shouldSetName() { + var result = mapToAbsender(); + + assertThat(result.getName()).isEqualTo(GrpcAbsenderTestFactory.NAME); + } + + @Test + void shouldSetAnschrift() { + var result = mapToAbsender(); + + assertThat(result.getAnschrift()).isEqualTo(GrpcAbsenderTestFactory.ANSCHRIFT); + } + + @Test + void shouldSetEmail() { + var result = mapToAbsender(); + + assertThat(result.getEmail()).isEqualTo(GrpcAbsenderTestFactory.EMAIL); + } + + @Test + void shouldSetTelefon() { + var result = mapToAbsender(); + + assertThat(result.getTelefon()).isEqualTo(GrpcAbsenderTestFactory.TELEFON); + } + + @Test + void shouldSetHyperlink() { + var result = mapToAbsender(); + + assertThat(result.getHyperlink()).isEqualTo(GrpcAbsenderTestFactory.HYPERLINK); + } + + @Test + void shouldSetMandant() { + var result = mapToAbsender(); + + assertThat(result.getMandant()).isEqualTo(GrpcAbsenderTestFactory.MANDANT); + } + + @Test + void shouldSetDienst() { + var result = mapToAbsender(); + + assertThat(result.getDienst()).isEqualTo(GrpcAbsenderTestFactory.DIENST); + } + + @Test + void shouldSetGemeindeschluessel() { + var result = mapToAbsender(); + + assertThat(result.getGemeindeschluessel()).isEqualTo(GrpcAbsenderTestFactory.GEMEINDE_SCHLUESSEL); + } + + private Absender mapToAbsender() { + var bayernIdMessage = mapToBayernIdMessage(); + assertThat(bayernIdMessage.getAbsender()).isNotNull(); + return bayernIdMessage.getAbsender(); + } + } + + @Nested + class TestSetEmpfaenger { + + @Test + void shouldSetPostfachId() { + var result = mapToEmpfänger(); + + assertThat(result.getPostkorbId()).isEqualTo(GrpcEmpfaengerTestFactory.POSTFACH_ID); + } + + @Test + void shouldSetName() { + var result = mapToEmpfänger(); + + assertThat(result.getName()).isEqualTo(GrpcEmpfaengerTestFactory.NAME); + } + + @Test + void shouldSetAnschrift() { + var result = mapToEmpfänger(); + + assertThat(result.getAnschrift()).isEqualTo(GrpcEmpfaengerTestFactory.ANSCHRIFT); + } + + private Empfaenger mapToEmpfänger() { + var bayernIdMessage = mapToBayernIdMessage(); + assertThat(bayernIdMessage.getEmpfaenger()).isNotNull(); + return bayernIdMessage.getEmpfaenger(); + + } + } + + private BayernIdMessage mapToBayernIdMessage() { + return mapper.toBayernIdMessage(MESSAGE_METADATA).build(); + } + } + + @Nested + class TestFromBayernIdResponse { + + private static final BayernIdResponse BAYERN_ID_RESPONSE = BayernIdResponseTestFactory.create(); + + @Test + void shouldSetSuccess() { + var result = mapToGrpcSendBayernIdMessageResponse(); + + assertThat(result.getSuccess()).isTrue(); + } + + @Test + void shouldSetStatus() { + var result = mapToGrpcSendBayernIdMessageResponse(); + + assertThat(result.getStatus()).isEqualTo(BayernIdResponseTestFactory.STATUS); + } + + @Test + void shouldSetMessage() { + var result = mapToGrpcSendBayernIdMessageResponse(); + + assertThat(result.getMessage()).isEqualTo(BayernIdResponseTestFactory.MESSAGE); + } + + private GrpcSendBayernIdMessageResponse mapToGrpcSendBayernIdMessageResponse() { + return mapper.fromBayernIdResponse(BAYERN_ID_RESPONSE); + } + } + + @Nested + class TestToBspNachricht { + + @Nested + class TestSetNachrichtenKopf { + + @Test + void shouldSetNachrichtId() { + var result = mapToNachrichtenKopf().getIdentifikationNachricht(); + + assertThat(result.getNachrichtenId()).isEqualTo(BayernIdMessageTestFactory.MESSAGE_ID); + } + + @Test + void shouldSetErstellungszeitpunkt() { + var result = mapToNachrichtenKopf().getIdentifikationNachricht(); + + assertThat(result.getErstellungszeitpunkt()).hasToString(BayernIdMessageTestFactory.CREATED_AT); + } + + @Nested + class TestMapEmpfaenger { + + @Test + void shouldSetPostkorbId() { + var result = mapToNachrichtenKopf().getEmpfaenger(); + + assertThat(result.getPostkorbId()).isEqualTo(EmpfaengerTestFactory.POSTKORB_ID); + } + + @Test + void shouldSetName() { + var result = mapToNachrichtenKopf().getEmpfaenger(); + + assertThat(result.getName()).isEqualTo(EmpfaengerTestFactory.NAME); + } + + @Test + void shouldSetAnschrift() { + var result = mapToNachrichtenKopf().getEmpfaenger(); + + assertThat(result.getAnschrift()).isEqualTo(EmpfaengerTestFactory.ANSCHRIFT); + } + } + + @Nested + class TestMapAbsender { + + @Test + void shouldSetName() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getName()).isEqualTo(AbsenderTestFactory.NAME); + } + + @Test + void shouldSetAnschrift() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getAnschrift()).isEqualTo(AbsenderTestFactory.ANSCHRIFT); + } + + @Test + void shouldSetEmail() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getEmail()).isEqualTo(AbsenderTestFactory.EMAIL); + } + + @Test + void shouldSetTelefon() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getTelefon()).isEqualTo(AbsenderTestFactory.TELEFON); + } + + @Test + void shouldSetHyperlink() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getHyperlink()).isEqualTo(AbsenderTestFactory.HYPERLINK); + } + + @Test + void shouldSetMandant() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getMandant()).isEqualTo(AbsenderTestFactory.MANDANT); + } + + @Test + void shouldSetDienst() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getDienst()).isEqualTo(AbsenderTestFactory.DIENST); + } + + @Test + void shouldSetGemeindeschluessel() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getGemeindeschluessel().getSchluessel()).isEqualTo(AbsenderTestFactory.GEMEINDE_SCHLUESSEL); + } + + @Test + void shouldSetPostkorbId() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getPostkorbId()).isEqualTo(AbsenderTestFactory.ABSENDER_POSTKORB_ID); + } + + @Test + void shouldSetGemeindeschluesselTabelle() { + var result = mapToNachrichtenKopf().getAbsender(); + + assertThat(result.getGemeindeschluessel().getTabelle()).isEqualTo(BayernIdMessageMapper.TABELLE_NUMMER_GEMEINDE_SCHLUESSEL); + } + + } + + private NachrichtenKopfType mapToNachrichtenKopf() { + var bspNachricht = mapToBspNachricht(); + assertThat(bspNachricht.getNachrichtenKopf()).isNotNull(); + return bspNachricht.getNachrichtenKopf(); + } + } + + @Nested + class TestNachrichtenInhalt { + + @Test + void shouldSetBetreff() { + var result = mapToNachrichtenInhalt(); + + assertThat(result.getBetreff()).isEqualTo(BayernIdMessageTestFactory.SUBJECT); + } + + @Test + void shouldSetStorkQaaLevel() { + var result = mapToNachrichtenInhalt(); + + assertThat(result.getStorkQaaLevel().name()).isEqualTo(BayernIdMessageTestFactory.STORK_QAA_LEVEL); + } + + @Test + void shouldSetVorgangsId() { + var result = mapToNachrichtenInhalt(); + + assertThat(result.getZuVorgang().getVorgangsId()).isEqualTo(BayernIdMessageTestFactory.VORGANG_ID); + } + + @Nested + class TestMapFreiText { + + @Test + void shouldSetEncodingSchluessel() { + var result = mapToFreiText(); + + assertThat(result.getEncoding().getSchluessel()).isEqualTo(BayernIdMessageMapper.TEXT_ENCODING_PLAIN_TEXT); + } + + @Test + void shouldSetEncodingTabelle() { + var result = mapToFreiText(); + + assertThat(result.getEncoding().getTabelle()).isEqualTo(BayernIdMessageMapper.TABELLE_NUMMER_TEXT_ENCODING); + } + + @Test + void shouldSetText() { + var result = mapToFreiText(); + + assertThat(result.getText()).isEqualTo(BayernIdMessageTestFactory.TEXT); + } + + private FreiTextType mapToFreiText() { + var bspNachricht = mapToBspNachricht(); + assertThat(bspNachricht.getNachrichtenInhalt().getFreiText()).isNotNull(); + return bspNachricht.getNachrichtenInhalt().getFreiText(); + } + } + + @Nested + class TestMapAttachments { + + @Test + void shouldSetName() { + var result = mapToDataContainerType(); + + assertThat(result.get(0).getFileName()).isEqualTo(AttachmentTestFactory.FILE_NAME); + } + + @Test + void shouldSetFileType() { + var result = mapToDataContainerType(); + + assertThat(result.get(0).getFileType().getSchluessel()).isEqualTo(AttachmentTestFactory.TYPE); + } + + @Test + void shouldSetFielTypeTable() { + var result = mapToDataContainerType(); + + assertThat(result.get(0).getFileType().getTabelle()).isEqualTo(BayernIdMessageMapper.TABELLE_NUMMER_MIME_TYPE); + } + + @Test + void shouldSetInhalt() { + var result = mapToDataContainerType(); + + var attachmentInputStream = result.get(0); + assertThat(attachmentInputStream.getInhalt()).isEqualTo(AttachmentTestFactory.CONTENT); + } + + @SneakyThrows + @Test + void shouldCloseSourceStream() { + var inputStream = spy(new ByteArrayInputStream(AttachmentTestFactory.CONTENT)); + + var r1 = mapper.toDataContainerType(AttachmentTestFactory.createBuilder().content(inputStream).build()); + + verify(inputStream).close(); + } + + private List<DataContainerType> mapToDataContainerType() { + return mapToNachrichtenInhalt().getDataContainer(); + } + } + + private NachrichtenInhaltType mapToNachrichtenInhalt() { + var bspNachricht = mapToBspNachricht(); + assertThat(bspNachricht.getNachrichtenInhalt()).isNotNull(); + return bspNachricht.getNachrichtenInhalt(); + } + } + + private BspNachricht mapToBspNachricht() { + return mapper.toBspNachricht(BayernIdMessageTestFactory.create()); + } + } + + @Nested + class TestMapToBayernIdResponse { + + @Test + void shouldSetSuccess() { + var result = mapToBayernIdResponse(); + + assertThat(result.isSuccess()).isTrue(); + } + + @Test + void shouldSetStatus() { + var result = mapToBayernIdResponse(); + + assertThat(result.getStatus()).isEqualTo(BspQuitungTestFactory.STATUS_SCHLUESSEL); + } + + @Test + void shouldSetMessage() { + var result = mapToBayernIdResponse(); + + assertThat(result.getMessage()).isEqualTo(BspQuitungTestFactory.ERGAENZENDE_HINWEISE); + } + + private BayernIdResponse mapToBayernIdResponse() { + return mapper.toBayernIdResponse(BspQuitungTestFactory.create()); + } + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageTestFactory.java new file mode 100644 index 0000000..a9de0cb --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdMessageTestFactory.java @@ -0,0 +1,57 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import java.util.Collections; +import java.util.List; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.message.BayernIdMessage.BayernIdMessageBuilder; + +public class BayernIdMessageTestFactory { + + public static final String MESSAGE_ID = "messageId"; + public static final String CREATED_AT = "2021-01-01T00:00:00Z"; + public static final String VORGANG_ID = "vorgangId"; + public static final String SUBJECT = "subject"; + public static final String STORK_QAA_LEVEL = "LEVEL_1"; + public static final String TEXT = "text"; + + public static BayernIdMessage create() { + return createBuilder().build(); + } + + public static BayernIdMessageBuilder createBuilder() { + return BayernIdMessage.builder() + .messageId(MESSAGE_ID) + .createdAt(CREATED_AT) + .vorgangId(VORGANG_ID) + .subject(SUBJECT) + .storkQaaLevel(STORK_QAA_LEVEL) + .text(TEXT) + .empfaenger(EmpfaengerTestFactory.create()) + .absender(AbsenderTestFactory.create()) + .attachments(List.of(AttachmentTestFactory.create())); + } + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandExecutedEventTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdRsponseTestFactory.java similarity index 77% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandExecutedEventTestFactory.java rename to nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdRsponseTestFactory.java index a7a1ec1..a66934b 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandExecutedEventTestFactory.java +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BayernIdRsponseTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.nachrichten.postfach.bayernid.proxy.message; -public class CommandExecutedEventTestFactory { +public class BayernIdRsponseTestFactory { - public static CommandExecutedEvent createFor(Command command) { - return new CommandExecutedEvent(command.getId()); - } } diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BspQuitungTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BspQuitungTestFactory.java new file mode 100644 index 0000000..a526db4 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/BspQuitungTestFactory.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.akdb.egov.bsp.nachrichten.SchluesseltabelleType; + +public class BspQuitungTestFactory { + + public static final String STATUS_SCHLUESSEL = "OK"; + public static final String ERGAENZENDE_HINWEISE = "Hinweis"; + + public static BspQuittung create() { + var statusTable = new SchluesseltabelleType(); + statusTable.setSchluessel(STATUS_SCHLUESSEL); + var quittung = new BspQuittung(); + quittung.setAnnahmeErfolgreich(true); + quittung.setErgebnisStatus(statusTable); + quittung.setErgaenzendeHinweise(ERGAENZENDE_HINWEISE); + return quittung; + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/EmpfaengerTestFactory.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/EmpfaengerTestFactory.java new file mode 100644 index 0000000..ce10fb2 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/message/EmpfaengerTestFactory.java @@ -0,0 +1,42 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.message; + +public class EmpfaengerTestFactory { + + public static final String POSTKORB_ID = "postfachId"; + public static final String NAME = "name"; + public static final String ANSCHRIFT = "anschrift"; + + public static Empfaenger create() { + return createBuilder().build(); + } + + public static Empfaenger.EmpfaengerBuilder createBuilder() { + return Empfaenger.builder() + .postkorbId(POSTKORB_ID) + .name(NAME) + .anschrift(ANSCHRIFT); + } +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/BayernIdResponse.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/BayernIdResponse.java new file mode 100644 index 0000000..7e580ef --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/BayernIdResponse.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.mock; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class BayernIdResponse { + + private boolean success; + private String status; + private String message; + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/GrpcBayernIdProxyTestClient.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/GrpcBayernIdProxyTestClient.java new file mode 100644 index 0000000..1437784 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/GrpcBayernIdProxyTestClient.java @@ -0,0 +1,56 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.mock; + +import java.io.InputStream; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.tuple.Pair; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.BayernIdProxyServiceGrpc; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachmentMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +@RequiredArgsConstructor +public class GrpcBayernIdProxyTestClient { + + static final int CHUNK_SIZE = 255 * 1024; + + private final BayernIdProxyServiceGrpc.BayernIdProxyServiceStub serviceStub; + + @SneakyThrows + public BayernIdResponse sendMessage(GrpcBayernIdMessageMetadata messageMetadata, Set<Pair<GrpcAttachmentMetadata, InputStream>> attachments) throws + ExecutionException { + var streamer = new MockChunkedDataStreamer(messageMetadata, attachments, CHUNK_SIZE); + var future = new CompletableFuture<BayernIdResponse>(); + serviceStub.sendMessageAsStream(new MockBayernIdSendStreamObserver(future, streamer)); + return future.get(10, TimeUnit.SECONDS); + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdInitializer.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdInitializer.java new file mode 100644 index 0000000..b878396 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdInitializer.java @@ -0,0 +1,88 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.mock; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; + +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class MockBayernIdInitializer { + + private static final String RESPONSE_TEMPLATE = """ + <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> + <SOAP-ENV:Header/> + <SOAP-ENV:Body> + <ns2:sendBspNachrichtNativeOutput xmlns:ns2="urn:akdb:bsp:postkorb:komm:webservice"> + <bspQuittung>%s</bspQuittung> + </ns2:sendBspNachrichtNativeOutput> + </SOAP-ENV:Body> + </SOAP-ENV:Envelope> + """; + public static final String BSP_NACHRICHT_SUCCESS = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><BspQuittung version=\"1.5\" fassung=\"2020-03-15\" xmlns=\"http://www.akdb.de/egov/bsp/nachrichten\"><AnnahmeErfolgreich>true</AnnahmeErfolgreich><ErgebnisStatus><Tabelle>9006</Tabelle><Schluessel>0</Schluessel></ErgebnisStatus><ErgaenzendeHinweise>Nachricht wurde angenommen</ErgaenzendeHinweise></BspQuittung>"; + public static final String BSP_NACHRICHT_ERROR = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><BspQuittung version=\"1.5\" fassung=\"2020-03-15\" xmlns=\"http://www.akdb.de/egov/bsp/nachrichten\"><AnnahmeErfolgreich>false</AnnahmeErfolgreich><ErgebnisStatus><Tabelle>9006</Tabelle><Schluessel>31</Schluessel></ErgebnisStatus><ErgaenzendeHinweise>Unzulässiger Nachrichteninhalt</ErgaenzendeHinweise></BspQuittung>"; + + public final WireMockRuntimeInfo wmRuntimeInfo; + + public void createResponseOk() { + wmRuntimeInfo.getWireMock().register( + post("/").willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "text/xml") + .withHeader("charset", "UTF-8") + .withBody(RESPONSE_TEMPLATE.formatted(BSP_NACHRICHT_SUCCESS)) + )); + } + + public void createResponseError() { + wmRuntimeInfo.getWireMock().register( + post("/").willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "text/xml") + .withHeader("charset", "UTF-8") + .withBody(RESPONSE_TEMPLATE.formatted(BSP_NACHRICHT_ERROR)) + )); + } + + public void createResponseWithException() { + wmRuntimeInfo.getWireMock().register( + post("/").willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "text/xml") + .withHeader("charset", "UTF-8") + .withBody("Internal Server Error") + )); + } + + public void create500Response() { + wmRuntimeInfo.getWireMock().register( + post("/").willReturn(aResponse() + .withStatus(500) + .withBody("Internal Server Error") + )); + } + +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdSendStreamObserver.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdSendStreamObserver.java new file mode 100644 index 0000000..2421367 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockBayernIdSendStreamObserver.java @@ -0,0 +1,68 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.mock; + +import java.util.concurrent.CompletableFuture; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import io.grpc.stub.ClientCallStreamObserver; +import io.grpc.stub.ClientResponseObserver; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +class MockBayernIdSendStreamObserver implements ClientResponseObserver<GrpcSendBayernIdMessageRequest, GrpcSendBayernIdMessageResponse> { + + private final CompletableFuture<BayernIdResponse> fileIdFuture; + private final MockChunkedDataStreamer fileStreamer; + + @Getter + private BayernIdResponse bayernIdResponse; + + private ClientCallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @Override + public void beforeStart(ClientCallStreamObserver<GrpcSendBayernIdMessageRequest> requestStream) { + this.requestObserver = requestStream; + requestObserver.setOnReadyHandler(() -> fileStreamer.sendChunkedTo(requestObserver)); + } + + @Override + public void onNext(GrpcSendBayernIdMessageResponse response) { + bayernIdResponse = BayernIdResponse.builder().success(response.getSuccess()).message(response.getMessage()).status(response.getStatus()) + .build(); + } + + @Override + public void onError(Throwable t) { + fileIdFuture.completeExceptionally(t); + } + + @Override + public void onCompleted() { + fileIdFuture.complete(bayernIdResponse); + } +} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockChunkedDataStreamer.java b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockChunkedDataStreamer.java new file mode 100644 index 0000000..3ecf223 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/proxy/mock/MockChunkedDataStreamer.java @@ -0,0 +1,126 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy.mock; + +import static java.util.Objects.*; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.Pair; + +import com.google.protobuf.ByteString; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachmentMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachments; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import io.grpc.stub.CallStreamObserver; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +class MockChunkedDataStreamer { + + private Set<Pair<GrpcAttachmentMetadata, InputStream>> attachments; + private final int chunkSize; + private boolean isFinished = false; + private GrpcBayernIdMessageMetadata messageMetadata; + + public MockChunkedDataStreamer(GrpcBayernIdMessageMetadata metadata, Set<Pair<GrpcAttachmentMetadata, InputStream>> attachments, int chunkSize) { + this.messageMetadata = metadata; + this.attachments = attachments; + this.chunkSize = chunkSize; + } + + public synchronized void sendChunkedTo(CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + if (isFinished) { + return; + } + sendMessageMetadata(streamObserver); + attachments.forEach(attachment -> { + sendAttachmentMetadata(attachment.getLeft(), streamObserver); + sendContentChunked(attachment.getRight(), streamObserver); + }); + handleFileEndReached(streamObserver); + } + + void sendContentChunked(InputStream contentStream, CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + var inProgerss = true; + do { + int size = sendNextChunk(contentStream, streamObserver); + if (size < chunkSize) { + sendNextChunk(contentStream, streamObserver); + inProgerss = false; + } + } while (inProgerss && streamObserver.isReady()); + IOUtils.closeQuietly(contentStream); + } + + void sendMessageMetadata(CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + if (nonNull(messageMetadata)) { + streamObserver.onNext(buildRequestWithMetadata(messageMetadata)); + messageMetadata = null; + } + } + + GrpcSendBayernIdMessageRequest buildRequestWithMetadata(GrpcBayernIdMessageMetadata metadata) { + return GrpcSendBayernIdMessageRequest.newBuilder().setMessageMetadata(metadata).build(); + } + + void sendAttachmentMetadata(GrpcAttachmentMetadata metadata, CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + streamObserver.onNext(buildRequestWithAttachmentMetadata(metadata)); + } + + GrpcSendBayernIdMessageRequest buildRequestWithAttachmentMetadata(GrpcAttachmentMetadata attachmentMetadata) { + return GrpcSendBayernIdMessageRequest.newBuilder() + .setAttachments(GrpcAttachments.newBuilder().setAttachmentMetadata(attachmentMetadata).build()).build(); + } + + private int sendNextChunk(InputStream contentStream, CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + try { + var content = contentStream.readNBytes(chunkSize); + var size = content.length; + if (size > 0) { + streamObserver.onNext(buildRequestWithContent(content)); + } + return size; + } catch (IOException e) { + throw new TechnicalException("Error on sending a single chunk", e); + } + } + + GrpcSendBayernIdMessageRequest buildRequestWithContent(byte[] bytes) { + return GrpcSendBayernIdMessageRequest.newBuilder().setAttachments(GrpcAttachments.newBuilder().setContent(ByteString.copyFrom(bytes)).build()) + .build(); + } + + synchronized void handleFileEndReached(CallStreamObserver<GrpcSendBayernIdMessageRequest> streamObserver) { + isFinished = true; + streamObserver.onCompleted(); + } + +} diff --git a/pluto-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 100% rename from pluto-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/application-itcase.yml b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/application-itcase.yml new file mode 100644 index 0000000..d4d2417 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/application-itcase.yml @@ -0,0 +1,10 @@ +logging: + level: + ROOT: INFO + '[org.springframework]': WARN + '[de.ozgcloud]': INFO + config: classpath:log4j2-local.xml + +grpc: + server: + port: -1 diff --git a/pluto-server/src/test/resources/junit-platform.properties b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/junit-platform.properties similarity index 100% rename from pluto-server/src/test/resources/junit-platform.properties rename to nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/junit-platform.properties diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.pdf b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..184dd5915515ca49dfaa8840883e6259d2a667aa GIT binary patch literal 5705 zcmY!laB<T$)HCH$UA216S}sEc1BLvgEG`=xF8z?qlAKfp4P8wxednUo#FG3X1r5i7 z#N>=r1vmcyg|O73;>`R!1tUFkO)mX_qWqN7<Wzi0z=mYz=eZ=7q$+5*SQ!}@85<fI zni^ObnHm{JX>!@wai!*^fUGw{I72}}-%r7qOF=>3Cp9m<BtyYi!9XDh#COZgDM>9- z(09v8EJ<}qP0mkA1sPFXQk0sQ%T+Pw?acImkVvtH_tkTSdGGp8UU<@TQ45>Oa}~!; zD;&xvXD&SH7?@JP;wB*I*`=_kfw_;*(JfH$XoH5vf<=DH%?(C;eM(wd-jDlluKl@j zYiRWE^xuCf-mfn9-&_1{b@bPLtJoWO4ChUq!1J1U!U5lhKdo*XHZ?g*%wT8W_GsYH zV30lM<+tVQw{Hxq6<4s<cYjZ25W4gJHOIB$^Ai_!+r5yGn_XD>r)*K>>HDw$t9HC$ z(UWHA*mi1Tj-OHX)bh1OCf1F*C(d(O*s2<`GTf-1nz`pHWB5$n2Oary6d$a}kJ%IU z_<8pJQ^y$&2ra%QQ6F_cFx%&)n1S}J=?o1e|FiaTX;0k#t0vP?|7gDPn${Hw_B|SW z(+_j|KinYsKTZ38<)2{vkWa5p|6gzZL;kzqoVod5t`)uYarkm-f6?vJj0yYL7y^HV z`#t4gcw);?^6lT$ZVN_-a7~6u=Ob3`*^+Ph<klMo{u2#sOB!qf*rXiTC76N}7;_qw z3z*{$@Ut|pZD3vG$n>DGWCC+pGgAPI*FnVq-d7IF8Em-^bY3ut9}q2&y~FnXfW{1l z8Ux<AM%E8<I?e(ujUED`lbS>nLOrC7T4qcTeZo=curI(sgw544Mnm*e<2MJ_0Lc*E ztIlUH_+O}e!BrwG)h6dS`GU+B^)H-m2V7>boj#bgLGDaTZesZj{(DUB2R#eK=J3C7 z*M7+M!{iQUd}IFM#Rl?qtolj}O$`f_MFg!l)DFo#Y~^rtQL5;e+u`KGx`^>&+Y3h? zg?Gw7Ix3I2t4Mje8cneB;9kOgN&cjhnqs+9_r$9wf=~FR*nhGs6584Dr%P#JO5iPx z;wjo%9HOmW?xG8{0(@8ST`|3)ktOw2uGj7I#a9`@Tez(xWV_F~i7)P7aQou)i-%um zeo<m;o_HuDS;sJLMu894GKSz*%if(Wk_UZ~?GiX6Sl1|C<CJcCn)G>t=nb(P{W2Eo z=GbGMk3tHcS?J41Pw&(|X!@wCpuF(%j?_I8akBZH-wz*uRQ_1|WA2aaAL>80voJY! zCb)f2JR(pgsKuGiVa_qRrQd}susg$_M|GLdcVT}aePMaQ`;$CWOegVbwoGxl<)5V% zt7@xUE3mNZMc0n54X#D5SuR$tZZ2_?3sXWj=~il6cE>o{x$pCyCw{bZRp+hlw(fT# zYXxoft@L(jxQQAId=~N+&=$)U+^uQmeK6pPMxTh8>inWPMN^GjT?3}B{1zfs%D;7D zRj-w=^W`g<>$XHh3BGl|C6MblM=4K5PGO#6oN`^@9Dnx<S6{6AQc=bESEsh;pQn@G zp|B?9jsA;#lU$NKgWN8;O;V23xT$BU_0zLU@u`NWda1)I?^i2Lf}*@{xm(5lTJgp7 zWu@e-o>m_3WdYCDoJo$12=l%cZWjG*$D0Lj7R}i+XLHP=n5lO{cUD&J+S6OJre<f& z`ag4+LJxW=x-E=(IO&jgo5kU2g6CJHd@&XiNfnJ12^M`V+AcDE>XoT~rhb}oYwA3$ z$5UsXnt1BzsoGQAT3lN5v@EsOYW0T}uJXB>arN*j=2hNVud*7ms;}<4l6F<~YV6g` zSE8@Z&zNAc#&nX2l!;u%BGZ|(3TL^Syw5xsbu8*)lxbA?*2G-lw-RraZykOe@cPWP z!t17Mq^~Q!y76ks%Pp^bUR^4+E%{usyCnYg$``FKWG_fx_`NEBjr{uiE9?^;3=51; z7{4(5aXH}hgw%-S9|^XZdoTaG^Y!lQ`x2Sbg*|;zwkFG@s-@nWzBB%pl$3SIIMaBh zai}4$@mf>a^h-1Dok@DeYdmG<+{kq|SvU7TQ+uZQEdA{N4Hq_cY|hv?<L-iejhh!1 z9-gvvQtFP>y{h-S5=GNW&vfOl&5+HzoACFJ+s(Gz%PGdmt23put8abVI(MJ!`E`f$ zPTspy*Zwz^y`_1x^TNXul#gD#zwy?`nUg04PYGUqxoPvp;%%Q(#iw-dKFv72Fx)bH zTK4AGO|w_t=G$IZzUa5w_pI;F<)Y+l`sMs@Tt54G!Sl(ztE6{I@7~ieef4$6^~>+Q zy61Us|BnT=dup?4;(kc|c=m%YXHnj*Z7WkRSKC|f7uwHR&-*{*|2~EyhYW|}13?R% z6CxGtJ@hl&FT727`C!I_cLF{h4j#cL9;F>W+ivFHF4Zp9(w7@}f6~UM&%$1={TQvE zr<~7yzf6xuR7~QU&^OCF+Itjh3=f$uGD~VqJ#TfU>gcw_>6@QhOq*kL&Syz#O5~HA zDXCWuuGpFJ`bF1^pAx@kyqaOYQEy}EM(@J7LiNXCkC-3d7T&;_$oYJyNS@60`rUuN z^}IdYd8?DP^N-5sCC;AQHsx`_MpO2v?zC>*_G_Y?&sC4VdZk8ZwbrV=b*^&wwUcKf zPu{VFWns_uotde#e2wtU6FFgJ@qJ0>-px5FyUqGlxs$bW*|(=!&!0W_dtY>~G|RlM z{LVY;%3qbKmG8f?ynA_a`sw>q?Z3|bT)vi7iFHrY$Gu|JulKpv$$$QPVc*x^tG?Ch zrikCux}?8K<5$cXt$kmc5Asj7U-PE_j(tc{P|+5V*i*W))(N!_LS{xphTXj4c)oe= z)1FU<K9#p`lid}W7!p`6QE&0pVE?7Xn|6CGUA5&^acRldjNVw^>a{s<_uX2m{6<;X zJ-2V$)st66uhv?L6~9T`TU?vo9OZnp@XN<7kM*UPrP%!p{7uX~%|%UXEl=8>w0~N? zYX8kGJ9oNnTe?Iv&o_6jwQSX|d;NU&W!qnFxw`%G?e238#w*j~{)v3Md?WJv=Gx~o zp5Lkq`@3^n^R2)eoTX`HdL^#qA9pwJZa=?!?)%ppU%dR``hEIjaS{D1F(UgTE_J^@ z`#yH(l+w(PMUS5T)D8?^_G{Z$-x%IqzZTqIUjJg&@2%3;=dO#F-5|T8<nX6st+St* zpTD1U@71o{qTR(8DmFas`#85xaq_}*yO)*ken0c>Ysq^CcdV0ai=OT~{P#6~jQkzB zyB1b9&+NYy*p$rqKjCk|x4=J(&HFFQ>HEK_YN`tQ5%MMTsPWBo-u+qsZk;oK7(b_E zhD^=Amp_k)WWTzae{z5AymR%ARe^?!4KCYcTT~~W%Y1k5^jZDo@v8fx=IQ^4ee?a+ zb*c6B{|-OvKiImU^`-e9bM1Pu{Zp%|Kh3?kd!Ot3qv`L3@9FD{)=l_T@Jjjf;{(eN z_#2;oIp1);_Wq2zmp@<q`+Cyr(5bEqtSx#9C5#KXIbt1NFgb|}>}o(4`e9$zxb?rq z>PCT>zJBHh(|H??%QCE5#Td}d(jYVI&`A%$HAUNvBW?>DR~iOh)O;<m@}!KLO8?=` z^CD~hGGDJ2<^whPpiMSt;}6up12+Oq%#A>@Ahrp#K^U#?>Fn&3Se%-o0BR!!#ljSr zLKWE9fSQIOl?AB^`o5_pi7AOCi6D{S(xeiwV1%y^h!1T{nt>aWc6MA)C)n6m6eK2R zr<N!rrKV@**($x?y<bToGsRXZ+|<{=x4=0yBh#a*C^fjsFC@7tJJ~Wt$==SU!m1*- zAUCxnQK2F?C$HG5!d59UB|j<EDzDfIB&@Gw$7NHLl4cd;;s#Yxl#*tvlu=SrV5P5L zUS6(OZmgGIl&)`RX=$l%V5Dzkq+67drdwQ@SCUwvn^&w1Gr=XbIJqdZpaj(NhFF%8 z3^%Btv?vE`OiHqTYEEiyYF<gPzM-C>zLEmS_Qa(8(h^%GkWnegR%!V~xrrrqi3J5Y znaPPD1N941(rok*Qd~AE$yOzxUVxo0SRBFz3+E)}rI#kAr`lEMmgZ&W<(KDyRltS8 zic%6wQtd#^d|g8$T|?6l0}Cr7Q!69GD6m?vESHTw$Z1I4f(8|m2sFqFkb*3)SPvY+ zddc~@AZP0v>KSADvLGeR3f3{P!`^kV0qI64;<5qjadCt8ZtM*8Orc5;VkEe^BDVk@ zJ1B0hNG#Ad)HA?zb46}}6}YFAUlfv`pM%rc=<2v^Kq9at59(v#2zd-;5S?H<Qwiup zQiL@Sz;PMm;%3KXqYuv%c8E-snwMg$RHS5Y#|6r_&^!mt_Mof?%IX&8#vn-$(;S|u z;k`c#P=-~|$I|yxK;+_zIdj8q=iPD;sC};eY~$2ZY5L#R&E3A>!t5zwf-CqnLsJqA z!rm_3c-?pE`u93BIC7j`HyoI@xBA>nWAWdK3JsUbU+@PiM2H;Spuxs}wv=&Un$@)5 z%y%D6;B&it@MtxoQp3wv0*)MF(uXalmn?61pT95nl*z`-)X7Zu|24dPez2m7L9gSY zhUasZKlc~NXYW38L~MqB_UwD!dZN?s*gU>3XK=xP^9u1lo1g8{*kIGS>-t^k-Ku*J zly<7#i?^JvbB#4Be6K)jn2)?sr&#bACb`S%T;(p|*QR<#S)Tb^f8>IA<)ebB5fZ99 ztE(7i)!C#dUD&(lr<2%}n@Mjk%+nBMHA?APT^!V!v)f?(1RndfMqLu&9~s}g6^s?w zutEK9>7!SVWUgx)xE^>hYki@>!=(?VYqiY&c-K?x>Ez5Rp`Hs<cSOyd{Fm!WVcK?I zljEn(h6wD?S=!WYw|2F{B%OCBt&iHji_uu$FehNLQ`eXG9~QM7KDQ`A?^L<<K4uQl zjUEB1+^J;(^RNA`oe;|RY=&d5cEu|09f!~SUG>(V{jN{3!zRJK6EiZ83(37M>Xh9V zVDwJa{mQv$yI1E^+gkP;-`CqLlDKKA&%~VSLmT;e_&V>ppIf|a9_Ql<DW`c?_+qX5 z)t^O(+ll#9hwl*ceVTf%(zci@&nZM@=PQA#^+Nfkk~@@`Up`sMW+c+RcWLL_Nt}*9 zzvTp(JbtQHyg_SX%X5<yj%Uu6!D=%!Q!kViYfMSF#GIi#Z*s?ntIuX0eaLa$c&VxC zW0um4sK&T_W@-NXNjmqJ3Y<9RJ8{RFs5K`UyHneiCU4lRvhiJ^^VMyekN%qJAsyE1 z_&9O;r2?^^S7rv7UlbCpUbuG2v%SYJOpVRg);!95;kNRFXQBsPOnxO_t_tnw=g`pf zkrqCFN<v}#qZ7fdzw1t)Xb$TM`kAVtIbqjk=Plywlfqi&{C*x?ZTRQj4ZdC9dY{X? zx$SMa=kiC~_PI?YD1V@49#FOb=NMx%kR*s{3C}#B`YtH7IKQ+gIki~9&;XQ$Kw^+u zG9WQM6~yyRP037j%CAs}1}QMLG}SXQH&w7OG1RlLu#5$%a4yO(z^lM1Cp9$%uZobO z%v`(*0uqZ-^GXy9K?70XQ6A^~yb@47rT{7of<Oa2(DK3%)Bpf^6uHWG%g-wTITc>r zgZyX+5&<<DK(Y$@9;rEHsU?}o;C6v)UUGg)W?s62et2e{V_tD4OaR#?kYgY=Dd>X? zRL}<nS}~WtbABnvv0VDznJL8z(V!p?QiuhWL@-Cf8Z*d_bWSWu%*js&xe9C!l5c$y z^U@VG;B~4dNDZt^R{*tfz+nQ?<&&6{np3P`2x=Lj1PdtkAdUrT27B4YMnT`rPyrlb zK_J&DDCh?i<tGQHmMBE)2e`N?=zHcSrl&eVX=erfkkpD2NTlcI<QD}OBqpaSfQ)fT zO-n4zDG73SQUKcwG7T|q2X+m_as_?A(%fQDVghLkR?v4*u(LxBnu?;-G%f=LLsKpT zI8ZP%H8nO>NK=4|8Ja49Wfk(^Vuq#$=we3Z2IiPzMp(qmF!UOm8yTVNH8wXfL>DtL zHN_%kj$xjufw?h;UP}WEbtdMPCYb6>Ez!kH4J|DYVkJe1nK`LNpaEJ11^uA>{1OF2 zP#OcL3(vf?d<9Tqh45SyqHQb<&0O7_Ow5gpot@0gUCoSK%-oFKOdU;J3{9MjOfBpb j2rB`ngW$}nR8VArYuUu25^(gH8krbzsj9mAyKw;kn^5b< literal 0 HcmV?d00001 diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.txt b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.txt new file mode 100644 index 0000000..814be41 --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-impl/src/test/resources/test.txt @@ -0,0 +1 @@ +some simple text \ No newline at end of file diff --git a/pluto-interface/pom.xml b/nachrichten-bayernid-proxy/bayernid-proxy-interface/pom.xml similarity index 53% rename from pluto-interface/pom.xml rename to nachrichten-bayernid-proxy/bayernid-proxy-interface/pom.xml index 838027c..90b8f0d 100644 --- a/pluto-interface/pom.xml +++ b/nachrichten-bayernid-proxy/bayernid-proxy-interface/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,62 +24,34 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-dependencies</artifactId> - <version>1.2.1</version> - <relativePath /> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-dependencies</artifactId> + <version>3.0.1</version> + <relativePath/> </parent> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-interface</artifactId> - <version>1.0.0</version> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>bayernid-proxy-interface</artifactId> + <version>0.1.0</version> - <name>Pluto Interface</name> - <description>Interface (gRPC) for Pluto Server</description> + <name>OZG-Cloud BayernID Proxy Interface</name> + <description>Interface (gRPC) for BayernID Proxy Service</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <java.version>17</java.version> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> - </properties> - <dependencyManagement> - <dependencies> - <dependency> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-dependencies</artifactId> - <version>${kop-common.version}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - </dependencies> - </dependencyManagement> + <find-and-replace-maven-plugin.version>1.1.0</find-and-replace-maven-plugin.version> + </properties> <dependencies> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - </dependency> - - <dependency> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-lib</artifactId> - </dependency> - - <dependency> - <groupId>org.projectlombok</groupId> - <artifactId>lombok</artifactId> - <optional>true</optional> - </dependency> - <!-- GRPC --> <dependency> <groupId>io.grpc</groupId> @@ -89,24 +61,13 @@ <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> </dependency> - - <!-- Java 9+ compatibility --> <dependency> - <groupId>javax.annotation</groupId> - <artifactId>javax.annotation-api</artifactId> + <groupId>jakarta.annotation</groupId> + <artifactId>jakarta.annotation-api</artifactId> </dependency> - - </dependencies> <build> - <extensions> - <extension> - <groupId>kr.motd.maven</groupId> - <artifactId>os-maven-plugin</artifactId> - </extension> - </extensions> - <plugins> <plugin> <groupId>com.github.os72</groupId> @@ -119,32 +80,42 @@ <goal>run</goal> </goals> <configuration> + <includeMavenTypes>direct</includeMavenTypes> <outputTargets> <outputTarget> <type>java</type> </outputTarget> <outputTarget> <type>grpc-java</type> - <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.47.0</pluginArtifact> + <pluginArtifact>io.grpc:protoc-gen-grpc-java:${protoc-gen.version}</pluginArtifact> </outputTarget> </outputTargets> </configuration> </execution> </executions> </plugin> + <plugin> + <groupId>io.github.floverfelt</groupId> + <artifactId>find-and-replace-maven-plugin</artifactId> + <version>${find-and-replace-maven-plugin.version}</version> + <executions> + <execution> + <id>exec</id> + <phase>process-sources</phase> + <goals> + <goal>find-and-replace</goal> + </goals> + <configuration> + <replacementType>file-contents</replacementType> + <baseDir>target/generated-sources/</baseDir> + <findRegex>javax</findRegex> + <replaceValue>jakarta</replaceValue> + <recursive>true</recursive> + <fileMask>.java</fileMask> + </configuration> + </execution> + </executions> + </plugin> </plugins> </build> - - <distributionManagement> - <repository> - <id>ozg-nexus</id> - <name>ozg-releases</name> - <url>https://nexus.ozg-sh.de/repository/ozg-releases/</url> - </repository> - <snapshotRepository> - <id>ozg-snapshots-nexus</id> - <name>ozg-snapshots</name> - <url>https://nexus.ozg-sh.de/repository/ozg-snapshots/</url> - </snapshotRepository> - </distributionManagement> </project> \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernidproxy.model.proto b/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernidproxy.model.proto new file mode 100644 index 0000000..91ed9ee --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernidproxy.model.proto @@ -0,0 +1,83 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.nachrichten.postfach.bayernid.proxy"; +option java_outer_classname = "BayernIdProxyModelProto"; + +message GrpcSendBayernIdMessageRequest { + oneof request { + GrpcBayernIdMessageMetadata messageMetadata = 1; + GrpcAttachments attachments = 2; + } +} + +message GrpcBayernIdMessageMetadata { + string messageId = 1; + string createdAt = 2; + GrpcAbsender absender = 3; + GrpcEmpfaenger empfaenger = 4; + string subject = 5; + string storkQaaLevel = 6; + string vorgangId = 7; + string text = 8; +} + +message GrpcAbsender { + string name = 1; + string anschrift = 2; + string email = 3; + string telefon = 4; + string hyperlink = 5; + string dienst = 6; + string mandant = 7; + string gemeindeschluessel = 8; +} + +message GrpcEmpfaenger { + string postkorbId = 1; + string name = 2; + string anschrift = 3; +} + +message GrpcAttachments { + oneof request { + GrpcAttachmentMetadata attachmentMetadata = 1; + bytes content = 2; + } +} + +message GrpcAttachmentMetadata { + string fileType = 1; + string fileName = 2; +} + +message GrpcSendBayernIdMessageResponse { + bool success = 1; + string status = 2; + string message = 3; +} diff --git a/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernproxy.proto b/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernproxy.proto new file mode 100644 index 0000000..039909e --- /dev/null +++ b/nachrichten-bayernid-proxy/bayernid-proxy-interface/src/main/protobuf/bayernproxy.proto @@ -0,0 +1,38 @@ +/* + * 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.nachrichten.postfach.bayernid.proxy; + +import "bayernidproxy.model.proto"; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.nachrichten.postfach.bayernid.proxy"; +option java_outer_classname = "BayernIdProxyProto"; + +service BayernIdProxyService { + + rpc SendMessageAsStream(stream GrpcSendBayernIdMessageRequest) returns (GrpcSendBayernIdMessageResponse); + +} diff --git a/nachrichten-bayernid-proxy/pom.xml b/nachrichten-bayernid-proxy/pom.xml new file mode 100644 index 0000000..928e844 --- /dev/null +++ b/nachrichten-bayernid-proxy/pom.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> + <relativePath/> + </parent> + + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>nachrichten-bayernid-proxy</artifactId> + <version>0.1.0</version> + <packaging>pom</packaging> + + <name>OZG-Cloud BayernID Proxy</name> + <description>Proxy Service for BayernID</description> + + <modules> + <module>bayernid-proxy-impl</module> + <module>bayernid-proxy-interface</module> + </modules> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <java.version>17</java.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + <jaxb-maven-plugin.version>4.0.0</jaxb-maven-plugin.version> + <wiremock.version>3.3.1</wiremock.version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/run_helm_test.sh b/nachrichten-bayernid-proxy/run_helm_test.sh new file mode 100755 index 0000000..4bcf613 --- /dev/null +++ b/nachrichten-bayernid-proxy/run_helm_test.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# 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. +# + + +set -e + +helm template ./src/main/helm/ -f src/test/helm-linter-values.yaml +helm lint -f src/test/helm-linter-values.yaml ./src/main/helm/ +cd src/main/helm && helm unittest -f '../../test/helm/*.yaml' . + diff --git a/nachrichten-bayernid-proxy/src/main/helm/.helmignore b/nachrichten-bayernid-proxy/src/main/helm/.helmignore new file mode 100644 index 0000000..3d0dbe4 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/.helmignore @@ -0,0 +1 @@ +tests/ \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/main/helm/Chart.yaml b/nachrichten-bayernid-proxy/src/main/helm/Chart.yaml new file mode 100644 index 0000000..95a5e39 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/Chart.yaml @@ -0,0 +1,30 @@ +# +# 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. +# + +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Bayernid-Proxy +name: bayernid-proxy +version: 0.0.0-MANAGED-BY-JENKINS +icon: https://simpleicons.org/icons/helm.svg diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/_helpers.tpl b/nachrichten-bayernid-proxy/src/main/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0ea6c8d --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/_helpers.tpl @@ -0,0 +1,47 @@ + +{{/* Default Labels: Helm recommended best-practice labels https://helm.sh/docs/chart_best_practices/labels/ */}} +{{- define "app.defaultLabels" }} +app.kubernetes.io/instance: bayernid-proxy +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ .Release.Namespace }} +app.kubernetes.io/part-of: ozgcloud +app.kubernetes.io/version: {{ .Chart.Version }} +helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }} +app.kubernetes.io/component: bayernid-proxy +component: bayernid-proxy +{{- end -}} + +{{- define "app.matchLabels" }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ .Release.Namespace }} +component: bayernid-proxy +{{- end -}} + +{{- define "app.envSpringProfiles" }} +{{- if (.Values.env).overrideSpringProfiles -}} +{{ printf "%s" (.Values.env).overrideSpringProfiles }} +{{- else -}} +{{ printf "oc, %s" (include "app.ozgcloudEnvironment" . ) }} +{{- end -}} +{{- end -}} + +{{- define "app.ozgcloudEnvironment" -}} +{{- required "ozgcloud.environment muss angegeben sein" (.Values.ozgcloud).environment -}} +{{- end -}} + + +{{ define "app.zertifikatPath" }} +{{- required "ozgcloud zertifikat path muss angegeben sein" (.Values.ozgcloud).bayernid.zertifikat.path -}} +{{- end -}} + + +{{ define "app.zertifikatFilename" }} +{{- required "ozgcloud zertifikat fileName muss angegeben sein" (.Values.ozgcloud).bayernid.zertifikat.fileName -}} +{{- end -}} + + +{{- define "app.serviceAccountName" -}} +{{ printf "%s" ( (.Values.serviceAccount).name | default "bayernid-proxy-service-account" ) }} +{{- end -}} + diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/configmap_bindings_type.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/configmap_bindings_type.yaml new file mode 100644 index 0000000..6216704 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/configmap_bindings_type.yaml @@ -0,0 +1,32 @@ +# +# 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. +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: bindings-type + namespace: {{ .Release.Namespace }} +data: + type: | + ca-certificates \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/deployment.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/deployment.yaml new file mode 100644 index 0000000..e78b630 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/deployment.yaml @@ -0,0 +1,166 @@ +# +# 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. +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} +spec: + progressDeadlineSeconds: 600 + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "app.matchLabels" . | indent 6 }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + {{- include "app.defaultLabels" . | indent 8 }} + spec: + {{- if (.Values.serviceAccount).create }} + serviceAccountName: {{ include "app.serviceAccountName" . }} + {{- end }} + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ .Release.Name }} + containers: + - env: + - name: SERVICE_BINDING_ROOT + value: "/bindings" + - name: spring_profiles_active + value: {{ include "app.envSpringProfiles" . }} + + {{- with (.Values.env).customList }} +{{ toYaml . | indent 10 }} + {{- end }} + + - name: ozgcloud_bayernid_server + value: {{ required "ozgcloud.bayernid.server must be set" (.Values.ozgcloud).bayernid.server }} + + - name: spring_ssl_bundle_jks_bayern-id-ca_keystore_location + value: "/keystore/bayernid/bayern-id-ca.p12" + - name: spring_ssl_bundle_jks_bayern-id-ca_keystore_type + value: PKCS12 + - name: spring_ssl_bundle_jks_bayern-id-ca_keystore_password + valueFrom: + secretKeyRef: + name: {{ required "ozgcloud.bayernid.certificateSecretName must be set" ((.Values.ozgcloud).bayernid).certificateSecretName }} + key: password + optional: false + + image: "{{ .Values.image.repo }}/{{ .Values.image.name }}:{{ coalesce (.Values.image).tag "latest" }}" + imagePullPolicy: Always + name: bayernid-proxy + ports: + - containerPort: 9090 + name: grpc-9090 + protocol: TCP + - containerPort: 8081 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + startupProbe: + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + failureThreshold: 10 + initialDelaySeconds: 20 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: + {{- with .Values.resources }} +{{ toYaml . | indent 10 }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: true + {{- with (.Values.securityContext).runAsUser }} + runAsUser: {{ . }} + {{- end }} + {{- with (.Values.securityContext).runAsGroup }} + runAsGroup: {{ . }} + {{- end }} + stdin: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + tty: true + volumeMounts: + - name: bindings + mountPath: "/bindings/ca-certificates/type" + subPath: type + readOnly: true + - name: bayern-id-ca + mountPath: "/keystore/bayernid/bayern-id-ca.p12" + subPath: zertifikat + readOnly: true + - name: temp-dir + mountPath: "/tmp" + + volumes: + - name: bindings + configMap: + name: bindings-type + - name: bayern-id-ca + secret: + secretName: {{ required "ozgcloud.bayernid.certificateSecretName must be set" ((.Values.ozgcloud).bayernid).certificateSecretName }} + optional: false + - name: temp-dir + emptyDir: {} + dnsConfig: {} + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: {{ required "imagePullSecret must be set" .Values.imagePullSecret }} + + restartPolicy: Always + {{- with .Values.hostAliases }} + hostAliases: +{{ toYaml . | indent 8 }} + {{- end }} + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml new file mode 100644 index 0000000..e0effc8 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/network_policy.yaml @@ -0,0 +1,66 @@ +# +# 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. +# + +{{- if not (.Values.networkPolicy).disabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: network-policy-bayernid-proxy + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + component: bayernid-proxy + policyTypes: + - Ingress + - Egress + ingress: + - ports: + - port: 9090 + from: + - podSelector: + matchLabels: + component: vorgang-manager +{{- with (.Values.networkPolicy).additionalIngressConfig }} +{{ toYaml . | indent 2 }} +{{- end }} + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ required "networkPolicy.dnsServerNamespace must be set" (.Values.networkPolicy).dnsServerNamespace }} + ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP +{{- with (.Values.networkPolicy).additionalEgressConfig }} +{{ toYaml . | indent 2 }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/service.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/service.yaml new file mode 100644 index 0000000..082882c --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/service.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +apiVersion: v1 +kind: Service +metadata: + name: {{.Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} +spec: + type: ClusterIP + ports: + - name: grpc-9090 + port: 9090 + protocol: TCP + - name: metrics + port: 8081 + protocol: TCP + selector: + {{- include "app.matchLabels" . | indent 4 }} diff --git a/nachrichten-bayernid-proxy/src/main/helm/templates/service_account.yaml b/nachrichten-bayernid-proxy/src/main/helm/templates/service_account.yaml new file mode 100644 index 0000000..231d53f --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/templates/service_account.yaml @@ -0,0 +1,31 @@ +# +# 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. +# + +{{- if (.Values.serviceAccount).create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "app.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/main/helm/values.yaml b/nachrichten-bayernid-proxy/src/main/helm/values.yaml new file mode 100644 index 0000000..da92066 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/main/helm/values.yaml @@ -0,0 +1,39 @@ +# +# 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. +# + + +replicaCount: 2 + + +image: + repo: docker.ozg-sh.de + name: bayernid-proxy + tag: latest # [default: latest] + + +vorgangmanagerName: vorgang-manager + +imagePullSecret: ozgcloud-image-pull-secret + + diff --git a/nachrichten-bayernid-proxy/src/test/helm-linter-values.yaml b/nachrichten-bayernid-proxy/src/test/helm-linter-values.yaml new file mode 100644 index 0000000..7712c51 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm-linter-values.yaml @@ -0,0 +1,33 @@ +# +# 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. +# + +ozgcloud: + environment: test + bayernid: + server: "https://test" + certificateSecretName: "bayernidCertificat" + +networkPolicy: + dnsServerNamespace: test-dns-namespace + diff --git a/nachrichten-bayernid-proxy/src/test/helm/configmap_bindings_type_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/configmap_bindings_type_test.yaml new file mode 100644 index 0000000..1c592b4 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/configmap_bindings_type_test.yaml @@ -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. +# + +suite: Certificate ConfigMap Binding +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/configmap_bindings_type.yaml +tests: + - it: validate configMap values + asserts: + - isKind: + of: ConfigMap + - equal: + path: metadata.name + value: bindings-type + - equal: + path: metadata.namespace + value: sh-helm-test + - equal: + path: data + value: + type: | + ca-certificates \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_actuator_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_actuator_test.yaml new file mode 100644 index 0000000..f038b3e --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_actuator_test.yaml @@ -0,0 +1,67 @@ +# +# 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. +# + +suite: test deployment actuator +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: testIsDeployment + template: deployment.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe + value: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + - equal: + path: spec.template.spec.containers[0].startupProbe + value: + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + failureThreshold: 10 + initialDelaySeconds: 20 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + + + + diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_bayernid_certificate_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_bayernid_certificate_test.yaml new file mode 100644 index 0000000..70bd21d --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_bayernid_certificate_test.yaml @@ -0,0 +1,114 @@ +# +# 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. +# + +suite: test bayernid certificate +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "https://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should contains bayernid server + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_server + value: "https://test" + + - it: should fail when bayernid server not set + set: + ozgcloud: + environment: dev + bayernid: + server: "" + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.server must be set" + + + - it: should set variable keystore certificate + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_ssl_bundle_jks_bayern-id-ca_keystore_location + value: /keystore/bayernid/bayern-id-ca.p12 + + - it: should set variable keystore type + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_ssl_bundle_jks_bayern-id-ca_keystore_type + value: PKCS12 + + - it: should set variable keystore password secret reference + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_ssl_bundle_jks_bayern-id-ca_keystore_password + valueFrom: + secretKeyRef: + name: bayernidCertificat + key: password + optional: false + + - it: should fail when secret name for bayernid certificat is not set + set: + ozgcloud: + environment: dev + bayernid: + server: "bayernIdServer" + certificateSecretName: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.certificateSecretName must be set" + + - it: should have volumeMount for bayernid certificate keystore + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: bayern-id-ca + mountPath: "/keystore/bayernid/bayern-id-ca.p12" + subPath: zertifikat + readOnly: true + + - it: should have volume for bayernid certificate keystore + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: bayern-id-ca + secret: + secretName: bayernidCertificat + optional: false \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_bindings_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_bindings_test.yaml new file mode 100644 index 0000000..c33535a --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_bindings_test.yaml @@ -0,0 +1,72 @@ +# +# 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. +# + +suite: deployment bayernid-proxy bindings +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should have volumeMounts for temp folder + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: temp-dir + mountPath: "/tmp" + + - it: should have volume for temp folder + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: temp-dir + emptyDir: {} + + - it: should have bindings-type volume + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: bindings + configMap: + name: bindings-type + + - it: should have bindings-type volumeMount + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: bindings + mountPath: "/bindings/ca-certificates/type" + subPath: type + readOnly: true + \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_container_basic_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_basic_test.yaml new file mode 100644 index 0000000..ac4a183 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_basic_test.yaml @@ -0,0 +1,64 @@ +# +# 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. +# + +suite: test deployment container basics +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should have correct values for container image, name, imagePullPolicy + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.ozg-sh.de/bayernid-proxy:latest + - equal: + path: spec.template.spec.containers[0].name + value: bayernid-proxy + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + - it: should have correct values for container ports + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + containerPort: 9090 + name: grpc-9090 + protocol: TCP + - contains: + path: spec.template.spec.containers[0].ports + content: + containerPort: 8081 + name: metrics + protocol: TCP + + diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_container_other_values_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_other_values_test.yaml new file mode 100644 index 0000000..af6154a --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_other_values_test.yaml @@ -0,0 +1,76 @@ +# +# 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. +# + + + # +# Copyright (C) 2022 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. +# + +suite: test deployment container other values +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should have correct values for container terminationMessagePolicy, terminationMessagePath, stdin, tty + asserts: + - equal: + path: spec.template.spec.containers[0].terminationMessagePolicy + value: File + - equal: + path: spec.template.spec.containers[0].terminationMessagePath + value: /dev/termination-log + - equal: + path: spec.template.spec.containers[0].stdin + value: true + - equal: + path: spec.template.spec.containers[0].tty + value: true \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_container_security_context_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_security_context_test.yaml new file mode 100644 index 0000000..8d56527 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_container_security_context_test.yaml @@ -0,0 +1,69 @@ +# +# 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. +# + +suite: test deployment container security context +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: check default values + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.runAsNonRoot + value: true + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsUser + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsGroup + - it: check runAsUser + set: + securityContext.runAsUser: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 1000 + - it: check runAsGroup + set: + securityContext.runAsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsGroup + value: 1000 \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_defaults_labels_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_defaults_labels_test.yaml new file mode 100644 index 0000000..0d8eea9 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_defaults_labels_test.yaml @@ -0,0 +1,75 @@ +# +# 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. +# + +suite: test deployment default labels +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: check metadata.labels + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: bayernid-proxy + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bayernid-proxy + app.kubernetes.io/namespace: sh-helm-test + app.kubernetes.io/part-of: ozgcloud + app.kubernetes.io/version: 0.0.0-MANAGED-BY-JENKINS + helm.sh/chart: bayernid-proxy-0.0.0-MANAGED-BY-JENKINS + app.kubernetes.io/component: bayernid-proxy + component: bayernid-proxy + + - it: should set spec.selector.matchLabels + asserts: + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/name: bayernid-proxy + app.kubernetes.io/namespace: sh-helm-test + component: bayernid-proxy + + - it: should have correct deyploment spec.template.metadata.labels + asserts: + - equal: + path: spec.template.metadata.labels + value: + app.kubernetes.io/instance: bayernid-proxy + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bayernid-proxy + app.kubernetes.io/namespace: sh-helm-test + app.kubernetes.io/part-of: ozgcloud + app.kubernetes.io/version: 0.0.0-MANAGED-BY-JENKINS + helm.sh/chart: bayernid-proxy-0.0.0-MANAGED-BY-JENKINS + app.kubernetes.io/component: bayernid-proxy + component: bayernid-proxy diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_env_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_env_test.yaml new file mode 100644 index 0000000..b633ee6 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_env_test.yaml @@ -0,0 +1,53 @@ +# +# 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. +# + +suite: test deployment container environments +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "https://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: check customList + set: + env.customList: + - name: my_test_environment_name + value: "A test value" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" + + - it: check customList test value is not set by default + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_imagepull_secret_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_imagepull_secret_test.yaml new file mode 100644 index 0000000..c7a633a --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_imagepull_secret_test.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +suite: test deployment image pull secret +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should use correct imagePull secret + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: ozgcloud-image-pull-secret \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_ozgcloud_base_values_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_ozgcloud_base_values_test.yaml new file mode 100644 index 0000000..5f6befa --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_ozgcloud_base_values_test.yaml @@ -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. +# + +suite: test ozgcloud base values +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml + +tests: + + - it: should fail on missing environment + asserts: + - failedTemplate: + errorMessage: ozgcloud.environment muss angegeben sein + - it: should not fail on not missing environment + set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" + asserts: + - notFailedTemplate: {} diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_resources_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_resources_test.yaml new file mode 100644 index 0000000..39bcbe6 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_resources_test.yaml @@ -0,0 +1,63 @@ +# +# 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. +# + +suite: test deployment container resources +release: + name: bayernid-proxy +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should generate resources when values set + set: + resources: + limits: + cpu: 11m + memory: 22Mi + requests: + cpu: 33m + memory: 44Mi + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 11m + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 22Mi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 33m + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 44Mi + - it: should not generate resources when values not set + asserts: + - isEmpty: + path: spec.template.spec.containers[0].resources + diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_service_account_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_service_account_test.yaml new file mode 100644 index 0000000..334d3f7 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_service_account_test.yaml @@ -0,0 +1,57 @@ +# +# 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. +# + +suite: deployment service account +release: + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should use service account with default name + set: + serviceAccount: + create: true + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: bayernid-proxy-service-account + - it: should use service account with name + set: + serviceAccount: + create: true + name: helm-service-account + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: helm-service-account + - it: should use default service account + asserts: + - isNull: + path: spec.template.spec.serviceAccountName \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_springProfile_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_springProfile_test.yaml new file mode 100644 index 0000000..2083807 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_springProfile_test.yaml @@ -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. +# + +suite: test deployment spring profiles +release: + name: bayernid-proxy +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should override spring profiles + set: + env.overrideSpringProfiles: oc,stage,ea + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_profiles_active + value: oc,stage,ea + - it: should generate spring profiles + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_profiles_active + value: oc, dev \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/deployment_template_other_values_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deployment_template_other_values_test.yaml new file mode 100644 index 0000000..5d54017 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deployment_template_other_values_test.yaml @@ -0,0 +1,81 @@ +# +# 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. +# + +suite: test deployment template other values +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" +tests: + - it: should have correct spec.template.spec.topologySpreadConstraints values + asserts: + - contains: + path: spec.template.spec.topologySpreadConstraints + content: + maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: bayernid-proxy + - it: should have correct deployment spec.template.spec.dnsConfig dnsPolicy restartPolicy schedulerName and terminationGracePeriodSeconds values + asserts: + - equal: + path: spec.template.spec.dnsConfig + value: {} + - equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + - equal: + path: spec.template.spec.restartPolicy + value: Always + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 30 + - equal: + path: spec.template.spec.schedulerName + value: default-scheduler + - it: should not generate spec.template.spec.hostAlias when values set + set: + hostAliases: test-alias + asserts: + - equal: + path: spec.template.spec.hostAliases + value: test-alias + + + - it: should not generate spec.template.spec.hostAlias when values not set + asserts: + - isNull: + path: spec.template.spec.hostAliases + + + diff --git a/nachrichten-bayernid-proxy/src/test/helm/deyploment_general_value_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/deyploment_general_value_test.yaml new file mode 100644 index 0000000..8df0a6a --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/deyploment_general_value_test.yaml @@ -0,0 +1,78 @@ +# +# 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. +# + +suite: test deployment general values +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + server: "http://test" + certificateSecretName: "bayernidCertificat" + +tests: + - it: should have correct apiVersion + asserts: + - isKind: + of: Deployment + - isAPIVersion: + of: "apps/v1" + + + - it: should have correct deployment metadata + asserts: + - equal: + path: metadata.name + value: bayernid-proxy + - equal: + path: metadata.namespace + value: sh-helm-test + + + - it: should have correct deyployment general spec values + asserts: + - equal: + path: spec.progressDeadlineSeconds + value: 600 + - equal: + path: spec.replicas + value: 2 + - equal: + path: spec.revisionHistoryLimit + value: 10 + - it: should have correct deployment spec strategy values + asserts: + - equal: + path: spec.strategy + value: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + diff --git a/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml new file mode 100644 index 0000000..7382ad0 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/network_policy_test.yaml @@ -0,0 +1,163 @@ +# +# 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. +# + +suite: network policy test +release: + namespace: by-helm-test +templates: + - templates/network_policy.yaml +tests: + - it: should match apiVersion + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - isAPIVersion: + of: networking.k8s.io/v1 + + - it: should match kind + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - isKind: + of: NetworkPolicy + + - it: should match metadata + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - equal: + path: metadata + value: + name: network-policy-bayernid-proxy + namespace: by-helm-test + + - it: should generate spec + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - equal: + path: spec + value: + podSelector: + matchLabels: + component: bayernid-proxy + policyTypes: + - Ingress + - Egress + ingress: + - ports: + - port: 9090 + from: + - podSelector: + matchLabels: + component: vorgang-manager + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: test-dns-namespace + ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + + - it: add ingress rule by values + set: + networkPolicy: + ssoPublicIp: 51.89.117.53/32 + dnsServerNamespace: test-namespace-dns + additionalIngressConfig: + - from: + - podSelector: + matchLabels: + component: client2 + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + component: client2 + + - it: add egress rules by values + set: + networkPolicy: + additionalEgressConfig: + - to: + - ipBlock: + cidr: 1.2.3.4/32 + - to: + - podSelector: + matchLabels: + component: ozg-testservice + ports: + - port: 12345 + protocol: TCP + + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 1.2.3.4/32 + - contains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: ozg-testservice + ports: + - port: 12345 + protocol: TCP + + - it: test network policy disabled + set: + networkPolicy: + disabled: true + dnsServerNamespace: test-dns-namespace + asserts: + - hasDocuments: + count: 0 + + - it: test network policy unset should be disabled + set: + networkPolicy: + disabled: false + dnsServerNamespace: test-dns-namespace + asserts: + - hasDocuments: + count: 1 \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/service_account_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/service_account_test.yaml new file mode 100644 index 0000000..4156554 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/service_account_test.yaml @@ -0,0 +1,65 @@ +# +# 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. +# + +suite: test service account +release: + namespace: sh-helm-test +templates: + - templates/service_account.yaml +tests: + - it: should create service account with default name + set: + serviceAccount: + create: true + asserts: + - isKind: + of: ServiceAccount + - isAPIVersion: + of: v1 + - equal: + path: metadata.name + value: bayernid-proxy-service-account + - equal: + path: metadata.namespace + value: sh-helm-test + + - it: should create service account with name + set: + serviceAccount: + create: true + name: helm-service-account + asserts: + - isKind: + of: ServiceAccount + - equal: + path: metadata.name + value: helm-service-account + - equal: + path: metadata.namespace + value: sh-helm-test + + - it: should not create service account + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/nachrichten-bayernid-proxy/src/test/helm/service_test.yaml b/nachrichten-bayernid-proxy/src/test/helm/service_test.yaml new file mode 100644 index 0000000..2953b47 --- /dev/null +++ b/nachrichten-bayernid-proxy/src/test/helm/service_test.yaml @@ -0,0 +1,85 @@ +# +# 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. +# + +suite: test service +release: + name: bayernid-proxy + namespace: sh-helm-test +templates: + - templates/service.yaml +tests: + - it: should have the label component with correct value + asserts: + - isKind: + of: Service + - isAPIVersion: + of: v1 + - equal: + path: metadata.labels.component + value: bayernid-proxy + - it: should be of type ClusterIP + asserts: + - equal: + path: spec.type + value: ClusterIP + - it: ports should contain the grpc port + asserts: + - contains: + path: spec.ports + content: + name: grpc-9090 + port: 9090 + protocol: TCP + count: 1 + any: true + - it: ports should contain the metrics port + asserts: + - contains: + path: spec.ports + content: + name: metrics + port: 8081 + protocol: TCP + count: 1 + any: true + - it: selector should contain the component label with correct value + asserts: + - equal: + path: spec.selector.component + value: bayernid-proxy + + - it: selector should contain helm recommended labels name and namespace + asserts: + - equal: + path: spec.selector + value: + app.kubernetes.io/name: bayernid-proxy + app.kubernetes.io/namespace: sh-helm-test + component: bayernid-proxy + + - it: check component label for service + asserts: + - equal: + path: metadata.labels["component"] + value: bayernid-proxy \ No newline at end of file diff --git a/nachrichten-manager/lombok.config b/nachrichten-manager/lombok.config new file mode 100644 index 0000000..81661f0 --- /dev/null +++ b/nachrichten-manager/lombok.config @@ -0,0 +1,30 @@ +# +# 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. +# + +lombok.log.fieldName=LOG +lombok.log.slf4j.flagUsage = ERROR +lombok.log.log4j.flagUsage = ERROR +lombok.data.flagUsage = ERROR +lombok.nonNull.exceptionType = IllegalArgumentException +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/mail-service/pom.xml b/nachrichten-manager/pom.xml similarity index 55% rename from mail-service/pom.xml rename to nachrichten-manager/pom.xml index 89d1ab8..321d637 100644 --- a/mail-service/pom.xml +++ b/nachrichten-manager/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,34 +24,64 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-parent</artifactId> - <version>1.2.1</version> - <relativePath /> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> + <relativePath/> </parent> - <groupId>de.itvsh.ozg.mail</groupId> - <artifactId>mail-service</artifactId> - <version>1.0.0</version> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>nachrichten-manager</artifactId> + <version>2.4.0</version> + <name>OZG-Cloud Nachrichten Manager</name> <properties> <java.version>17</java.version> <!-- TODO version management --> <shedlock.version>4.25.0</shedlock.version> <logcaptor.version>2.7.10</logcaptor.version> + <ozgcloud.license.version>1.6.0</ozgcloud.license.version> + <jaxb-maven-plugin.version>3.0.1</jaxb-maven-plugin.version> + <ozg-info-manager-interface.version>0.1.0-SNAPSHOT</ozg-info-manager-interface.version> + <bayernid-proxy-interface.version>0.1.0</bayernid-proxy-interface.version> </properties> <dependencies> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-interface</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-base</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>bayernid-proxy-interface</artifactId> + <version>${bayernid-proxy-interface.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.info</groupId> + <artifactId>info-manager-interface</artifactId> + <version>${ozg-info-manager-interface.version}</version> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> @@ -74,6 +104,15 @@ <artifactId>spring-boot-starter-validation</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web-services</artifactId> + </dependency> + + <dependency> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-runtime</artifactId> + </dependency> <dependency> <groupId>net.javacrumbs.shedlock</groupId> @@ -107,8 +146,12 @@ <artifactId>commons-lang3</artifactId> </dependency> <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> + <groupId>org.apache.httpcomponents.client5</groupId> + <artifactId>httpclient5</artifactId> + </dependency> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> </dependency> <!-- DEV --> @@ -142,6 +185,13 @@ <version>${logcaptor.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-base</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> </dependencies> <build> @@ -166,6 +216,40 @@ </executions> </plugin> + <plugin> + <groupId>org.jvnet.jaxb</groupId> + <artifactId>jaxb-maven-plugin</artifactId> + <version>${jaxb-maven-plugin.version}</version> + <configuration> + <schemas> + <schema> + <fileset> + <directory>${basedir}/src/main/resources/bayernid</directory> + <includes> + <include>*.wsdl</include> + </includes> + </fileset> + </schema> + <schema> + <fileset> + <directory>${basedir}/src/main/resources/bayernid</directory> + <includes> + <include>*.xsd</include> + </includes> + </fileset> + </schema> + </schemas> + <episode>false</episode> + </configuration> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> @@ -187,6 +271,33 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> + + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <mapping> + <config>SCRIPT_STYLE</config> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/README</exclude> + <exclude>src/test/resources/**</exclude> + <exclude>src/main/resources/**</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> + </plugin> </plugins> </build> @@ -202,4 +313,4 @@ <url>https://nexus.ozg-sh.de/repository/ozg-snapshots/</url> </snapshotRepository> </distributionManagement> -</project> \ No newline at end of file +</project> diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerProperties.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerProperties.java new file mode 100644 index 0000000..5ed6c04 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerProperties.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.Getter; +import lombok.Setter; + +@Configuration +@ConfigurationProperties(prefix = "ozgcloud.nachrichten-manager") +@Setter +@Getter +public class NachrichtenManagerProperties { + + private String url; +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteService.java similarity index 81% rename from mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteService.java index 25dfbcc..099d976 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; import org.springframework.stereotype.Service; -import de.itvsh.ozg.mail.common.grpc.NachrichtenCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.nachrichten.common.grpc.NachrichtenCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; import net.devh.boot.grpc.client.inject.GrpcClient; @Service diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeService.java similarity index 94% rename from mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeService.java index 9715632..4046f7f 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeTestFactory.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeTestFactory.java similarity index 90% rename from mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeTestFactory.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeTestFactory.java index a8a6aa8..2162b80 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/attributes/ClientAttributeTestFactory.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/attributes/ClientAttributeTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; public class ClientAttributeTestFactory { diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/FunctionalException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/FunctionalException.java similarity index 90% rename from mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/FunctionalException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/FunctionalException.java index 8baeb15..08afd94 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/FunctionalException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/FunctionalException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.common.errorhandling; +package de.ozgcloud.nachrichten.common.errorhandling; public class FunctionalException extends RuntimeException { diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/TechnicalException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/TechnicalException.java similarity index 84% rename from mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/TechnicalException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/TechnicalException.java index 4bc6282..0620d84 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/common/errorhandling/TechnicalException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/errorhandling/TechnicalException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.common.errorhandling; +package de.ozgcloud.nachrichten.common.errorhandling; -@Deprecated /** please use {@link de.itvsh.kop.common.errorhandling.TechnicalException} */ +@Deprecated /** please use {@link de.ozgcloud.common.errorhandling.TechnicalException} */ public class TechnicalException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/common/grpc/NachrichtenCallContextAttachingInterceptor.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/grpc/NachrichtenCallContextAttachingInterceptor.java similarity index 87% rename from mail-service/src/main/java/de/itvsh/ozg/mail/common/grpc/NachrichtenCallContextAttachingInterceptor.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/grpc/NachrichtenCallContextAttachingInterceptor.java index d6867de..d94e538 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/common/grpc/NachrichtenCallContextAttachingInterceptor.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/common/grpc/NachrichtenCallContextAttachingInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.common.grpc; +package de.ozgcloud.nachrichten.common.grpc; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; import java.util.UUID; @@ -31,7 +33,6 @@ import io.grpc.ClientCall; import io.grpc.ClientInterceptor; import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; import io.grpc.Metadata; -import io.grpc.Metadata.Key; import io.grpc.MethodDescriptor; public class NachrichtenCallContextAttachingInterceptor implements ClientInterceptor { @@ -40,7 +41,7 @@ public class NachrichtenCallContextAttachingInterceptor implements ClientInterce static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin"; static final String KEY_REQUEST_ID = "REQUEST_ID-bin"; - public static final String NACHRICHTEN_MANAGER_CLIENT_NAME = "KopNachrichtenManager"; + public static final String NACHRICHTEN_MANAGER_CLIENT_NAME = "OzgCloud_NachrichtenManager"; static final String NACHRICHTEN_MANAGER_SENDER_USER_ID = "system-nachrichten_manager-sender"; // <A> = Request, <B> = Response @@ -78,9 +79,4 @@ public class NachrichtenCallContextAttachingInterceptor implements ClientInterce } - // TODO move to common grpc utils - public static Key<byte[]> createKeyOf(String key) { - return Key.of(key, Metadata.BINARY_BYTE_MARSHALLER); - } - } diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/EMailService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EMailService.java similarity index 93% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/EMailService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EMailService.java index 63f0afb..cb67b46 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/EMailService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EMailService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import java.util.Objects; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; - import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; @@ -36,8 +33,10 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.mail.email.MailSendRequest.MailAttachment; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.email.MailSendRequest.MailAttachment; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import lombok.extern.log4j.Log4j2; @Service @@ -92,7 +91,7 @@ class EMailService { return mailRecipient.email(); } var builder = new StringBuilder(); - if (StringUtils.isNotEmpty(mailRecipient.firstName())){ + if (StringUtils.isNotEmpty(mailRecipient.firstName())) { builder.append(mailRecipient.firstName()).append(" "); } if (StringUtils.isNotEmpty(mailRecipient.lastName())) { diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/EmailGrpcService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EmailGrpcService.java similarity index 90% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/EmailGrpcService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EmailGrpcService.java index e11c6f4..f984bbe 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/EmailGrpcService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/EmailGrpcService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; + +import java.util.List; -import de.itvsh.ozg.mail.email.MailSendRequest.MailSendRequestBuilder; -import io.grpc.stub.StreamObserver; -import net.devh.boot.grpc.server.service.GrpcService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import java.util.List; +import de.ozgcloud.nachrichten.email.MailSendRequest.MailSendRequestBuilder; +import io.grpc.stub.StreamObserver; +import net.devh.boot.grpc.server.service.GrpcService; @GrpcService public class EmailGrpcService extends EmailServiceGrpc.EmailServiceImplBase { @@ -37,7 +38,7 @@ public class EmailGrpcService extends EmailServiceGrpc.EmailServiceImplBase { @Autowired private MailService mailService; - @Value("${kop.notification.mail-from}") + @Value("${ozgcloud.notification.mail-from}") private String mailFrom; @Override diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailRecipient.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailRecipient.java similarity index 90% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/MailRecipient.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailRecipient.java index b115dbc..59dded3 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailRecipient.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailRecipient.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import lombok.Builder; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendErrorEvent.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendErrorEvent.java similarity index 92% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendErrorEvent.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendErrorEvent.java index 6883892..acd5503 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendErrorEvent.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendErrorEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import org.springframework.context.ApplicationEvent; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendRequest.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendRequest.java similarity index 91% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendRequest.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendRequest.java index 12e2915..f361127 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSendRequest.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSendRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import java.util.Collection; -import javax.activation.DataSource; - +import jakarta.activation.DataSource; import lombok.Builder; import lombok.Getter; import lombok.Singular; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSentEvent.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSentEvent.java similarity index 92% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSentEvent.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSentEvent.java index 50eaf09..aea4e8d 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailSentEvent.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailSentEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import org.springframework.context.ApplicationEvent; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailService.java similarity index 92% rename from mail-service/src/main/java/de/itvsh/ozg/mail/email/MailService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailService.java index 68704ba..53e0093 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/email/MailService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/email/MailService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/AttachmentFile.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/AttachmentFile.java new file mode 100644 index 0000000..995f3d1 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/AttachmentFile.java @@ -0,0 +1,53 @@ +/* + * 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.nachrichten.postfach; + +import static java.util.Objects.*; + +import java.io.InputStream; +import java.util.function.Supplier; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Builder +@Getter +@ToString +public class AttachmentFile { + private String name; + private String contentType; + @Getter(AccessLevel.NONE) + @ToString.Exclude + private Supplier<InputStream> content; + + public InputStream getContent() { + if (isNull(content)) { + return InputStream.nullInputStream(); + } + return content.get(); + } + +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/BinaryFileService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/BinaryFileService.java similarity index 91% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/BinaryFileService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/BinaryFileService.java index 75942f2..f6a1c0f 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/BinaryFileService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/BinaryFileService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.io.InputStream; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/FileId.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/FileId.java similarity index 89% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/FileId.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/FileId.java index c596e38..3c8e6f0 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/FileId.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/FileId.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.util.UUID; -import de.itvsh.kop.common.datatype.StringBasedValue; +import de.ozgcloud.common.datatype.StringBasedValue; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachNachrichtMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachNachrichtMapper.java new file mode 100644 index 0000000..775675f --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachNachrichtMapper.java @@ -0,0 +1,50 @@ +/* + * 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.nachrichten.postfach; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; + +@Mapper(uses = GrpcObjectMapper.class) +public interface GrpcPostfachNachrichtMapper { + + @Mapping(target = "attachments", source = "attachmentList") + @Mapping(target = "createdAt", ignore = true) + @Mapping(target = "createdBy", ignore = true) + @Mapping(target = "direction", constant = "OUT") + @Mapping(target = "messageCode", ignore = true) + @Mapping(target = "messageId", ignore = true) + @Mapping(target = "postfachId", ignore = true) + @Mapping(target = "sentAt", ignore = true) + @Mapping(target = "sentSuccessful", ignore = true) + @Mapping(target = "vorgangId", ignore = true) + PostfachNachricht mapFromGrpc(GrpcPostfachNachricht nachricht); + + default PostfachAddressIdentifier map(GrpcObject value) { + return StringBasedIdentifier.builder().postfachId(value.getProperty(0).getValue(0)).build(); + } +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/NotConfiguredException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/NotConfiguredException.java similarity index 73% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/NotConfiguredException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/NotConfiguredException.java index f6650b9..544d425 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/NotConfiguredException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/NotConfiguredException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -class NotConfiguredException extends OsiPostfachException { // NOSONAR +public class NotConfiguredException extends PostfachException { // NOSONAR private static final long serialVersionUID = 1L; public NotConfiguredException() { - super("Osi-Postfach is not completely configured. Sending and receiving of postfach mails is not possible.", - OsiPostfachMessageCode.SERVER_CONNECTION_FAILED_MESSAGE_CODE); + super("Postfach is not completely configured. Sending and receiving of postfach mails is not possible.", + PostfachMessageCode.SERVER_CONNECTION_FAILED_MESSAGE_CODE); } } diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PersistPostfachMailService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java similarity index 81% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PersistPostfachMailService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java index 8c45304..e5936b5 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PersistPostfachMailService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; //Temporally replacement for usign GRPC Api -public interface PersistPostfachMailService { +public interface PersistPostfachNachrichtService { - void persistMail(Optional<String> userId, PostfachMail mail); + void persistNachricht(Optional<String> userId, PostfachNachricht nachricht); Stream<Map<String, Object>> findByVorgangAsMap(String vorgangId); @@ -41,5 +41,5 @@ public interface PersistPostfachMailService { Map<String, Object> getById(String itemId); // TODO use file id as soon it is available - String persistAttachment(String vorgangId, MessageAttachment attachment); + String persistAttachment(String vorgangId, AttachmentFile attachment); } diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/Postfach.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/Postfach.java new file mode 100644 index 0000000..6f47589 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/Postfach.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.nachrichten.postfach; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +class Postfach { + + private String type; + + private boolean isReplyAllowed; +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java new file mode 100644 index 0000000..5681a1c --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java @@ -0,0 +1,42 @@ +/* + * 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.nachrichten.postfach; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class PostfachAddress { + + public static final String VERSION_FIELD = "version"; + public static final String TYPE_FIELD = "type"; + public static final String IDENTIFIER_FIELD = "identifier"; + public static final String SERVICEKONTO_TYPE_FIELD = "serviceKontoType"; + + private String version; + private int type; + private PostfachAddressIdentifier identifier; + private String serviceKontoType; +} \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddressIdentifier.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddressIdentifier.java new file mode 100644 index 0000000..b237435 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddressIdentifier.java @@ -0,0 +1,28 @@ +/* + * 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.nachrichten.postfach; + +public interface PostfachAddressIdentifier { + +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachBadRequestException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachBadRequestException.java similarity index 73% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachBadRequestException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachBadRequestException.java index 6b54c44..0899631 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachBadRequestException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachBadRequestException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -class OsiPostfachBadRequestException extends OsiPostfachException { +public class PostfachBadRequestException extends PostfachException { private static final long serialVersionUID = 1L; - public OsiPostfachBadRequestException(Throwable cause) { - super("Bad-Request Received from OSI-Postfach Server", OsiPostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE, cause); + public PostfachBadRequestException(Throwable cause) { + super("Bad-Request Received from Postfach Server", PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE, cause); } } \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachEventListener.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachEventListener.java new file mode 100644 index 0000000..7928256 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachEventListener.java @@ -0,0 +1,125 @@ +/* + * 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.nachrichten.postfach; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import lombok.extern.log4j.Log4j2; + +@Component +@Log4j2 +public class PostfachEventListener { + + private static final String IS_SEND_POSTFACH_NACHRICHT_COMMAND = "{T(de.ozgcloud.nachrichten.postfach.PostfachEventListener).IS_SEND_POSTFACH_NACHRICHT.test(event.getSource())}"; + + public static final Predicate<Command> IS_SEND_POSTFACH_NACHRICHT = command -> command.getOrder().equals("SEND_POSTFACH_NACHRICHT"); + + @Autowired + private PostfachService service; + + @EventListener(condition = IS_SEND_POSTFACH_NACHRICHT_COMMAND) + public void sendPostfachNachricht(CommandCreatedEvent event) { + var command = event.getSource(); + try { + service.sendMail(command.getId(), command.getCreatedBy(), buildNachricht(command, command.getBodyObject())); + } catch (RuntimeException e) { + service.publishMailSentFailedEvent(command.getId(), "Error on sending Postfach Nachricht: " + e.getMessage()); + LOG.error("Error on sending Postfach Nachricht.", e); + } + } + + private PostfachNachricht buildNachricht(Command command, Map<String, Object> commandBody) { + var postfachMailBuilder = PostfachNachricht.builder() + .id(isNewNachricht(command) ? null : command.getRelationId()) + .vorgangId(command.getVorgangId()) + .postfachId(MapUtils.getString(commandBody, PostfachNachricht.FIELD_POSTFACH_ID)) + .replyOption(PostfachNachricht.ReplyOption.valueOf(MapUtils.getString(commandBody, PostfachNachricht.FIELD_REPLY_OPTION))) + .createdBy(command.getCreatedBy()) + .direction(Direction.OUT) + .subject(MapUtils.getString(commandBody, PostfachNachricht.FIELD_SUBJECT)) + .mailBody(MapUtils.getString(commandBody, PostfachNachricht.FIELD_MAIL_BODY)) + .attachments(getStringListValue(commandBody, PostfachNachricht.FIELD_ATTACHMENTS)); + + Optional.ofNullable(getPostfachAddress(commandBody)).map(this::buildPostfachAddress).ifPresent(postfachMailBuilder::postfachAddress); + + return postfachMailBuilder.build(); + } + + private boolean isNewNachricht(Command command) { + return Objects.isNull(command.getRelationId()) || StringUtils.equals(command.getVorgangId(), command.getRelationId()); + } + + private PostfachAddress buildPostfachAddress(Map<String, Object> postfachAddress) { + return PostfachAddress.builder() + .type(MapUtils.getIntValue(postfachAddress, PostfachAddress.TYPE_FIELD)) + .version(MapUtils.getString(postfachAddress, PostfachAddress.VERSION_FIELD)) + .identifier(buildIdentifier(postfachAddress)) + .serviceKontoType(MapUtils.getString(postfachAddress, PostfachAddress.SERVICEKONTO_TYPE_FIELD)) + .build(); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> getPostfachAddress(Map<String, Object> commandBody) { + return (Map<String, Object>) commandBody.get(PostfachNachricht.POSTFACH_ADDRESS_FIELD); + } + + private PostfachAddressIdentifier buildIdentifier(Map<String, Object> postfachAddress) { + var identifier = getIdentifier(postfachAddress); + return StringBasedIdentifier.builder().postfachId(MapUtils.getString(identifier, PostfachNachricht.FIELD_POSTFACH_ID)).build(); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> getIdentifier(Map<String, Object> postfachAddress) { + return (Map<String, Object>) postfachAddress.get(PostfachAddress.IDENTIFIER_FIELD); + } + + List<String> getStringListValue(Map<String, Object> commandBody, String fieldName) { + return Optional.ofNullable(commandBody.get(fieldName)) + .map(this::mapObjectToList) + .orElse(Collections.emptyList()); + } + + private List<String> mapObjectToList(Object object) { + if (object instanceof Collection<?> objects) { + return objects.stream().map(Objects::toString).toList(); + } else { + return List.of(object.toString()); + } + } +} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachException.java similarity index 70% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachException.java index f24953a..93851e6 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,23 +21,23 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -import de.itvsh.ozg.mail.common.errorhandling.TechnicalException; +import de.ozgcloud.common.errorhandling.TechnicalException; import lombok.Getter; -public class OsiPostfachException extends TechnicalException { +public class PostfachException extends TechnicalException { private static final long serialVersionUID = 1L; @Getter - private final OsiPostfachMessageCode messageCode; + private final PostfachMessageCode messageCode; - public OsiPostfachException(String message, OsiPostfachMessageCode messageCode) { + public PostfachException(String message, PostfachMessageCode messageCode) { super(message); this.messageCode = messageCode; } - public OsiPostfachException(String message, OsiPostfachMessageCode messageCode, Throwable cause) { + public PostfachException(String message, PostfachMessageCode messageCode, Throwable cause) { super(message, cause); this.messageCode = messageCode; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachGrpcService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcService.java similarity index 67% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachGrpcService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcService.java index d132d1a..84ae639 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachGrpcService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.mail.postfach.PostfachServiceGrpc.PostfachServiceImplBase; +import de.ozgcloud.nachrichten.postfach.PostfachServiceGrpc.PostfachServiceImplBase; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; @@ -35,7 +36,20 @@ class PostfachGrpcService extends PostfachServiceImplBase { @Autowired private PostfachService service; @Autowired - private PostfachMailMapper mapper; + private PostfachNachrichtMapper mapper; + @Autowired + private PostfachMapper postfachMapper; + + @Autowired + private GrpcPostfachNachrichtMapper nachrichtMapper; + + @Override + public void saveNachrichtDraft(GrpcSaveNachrichtDraftRequest request, StreamObserver<GrpcSaveNachrichtDraftResponse> response) { + service.saveDraft(request.getVorgangId(), nachrichtMapper.mapFromGrpc(request.getNachricht())); + + response.onNext(GrpcSaveNachrichtDraftResponse.newBuilder().build()); + response.onCompleted(); + } @Override public void sendPostfachMail(GrpcSendPostfachMailRequest req, StreamObserver<GrpcSendPostfachMailResponse> response) { @@ -75,4 +89,18 @@ class PostfachGrpcService extends PostfachServiceImplBase { response.onNext(GrpcIsPostfachConfiguredResponse.newBuilder().setIsConfigured(service.isPostfachConfigured()).build()); response.onCompleted(); } + + @Override + public void getPostfachConfig(GrpcGetPostfachConfigRequest request, StreamObserver<GrpcGetPostfachConfigResponse> response) { + response.onNext(buildGetPostfachConfigResponse()); + response.onCompleted(); + } + + GrpcGetPostfachConfigResponse buildGetPostfachConfigResponse() { + var grpcPostfachs = service.getPostfachs().map(postfachMapper::toGrpc).toList(); + if (CollectionUtils.isEmpty(grpcPostfachs)) { + return GrpcGetPostfachConfigResponse.newBuilder().setConfigured(false).build(); + } + return GrpcGetPostfachConfigResponse.newBuilder().setConfigured(true).addAllPostfach(grpcPostfachs).build(); + } } \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentEvent.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentEvent.java similarity index 87% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentEvent.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentEvent.java index 2bdab22..8e1b821 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentEvent.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandExecutedEvent; public class PostfachMailSentEvent extends CommandExecutedEvent { diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentFailedEvent.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentFailedEvent.java similarity index 88% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentFailedEvent.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentFailedEvent.java index bf3d724..314c217 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMailSentFailedEvent.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMailSentFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -import de.itvsh.ozg.pluto.command.CommandFailedEvent; +import de.ozgcloud.command.CommandFailedEvent; public class PostfachMailSentFailedEvent extends CommandFailedEvent { diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMapper.java new file mode 100644 index 0000000..ee1555b --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMapper.java @@ -0,0 +1,32 @@ +/* + * 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.nachrichten.postfach; + +import org.mapstruct.Mapper; + +@Mapper +public interface PostfachMapper { + + GrpcPostfach toGrpc(Postfach postfach); +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachMessageCode.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMessageCode.java similarity index 90% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachMessageCode.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMessageCode.java index fdd9103..a335f84 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachMessageCode.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachMessageCode.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor(access = AccessLevel.PRIVATE) -enum OsiPostfachMessageCode { +public enum PostfachMessageCode { PROCESS_FAILED_MESSAGE_CODE("postfachnachricht.server.processing_failed"), SERVER_CONNECTION_FAILED_MESSAGE_CODE("postfachnachricht.server.connection_failed"), diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMail.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java similarity index 87% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMail.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java index 9f93f5e..77682b4 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachMail.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,25 +21,30 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.time.ZonedDateTime; import java.util.Collections; import java.util.List; -import javax.validation.constraints.NotNull; - -import de.itvsh.ozg.mail.postfach.Message.ReplyOption; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import lombok.Getter; @Builder(toBuilder = true) @Getter -public class PostfachMail { +public class PostfachNachricht { + + public enum ReplyOption { + POSSIBLE, MANDATORY, FORBIDDEN + } public static final String FIELD_ID = "id"; public static final String FIELD_VORGANG_ID = "vorgangId"; + public static final String FIELD_POSTFACH_ID = "postfachId"; + public static final String POSTFACH_ADDRESS_FIELD = "postfachAddress"; + public static final String FIELD_MESSAGE_ID = "messageId"; public static final String FIELD_CREATED_AT = "createdAt"; public static final String FIELD_CREATED_BY = "createdBy"; @@ -60,6 +65,7 @@ public class PostfachMail { private String vorgangId; private String postfachId; + private PostfachAddress postfachAddress; private String messageId; @Builder.Default diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java new file mode 100644 index 0000000..cb72cb4 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java @@ -0,0 +1,159 @@ +/* + * 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.nachrichten.postfach; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ValueMapping; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) +public abstract class PostfachNachrichtMapper { + + @Autowired + private GrpcObjectMapper grpcObjectMapper; + + @Mapping(target = "attachments", source = "attachmentList") + @Mapping(target = "createdAt", ignore = true) + @Mapping(target = "createdBy", ignore = true) + @Mapping(target = "direction", ignore = true) + @Mapping(target = "messageId", ignore = true) + @Mapping(target = "sentAt", ignore = true) + @Mapping(target = "sentSuccessful", ignore = true) + @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) + @ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL) + public abstract PostfachNachricht fromGrpcMail(GrpcPostfachMail grpcMail); + + public PostfachAddressIdentifier toPostfachAddressIdentifier(GrpcObject grpcObject) { + var postfachId = grpcObject.getPropertyList().get(0).getValue(0); + return StringBasedIdentifier.builder().postfachId(postfachId).build(); + } + + @SuppressWarnings("unchecked") + public GrpcPostfachMail fromMap(Map<String, Object> mailMap) { + var postfachMailBuilder = GrpcPostfachMail.newBuilder() + .setId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_ID)) + .setVorgangId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_VORGANG_ID)) + .setPostfachId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_POSTFACH_ID, StringUtils.EMPTY)) + .setCreatedAt(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_AT)) + .setCreatedBy(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_BY, StringUtils.EMPTY)) + .setSentAt(MapUtils.getString(mailMap, PostfachNachricht.FIELD_SENT_AT, StringUtils.EMPTY)) + .setSentSuccessful(MapUtils.getBooleanValue(mailMap, PostfachNachricht.FIELD_SENT_SUCCESSFUL, false)) + .setMessageCode(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MESSAGE_CODE, StringUtils.EMPTY)) + .setDirection(GrpcDirection.valueOf(MapUtils.getString(mailMap, PostfachNachricht.FIELD_DIRECTION))) + .setSubject(MapUtils.getString(mailMap, PostfachNachricht.FIELD_SUBJECT)) + .setMailBody(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MAIL_BODY)) + .setReplyOption(MapUtils.getString(mailMap, PostfachNachricht.FIELD_REPLY_OPTION)) + .addAllAttachment((Iterable<String>) mailMap.getOrDefault(PostfachNachricht.FIELD_ATTACHMENTS, Collections.emptyList())); + + Optional.ofNullable(getAsMap(mailMap, PostfachNachricht.POSTFACH_ADDRESS_FIELD)) + .filter(MapUtils::isNotEmpty) + .map(this::buildGrpcPostfachAddress) + .ifPresent(postfachMailBuilder::setPostfachAddress); + + return postfachMailBuilder.build(); + } + + GrpcPostfachAddress buildGrpcPostfachAddress(Map<String, Object> postfachAddressMap) { + var postfachAddressBuilder = GrpcPostfachAddress.newBuilder() + .setType(MapUtils.getIntValue(postfachAddressMap, PostfachAddress.TYPE_FIELD)) + .setVersion(MapUtils.getString(postfachAddressMap, PostfachAddress.VERSION_FIELD)) + .setIdentifier(grpcObjectMapper.fromMap(postfachAddressMap)); + Optional.ofNullable(MapUtils.getString(postfachAddressMap, PostfachAddress.SERVICEKONTO_TYPE_FIELD)) + .ifPresent(postfachAddressBuilder::setServiceKontoType); + return postfachAddressBuilder.build(); + } + + PostfachNachricht fromMapToPostfachMail(Map<String, Object> mailMap) { + var postfachMailBuilder = PostfachNachricht.builder() + .id(MapUtils.getString(mailMap, PostfachNachricht.FIELD_ID)) + .vorgangId(MapUtils.getString(mailMap, (PostfachNachricht.FIELD_VORGANG_ID))) + .postfachId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_POSTFACH_ID, StringUtils.EMPTY)) + .messageId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MESSAGE_ID)) + .createdAt(ZonedDateTime.parse(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_AT))) + .createdBy(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_BY)) + .sentAt(getString(mailMap, PostfachNachricht.FIELD_SENT_AT).map(ZonedDateTime::parse).orElse(null)) + .sentSuccessful(MapUtils.getBoolean(mailMap, PostfachNachricht.FIELD_SENT_SUCCESSFUL)) + .messageCode(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MESSAGE_CODE)) + .direction(Direction.valueOf(MapUtils.getString(mailMap, PostfachNachricht.FIELD_DIRECTION))) + .subject(MapUtils.getString(mailMap, PostfachNachricht.FIELD_SUBJECT)) + .mailBody(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MAIL_BODY)) + .replyOption(PostfachNachricht.ReplyOption.valueOf(MapUtils.getString(mailMap, PostfachNachricht.FIELD_REPLY_OPTION))) + .attachments(getAsList(mailMap, PostfachNachricht.FIELD_ATTACHMENTS)); + + Optional.ofNullable(getAsMap(mailMap, PostfachNachricht.POSTFACH_ADDRESS_FIELD)) + .filter(MapUtils::isNotEmpty) + .map(this::buildPostfachAddress) + .ifPresent(postfachMailBuilder::postfachAddress); + + return postfachMailBuilder.build(); + } + + private Optional<String> getString(Map<String, Object> mailMap, String key) { + return Optional.ofNullable(MapUtils.getString(mailMap, key)); + } + + @SuppressWarnings("unchecked") + private List<String> getAsList(Map<String, Object> mailMap, String fieldName) { + return (List<String>) mailMap.getOrDefault(fieldName, Collections.emptyList()); + } + + PostfachAddress buildPostfachAddress(Map<String, Object> postfachAddressMap) { + return PostfachAddress.builder() + .type(MapUtils.getIntValue(postfachAddressMap, PostfachAddress.TYPE_FIELD)) + .version(MapUtils.getString(postfachAddressMap, PostfachAddress.VERSION_FIELD)) + .identifier(buildIdentifier(postfachAddressMap)) + .serviceKontoType(MapUtils.getString(postfachAddressMap, PostfachAddress.SERVICEKONTO_TYPE_FIELD)) + .build(); + } + + PostfachAddressIdentifier buildIdentifier(Map<String, Object> postfachAddressMap) { + return StringBasedIdentifier.builder().postfachId(getPostfachId(postfachAddressMap)).build(); + } + + private String getPostfachId(Map<String, Object> postfachAddressMap) { + var identifier = getAsMap(postfachAddressMap, PostfachAddress.IDENTIFIER_FIELD); + return MapUtils.getString(identifier, PostfachNachricht.FIELD_POSTFACH_ID); + + } + + @SuppressWarnings("unchecked") + Map<String, Object> getAsMap(Map<String, Object> map, String fieldName) { + return MapUtils.getMap(map, fieldName, Collections.emptyMap()); + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java new file mode 100644 index 0000000..c4e2d19 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach; + +import java.util.stream.Stream; + +public interface PostfachRemoteService { + + void sendMessage(PostfachNachricht nachricht); + + Stream<PostfachNachricht> getAllMessages(); + + void deleteMessage(String messageId); + + String getPostfachType(); + + boolean isReplyAllowed(); +} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachRuntimeException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRuntimeException.java similarity index 73% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachRuntimeException.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRuntimeException.java index cba2d92..93c7251 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachRuntimeException.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRuntimeException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -class OsiPostfachRuntimeException extends OsiPostfachException {// NOSONAR +public class PostfachRuntimeException extends PostfachException {// NOSONAR private static final long serialVersionUID = 1L; - public OsiPostfachRuntimeException(Throwable cause) { - super("Error executing Request to OSI Postfach", OsiPostfachMessageCode.SERVER_CONNECTION_FAILED_MESSAGE_CODE, cause); + public PostfachRuntimeException(Throwable cause) { + super("Error executing Request to Postfach", PostfachMessageCode.SERVER_CONNECTION_FAILED_MESSAGE_CODE, cause); } } \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachScheduler.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachScheduler.java similarity index 75% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachScheduler.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachScheduler.java index 9ec80e6..2c1dd27 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachScheduler.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.Scheduled; @@ -33,14 +34,15 @@ import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; @Component @Profile("!itcase") -@ConditionalOnProperty(prefix = OsiPostfachProperties.PREFIX, name = { "proxyapi.url", "proxyapi.key", "proxyapi.realm", "scheduler.enabled" }) +@ConditionalOnBean(PostfachRemoteService.class) +@ConditionalOnProperty(name = { "ozgcloud.osi.postfach.scheduler.enabled" }) class PostfachScheduler { @Autowired private PostfachService service; - @Scheduled(initialDelayString = "${kop.osi.postfach.scheduler.initialDelay:5000}", // - fixedDelayString = "${kop.osi.postfach.scheduler.fixedDelay:900000}") + @Scheduled(initialDelayString = "${ozgcloud.osi.postfach.scheduler.initialDelay:5000}", // + fixedDelayString = "${ozgcloud.osi.postfach.scheduler.fixedDelay:900000}") @SchedulerLock(name = "PostfachScheduler") void runGetMessagesTask() { service.fetchAndPersistReplies(); diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java new file mode 100644 index 0000000..bfe95c2 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java @@ -0,0 +1,245 @@ +/* + * 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.nachrichten.postfach; + +import java.time.ZonedDateTime; +import java.util.EnumSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import jakarta.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import de.ozgcloud.nachrichten.attributes.ClientAttributeService; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.ReplyOption; +import de.ozgcloud.nachrichten.postfach.antragsraum.AntragsraumService; +import de.ozgcloud.nachrichten.postfach.osi.OsiPostfachServerProcessException; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Service +@Validated +class PostfachService { + + private static final Predicate<PostfachNachricht> IS_FROM_HUMAN_USER = nachricht -> !StringUtils.startsWith(nachricht.getCreatedBy(), "system"); + private static final Set<String> POSTFACH_TYPES_WITH_ANTRAGSRAUM = Set.of("BayernId"); + + @Autowired(required = false) + private PostfachRemoteService postfachRemoteService; + + private static final Set<ReplyOption> REPLY_POSSIBLE_OPTION = EnumSet.of(ReplyOption.POSSIBLE, ReplyOption.MANDATORY); + + @Autowired + private PostfachNachrichtMapper mapper; + + @Autowired + private PersistPostfachNachrichtService persistingService; + @Autowired + private ClientAttributeService clientAttributeService; + + @Autowired + private ApplicationEventPublisher publisher; + + @Autowired + private CurrentUserService userService; + + @Autowired(required = false) + private AntragsraumService antragsraumService; + + public void saveDraft(String vorgangId, PostfachNachricht nachricht) { + persistMail(userService.getUser().getUserId(), + nachricht.toBuilder().vorgangId(vorgangId) + .createdBy(userService.getUser().getUserId().orElse(null)) + .build()); + } + + public void sendMail(String commandId, String userId, @Valid PostfachNachricht mail) { + var sendResponse = handleSendMail(commandId, mail); + persistSentMail(userId, addMailSentInformation(mail, sendResponse)); + } + + PostfachNachricht addMailSentInformation(PostfachNachricht mail, SendPostfachNachrichtResponse sendResponse) { + return mail.toBuilder().sentAt(ZonedDateTime.now()).sentSuccessful(sendResponse.isSentSuccessful()) + .messageCode(sendResponse.getMessageCode().getMessageCode()) + .build(); + } + + void persistSentMail(@NonNull String userId, PostfachNachricht mail) { + persistMail(Optional.of(userId), mail.toBuilder() + .direction(Direction.OUT) + .createdAt(ZonedDateTime.now().withNano(0)).createdBy(userId) + .build()); + + } + + public Optional<Map<String, Object>> findById(String nachrichtId) { + return persistingService.findById(nachrichtId); + } + + public Stream<Map<String, Object>> findByVorgang(String vorgangId) { + return persistingService.findByVorgangAsMap(vorgangId); + } + + public void fetchAndPersistReplies() { + ifPostfachConfigured(() -> postfachRemoteService.getAllMessages().forEach(this::persistReceivedMail)); + } + + private void persistReceivedMail(PostfachNachricht nachricht) { + persistMail(Optional.empty(), nachricht); + clientAttributeService.setHasNewPostfachNachricht(nachricht.getVorgangId()); + + postfachRemoteService.deleteMessage(nachricht.getMessageId()); + } + + void persistMail(Optional<String> userId, PostfachNachricht mail) { + persistingService.persistNachricht(userId, mail); + + if (IS_FROM_HUMAN_USER.test(mail)) { + clientAttributeService.setHasPostfachNachricht(mail.getVorgangId()); + } + } + + public void resendMail(String commandId, String postfachMailId) { + PostfachNachricht nachricht = mapper.fromMapToPostfachMail(persistingService.getById(postfachMailId)); + + var sendResponse = handleSendMail(commandId, nachricht); + patchMail(nachricht.getId(), createResendPatchMap(sendResponse)); + } + + SendPostfachNachrichtResponse handleSendMail(String commandId, PostfachNachricht mail) { + try { + var processedPostfachNachricht = processForAntragsraum(mail).orElse(mail); + doSendMail(processedPostfachNachricht); + + publishMailSentEvent(commandId); + return buildSendNachrichtResponse(true, PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); + } catch (OsiPostfachServerProcessException e) { + return proceedwithWarnException(commandId, e); + + } catch (PostfachException e) { + return proceedWithErrorException(commandId, e); + } + } + + Optional<PostfachNachricht> processForAntragsraum(PostfachNachricht mail) { + if (isNotifyAntragsraum(mail.getReplyOption())) { + antragsraumService.notifyAntragsraum(mail); + return adjustMail(mail); + } + return Optional.empty(); + } + + boolean isNotifyAntragsraum(ReplyOption replyOption) { + return REPLY_POSSIBLE_OPTION.contains(replyOption) && isPostfachWithAntragsraum(postfachRemoteService); + } + + Optional<PostfachNachricht> adjustMail(PostfachNachricht nachricht) { + return getAntragsraumService().map(antragsraum -> nachricht.toBuilder().mailBody(antragsraum.getUserNotificationText()).build()); + } + + SendPostfachNachrichtResponse proceedwithWarnException(String commandId, OsiPostfachServerProcessException e) { + LOG.warn(e.getMessage(), e); + return proceedWithException(commandId, e); + } + + SendPostfachNachrichtResponse proceedWithErrorException(String commandId, PostfachException e) { + LOG.error(e.getMessage(), e); + return proceedWithException(commandId, e); + } + + private SendPostfachNachrichtResponse proceedWithException(String commandId, PostfachException e) { + publishMailSentFailedEvent(commandId, e.getMessage()); + return buildSendNachrichtResponse(false, e.getMessageCode()); + + } + + void doSendMail(PostfachNachricht nachricht) { + ifPostfachConfigured(() -> postfachRemoteService.sendMessage(nachricht)); + } + + private void publishMailSentEvent(String commandId) { + publisher.publishEvent(new PostfachMailSentEvent(commandId)); + } + + public void publishMailSentFailedEvent(String commandId, String message) { + publisher.publishEvent(new PostfachMailSentFailedEvent(commandId, message)); + } + + private SendPostfachNachrichtResponse buildSendNachrichtResponse(boolean sentSuccesful, PostfachMessageCode messageCode) { + return SendPostfachNachrichtResponse.builder().sentSuccessful(sentSuccesful).messageCode(messageCode).build(); + } + + Map<String, Object> createResendPatchMap(SendPostfachNachrichtResponse sendResponse) { + return Map.of(PostfachNachricht.FIELD_SENT_AT, ZonedDateTime.now().withNano(0).toString(), + PostfachNachricht.FIELD_SENT_SUCCESSFUL, sendResponse.isSentSuccessful(), + PostfachNachricht.FIELD_MESSAGE_CODE, sendResponse.getMessageCode().getMessageCode()); + } + + private void patchMail(String postfachMailId, Map<String, Object> propertyMap) { + persistingService.patch(postfachMailId, propertyMap); + } + + public boolean isPostfachConfigured() { + return postfachRemoteService != null; + } + + public Stream<Postfach> getPostfachs() { + return isPostfachConfigured() ? Stream.of(buildPostfach(postfachRemoteService)) : Stream.empty(); + } + + Postfach buildPostfach(PostfachRemoteService postfachRemoteService) { + return Postfach.builder().type(postfachRemoteService.getPostfachType()).isReplyAllowed(isReplyAllowed(postfachRemoteService)).build(); + } + + boolean isReplyAllowed(PostfachRemoteService postfachRemoteService) { + return isPostfachWithAntragsraum(postfachRemoteService) || postfachRemoteService.isReplyAllowed(); + } + + boolean isPostfachWithAntragsraum(PostfachRemoteService postfachRemoteService) { + return POSTFACH_TYPES_WITH_ANTRAGSRAUM.contains(postfachRemoteService.getPostfachType()) && getAntragsraumService().isPresent(); + } + + Optional<AntragsraumService> getAntragsraumService() { + return Optional.ofNullable(antragsraumService); + } + + private void ifPostfachConfigured(Runnable block) { + if (!isPostfachConfigured()) { + throw new NotConfiguredException(); + } + block.run(); + } + +} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponse.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponse.java similarity index 88% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponse.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponse.java index 24e60ff..0ac7feb 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponse.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import lombok.AllArgsConstructor; import lombok.Builder; @@ -32,5 +32,5 @@ import lombok.Getter; @AllArgsConstructor class SendPostfachNachrichtResponse { private boolean sentSuccessful; - private OsiPostfachMessageCode messageCode; + private PostfachMessageCode messageCode; } \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/StringBasedIdentifier.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/StringBasedIdentifier.java new file mode 100644 index 0000000..12f171c --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/StringBasedIdentifier.java @@ -0,0 +1,34 @@ +/* + * 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.nachrichten.postfach; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class StringBasedIdentifier implements PostfachAddressIdentifier { + + private String postfachId; +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumProperties.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumProperties.java new file mode 100644 index 0000000..3685aac --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumProperties.java @@ -0,0 +1,49 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import jakarta.validation.constraints.NotEmpty; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Configuration +@ConditionalOnProperty(AntragsraumProperties.PROPERTY_ANTRAGSRAUM_URL) +@ConfigurationProperties(prefix = "ozgcloud.antragsraum") +@Validated +class AntragsraumProperties { + + static final String PROPERTY_ANTRAGSRAUM_URL = "ozgcloud.antragsraum.url"; + + @NotEmpty + private String url; + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumService.java new file mode 100644 index 0000000..50defe4 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumService.java @@ -0,0 +1,94 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import static java.util.Objects.*; + +import jakarta.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + +import de.ozgcloud.nachrichten.NachrichtenManagerProperties; +import de.ozgcloud.nachrichten.postfach.PostfachException; +import de.ozgcloud.nachrichten.postfach.PostfachMessageCode; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; + +@Service +@ConditionalOnProperty(AntragsraumProperties.PROPERTY_ANTRAGSRAUM_URL) +public class AntragsraumService { + + static final String USER_NOTIFICATION_TEMPLATE = """ + Guten Tag, + + bei der Bearbeitung Ihres Antrags hat sich eine Rückfrage ergeben. Bitte beantworten Sie diese im Antragsraum: + + %s + + Vielen Dank, + Ihre digitale Verwaltung + """; + + @Autowired + private AntragsraumProperties properties; + + @Autowired + private NachrichtenManagerProperties nachrichtenManagerProperties; + + @Autowired + private InfomanagerRemoteService infomanagerRemoteService; + + @PostConstruct + void init() { + if (isNull(nachrichtenManagerProperties.getUrl())) { + throw new IllegalStateException("Address of Nachrichten-Manager is not set"); + } + } + + public String getAntragsraumUrl() { + return properties.getUrl(); + } + + public String getUserNotificationText() { + return USER_NOTIFICATION_TEMPLATE.formatted(getAntragsraumUrl()); + } + + public void notifyAntragsraum(PostfachNachricht postfachNachricht) { + try { + infomanagerRemoteService.sendNotification(builInfomanagerNachricht(postfachNachricht)); + } catch (RuntimeException e) { + throw new PostfachException("Error while sending notification to Antragsraum", PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE, e); + } + } + + InfomanagerNachricht builInfomanagerNachricht(PostfachNachricht postfachNachricht) { + return InfomanagerNachricht.builder() + .nachrichtId(postfachNachricht.getId()) + .vorgangId(postfachNachricht.getVorgangId()) + .postfachId(postfachNachricht.getPostfachId()) + .nachrichtenManagerUrl(nachrichtenManagerProperties.getUrl()) + .build(); + } +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachricht.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachricht.java new file mode 100644 index 0000000..21babda --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachricht.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class InfomanagerNachricht { + + private String nachrichtId; + private String vorgangId; + private String postfachId; + private String nachrichtenManagerUrl; +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtMapper.java new file mode 100644 index 0000000..a02c587 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtMapper.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import de.ozgcloud.info.nachricht.GrpcNachricht; + +@Mapper +interface InfomanagerNachrichtMapper { + + @Mapping(target = "nachrichtenListUrl", source = "nachrichtenManagerUrl") + GrpcNachricht toGrpc(InfomanagerNachricht infomanagerNachricht); + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerProperties.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerProperties.java new file mode 100644 index 0000000..e44ba7c --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerProperties.java @@ -0,0 +1,47 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import jakarta.validation.constraints.NotEmpty; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Configuration +@ConfigurationProperties(prefix = "grpc.client.info-manager") +@ConditionalOnProperty(AntragsraumProperties.PROPERTY_ANTRAGSRAUM_URL) +@Validated +public class InfomanagerProperties { + + @NotEmpty + private String address; + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteService.java new file mode 100644 index 0000000..0d25099 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteService.java @@ -0,0 +1,51 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.info.nachricht.GrpcNewNachrichtRequest; +import de.ozgcloud.info.nachricht.NachrichtServiceGrpc.NachrichtServiceBlockingStub; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class InfomanagerRemoteService { + + @GrpcClient("info-manager") + private NachrichtServiceBlockingStub nachrichtServiceStub; + + @Autowired + private InfomanagerNachrichtMapper nachrichtMapper; + + public String sendNotification(InfomanagerNachricht nachricht) { + var grpcNewNachrichtReply = nachrichtServiceStub.saveNewNachricht(buildNachrichtRequest(nachricht)); + return grpcNewNachrichtReply.getStatus(); + } + + GrpcNewNachrichtRequest buildNachrichtRequest(InfomanagerNachricht nachricht) { + return GrpcNewNachrichtRequest.newBuilder().setNachricht(nachrichtMapper.toGrpc(nachricht)).build(); + } + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/Absender.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/Absender.java new file mode 100644 index 0000000..c7b39b9 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/Absender.java @@ -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. + */ +package de.ozgcloud.nachrichten.postfach.bayernid; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +class Absender { + @Pattern(regexp = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}") + private String postkorbId; + @NotBlank + private String name; + private String anschrift; + @NotBlank + private String dienst; + @NotBlank + private String mandant; + private String gemeindeSchluessel; +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachment.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachment.java new file mode 100644 index 0000000..75b2843 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachment.java @@ -0,0 +1,38 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.io.InputStream; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class BayernIdAttachment { + + private String fileName; + private String contentType; + private InputStream content; +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentService.java new file mode 100644 index 0000000..699214a --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentService.java @@ -0,0 +1,68 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.io.InputStream; +import java.util.Optional; + +import org.bson.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + +import com.mongodb.client.gridfs.model.GridFSFile; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.BinaryFileService; +import de.ozgcloud.nachrichten.postfach.FileId; + +@Service +@ConditionalOnProperty(prefix = "ozgcloud.bayernid", name = { "enabled" }) +public class BayernIdAttachmentService { + + static final String NAME_KEY = "name"; + static final String CONTENT_TYPE_KEY = "contentType"; + + @Autowired + private BinaryFileService binaryFileService; + + public BayernIdAttachment getMessageAttachment(FileId fileId) { + return Optional.ofNullable(binaryFileService.getFile(fileId)) + .map(GridFSFile::getMetadata) + .map(metadata -> buildBayernIdAttachment(metadata, getAttachmentContentStream(fileId))) + .orElseThrow(() -> new TechnicalException("Can not find attachment with id " + fileId)); + } + + BayernIdAttachment buildBayernIdAttachment(Document metadata, InputStream attachmentContent) { + return BayernIdAttachment.builder() + .fileName(metadata.getString(NAME_KEY)) + .contentType(metadata.getString(CONTENT_TYPE_KEY)) + .content(attachmentContent) + .build(); + } + + InputStream getAttachmentContentStream(FileId fileId) { + return binaryFileService.getUploadedFileStream(fileId); + } +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapper.java new file mode 100644 index 0000000..9c33343 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapper.java @@ -0,0 +1,96 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.time.ZonedDateTime; +import java.util.GregorianCalendar; +import java.util.Objects; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.PostfachAddress; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAbsender; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachmentMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +interface BayernIdPostfachNachrichtMapper { + + String MESSAGE_LEVEL = "LEVEL_1"; + + @Mapping(target = "attachments", ignore = true) + @Mapping(target = "messageMetadata", expression = "java(toBayernIdMessageMetadata(nachricht, absender))") + GrpcSendBayernIdMessageRequest toSendBayernIdMessageMetadataRequest(PostfachNachricht nachricht, Absender absender); + + @Mapping(target = "messageId", source = "nachricht.messageId") + @Mapping(target = "createdAt", expression = "java(convertZonedDateTime(nachricht.getCreatedAt()))") + @Mapping(target = "subject", source = "nachricht.subject") + @Mapping(target = "storkQaaLevel", constant = MESSAGE_LEVEL) + @Mapping(target = "vorgangId", source = "nachricht.vorgangId") + @Mapping(target = "text", source = "nachricht.mailBody") + @Mapping(target = "empfaenger.postkorbId", source = "nachricht.postfachAddress") + GrpcBayernIdMessageMetadata toBayernIdMessageMetadata(PostfachNachricht nachricht, Absender absender); + + @Mapping(target = "gemeindeschluessel", source = "gemeindeSchluessel") + GrpcAbsender toAbsender(Absender absender); + + @Mapping(target = "messageMetadata", ignore = true) + @Mapping(target = "attachments.content", ignore = true) + @Mapping(target = "attachments.attachmentMetadata", expression = "java(toAttachmentMetadata(bayernIdAttachment))") + GrpcSendBayernIdMessageRequest toSendBayernIdAttachmentsMetadataRequest(BayernIdAttachment bayernIdAttachment); + + @Mapping(target = "fileType", source = "contentType") + GrpcAttachmentMetadata toAttachmentMetadata(BayernIdAttachment attachment); + + default String convertZonedDateTime(ZonedDateTime zonedDateTime) { + try { + return DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar.from(zonedDateTime)).toString(); + } catch (DatatypeConfigurationException e) { + throw new TechnicalException("Error creating XMLGregorianCalendar which should not happen in this case.", e); + } + } + + BayernIdResponse fromSendBayernIdMessageResponse(GrpcSendBayernIdMessageResponse response); + + default String toPostkorbId(PostfachAddress postfachAddress) { + return ((StringBasedIdentifier) postfachAddress.getIdentifier()).getPostfachId(); + } + + @Condition + default boolean nonNull(String value) { + return Objects.nonNull(value); + } + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java new file mode 100644 index 0000000..9666abd --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java @@ -0,0 +1,155 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; + +import jakarta.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import com.google.protobuf.ByteString; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachRemoteService; +import de.ozgcloud.nachrichten.postfach.PostfachRuntimeException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.BayernIdProxyServiceGrpc.BayernIdProxyServiceStub; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachments; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import io.grpc.stub.CallStreamObserver; +import io.grpc.stub.StreamObserver; +import lombok.extern.log4j.Log4j2; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Log4j2 +@ConditionalOnProperty(prefix = "ozgcloud.bayernid", name = { "enabled" }, havingValue = "true") +@Component +class BayernIdPostfachRemoteService implements PostfachRemoteService { + + static final String POSTFACH_TYPE = "BayernId"; + + @GrpcClient("bayern-id") + private BayernIdProxyServiceStub bayernIdProxyServiceStub; + + @Autowired + private BayernIdProperties bayernIdProperties; + @Autowired + private BayernIdPostfachResponseHandler responseHandler; + @Autowired + private BayernIdPostfachNachrichtMapper mapper; + @Autowired + private BayernIdAttachmentService bayernIdAttachmentService; + + @PostConstruct + void init() { + LOG.info("BayernID Postfach remote service initialized."); + } + + @Override + public void sendMessage(PostfachNachricht nachricht) { + try { + var sender = createMessageWithFilesSender(nachricht).send(); + var response = waitUntilTransferCompleted(sender); + responseHandler.handleResponse(mapper.fromSendBayernIdMessageResponse(response)); + } catch (BayernIdServerException e) { + throw e; + } catch (RuntimeException e) { + throw new PostfachRuntimeException(e); + } + } + + MessageWithFilesSender createMessageWithFilesSender(PostfachNachricht nachricht) { + return MessageWithFilesSender.builder() + .reqObserverBuilder(buildCallStreamObserverBuilder()) + .messageMetadata(mapper.toSendBayernIdMessageMetadataRequest(nachricht, bayernIdProperties.getAbsender())) + .attachmentIds(nachricht.getAttachments()) + .toAttachment(buildAttachmentBuilder()) + .attachmentMetadataMapper(buildAttachmentMetadataMapper()) + .chunkBuilder(buildChunkRequest()) + .build(); + } + + Function<StreamObserver<GrpcSendBayernIdMessageResponse>, CallStreamObserver<GrpcSendBayernIdMessageRequest>> buildCallStreamObserverBuilder() { + return responseObserver -> + (CallStreamObserver<GrpcSendBayernIdMessageRequest>) bayernIdProxyServiceStub.sendMessageAsStream(responseObserver); + } + + Function<String, BayernIdAttachment> buildAttachmentBuilder() { + return attachmentId -> bayernIdAttachmentService.getMessageAttachment(FileId.from(attachmentId)); + } + + BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> buildChunkRequest() { + return (bytes, length) -> GrpcSendBayernIdMessageRequest.newBuilder() + .setAttachments(GrpcAttachments.newBuilder().setContent(ByteString.copyFrom(bytes, 0, length)).build()) + .build(); + } + + Function<BayernIdAttachment, GrpcSendBayernIdMessageRequest> buildAttachmentMetadataMapper() { + return mapper::toSendBayernIdAttachmentsMetadataRequest; + } + + GrpcSendBayernIdMessageResponse waitUntilTransferCompleted(MessageWithFilesSender sender) { + try { + return sender.getResultFuture().get(2, TimeUnit.MINUTES); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + sender.cancelOnError(e); + throw new TechnicalException("Waiting for finishing upload was interrupted.", e); + } catch (ExecutionException | TimeoutException e) { + sender.cancelOnTimeout(); + throw new TechnicalException("Error / Timeout on uploading data.", e); + } + } + + @Override + public Stream<PostfachNachricht> getAllMessages() { + throw new UnsupportedOperationException("Bayern ID doesn't support this operation."); + } + + @Override + public void deleteMessage(String messageId) { + throw new UnsupportedOperationException("Bayern ID doesn't support this operation."); + } + + @Override + public String getPostfachType() { + return POSTFACH_TYPE; + } + + @Override + public boolean isReplyAllowed() { + return false; + } + +} diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandler.java similarity index 53% rename from notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangMapper.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandler.java index 651caa2..a42bdf3 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangMapper.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,26 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.nachrichten.postfach.bayernid; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; -import de.itvsh.ozg.pluto.vorgang.GrpcVorgangWithEingang; +import lombok.extern.log4j.Log4j2; -@Mapper -interface VorgangMapper { +@Log4j2 +@Component +@ConditionalOnProperty(prefix = "ozgcloud.bayernid", name = { "enabled" }) +class BayernIdPostfachResponseHandler { - @Mapping(target = "postfachId", source = "eingang.antragsteller.postfachId") - @Mapping(target = "vorgangName", source = "name") - @Mapping(target = "vorgangNummer", source = "nummer") - @Mapping(target = "organisationseinheitenId", source = "eingang.zustaendigeStelle.organisationseinheitenId") - Vorgang fromGrpc(GrpcVorgangWithEingang vorgang); - - default VorgangId fromString(String vorgangId) { - if (vorgangId == null) { - return null; + public void handleResponse(BayernIdResponse bayernIdResponse) { + if (bayernIdResponse.isSuccess()) { + return; } - return VorgangId.from(vorgangId); + var message = StringUtils.defaultIfBlank(bayernIdResponse.getMessage(), "Cannot send message to BayernID."); + throw new BayernIdServerException(message, MailSendingResponseStatus.fromSchluessel(bayernIdResponse.getStatus())); } } diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdProperties.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdProperties.java new file mode 100644 index 0000000..41fe160 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdProperties.java @@ -0,0 +1,49 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import jakarta.validation.constraints.NotNull; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Validated +@Configuration +@ConfigurationProperties(prefix = "ozgcloud.bayernid") +@ConditionalOnProperty(prefix = "ozgcloud.bayernid", name = { "enabled" }) +@ConfigurationPropertiesScan +class BayernIdProperties { + + @NotNull + private Absender absender; + +} \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponse.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponse.java new file mode 100644 index 0000000..329282c --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponse.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class BayernIdResponse { + + private boolean success; + private String status; + private String message; + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdServerException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdServerException.java new file mode 100644 index 0000000..6f22e39 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdServerException.java @@ -0,0 +1,53 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.ozgcloud.nachrichten.postfach.PostfachException; +import de.ozgcloud.nachrichten.postfach.PostfachMessageCode; + +class BayernIdServerException extends PostfachException { + + static final String TABELLE_NUMMER_EMPFANG_ERGEBNISSTATUS = "9006"; + private static final String ERROR_MESSAGE_TEMPLATE = TABELLE_NUMMER_EMPFANG_ERGEBNISSTATUS + " / %s / %s / %s"; + + private final MailSendingResponseStatus mailSendingResponseStatus; + + public BayernIdServerException(String message) { + super(message, PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + this.mailSendingResponseStatus = null; + } + + public BayernIdServerException(String message, MailSendingResponseStatus mailSendingResponseStatus) { + super(message, PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + this.mailSendingResponseStatus = mailSendingResponseStatus; + } + + @Override + public String getMessage() { + if (mailSendingResponseStatus == null) { + return super.getMessage(); + } + return ERROR_MESSAGE_TEMPLATE.formatted(mailSendingResponseStatus.getSchluessel(), mailSendingResponseStatus.getMessage(), super.getMessage()); + } +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java new file mode 100644 index 0000000..610b380 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java @@ -0,0 +1,132 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; + +import org.apache.commons.io.IOUtils; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import io.grpc.stub.CallStreamObserver; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +class FileSender { + + static final int CHUNK_SIZE = 4 * 1024; + + private final AtomicBoolean metaDataSent = new AtomicBoolean(false); + private final AtomicBoolean done = new AtomicBoolean(false); + + private final BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; + private final CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + private final GrpcSendBayernIdMessageRequest metadata; + private final StreamReader streamReader; + + public FileSender(BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder, + CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver, GrpcSendBayernIdMessageRequest metadata, + InputStream inputStream) { + this.chunkBuilder = chunkBuilder; + this.requestObserver = requestObserver; + this.metadata = metadata; + this.streamReader = new StreamReader(inputStream); + } + + public void send() { + if (!done.get()) { + sendMetadata(); + while (!done.get() && requestObserver.isReady()) { + LOG.debug("Sending next chunk."); + sendNextChunk(); + } + LOG.debug("Finished or waiting to become ready."); + } + } + + void sendMetadata() { + if (metaDataSent.getAndSet(true)) { + return; + } + LOG.debug("Sending Attachment Metadata."); + requestObserver.onNext(metadata); + } + + long sendNextChunk() { + byte[] contentToSend = streamReader.getNextData(); + + if (streamReader.getLastReadSize() > 0) { + sendChunk(contentToSend, streamReader.getLastReadSize()); + } else { + endTransfer(); + } + return contentToSend.length; + } + + void endTransfer() { + done.set(true); + LOG.debug("File Transfer done. Closing stream."); + streamReader.close(); + } + + void sendChunk(byte[] content, int length) { + LOG.debug("Sending {} byte Data.", length); + var chunk = chunkBuilder.apply(content, length); + requestObserver.onNext(chunk); + } + + @RequiredArgsConstructor + class StreamReader { + + private final InputStream inStream; + private final byte[] buffer = new byte[CHUNK_SIZE]; + @Getter + private int lastReadSize = 0; + @Getter + private final AtomicBoolean done = new AtomicBoolean(false); + + byte[] getNextData() { + readNext(); + return buffer; + } + + void close() { + IOUtils.closeQuietly(inStream); + } + + void readNext() { + try { + lastReadSize = inStream.read(buffer, 0, CHUNK_SIZE); + } catch (IOException e) { + throw new TechnicalException("Error on reading a single chunk", e); + } + } + } + +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatus.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatus.java new file mode 100644 index 0000000..921a6d3 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatus.java @@ -0,0 +1,66 @@ +/* + * 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.nachrichten.postfach.bayernid; + +enum MailSendingResponseStatus { + SUCCESS("0", "Nachricht wurde erfolgreich übernommen"), + OK_KOMM_SCHEMA_ERROR("10", "Fehler im OK.KOMM-Schema"), + OK_KOMM_INVALID_SCHEMA_PARAMETER("11", "Ungültige Parameter im OK.KOMM-Schema"), + ERROR_IN_MESSAGE_SCHEMA("20", "Fehler im BSP-Nachrichtenschema"), + INVALID_POSTKORB_ID("30", "Ungültiger Postkorb-Handle"), + IMPROPER_MESSAGE_CONTENT("31", "Unzulässiger Nachrichteninhalt"), + IMPROPER_MESSAGE_ATTACHMENT("32", "Unzulässiger Nachrichtenanhang"), + TECHNICAL_ERROR("99", "Sonstiger technischer Fehler"), + UNKNOWN("-1", "Unbekannte Server Antwort"); + + private String schluessel; + private String message; + + MailSendingResponseStatus(String schluessel, String message) { + this.schluessel = schluessel; + this.message = message; + } + + public static MailSendingResponseStatus fromSchluessel(String schluessel) { + return switch (schluessel) { + case "0" -> MailSendingResponseStatus.SUCCESS; + case "10" -> MailSendingResponseStatus.OK_KOMM_SCHEMA_ERROR; + case "11" -> MailSendingResponseStatus.OK_KOMM_INVALID_SCHEMA_PARAMETER; + case "20" -> MailSendingResponseStatus.ERROR_IN_MESSAGE_SCHEMA; + case "30" -> MailSendingResponseStatus.INVALID_POSTKORB_ID; + case "31" -> MailSendingResponseStatus.IMPROPER_MESSAGE_CONTENT; + case "32" -> MailSendingResponseStatus.IMPROPER_MESSAGE_ATTACHMENT; + case "99" -> MailSendingResponseStatus.TECHNICAL_ERROR; + default -> MailSendingResponseStatus.UNKNOWN; + }; + } + + public String getSchluessel() { + return schluessel; + } + + public String getMessage() { + return message; + } +} diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java new file mode 100644 index 0000000..29457e1 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java @@ -0,0 +1,132 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static java.util.Objects.*; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; +import java.util.function.Function; + +import de.ozgcloud.common.binaryfile.BinaryFileUploadStreamObserver; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import io.grpc.stub.CallStreamObserver; +import io.grpc.stub.StreamObserver; +import lombok.Builder; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Builder +public class MessageWithFilesSender { + + static final int CHUNK_SIZE = 4 * 1024; + + @Getter + private final CompletableFuture<GrpcSendBayernIdMessageResponse> resultFuture = new CompletableFuture<>(); + private final AtomicBoolean done = new AtomicBoolean(false); + private final AtomicBoolean metaDataSent = new AtomicBoolean(false); + + private final Function<StreamObserver<GrpcSendBayernIdMessageResponse>, CallStreamObserver<GrpcSendBayernIdMessageRequest>> reqObserverBuilder; + private final GrpcSendBayernIdMessageRequest messageMetadata; + @Builder.Default + private final List<String> attachmentIds = Collections.emptyList(); + private final Function<String, BayernIdAttachment> toAttachment; + private final Function<BayernIdAttachment, GrpcSendBayernIdMessageRequest> attachmentMetadataMapper; + private final BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; + + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + private List<FileSender> fileSenders; + + public MessageWithFilesSender send() { + var responseStreamObserver = BinaryFileUploadStreamObserver.create(resultFuture, this::sendNext); + requestObserver = reqObserverBuilder.apply(responseStreamObserver); + return this; + } + + public void sendNext() { + if (done.get()) { + return; + } + waitForObserver(); + sendMetadata(); + sendAttachments(); + } + + synchronized void waitForObserver() { + while (isNull(requestObserver)) { + try { + LOG.debug("wait for observer"); + wait(300); + } catch (InterruptedException e) { + LOG.error("Error on waiting for request Observer.", e); + Thread.currentThread().interrupt(); + } + } + } + + void sendMetadata() { + if (metaDataSent.getAndSet(true)) { + return; + } + requestObserver.onNext(messageMetadata); + } + + void sendAttachments() { + if (isNull(fileSenders)) { + fileSenders = createFileSenders(); + } + fileSenders.forEach(FileSender::send); + completeRequest(); + } + + List<FileSender> createFileSenders() { + return attachmentIds.stream().map(toAttachment).map(this::buildFileSender).toList(); + } + + FileSender buildFileSender(BayernIdAttachment attachment) { + return new FileSender(chunkBuilder, requestObserver, attachmentMetadataMapper.apply(attachment), attachment.getContent()); + } + + void completeRequest() { + done.set(true); + requestObserver.onCompleted(); + } + + public void cancelOnTimeout() { + LOG.warn("File transfer canceled on timeout"); + resultFuture.cancel(true); + requestObserver.onError(new TechnicalException("Timeout on waiting for upload.")); + } + + public void cancelOnError(Throwable t) { + resultFuture.cancel(true); + requestObserver.onError(t); + } +} diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/Message.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/Message.java similarity index 87% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/Message.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/Message.java index 005db62..ec175d7 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/Message.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/Message.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import java.util.List; @@ -42,19 +42,7 @@ import lombok.ToString; @AllArgsConstructor @ToString @Builder -class Message { - - @RequiredArgsConstructor - public enum ReplyOption { - POSSIBLE(0), MANDATORY(1), FORBIDDEN(2); - - private final int numValue; - - @JsonValue - public int toValue() { - return numValue; - } - } +public class Message { @RequiredArgsConstructor public enum EidasLevel { @@ -80,6 +68,7 @@ class Message { @JsonProperty("body") private String mailBody; + @JsonProperty("isHtml") private boolean isHtml; @JsonProperty("replyAction") diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MessageAttachment.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachment.java similarity index 91% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MessageAttachment.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachment.java index f3cf571..d1612fa 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MessageAttachment.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/AttachmentService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java similarity index 59% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/AttachmentService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java index 70ceb28..0b1d1ef 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/AttachmentService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,32 +21,39 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Base64; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.Base64Utils; -import de.itvsh.kop.common.errorhandling.TechnicalException; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.AttachmentFile; +import de.ozgcloud.nachrichten.postfach.BinaryFileService; +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtService; +import lombok.val; @Service -class AttachmentService { +public class MessageAttachmentService { @Autowired - private PersistPostfachMailService persistPostfachMailService; + private PersistPostfachNachrichtService persistPostfachNachrichtService; @Autowired private BinaryFileService binaryFileService; - MessageAttachment getMessageAttachment(FileId fileId) { + public MessageAttachment getMessageAttachment(FileId fileId) { try { + val metadata = binaryFileService.getFile(fileId).getMetadata(); return MessageAttachment.builder() - .fileName(binaryFileService.getFile(fileId).getMetadata().getString("name")) + .fileName(metadata.getString("name")) .content(getAttachmentContent(fileId)) .build(); } catch (IOException e) { @@ -61,11 +68,17 @@ class AttachmentService { } private String encodeAttachmentContent(byte[] content) { - return Base64Utils.encodeToString(content); + return new String(Base64.getEncoder().encode(content)); } - String persistAttachment(String vorgangId, MessageAttachment attachment) { - return persistPostfachMailService.persistAttachment(vorgangId, attachment); + public String persistAttachment(String vorgangId, MessageAttachment attachment) { + return persistPostfachNachrichtService.persistAttachment(vorgangId, mapAttachmentFile(attachment)); + } + + AttachmentFile mapAttachmentFile(MessageAttachment attachment) { + return AttachmentFile.builder() + .name(attachment.getFileName()) + .content(() -> IOUtils.toInputStream(attachment.getContent(), Charset.defaultCharset())).build(); } InputStream getAttachmentContentStream(FileId fileId) { diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachConfiguration.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachConfiguration.java similarity index 92% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachConfiguration.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachConfiguration.java index 08e8d32..d46ca54 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachConfiguration.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachRestTemplate.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachRestTemplate.java similarity index 92% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachRestTemplate.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachRestTemplate.java index 1f6e9ed..543602e 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/MockOsiPostfachRestTemplate.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MockOsiPostfachRestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapper.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapper.java new file mode 100644 index 0000000..97b3af4 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapper.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.nachrichten.postfach.osi; + +import java.util.List; +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PostfachAddress; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) +public abstract class OsiPostfachMessageMapper { + + private static final String POSTFACH_ADDRESS_VERSION = "1.0"; + private static final int POSTFACH_ADDRESS_TYPE = 1; + + @Autowired + private MessageAttachmentService messageAttachmentService; + + @Mapping(target = "attachment", ignore = true) + @Mapping(target = "isHtml", constant = "true") + @Mapping(target = "rechtsverbindlich", constant = "false") + @Mapping(target = "eidasLevel", constant = "MEDIUM") + @Mapping(target = "postfachId", expression = "java(toPostfachId(nachricht))") + @Mapping(target = "mailBody", qualifiedByName = "replaceNewLine") + public abstract Message toOsiMessage(PostfachNachricht nachricht); + + @Mapping(target = "createdBy", ignore = true) + @Mapping(target = "id", ignore = true) + @Mapping(target = "messageCode", ignore = true) + @Mapping(target = "sentAt", ignore = true) + @Mapping(target = "sentSuccessful", ignore = true) + @Mapping(target = "createdAt", expression = "java(java.time.ZonedDateTime.now())") + @Mapping(target = "direction", constant = "IN") + @Mapping(target = "attachments", expression = "java(persistAttachements(message.getVorgangId() ,message.getAttachments()))") + @Mapping(target = "postfachAddress", expression = "java(buildPostfachAddressByPostfachId(message.getPostfachId()))") + @Mapping(target = "mailBody", qualifiedByName = "clearReceivedMessage") + public abstract PostfachNachricht toPostfachNachricht(Message message); + + List<MessageAttachment> map(List<String> attachedFileIds) { + return attachedFileIds.stream().map(FileId::from).map(fileId -> messageAttachmentService.getMessageAttachment(fileId)).toList(); + } + + List<String> persistAttachements(String vorgangId, List<MessageAttachment> attachments) { + return attachments.stream().map(attachment -> messageAttachmentService.persistAttachment(vorgangId, attachment)).toList(); + } + + @Mapping(target = "attachment", ignore = true) + @Mapping(target = "messageId", ignore = true) + String toPostfachId(PostfachNachricht nachricht) { + return Optional.ofNullable(nachricht.getPostfachAddress()) + .map(PostfachAddress::getIdentifier) + .filter(StringBasedIdentifier.class::isInstance) + .map(StringBasedIdentifier.class::cast) + .map(StringBasedIdentifier::getPostfachId) + .orElse(nachricht.getPostfachId()); + } + + PostfachAddress buildPostfachAddressByPostfachId(String postfachId) { + return PostfachAddress.builder() + .type(POSTFACH_ADDRESS_TYPE) + .version(POSTFACH_ADDRESS_VERSION) + .identifier(StringBasedIdentifier.builder().postfachId(postfachId).build()) + .serviceKontoType(OsiPostfachRemoteService.POSTFACH_TYPE) + .build(); + + } + + @Named("replaceNewLine") + String replaceNewlines(String nachricht) { + return Optional.ofNullable(nachricht).map(str -> str.replaceAll("(\r\n|\n)", "<br>")).orElse(null); + } + + @Named("clearReceivedMessage") + String clearReceivedMessage(String nachricht) { + return Optional.ofNullable(nachricht).map(str -> str.replace("&", "&")).orElse(null); + } +} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachProperties.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachProperties.java similarity index 89% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachProperties.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachProperties.java index 09e5a27..4912cda 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachProperties.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -34,9 +34,9 @@ import lombok.Setter; @Setter @Configuration @ConfigurationProperties(prefix = OsiPostfachProperties.PROXY_API_PREFIX) -class OsiPostfachProperties { +public class OsiPostfachProperties { - static final String PREFIX = "kop.osi.postfach"; + static final String PREFIX = "ozgcloud.osi.postfach"; static final String PROXY_API_PREFIX = PREFIX + ".proxyapi"; private String url; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachService.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteService.java similarity index 71% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachService.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteService.java index 92ef02e..cd56c72 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachService.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import java.util.Arrays; import java.util.Objects; import java.util.function.Supplier; import java.util.stream.Stream; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -40,12 +41,22 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; +import de.ozgcloud.nachrichten.postfach.NotConfiguredException; +import de.ozgcloud.nachrichten.postfach.PostfachBadRequestException; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachRemoteService; +import de.ozgcloud.nachrichten.postfach.PostfachRuntimeException; import lombok.extern.log4j.Log4j2; @Service @Log4j2 -class OsiPostfachService { +@ConditionalOnProperty(prefix = OsiPostfachProperties.PROXY_API_PREFIX, name = { "url", "key", "realm" }) +class OsiPostfachRemoteService implements PostfachRemoteService { + static final String POSTFACH_TYPE = "OSI"; + + @Autowired + private OsiPostfachMessageMapper mapper; @Autowired private OsiPostfachProperties properties; @Autowired(required = false) @@ -53,12 +64,26 @@ class OsiPostfachService { @PostConstruct public void init() { + LOG.info("OSI Postfach remote service initialized."); if (isNotConfigured()) { LOG.warn("OSI Postfach Api not configured. Failed to read config " + OsiPostfachProperties.PROXY_API_PREFIX); } } - public Stream<Message> getAllMessages() { + @Override + public void sendMessage(PostfachNachricht nachricht) { + checkWhetherIsConfigured(); + + HttpEntity<Message> request = new HttpEntity<>(mapper.toOsiMessage(nachricht)); + + var response = executeHandlingException( + () -> restTemplate.exchange(properties.getUrl(), HttpMethod.POST, request, String.class)); + + sentFailed(response); + } + + @Override + public Stream<PostfachNachricht> getAllMessages() { checkWhetherIsConfigured(); ResponseEntity<Message[]> response = executeHandlingException( @@ -68,18 +93,7 @@ class OsiPostfachService { LOG.warn("OSI Postfach response with an empty body"); return Stream.empty(); } - return Arrays.stream(response.getBody()); - } - - public void sendMessage(Message message) { - checkWhetherIsConfigured(); - - HttpEntity<Message> request = new HttpEntity<>(message); - - var response = executeHandlingException( - () -> restTemplate.exchange(properties.getUrl(), HttpMethod.POST, request, String.class)); - - sentFailed(response); + return Arrays.stream(response.getBody()).map(mapper::toPostfachNachricht); } private void sentFailed(ResponseEntity<String> response) { @@ -92,6 +106,7 @@ class OsiPostfachService { return StringUtils.equals(response.getBody(), String.valueOf(false)); } + @Override public void deleteMessage(String messageId) { checkWhetherIsConfigured(); @@ -105,10 +120,6 @@ class OsiPostfachService { } } - public boolean isConfigured() { - return !isNotConfigured(); - } - private boolean isNotConfigured() { return Objects.isNull(restTemplate) || Objects.isNull(properties.getUrl()) || Objects.isNull(properties.getKey()); } @@ -117,9 +128,20 @@ class OsiPostfachService { try { return runnable.get(); } catch (HttpClientErrorException e) { - throw new OsiPostfachBadRequestException(e); + throw new PostfachBadRequestException(e); } catch (RuntimeException e) { - throw new OsiPostfachRuntimeException(e); + throw new PostfachRuntimeException(e); } } + + @Override + public String getPostfachType() { + return POSTFACH_TYPE; + } + + @Override + public boolean isReplyAllowed() { + return true; + } + } \ No newline at end of file diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessException.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessException.java new file mode 100644 index 0000000..4dd4862 --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessException.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.nachrichten.postfach.osi; + +import de.ozgcloud.nachrichten.postfach.PostfachException; +import de.ozgcloud.nachrichten.postfach.PostfachMessageCode; + +public class OsiPostfachServerProcessException extends PostfachException {// NOSONAR + + private static final long serialVersionUID = 1L; + + OsiPostfachServerProcessException() { + super("Postfach server returned false", PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + } +} \ No newline at end of file diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachConfiguration.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/PostfachConfiguration.java similarity index 81% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachConfiguration.java rename to nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/PostfachConfiguration.java index cf84089..e8fab9c 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/PostfachConfiguration.java +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/PostfachConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import java.util.Objects; import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.CredentialsProvider; +import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; +import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.HttpHost; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.client.RestTemplateBuilder; @@ -77,19 +78,21 @@ public class PostfachConfiguration implements RestTemplateCustomizer { .setProxy(proxy).setDefaultCredentialsProvider(buildCredentialsProvider(proxy)) .build(); + HttpClients.custom().build(); restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient)); } private CredentialsProvider buildCredentialsProvider(HttpHost proxyHost) { var proxyConfig = properties.getProxyConfiguration(); - if (!proxyConfig.isAuthenticationRequired()) + if (!proxyConfig.isAuthenticationRequired()) { return null; + } - CredentialsProvider credsProvider = new BasicCredentialsProvider(); + var credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(proxyHost), - new UsernamePasswordCredentials(proxyConfig.getUsername(), proxyConfig.getPassword())); + new UsernamePasswordCredentials(proxyConfig.getUsername(), proxyConfig.getPassword().toCharArray())); return credsProvider; } diff --git a/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/ReplyOption.java b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/ReplyOption.java new file mode 100644 index 0000000..148e61e --- /dev/null +++ b/nachrichten-manager/src/main/java/de/ozgcloud/nachrichten/postfach/osi/ReplyOption.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.nachrichten.postfach.osi; + +import com.fasterxml.jackson.annotation.JsonValue; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum ReplyOption { + POSSIBLE(0), MANDATORY(1), FORBIDDEN(2); + + private final int numValue; + + @JsonValue + public int toValue() { + return numValue; + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/nachrichten-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..08abec6 --- /dev/null +++ b/nachrichten-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,20 @@ +net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcHealthServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration diff --git a/nachrichten-manager/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl b/nachrichten-manager/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl new file mode 100644 index 0000000..a2df760 --- /dev/null +++ b/nachrichten-manager/src/main/resources/bayernid/PostfachnachrichtenServiceBy.wsdl @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<definitions name="PostkorbKommService" + xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:bsp="http://akdb.de/portal/gehaltsabrechnungen-bspnachricht" + xmlns:tns="urn:akdb:bsp:postkorb:komm:webservice" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="urn:akdb:bsp:postkorb:komm:webservice"> + <types> + <xs:schema + targetNamespace='urn:akdb:bsp:postkorb:komm:webservice' version='1.1' + xmlns:tns='urn:akdb:bsp:postkorb:komm:webservice' + xmlns:xs='http://www.w3.org/2001/XMLSchema'> + <xs:element name='sendBspNachricht' + type='tns:sendBspNachricht' /> + <xs:complexType name='sendBspNachricht'> + <xs:sequence> + <xs:element minOccurs='1' name='okKommBspNachrichtInput' + type='xs:base64Binary' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtOutput' + type='tns:sendBspNachrichtOutput' /> + <xs:complexType name='sendBspNachrichtOutput'> + <xs:sequence> + <xs:element minOccurs='1' + name='okKommBspNachrichtOutput' type='xs:base64Binary' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtNative' + type='tns:sendBspNachrichtNative' /> + <xs:complexType name='sendBspNachrichtNative'> + <xs:sequence> + <xs:element minOccurs='1' name='bspNachricht' + type='xs:string' /> + </xs:sequence> + </xs:complexType> + <xs:element name='sendBspNachrichtNativeOutput' + type='tns:sendBspNachrichtNativeOutput' /> + <xs:complexType name='sendBspNachrichtNativeOutput'> + <xs:sequence> + <xs:element minOccurs='1' name='bspQuittung' + type='xs:string' /> + </xs:sequence> + </xs:complexType> + </xs:schema> + </types> + <message name='PostkorbKommService_sendBspNachrichtInput'> + <part element='tns:sendBspNachricht' + name='okKommBspNachrichtInput'></part> + </message> + <message name='PostkorbKommService_sendBspNachrichtOutput'> + <part element='tns:sendBspNachrichtOutput' + name='sendBspNachrichtOutput'></part> + </message> + <message name='PostkorbKommService_sendBspNachrichtNativeInput'> + <part element='tns:sendBspNachrichtNative' + name='sendBspNachrichtNative'></part> + </message> + <message + name='PostkorbKommService_sendBspNachrichtNativeOutput'> + <part element='tns:sendBspNachrichtNativeOutput' + name='bspQuittung'></part> + </message> + <portType name='PostkorbKommPortType'> + <operation name='sendBspNachricht'> + <input message='tns:PostkorbKommService_sendBspNachrichtInput'></input> + <output + message='tns:PostkorbKommService_sendBspNachrichtOutput'></output> + </operation> + <operation name='sendBspNachrichtNative'> + <input + message='tns:PostkorbKommService_sendBspNachrichtNativeInput'></input> + <output + message='tns:PostkorbKommService_sendBspNachrichtNativeOutput'></output> + </operation> + </portType> + <binding name="PostkorbKommBinding" + type="tns:PostkorbKommPortType"> + <soap:binding style="document" + transport="http://schemas.xmlsoap.org/soap/http" /> + <operation name='sendBspNachricht'> + <soap:operation soapAction='' /> + <input> + <soap:body use='literal' /> + </input> + <output> + <soap:body use="literal" /> + </output> + </operation> + <operation name='sendBspNachrichtNative'> + <soap:operation soapAction='' /> + <input> + <soap:body use='literal' /> + </input> + <output> + <soap:body use="literal" /> + </output> + </operation> + </binding> + <service name="PostkorbKommService"> + <port name="PostkorbKommPort" binding="tns:PostkorbKommBinding"> + <!-- <soap:address location="${web-services-base- url}/bspservices/postkorbkomm" + /> --> + <soap:address location="http://localhost:8080/bspx-postkorb-okkomm-ws/bspservices/postkorbkomm" /> + </port> + </service> +</definitions> diff --git a/nachrichten-manager/src/main/resources/bayernid/bspnachrichten-2.13.xsd b/nachrichten-manager/src/main/resources/bayernid/bspnachrichten-2.13.xsd new file mode 100644 index 0000000..23b0e24 --- /dev/null +++ b/nachrichten-manager/src/main/resources/bayernid/bspnachrichten-2.13.xsd @@ -0,0 +1,343 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Service- und Portalplattform + AKDB München, Geschäftsfeld eGovernment + + Copyright (c) AKDB + +--> +<xsd:schema targetNamespace="http://www.akdb.de/egov/bsp/nachrichten" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:bsp="http://www.akdb.de/egov/bsp/nachrichten" + elementFormDefault="qualified"> + + <xsd:element name="BspNachricht"> + <xsd:annotation> + <xsd:appinfo> + <title>Nachricht für die Kommunikation zwischen Bürgerservice-Portal + und externen Fachverfahren</title> + </xsd:appinfo> + <xsd:documentation>Einheitliches Nachrichtenschema für die + Kommunikation zwischen Bürgerservice-Portal und externem Verfahren. + Nachrichten vom Bürgerservice-Portal an den Postkorb eines + Verfahrens + oder Nachrichten von den Verfahren an das Bürgerservice-Portal müssen + gemäß diesem Schema aufgebaut sein. + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="NachrichtenKopf" type="bsp:NachrichtenKopfType"/> + <xsd:element name="NachrichtenInhalt" type="bsp:NachrichtenInhaltType"/> + </xsd:sequence> + <xsd:attribute name="version" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet die + Nachrichten-Version, z. B. "1.0", "1.1".</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.1"/> + <xsd:enumeration value="1.2"/> + <xsd:enumeration value="1.3"/> + <xsd:enumeration value="1.4"/> + <xsd:enumeration value="1.5"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="fassung" use="required" > + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet das Datum, an dem + die diesen Schemata im Status final produziert wurde. Format: + YYYY-MM-DD.</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="2017-03-15"/> + <xsd:enumeration value="2018-04-01"/> + <xsd:enumeration value="2018-11-01"/> + <xsd:enumeration value="2019-06-28"/> + <xsd:enumeration value="2020-03-15"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="produkt" type="xsd:string" use="optional"> + <xsd:annotation> + <xsd:documentation>In diesem Attribut ist der Name des Produktes + (der Software) einzutragen, mit dem diese Nachricht erstellt + worden ist. z.B. BSP, PWS</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="produkthersteller" type="xsd:string" use="optional"/> + <xsd:attribute name="produktversion" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="BspQuittung"> + <xsd:annotation> + <xsd:appinfo> + <title>Quittung über den Empfang einer BSO-Nachricht</title> + </xsd:appinfo> + <xsd:documentation>Zu einer empfangenen BSP-Nachricht wird eine + Quittung geliefert, die bestätigt, dass die Nachricht übernommen wurde + oder aufgrund eines technischen oder fachlichen Fehlers abgewiesen wurde. + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="AnnahmeErfolgreich" type="xsd:boolean" minOccurs="1" maxOccurs="1"/> + <xsd:element name="ErgebnisStatus" type="bsp:SchluesseltabelleType" minOccurs="1" maxOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9006 (0 (erfolgreich angenommen), 99 (sonstiger technischer Fehler), ...)</xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="ErgaenzendeHinweise" type="xsd:string" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + <xsd:attribute name="version" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet die + Nachrichten-Version, z. B. "1.0", "1.1".</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.1"/> + <xsd:enumeration value="1.2"/> + <xsd:enumeration value="1.3"/> + <xsd:enumeration value="1.4"/> + <xsd:enumeration value="1.5"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="fassung" use="required"> + <xsd:annotation> + <xsd:documentation>Dieses Attribut kennzeichnet das Datum, an dem + die diesen Schemata im Status final produziert wurde. Format: + YYYY-MM-DD.</xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="2017-03-15"/> + <xsd:enumeration value="2018-04-01"/> + <xsd:enumeration value="2018-11-01"/> + <xsd:enumeration value="2019-06-28"/> + <xsd:enumeration value="2020-03-15"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="produkt" type="xsd:string" use="optional"> + <xsd:annotation> + <xsd:documentation>In diesem Attribut ist der Name des Produktes + (der Software) einzutragen, mit dem diese Nachricht erstellt + worden ist. z.B. BSP, PWS</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="produkthersteller" type="xsd:string" use="optional"/> + <xsd:attribute name="produktversion" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="NachrichtenKopfType"> + <xsd:sequence> + <xsd:element name="Identifikation.Nachricht" type="bsp:Identifikation.NachrichtType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Anwenderkennung" type="xsd:string" minOccurs="0"> + <xsd:annotation> + <xsd:documentation> Die Anwenderkennung stellt Informationen über die absendende Person + zur Verfügung und dient der Protokollierung. + Anhand dieser Kennung kann die absendende Person identifiziert werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Absender" type="bsp:AbsenderType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Empfaenger" type="bsp:EmpfaengerType" maxOccurs="1" minOccurs="1"/> + <xsd:element name="AntwortAuf" type="xsd:string" maxOccurs="1" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Eine Nachricht kann mit einer exisiterenden + Nachricht in Beziehung gebracht werden als Antwortnachricht oder + weitergeleitete Nachricht. Der Bezug erfolgt hierbei über die + NachrichtenId. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="WeiterleitungZu" type="xsd:string" minOccurs="0"/> + <xsd:element name="lesebestaetigungAntwortAdresse" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="Identifikation.NachrichtType"> + <xsd:sequence> + <xsd:element name="Ereignis" type="bsp:SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9001, Schluessel: BspNachricht + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Erstellungszeitpunkt" type="xsd:dateTime" maxOccurs="1" minOccurs="1"/> + <xsd:element name="NachrichtenId" type="xsd:string" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>eine beliebige, eindeutige ID, die durch den + erstellenden Client generiert wird. Zusammen mit + Erstellungszeitpunkt und Absender kann eine Nachricht bsp-global + eindeutig identifiziert werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="AbsenderType"> + <xsd:sequence> + <xsd:element name="PostkorbId" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Verfahren" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Dienst" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Mandant" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Gemeindeschluessel" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Der amtliche Gemeindeschlüssel (AGS). + Als Tabellennummer ist hier die 36 (OSCI-XMeld-Schlüsseltabelle "Amtlicher Gemeindeschluessel") zu verwenden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Name" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Anschrift" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Email" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Telefon" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Hyperlink" type="xsd:string" maxOccurs="1" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="EmpfaengerType"> + <xsd:sequence> + <xsd:element name="PostkorbId" type="xsd:string" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Verfahren" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Dienst" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Mandant" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Gemeindeschluessel" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Der amtliche Gemeindeschlüssel (AGS). + Als Tabellennummer ist hier die 36 (OSCI-XMeld-Schlüsseltabelle "Amtlicher Gemeindeschluessel") zu verwenden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Name" type="xsd:string" maxOccurs="1" minOccurs="0"/> + <xsd:element name="Anschrift" type="xsd:string" maxOccurs="1" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="NachrichtenInhaltType"> + <xsd:sequence> + <xsd:element name="Betreff" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="1"/> + <xsd:element name="Kategorie" type="bsp:SchluesseltabelleType" minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9002 (KAT_STATUS, KAT_INFOBSP, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:choice minOccurs="0"> + <xsd:element name="StorkQaaLevel" type="bsp:StorkQaaLevel"/> + <xsd:element name="NpaGescheutzt" type="xsd:boolean" > + <!-- deprecated, wird durch StorkQaaLevel="STORK-QAA-Level-1" ersetzt --> + <xsd:annotation> + <xsd:documentation> + Diese Nachricht kann im BüsP-Postkorb nur nach + vorheriger Anmeldung mit dem nPA gelesen werden. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:choice> + <xsd:element name="ZuVorgang" type="bsp:ZuVorgangType" minOccurs="0"/> + <xsd:element name="FreiText" type="bsp:FreiTextType"/> + <xsd:element name="DataContainer" type="bsp:DataContainerType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ZuVorgangType"> + <xsd:annotation> + <xsd:documentation>VorgangsName oder VorgangsId müssen angegeben + werden. Es können auch beide angegeben werden.</xsd:documentation> + </xsd:annotation> + <xsd:sequence minOccurs="0"> + <xsd:element name="VorgangsName" type="xsd:string"/> + <xsd:element name="VorgangsId" type="xsd:string"/> + <xsd:element name="VorgangStatus" type="bsp:SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9003 (ST_ERHALTEN, ST_GELESEN,...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="FreiTextType"> + <xsd:sequence> + <xsd:element name="Encoding" type="bsp:SchluesseltabelleType" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9004 (text/plain, text/html, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Text" type="bsp:NonEmptyString" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation> + Wenn als Encoding text/plain festgelegt ist, so wird die Zeichensequenz "\n" als ein Zeilenvorschub interpretiert. + Das Backslash-Zeichen (\) wird mit einem weiteren Backslash-Zeichen entwertet. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="DataContainerType"> + <xsd:sequence minOccurs="0"> + <xsd:element name="Inhalt" type="xsd:base64Binary" maxOccurs="1" minOccurs="1"/> + <xsd:element name="FileName" maxOccurs="1" minOccurs="0"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:maxLength value="255"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:element> + <xsd:element name="FileType" type="bsp:SchluesseltabelleType" maxOccurs="1" minOccurs="1"> + <xsd:annotation> + <xsd:documentation>Schluesseltabelle 9005 (application/pdf, text/html, ...) + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="SchluesseltabelleType"> + <xsd:annotation> + <xsd:documentation>Dieser Datentyp wird für Schlüsselwerte benötigt. + Mit dem Datentyp SchluesseltabelleType übermittelt man den Schlüssel + und die Nummer der Tabelle, in der das Schlüssel-Wert Paar definiert + worden ist. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="Tabelle" type="xsd:string"/> + <xsd:element name="Schluessel" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="StorkQaaLevel"> + <xsd:restriction base="xsd:string"> + <!-- since version 1.2 - deprecated --> + <xsd:enumeration value="LEVEL_1"/> + <xsd:enumeration value="LEVEL_2"/> + <xsd:enumeration value="LEVEL_3"/> + <xsd:enumeration value="LEVEL_4"/> + <!-- since version 1.3 --> + <xsd:enumeration value="STORK-QAA-Level-1"/> + <xsd:enumeration value="STORK-QAA-Level-2"/> + <xsd:enumeration value="STORK-QAA-Level-3"/> + <xsd:enumeration value="STORK-QAA-Level-4"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="NonEmptyString"> + <xsd:restriction base="xsd:string"> + <xsd:minLength value="1"/> + </xsd:restriction> + </xsd:simpleType> +</xsd:schema> + + diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteServiceTest.java similarity index 88% rename from mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteServiceTest.java index 3857109..7771926 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeRemoteServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeRemoteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -35,10 +35,10 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; class ClientAttributeRemoteServiceTest { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeServiceTest.java similarity index 94% rename from mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeServiceTest.java index 35e5819..374967d 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; import static org.mockito.Mockito.*; diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcClientAttributeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcClientAttributeTestFactory.java similarity index 81% rename from mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcClientAttributeTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcClientAttributeTestFactory.java index e804ea6..7593a73 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcClientAttributeTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcClientAttributeTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; public class GrpcClientAttributeTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcSetClientAttributeRequestTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcSetClientAttributeRequestTestFactory.java similarity index 82% rename from mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcSetClientAttributeRequestTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcSetClientAttributeRequestTestFactory.java index 3a932a0..f4a3c30 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/attributes/GrpcSetClientAttributeRequestTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/attributes/GrpcSetClientAttributeRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; class GrpcSetClientAttributeRequestTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/EMailServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EMailServiceTest.java similarity index 95% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/EMailServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EMailServiceTest.java index 2ef4b81..8da592d 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/EMailServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EMailServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; -import static de.itvsh.ozg.mail.email.MailSendRequestTestFactory.*; +import static de.ozgcloud.nachrichten.email.MailSendRequestTestFactory.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import javax.activation.DataSource; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; +import jakarta.activation.DataSource; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; -import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -43,7 +42,7 @@ import org.springframework.mail.MailSendException; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; -import java.util.Arrays; +import lombok.SneakyThrows; class EMailServiceTest { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/EmailGrpcServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EmailGrpcServiceTest.java similarity index 96% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/EmailGrpcServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EmailGrpcServiceTest.java index fca7339..d8a8332 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/EmailGrpcServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/EmailGrpcServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import io.grpc.stub.StreamObserver; import lombok.SneakyThrows; diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcNotificationRecipientsTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcNotificationRecipientsTestFactory.java similarity index 93% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcNotificationRecipientsTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcNotificationRecipientsTestFactory.java index d5fe98a..223c85b 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcNotificationRecipientsTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcNotificationRecipientsTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; public class GrpcNotificationRecipientsTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcRecipientTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcRecipientTestFactory.java similarity index 92% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcRecipientTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcRecipientTestFactory.java index 6183610..a9350ed 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/GrpcRecipientTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/GrpcRecipientTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; public class GrpcRecipientTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailRecipientTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailRecipientTestFactory.java similarity index 92% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/MailRecipientTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailRecipientTestFactory.java index 83bed7a..476b56a 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailRecipientTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailRecipientTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; public class MailRecipientTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendErrorEventTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendErrorEventTestFactory.java similarity index 91% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendErrorEventTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendErrorEventTestFactory.java index e737a4f..89ced29 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendErrorEventTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendErrorEventTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; public class MailSendErrorEventTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendRequestTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendRequestTestFactory.java similarity index 90% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendRequestTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendRequestTestFactory.java index 9e25737..fbb06c7 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSendRequestTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSendRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import java.util.UUID; -import javax.mail.util.ByteArrayDataSource; - -import de.itvsh.ozg.mail.email.MailSendRequest.MailAttachment; +import de.ozgcloud.nachrichten.email.MailSendRequest.MailAttachment; +import jakarta.mail.util.ByteArrayDataSource; class MailSendRequestTestFactory { diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSentEventTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSentEventTestFactory.java similarity index 91% rename from mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSentEventTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSentEventTestFactory.java index 3a439b0..b7a75c6 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/email/MailSentEventTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/email/MailSentEventTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; public class MailSentEventTestFactory { diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachAddressTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachAddressTestFactory.java new file mode 100644 index 0000000..45fceb5 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachAddressTestFactory.java @@ -0,0 +1,51 @@ +/* + * 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.nachrichten.postfach; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; + +public class GrpcPostfachAddressTestFactory { + + public static GrpcPostfachAddress create() { + return createBuilder().build(); + } + + public static GrpcPostfachAddress.Builder createBuilder() { + return GrpcPostfachAddress.newBuilder() + .setType(PostfachAddressTestFactory.TYPE) + .setIdentifier(createIdentifier()) + .setVersion(PostfachAddressTestFactory.VERSION) + .setServiceKontoType(PostfachTestFactory.POSTFACH_TYPE); + } + + public static GrpcObject createIdentifier() { + return GrpcObject.newBuilder() + .addProperty(GrpcProperty.newBuilder() + .setName(PostfachNachricht.FIELD_POSTFACH_ID) + .addValue(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build()) + .build(); + } +} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcPostfachMailTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java similarity index 73% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcPostfachMailTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java index 67ae8ce..fd40280 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcPostfachMailTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; -import static de.itvsh.ozg.mail.postfach.MessageTestFactory.*; -import static de.itvsh.ozg.mail.postfach.PostfachMailTestFactory.*; +import static de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory.*; +import static de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory.*; public class GrpcPostfachMailTestFactory { @@ -37,6 +37,7 @@ public class GrpcPostfachMailTestFactory { .setId(ID) .setVorgangId(VORGANG_ID) .setPostfachId(POSTFACH_ID) + .setPostfachAddress(GrpcPostfachAddressTestFactory.create()) .setCreatedAt(CREATED_AT_STR) .setCreatedBy(CREATED_BY) .setSentAt(SENT_AT_STR) @@ -44,8 +45,8 @@ public class GrpcPostfachMailTestFactory { .setMessageCode(MESSAGE_CODE) .setDirection(GrpcDirection.valueOf(DIRECTION.name())) .setSubject(SUBJECT) - .setMailBody(MAIL_BODY) - .setReplyOption(REPLY_OPTION.name()) - .addAllAttachment(PostfachMailTestFactory.ATTACHMENTS); + .setMailBody(PostfachNachrichtTestFactory.MAIL_BODY) + .setReplyOption(PostfachNachrichtTestFactory.REPLY_OPTION.name()) + .addAllAttachment(PostfachNachrichtTestFactory.ATTACHMENTS); } } \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcResendPostfachMailRequestTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcResendPostfachMailRequestTestFactory.java similarity index 84% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcResendPostfachMailRequestTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcResendPostfachMailRequestTestFactory.java index 4746b78..12962e5 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcResendPostfachMailRequestTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcResendPostfachMailRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.util.UUID; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcUser; +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.vorgang.grpc.command.GrpcUser; public class GrpcResendPostfachMailRequestTestFactory { @@ -41,6 +41,6 @@ public class GrpcResendPostfachMailRequestTestFactory { return GrpcResendPostfachMailRequest.newBuilder() .setContext(GrpcCallContext.newBuilder().setUser(GrpcUser.newBuilder().setId(USER_ID).build()).build()) .setCommandId(COMMAND_ID) - .setPostfachMailId(PostfachMailTestFactory.ID); + .setPostfachMailId(PostfachNachrichtTestFactory.ID); } } diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSaveNachrichtDraftRequestTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSaveNachrichtDraftRequestTestFactory.java new file mode 100644 index 0000000..904c223 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSaveNachrichtDraftRequestTestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach; + +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +public class GrpcSaveNachrichtDraftRequestTestFactory { + + static GrpcSaveNachrichtDraftRequest create() { + return createBuilder().build(); + } + + static GrpcSaveNachrichtDraftRequest.Builder createBuilder() { + return GrpcSaveNachrichtDraftRequest.newBuilder() + .setVorgangId(MessageTestFactory.VORGANG_ID); + + } +} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcSendPostfachMailRequestTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSendPostfachMailRequestTestFactory.java similarity index 88% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcSendPostfachMailRequestTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSendPostfachMailRequestTestFactory.java index de307cc..6635cfd 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/GrpcSendPostfachMailRequestTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcSendPostfachMailRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import java.util.UUID; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcUser; +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.vorgang.grpc.command.GrpcUser; class GrpcSendPostfachMailRequestTestFactory { diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachAddressTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachAddressTestFactory.java new file mode 100644 index 0000000..572b41d --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachAddressTestFactory.java @@ -0,0 +1,47 @@ +/* + * 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.nachrichten.postfach; + +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +public class PostfachAddressTestFactory { + + public final static int TYPE = 1; + public static final String STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE = MessageTestFactory.POSTFACH_ID; + public final static StringBasedIdentifier IDENTIFIER = StringBasedIdentifier.builder().postfachId(STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build(); + public static final String VERSION = "1.0"; + + public static PostfachAddress create() { + return createBuilder().build(); + } + + public static PostfachAddress.PostfachAddressBuilder createBuilder() { + return PostfachAddress.builder() + .type(TYPE) + .identifier(IDENTIFIER) + .version(VERSION) + .serviceKontoType(PostfachTestFactory.POSTFACH_TYPE); + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java new file mode 100644 index 0000000..7d26e95 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java @@ -0,0 +1,215 @@ +/* + * 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.nachrichten.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +class PostfachEventListenerTest { + + @InjectMocks + private PostfachEventListener listener; + + @Mock + private PostfachService service; + @Mock + private Command command; + + @Captor + private ArgumentCaptor<PostfachNachricht> nachrichtCaptor; + + @DisplayName("Send postfach nachricht") + @Nested + class TestSendPostfachNachricht { + + private static final String COMMAND_ID = UUID.randomUUID().toString(); + private static final String USER_ID = PostfachNachrichtTestFactory.CREATED_BY; + + @BeforeEach + void mockCommand() { + when(command.getId()).thenReturn(COMMAND_ID); + when(command.getCreatedBy()).thenReturn(USER_ID); + when(command.getVorgangId()).thenReturn(MessageTestFactory.VORGANG_ID); + when(command.getRelationId()).thenReturn(MessageTestFactory.VORGANG_ID); + when(command.getBodyObject()).thenReturn(buildCommandBody()); + } + + @Test + void shouldCallService() { + listener.sendPostfachNachricht(new CommandCreatedEvent(command)); + + verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); + assertThat(nachrichtCaptor.getValue()) + .usingRecursiveComparison().ignoringFields("id", "createdAt", "messageCode", "messageId", "sentAt", "sentSuccessful") + .isEqualTo(PostfachNachrichtTestFactory.createBuilder().direction(Direction.OUT).build()); + } + + @Test + void shouldNotHaveIdForNewNachricht() { + listener.sendPostfachNachricht(new CommandCreatedEvent(command)); + + verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); + assertThat(nachrichtCaptor.getValue().getId()).isNull(); + } + + @Test + void shouldHaveIdForSavedNachricht() { + when(command.getRelationId()).thenReturn(PostfachNachrichtTestFactory.ID); + + listener.sendPostfachNachricht(new CommandCreatedEvent(command)); + + verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); + assertThat(nachrichtCaptor.getValue().getId()).isEqualTo(PostfachNachrichtTestFactory.ID); + } + + @DisplayName("with postfachAddress") + @Nested + class TestWithPostfachAddress { + + @BeforeEach + void mockCommandBodyObject() { + var body = buildCommandBody(); + body.remove(PostfachNachricht.FIELD_POSTFACH_ID); + when(command.getBodyObject()).thenReturn(body); + } + + @Test + void shouldHandleEmptyPostfachId() { + var postfachMailToSend = sendPostfachNachricht(); + + assertThat(postfachMailToSend.getPostfachId()).isNull(); + } + } + + @DisplayName("with postfachId") + @Nested + class TestWithPostfachId { + + @BeforeEach + void mockCommandBodyObject() { + var body = buildCommandBody(); + body.remove(PostfachNachricht.POSTFACH_ADDRESS_FIELD); + when(command.getBodyObject()).thenReturn(body); + } + + @Test + void shouldHandleEmptyPostfachAddress() { + var postfachMailToSend = sendPostfachNachricht(); + + assertThat(postfachMailToSend.getPostfachAddress()).isNull(); + } + } + + private PostfachNachricht sendPostfachNachricht() { + listener.sendPostfachNachricht(new CommandCreatedEvent(command)); + + verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); + + return nachrichtCaptor.getValue(); + } + + private Map<String, Object> buildCommandBody() { + var map = new HashMap<String, Object>(); + map.putAll(Map.of( + PostfachNachricht.FIELD_VORGANG_ID, "fake", + PostfachNachricht.FIELD_POSTFACH_ID, MessageTestFactory.POSTFACH_ID, + PostfachNachricht.POSTFACH_ADDRESS_FIELD, // + Map.of(PostfachAddress.VERSION_FIELD, PostfachAddressTestFactory.VERSION, + PostfachAddress.TYPE_FIELD, PostfachAddressTestFactory.TYPE, + PostfachAddress.SERVICEKONTO_TYPE_FIELD, PostfachTestFactory.POSTFACH_TYPE, + PostfachAddress.IDENTIFIER_FIELD, // + Map.of(PostfachNachricht.FIELD_POSTFACH_ID, PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE)), + PostfachNachricht.FIELD_SUBJECT, MessageTestFactory.SUBJECT, + PostfachNachricht.FIELD_MAIL_BODY, PostfachNachrichtTestFactory.MAIL_BODY, + PostfachNachricht.FIELD_REPLY_OPTION, PostfachNachrichtTestFactory.REPLY_OPTION.name(), + PostfachNachricht.FIELD_ATTACHMENTS, PostfachNachrichtTestFactory.ATTACHMENTS)); + return map; + } + } + + @DisplayName("Get string list value") + @Nested + class TestGetStringListValue { + + @Test + void shouldReturnMultipleValuesFieldAsStringList() { + var commandBodyMap = new HashMap<String, Object>(); + commandBodyMap.put(PostfachNachricht.FIELD_ATTACHMENTS, List.of("1", "2")); + + var list = listener.getStringListValue(commandBodyMap, PostfachNachricht.FIELD_ATTACHMENTS); + + assertThat(list).contains("1").contains("2"); + } + + @Test + void shouldReturnSingleValueFieldAsStringList() { + var commandBodyMap = new HashMap<String, Object>(); + commandBodyMap.put(PostfachNachricht.FIELD_ATTACHMENTS, List.of("1", "2")); + + var list = listener.getStringListValue(commandBodyMap, PostfachNachricht.FIELD_ATTACHMENTS); + + assertThat(list).contains("1").contains("2"); + } + + @Test + void shouldReturnEmptyFieldValueAsEmptyCollection() { + var commandBodyMap = new HashMap<String, Object>(); + commandBodyMap.put(PostfachNachricht.FIELD_ATTACHMENTS, Collections.emptyList()); + + var list = listener.getStringListValue(commandBodyMap, PostfachNachricht.FIELD_ATTACHMENTS); + + assertThat(list).isEmpty(); + } + + @Test + void shouldReturnEmptyFieldAsEmptyCollection() { + var commandBodyMap = new HashMap<String, Object>(); + + var list = listener.getStringListValue(commandBodyMap, PostfachNachricht.FIELD_ATTACHMENTS); + + assertThat(list).isEmpty(); + } + } +} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachGrpcServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcServiceTest.java similarity index 60% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachGrpcServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcServiceTest.java index 649fc76..dae4307 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachGrpcServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachGrpcServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.stream.Stream; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -37,26 +39,69 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; import io.grpc.stub.StreamObserver; class PostfachGrpcServiceTest { - @InjectMocks // NOSONAR + @InjectMocks private PostfachGrpcService service; + @Mock private PostfachService postfachService; + @Mock + private GrpcPostfachNachrichtMapper nachrichtMapper; + @Mock + private PostfachMapper postfachMapper; @Spy - private PostfachMailMapper mapper = Mappers.getMapper(PostfachMailMapper.class); + private PostfachNachrichtMapper mapper = Mappers.getMapper(PostfachNachrichtMapper.class); + + @Nested + class TestSaveNachrichtDraft { + + @Mock + private StreamObserver<GrpcSaveNachrichtDraftResponse> responseObserver; + + @BeforeEach + void init() { + when(nachrichtMapper.mapFromGrpc(any())).thenReturn(PostfachNachrichtTestFactory.create()); + } + + @Test + void shouldCallService() { + var nachricht = PostfachNachrichtTestFactory.create(); + when(nachrichtMapper.mapFromGrpc(any())).thenReturn(nachricht); + + service.saveNachrichtDraft(GrpcSaveNachrichtDraftRequestTestFactory.create(), responseObserver); + + verify(postfachService).saveDraft(MessageTestFactory.VORGANG_ID, nachricht); + } + + @Test + void shouldSendResponse() { + service.saveNachrichtDraft(GrpcSaveNachrichtDraftRequestTestFactory.create(), responseObserver); + + verify(responseObserver).onNext(any()); + } + + @Test + void shouldCompleteCall() { + service.saveNachrichtDraft(GrpcSaveNachrichtDraftRequestTestFactory.create(), responseObserver); + + verify(responseObserver).onCompleted(); + } + + } @Nested class TestSendMail { - @Mock // NOSONAR + @Mock private StreamObserver<GrpcSendPostfachMailResponse> responseObserver; - @Captor // NOSONAR - private ArgumentCaptor<PostfachMail> mailCaptor; + @Captor + private ArgumentCaptor<PostfachNachricht> mailCaptor; @Test void shouldCallPostfachServiceWithCommandId() { @@ -71,11 +116,11 @@ class PostfachGrpcServiceTest { verify(postfachService).sendMail(anyString(), anyString(), mailCaptor.capture()); assertThat(mailCaptor.getValue()).usingRecursiveComparison() - .ignoringFields(PostfachMail.FIELD_MESSAGE_ID, PostfachMail.FIELD_CREATED_AT, PostfachMail.FIELD_CREATED_BY, - PostfachMail.FIELD_DIRECTION, PostfachMail.FIELD_SENT_SUCCESSFUL, PostfachMail.FIELD_SENT_AT, - PostfachMail.FIELD_MESSAGE_CODE, - PostfachMail.FIELD_ATTACHMENTS) // TODO remove this for sending attachments - .isEqualTo(PostfachMailTestFactory.create()); + .ignoringFields(PostfachNachricht.FIELD_MESSAGE_ID, PostfachNachricht.FIELD_CREATED_AT, PostfachNachricht.FIELD_CREATED_BY, + PostfachNachricht.FIELD_DIRECTION, PostfachNachricht.FIELD_SENT_SUCCESSFUL, PostfachNachricht.FIELD_SENT_AT, + PostfachNachricht.FIELD_MESSAGE_CODE, + PostfachNachricht.FIELD_ATTACHMENTS) // TODO remove this for sending attachments + .isEqualTo(PostfachNachrichtTestFactory.create()); } @Test @@ -109,14 +154,14 @@ class PostfachGrpcServiceTest { @BeforeEach void init() { - request = GrpcFindPostfachMailRequest.newBuilder().setNachrichtId(PostfachMailTestFactory.ID).build(); + request = GrpcFindPostfachMailRequest.newBuilder().setNachrichtId(PostfachNachrichtTestFactory.ID).build(); } @Test void shouldCallService() { service.findPostfachMail(request, responseObserver); - verify(postfachService).findById(PostfachMailTestFactory.ID); + verify(postfachService).findById(PostfachNachrichtTestFactory.ID); } @Test @@ -140,7 +185,7 @@ class PostfachGrpcServiceTest { private static final String VORGANG_ID = "42"; private GrpcFindPostfachMailsRequest request; - @Mock // NOSONAR + @Mock private StreamObserver<GrpcFindPostfachMailsResponse> responseObserver; @BeforeEach @@ -167,14 +212,14 @@ class PostfachGrpcServiceTest { @Nested class TestResendMail { - @Mock // NOSONAR + @Mock private StreamObserver<GrpcResendPostfachMailResponse> responseObserver; @Test void shouldCallPostfachService() { service.resendPostfachMail(GrpcResendPostfachMailRequestTestFactory.create(), responseObserver); - verify(postfachService).resendMail(GrpcResendPostfachMailRequestTestFactory.COMMAND_ID, PostfachMailTestFactory.ID); + verify(postfachService).resendMail(GrpcResendPostfachMailRequestTestFactory.COMMAND_ID, PostfachNachrichtTestFactory.ID); } @Test @@ -197,7 +242,7 @@ class PostfachGrpcServiceTest { private final GrpcIsPostfachConfiguredRequest request = GrpcIsPostfachConfiguredRequest.newBuilder().build(); - @Mock // NOSONAR + @Mock private StreamObserver<GrpcIsPostfachConfiguredResponse> responseObserver; @Test @@ -221,4 +266,66 @@ class PostfachGrpcServiceTest { verify(responseObserver).onCompleted(); } } + + @Nested + class TestGetPostfachConfig { + private GrpcGetPostfachConfigRequest request = GrpcGetPostfachConfigRequest.newBuilder().build(); + + @Mock + private StreamObserver<GrpcGetPostfachConfigResponse> responseObserver; + + @Test + void shouldSendResponse() { + service.getPostfachConfig(request, responseObserver); + + verify(responseObserver).onNext(notNull()); + } + + @Test + void shouldCompleteCall() { + service.getPostfachConfig(request, responseObserver); + + verify(responseObserver).onCompleted(); + } + + @Nested + class TestBuildGetPostfachConfigResponse { + + @Test + void shouldReturnNotConfigured() { + var response = service.buildGetPostfachConfigResponse(); + + assertThat(response).isEqualTo(GrpcGetPostfachConfigResponse.newBuilder().setConfigured(false).build()); + } + + @Nested + class TestConfigured { + + @Mock + private Postfach postfach; + @Mock + private GrpcPostfach grpcPostfach; + + @BeforeEach + void setup() { + when(postfachService.getPostfachs()).thenReturn(Stream.of(postfach)); + when(postfachMapper.toGrpc(postfach)).thenReturn(grpcPostfach); + } + + @Test + void shouldReturnPostfachs() { + var response = service.buildGetPostfachConfigResponse(); + + assertThat(response.getConfigured()).isTrue(); + } + + @Test + void shouldSetPostfach() { + var response = service.buildGetPostfachConfigResponse(); + + assertThat(response.getPostfachList()).containsExactly(grpcPostfach); + } + } + } + } } \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMapperTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMapperTest.java new file mode 100644 index 0000000..797ef5c --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMapperTest.java @@ -0,0 +1,49 @@ +/* + * 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.nachrichten.postfach; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +class PostfachMapperTest { + + private PostfachMapper mapper = Mappers.getMapper(PostfachMapper.class); + + @Test + void shouldMapType() { + var result = mapper.toGrpc(PostfachTestFactory.create()); + + assertThat(result.getType()).isEqualTo(PostfachTestFactory.POSTFACH_TYPE); + } + + @Test + void shouldMapReplyAllowed() { + var result = mapper.toGrpc(PostfachTestFactory.create()); + + assertThat(result.getReplyAllowed()).isTrue(); + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java new file mode 100644 index 0000000..06793b2 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java @@ -0,0 +1,209 @@ +/* + * 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.nachrichten.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import lombok.SneakyThrows; + +class PostfachNachrichtMapperTest { + + @InjectMocks + private PostfachNachrichtMapper mapper = Mappers.getMapper(PostfachNachrichtMapper.class); + @Mock + private GrpcObjectMapper grpcObjectMapper; + + @DisplayName("From map") + @Nested + class TestFromMap { + + @DisplayName("with existing postfachAddress") + @Nested + class TestWithExistingPostfachAddress { + + @BeforeEach + void mockGrpcObjectMapper() { + when(grpcObjectMapper.fromMap(any())).thenReturn(GrpcPostfachAddressTestFactory.createIdentifier()); + } + + @Test + void shouldFillGrpcMail() { + var grpcMail = fromMap(PostfachNachrichtTestFactory.asMap()); + + assertThat(grpcMail).usingRecursiveComparison().isEqualTo(GrpcPostfachMailTestFactory.create()); + } + + @Test + void shouldCallGrpcObjectMapper() { + fromMap(getMapWithoutProperty(PostfachNachricht.FIELD_SENT_SUCCESSFUL)); + + verify(grpcObjectMapper).fromMap(any()); + } + + @Test + void shouldIgnoreSentSuccessful() { + var grpcMail = fromMap(getMapWithoutProperty(PostfachNachricht.FIELD_SENT_SUCCESSFUL)); + + assertThat(grpcMail.getSentSuccessful()).isFalse(); + } + + @Test + void shouldIgnoreSentAt() { + var grpcMail = fromMap(getMapWithoutProperty(PostfachNachricht.FIELD_SENT_AT)); + + assertThat(grpcMail.getSentAt()).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = PostfachNachricht.FIELD_POSTFACH_ID) + void shouldMapDefaultOnNonExistingValues(String fieldName) { + var mapped = fromMap(getMapWithoutProperty(fieldName)); + + var fieldValue = getAttributeFromGrpcObject(mapped, fieldName); + assertThat((String) fieldValue).isEmpty(); + } + } + + @DisplayName("with missing postfachAddress") + @Nested + class TestWithMissinPostfachAddress { + + @Test + void shouldNotThrowException() { + assertDoesNotThrow(() -> fromMap(getMapWithoutProperty(PostfachNachricht.POSTFACH_ADDRESS_FIELD))); + } + } + + private GrpcPostfachMail fromMap(Map<String, Object> map) { + return mapper.fromMap(map); + } + } + + @DisplayName("From map to postfachMail") + @Nested + class TestFromMapToPostfachMail { + + @Test + void shouldMap() { + var mail = fromMapToPostfachMail(PostfachNachrichtTestFactory.asMap()); + + assertThat(mail).usingRecursiveComparison().isEqualTo(PostfachNachrichtTestFactory.create()); + } + + @DisplayName("with missing postfachAddress") + @Nested + class TestWithMissinPostfachAddress { + + @Test + void shouldMapAsNull() { + var mail = fromMapToPostfachMail(getMapWithoutProperty(PostfachNachricht.POSTFACH_ADDRESS_FIELD)); + + assertThat(mail.getPostfachAddress()).isNull(); + } + + @Test + void shouldNotThrowExceptionOnMissingPostfachAddress() { + assertDoesNotThrow(() -> fromMapToPostfachMail(getMapWithoutProperty(PostfachNachricht.POSTFACH_ADDRESS_FIELD))); + } + } + + @ParameterizedTest + @ValueSource(strings = PostfachNachricht.FIELD_POSTFACH_ID) + void shouldMapDefaultOnNonExistingValues(String fieldName) { + var mapped = fromMapToPostfachMail(getMapWithoutProperty(fieldName)); + + var fieldValue = getAttributeFromObject(mapped, fieldName); + assertThat((String) fieldValue).isEmpty(); + } + + private PostfachNachricht fromMapToPostfachMail(Map<String, Object> map) { + return mapper.fromMapToPostfachMail(map); + } + } + + @DisplayName("From grpc mail") + @Nested + class TestFromGrpcMail { + + @Test + void shouldMapFields() { + var mapped = fromGrpcMail(GrpcPostfachMailTestFactory.create()); + + assertThat(mapped).usingRecursiveComparison() + .ignoringFields("createdAt", "createdBy", "direction", "messageId", "sentAt", "sentSuccessful", "memoizedHashCode") + .isEqualTo(PostfachNachrichtTestFactory.create()); + } + + @Test + void shouldHandleEmptyPostfachId() { + var postfachMailWithoutPostfachId = GrpcPostfachMailTestFactory.createBuilder().clearPostfachId().build(); + + assertDoesNotThrow(() -> fromGrpcMail(postfachMailWithoutPostfachId)); + } + + private PostfachNachricht fromGrpcMail(GrpcPostfachMail postfachMail) { + return mapper.fromGrpcMail(postfachMail); + } + } + + private Map<String, Object> getMapWithoutProperty(String entryKey) { + var map = PostfachNachrichtTestFactory.asMap(); + map.remove(entryKey); + return map; + } + + private Object getAttributeFromGrpcObject(Object obj, String name) { + return getAttributeFrom(obj, name + "_"); + } + + @SneakyThrows + private Object getAttributeFromObject(Object obj, String name) { + return getAttributeFrom(obj, name); + } + + @SneakyThrows + private Object getAttributeFrom(Object obj, String name) { + var clazz = obj.getClass(); + var field = clazz.getDeclaredField(name); + field.setAccessible(true); + + return field.get(obj); + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java new file mode 100644 index 0000000..09391f7 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java @@ -0,0 +1,109 @@ +/* + * 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.nachrichten.postfach; + +import static de.ozgcloud.nachrichten.postfach.PostfachNachricht.ReplyOption.*; +import static de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory.*; + +import java.time.ZonedDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; + +public class PostfachNachrichtTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + public static final String CREATED_AT_STR = "2020-04-01T10:30:10Z"; + public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); + public static final String CREATED_BY = UUID.randomUUID().toString(); + public static final String MAIL_BODY = "Body\nString"; + + public static final String SENT_AT_STR = "2020-04-01T11:30:10Z"; + public static final ZonedDateTime SENT_AT = ZonedDateTime.parse(SENT_AT_STR); + public static final boolean SENT_SUCCESSFUL = true; + public static final String MESSAGE_CODE = PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE.getMessageCode(); + public static final PostfachNachricht.ReplyOption REPLY_OPTION = MANDATORY; + + public static final PostfachNachricht.Direction DIRECTION = Direction.IN; + + public static final String ATTACHMENT_FILE_ID = "21"; + public static final List<String> ATTACHMENTS = List.of(ATTACHMENT_FILE_ID); + + public static PostfachNachricht create() { + return createBuilder().build(); + } + + public static PostfachNachricht.PostfachNachrichtBuilder createBuilder() { + return PostfachNachricht.builder() + .id(ID) + .postfachId(POSTFACH_ID) + .postfachAddress(PostfachAddressTestFactory.create()) + .messageId(MESSAGE_ID) + .vorgangId(VORGANG_ID) + .direction(DIRECTION) + .createdAt(CREATED_AT) + .createdBy(CREATED_BY) + .sentAt(SENT_AT) + .sentSuccessful(SENT_SUCCESSFUL) + .messageCode(MESSAGE_CODE) + .replyOption(REPLY_OPTION) + .subject(SUBJECT) + .mailBody(MAIL_BODY) + .attachments(ATTACHMENTS); + } + + public static Map<String, Object> asMap() { + var map = new HashMap<String, Object>(); + map.put(PostfachNachricht.FIELD_ID, ID); + map.put(PostfachNachricht.FIELD_POSTFACH_ID, POSTFACH_ID); + map.put(PostfachNachricht.POSTFACH_ADDRESS_FIELD, getPostfachAddressAsMap()); + map.put(PostfachNachricht.FIELD_MESSAGE_ID, MESSAGE_ID); + map.put(PostfachNachricht.FIELD_VORGANG_ID, VORGANG_ID); + map.put(PostfachNachricht.FIELD_DIRECTION, DIRECTION.name()); + map.put(PostfachNachricht.FIELD_CREATED_AT, CREATED_AT_STR); + map.put(PostfachNachricht.FIELD_CREATED_BY, CREATED_BY); + map.put(PostfachNachricht.FIELD_SENT_AT, SENT_AT_STR); + map.put(PostfachNachricht.FIELD_SENT_SUCCESSFUL, SENT_SUCCESSFUL); + map.put(PostfachNachricht.FIELD_MESSAGE_CODE, MESSAGE_CODE); + map.put(PostfachNachricht.FIELD_REPLY_OPTION, REPLY_OPTION.name()); + map.put(PostfachNachricht.FIELD_SUBJECT, SUBJECT); + map.put(PostfachNachricht.FIELD_MAIL_BODY, MAIL_BODY); + map.put(PostfachNachricht.FIELD_ATTACHMENTS, ATTACHMENTS); + return map; + } + + private static Map<String, Object> getPostfachAddressAsMap() { + return Map.of(PostfachAddress.TYPE_FIELD, PostfachAddressTestFactory.TYPE, + PostfachAddress.VERSION_FIELD, PostfachAddressTestFactory.VERSION, + PostfachAddress.IDENTIFIER_FIELD, getPostfachAddressIdentifierAsMap(), + PostfachAddress.SERVICEKONTO_TYPE_FIELD, PostfachTestFactory.POSTFACH_TYPE); + } + + private static Map<String, Object> getPostfachAddressIdentifierAsMap() { + return Map.of(PostfachNachricht.FIELD_POSTFACH_ID, PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + } +} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachSchedulerTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachSchedulerTest.java similarity index 92% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachSchedulerTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachSchedulerTest.java index 7aba40a..00948b1 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/PostfachSchedulerTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachSchedulerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import static org.mockito.Mockito.*; diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java new file mode 100644 index 0000000..973c169 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java @@ -0,0 +1,811 @@ +/* + * 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.nachrichten.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; + +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mapstruct.factory.Mappers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.boot.logging.LogLevel; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.nachrichten.attributes.ClientAttributeService; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.ReplyOption; +import de.ozgcloud.nachrichten.postfach.antragsraum.AntragsraumService; +import de.ozgcloud.nachrichten.postfach.osi.MessageAttachmentService; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.OsiPostfachServerProcessException; +import de.ozgcloud.nachrichten.postfach.osi.OsiPostfachServerProcessExceptionTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import nl.altindag.log.LogCaptor; + +class PostfachServiceTest { + + @Spy + @InjectMocks + private PostfachService service; + @Mock + private PostfachRemoteService postfachRemoteService; + + @Mock + private PersistPostfachNachrichtService persistingService; + @Spy + private PostfachNachrichtMapper mapper = Mappers.getMapper(PostfachNachrichtMapper.class); + + @Mock + private ClientAttributeService clientAttributeService; + @Mock + private MessageAttachmentService messageAttachmentService; + @Mock + private ApplicationEventPublisher publisher; + + @Mock + private CurrentUserService userService; + @Mock + private AntragsraumService antragsraumService; + + static final String COMMAND_ID = UUID.randomUUID().toString(); + static final String USER_ID = UUID.randomUUID().toString(); + + @Nested + class TestSaveDraft { + + @Captor + private ArgumentCaptor<Optional<String>> userIdCaptor; + @Captor + private ArgumentCaptor<PostfachNachricht> nachrichtCaptor; + + @BeforeEach + void init() { + doNothing().when(service).persistMail(any(), any()); + + when(userService.getUser()).thenReturn(CallContextUserTestFactory.create()); + } + + @Test + void shouldUseUserIdFromContext() { + service.saveDraft(MessageTestFactory.VORGANG_ID, PostfachNachrichtTestFactory.create()); + + verify(service).persistMail(userIdCaptor.capture(), any()); + assertThat(userIdCaptor.getValue()).contains(CallContextUserTestFactory.ID); + } + + @Test + void shouldPersistNachricht() { + service.saveDraft(MessageTestFactory.VORGANG_ID, PostfachNachrichtTestFactory.create()); + + verify(service).persistMail(any(), any()); + } + + @Test + void shouldAddVorgangId() { + service.saveDraft(MessageTestFactory.VORGANG_ID, PostfachNachrichtTestFactory.createBuilder().vorgangId(null).build()); + + verify(service).persistMail(any(), nachrichtCaptor.capture()); + assertThat(nachrichtCaptor.getValue().getVorgangId()).isEqualTo(MessageTestFactory.VORGANG_ID); + } + } + + @Nested + class TestSendMail { + + @Test + void shouldCallDoSendMail() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + var mail = PostfachNachrichtTestFactory.create(); + + service.sendMail(COMMAND_ID, USER_ID, mail); + + verify(service).doSendMail(mail); + } + + @Test + void shouldCallPersistSentMail() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + var mail = PostfachNachrichtTestFactory.create(); + doReturn(mail).when(service).addMailSentInformation(any(PostfachNachricht.class), any(SendPostfachNachrichtResponse.class)); + + service.sendMail(COMMAND_ID, USER_ID, PostfachNachrichtTestFactory.create()); + + verify(service).persistSentMail(USER_ID, mail); + } + + @Test + void shouldAddMailSentInformation() { + var postfachMail = service.addMailSentInformation(PostfachNachrichtTestFactory.createBuilder().sentAt(null).sentSuccessful(null).build(), + SendPostfachNachrichtResponseTestFactory.create()); + + assertThat(postfachMail.getSentAt()).isNotNull(); + assertThat(postfachMail.getSentSuccessful()).isEqualTo(SendPostfachNachrichtResponseTestFactory.SENT_SUCCESSFUL); + assertThat(postfachMail.getMessageCode()).isEqualTo(SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); + } + + @Test + void shouldHandleSendMail() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + var mail = PostfachNachrichtTestFactory.create(); + service.sendMail(COMMAND_ID, USER_ID, mail); + + verify(service).handleSendMail(COMMAND_ID, mail); + } + + @Nested + class TestPersistSentMail { + + @Captor + private ArgumentCaptor<PostfachNachricht> mailCaptor; + + @Test + void shouldCallPersistingService() { + var mail = PostfachNachrichtTestFactory.create(); + + service.persistSentMail(USER_ID, mail); + + verify(persistingService).persistNachricht(any(), notNull()); + } + + @Test + void shouldSetDirectionToIN() { + service.persistSentMail(USER_ID, PostfachNachrichtTestFactory.createBuilder().direction(null).build()); + + verify(persistingService).persistNachricht(any(), mailCaptor.capture()); + assertThat(mailCaptor.getValue().getDirection()).isEqualTo(Direction.OUT); + } + + @Test + void shouldSetCreatedAt() { + service.persistSentMail(USER_ID, PostfachNachrichtTestFactory.createBuilder().createdAt(null).build()); + + verify(persistingService).persistNachricht(any(), mailCaptor.capture()); + assertThat(mailCaptor.getValue().getCreatedAt()).isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); + } + + @Test + void shouldSetCreatedBy() { + service.persistSentMail(USER_ID, PostfachNachrichtTestFactory.createBuilder().createdBy(null).build()); + + verify(persistingService).persistNachricht(any(), mailCaptor.capture()); + assertThat(mailCaptor.getValue().getCreatedBy()).isEqualTo(USER_ID); + } + + @Test + void shouldSetUserId() { + var mail = PostfachNachrichtTestFactory.create(); + + service.persistSentMail(USER_ID, mail); + + verify(persistingService).persistNachricht(eq(Optional.of(USER_ID)), any()); + } + + @Test + void shouldSetClientAttribute() { + service.persistSentMail(USER_ID, PostfachNachrichtTestFactory.create()); + + verify(clientAttributeService).setHasPostfachNachricht(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldNOTSetNewNachricht() { + service.persistSentMail(USER_ID, PostfachNachrichtTestFactory.create()); + + verify(clientAttributeService, never()).setHasNewPostfachNachricht(any()); + } + } + + @Nested + class TestProcessForAntragsraum { + + @Mock + private PostfachNachricht modifiedMail; + + @Test + void shouldReturnEmpty() { + doReturn(false).when(service).isPostfachWithAntragsraum(any()); + + var result = service.processForAntragsraum(PostfachNachrichtTestFactory.create()); + + assertThat(result).isEmpty(); + } + + @Test + void shouldCallNotifyAntragsraum() { + doReturn(true).when(service).isPostfachWithAntragsraum(any()); + var mail = PostfachNachrichtTestFactory.create(); + + service.processForAntragsraum(mail); + + verify(antragsraumService).notifyAntragsraum(mail); + } + + @Test + void shouldReturnAdjustedMail() { + doReturn(true).when(service).isPostfachWithAntragsraum(any()); + doReturn(Optional.of(modifiedMail)).when(service).adjustMail(any()); + + var result = service.processForAntragsraum(PostfachNachrichtTestFactory.create()); + + assertThat(result).contains(modifiedMail); + } + + @DisplayName("Is notify antragsraum") + @Nested + class TestIsNotifyAntragsraum { + + @DisplayName("should return true if") + @ParameterizedTest(name = "replyOption is {0}") + @EnumSource(value = ReplyOption.class, names = { "FORBIDDEN" }, mode = EnumSource.Mode.EXCLUDE) + void shouldConfirm(ReplyOption replyOption) { + doReturn(true).when(service).isPostfachWithAntragsraum(any()); + + var result = service.isNotifyAntragsraum(replyOption); + + assertThat(result).isTrue(); + } + + @DisplayName("should return false if reply is forbidden") + @Test + void shouldDeclineIfForbidden() { + var result = service.isNotifyAntragsraum(ReplyOption.FORBIDDEN); + + assertThat(result).isFalse(); + } + + @DisplayName("should return false if antragsraum is not configured") + @Test + void shouldDeclineIfNotConfigured() { + doReturn(false).when(service).isPostfachWithAntragsraum(any()); + + var result = service.isNotifyAntragsraum(ReplyOption.POSSIBLE); + + assertThat(result).isFalse(); + } + } + + @Nested + class TestAdjustMail { + + @Mock + private PostfachNachricht mail; + + @Nested + class TestReplaceBody { + + @Test + void shouldReturnEmptyIfNoAntragsraum() { + doReturn(Optional.empty()).when(service).getAntragsraumService(); + + var result = adjustMail(); + + assertThat(result).isEmpty(); + } + + @Test + void shouldAdjustMailBody() { + when(mail.toBuilder()).thenReturn(PostfachNachrichtTestFactory.createBuilder()); + var expectedMailBody = "Antragsraum Text"; + when(antragsraumService.getUserNotificationText()).thenReturn(expectedMailBody); + + var result = adjustMail(); + + assertThat(result).isPresent().get().extracting(PostfachNachricht::getMailBody).isEqualTo(expectedMailBody); + } + } + + private Optional<PostfachNachricht> adjustMail() { + return service.adjustMail(mail); + } + } + + } + } + + @Nested + class TestFindById { + @Test + void shouldCallPersistingService() { + service.findById(PostfachNachrichtTestFactory.ID); + + verify(persistingService).findById(PostfachNachrichtTestFactory.ID); + } + } + + @Nested + class TestFindByVorgang { + + private static final String VORGANG_ID = UUID.randomUUID().toString(); + + @Test + void shouldCallPersistingService() { + service.findByVorgang(VORGANG_ID); + + verify(persistingService).findByVorgangAsMap(VORGANG_ID); + } + } + + @Nested + class TestFetchAndPersistReplies { + + private static final PostfachNachricht nachricht = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void initTest() { + lenient().when(postfachRemoteService.getAllMessages()).thenReturn(Stream.of(nachricht)); + } + + @Test + void shouldCallGetAllMessages() { + service.fetchAndPersistReplies(); + + verify(postfachRemoteService).getAllMessages(); + } + + @Test + void shouldCallPersistingService() { + service.fetchAndPersistReplies(); + + verify(persistingService).persistNachricht(eq(Optional.empty()), any()); + } + + @Test + void shouldCallDelete() { + service.fetchAndPersistReplies(); + + verify(postfachRemoteService).deleteMessage(MessageTestFactory.MESSAGE_ID); + } + + @Test + void shouldSetNewPostfachNachricht() { + service.fetchAndPersistReplies(); + + verify(clientAttributeService).setHasNewPostfachNachricht(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldCallClientAttributeService() { + service.fetchAndPersistReplies(); + + verify(clientAttributeService).setHasNewPostfachNachricht(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldThrowNotConfiguredException() { + doReturn(false).when(service).isPostfachConfigured(); + + assertThatExceptionOfType(NotConfiguredException.class).isThrownBy(() -> service.fetchAndPersistReplies()); + verify(postfachRemoteService, never()).getAllMessages(); + } + } + + @Nested + class TestPeristMail { + @Test + void shouldPersistMail() { + PostfachNachricht mail = PostfachNachrichtTestFactory.create(); + + service.persistMail(Optional.of(USER_ID), mail); + + verify(persistingService).persistNachricht(eq(Optional.of(USER_ID)), same(mail)); + } + + @Test + void shouldSetHasPostfachNachricht() { + var mail = PostfachNachrichtTestFactory.create(); + + service.persistMail(Optional.of(USER_ID), mail); + + verify(clientAttributeService).setHasPostfachNachricht(MessageTestFactory.VORGANG_ID); + } + + @Test + @DisplayName("should NOT set hasPostfachNachricht if Nachricht is sent from system") + void shouldNOTSetHasNachrichtForSystemNachricht() { + var mail = PostfachNachrichtTestFactory.createBuilder().createdBy("system-123").build(); + + service.persistMail(Optional.of(USER_ID), mail); + + verify(clientAttributeService, never()).setHasPostfachNachricht(MessageTestFactory.VORGANG_ID); + } + } + + @Nested + class TestResendPostfachMail { + + static final String COMMAND_ID = UUID.randomUUID().toString(); + static final PostfachNachricht mail = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void mockService() { + when(persistingService.getById(anyString())).thenReturn(PostfachNachrichtTestFactory.asMap()); + doReturn(mail).when(mapper).fromMapToPostfachMail(anyMap()); + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + } + + @Test + void shouldCallPersistingServiceGetById() { + service.resendMail(COMMAND_ID, PostfachNachrichtTestFactory.ID); + + verify(persistingService).getById(PostfachNachrichtTestFactory.ID); + } + + @Test + void shouldMapFromMapToPostfachMail() { + service.resendMail(COMMAND_ID, PostfachNachrichtTestFactory.ID); + + verify(mapper).fromMapToPostfachMail(PostfachNachrichtTestFactory.asMap()); + } + + @Test + void shouldSendMail() { + service.resendMail(COMMAND_ID, PostfachNachrichtTestFactory.ID); + + verify(postfachRemoteService).sendMessage(any(PostfachNachricht.class)); + } + + @Test + void shouldPatchMail() { + service.resendMail(COMMAND_ID, PostfachNachrichtTestFactory.ID); + + verify(persistingService).patch(anyString(), anyMap()); + } + + @Test + void shouldHandleSentMail() { + service.resendMail(COMMAND_ID, PostfachNachrichtTestFactory.ID); + + verify(service).handleSendMail(COMMAND_ID, mail); + } + } + + @Nested + class TestCreateResendPatchMap { + + @Test + void shouldContainsSentAt() { + var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); + + assertThat(map).containsKey(PostfachNachricht.FIELD_SENT_AT); + assertThat(ZonedDateTime.parse(map.get(PostfachNachricht.FIELD_SENT_AT).toString())).isCloseTo(ZonedDateTime.now(), + within(2, ChronoUnit.SECONDS)); + } + + @Test + void shouldContainsSentSuccessful() { + var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); + + assertThat(map).containsEntry(PostfachNachricht.FIELD_SENT_SUCCESSFUL, true); + } + + @Test + void shouldContainsMessageCode() { + var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); + + assertThat(map).containsEntry(PostfachNachricht.FIELD_MESSAGE_CODE, + SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); + } + } + + @DisplayName("Handle send mail") + @Nested + class TestHandleSendMail { + + final String COMMAND_ID = UUID.randomUUID().toString(); + final PostfachNachricht mail = PostfachNachrichtTestFactory.create(); + + @Test + void shouldDoSendMail() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + service.handleSendMail(COMMAND_ID, mail); + + verify(service).doSendMail(mail); + } + + @Nested + class TestSentSuccess { + + @Captor + private ArgumentCaptor<PostfachMailSentEvent> eventCaptor; + + @Mock + private PostfachNachricht modifiedMail; + + @Test + void shouldDoSendMail() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + service.handleSendMail(COMMAND_ID, mail); + + verify(service).doSendMail(mail); + } + + @Test + void shouldPublishEvent() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + service.handleSendMail(COMMAND_ID, mail); + + verify(publisher).publishEvent(eventCaptor.capture()); + assertThat(eventCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); + } + + @Test + void shouldReturnResponse() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + var response = service.handleSendMail(COMMAND_ID, mail); + + assertThat(response.isSentSuccessful()).isTrue(); + assertThat(response.getMessageCode()).isEqualTo(PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); + } + + @Test + void shouldSendProcessedPostfachNachricht() { + doReturn(Optional.of(modifiedMail)).when(service).processForAntragsraum(any()); + + service.handleSendMail(COMMAND_ID, mail); + + verify(service).doSendMail(modifiedMail); + } + + } + + @DisplayName("receive") + @Nested + class TestSentFailed { + + @Captor + private ArgumentCaptor<PostfachMailSentFailedEvent> eventFailedCaptor; + + @DisplayName("OsiPostfachException") + @Nested + class TestOnOsiPostfachException { + + private final static String MESSAGE = "Osi Postfach throws an exception."; + + @BeforeEach + void mockService() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + doThrow(new PostfachException(MESSAGE, PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE)).when(postfachRemoteService) + .sendMessage(any()); + } + + @Test + void shouldPublishEvent() { + service.handleSendMail(COMMAND_ID, mail); + + verify(publisher).publishEvent(eventFailedCaptor.capture()); + assertThat(eventFailedCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); + assertThat(eventFailedCaptor.getValue().getErrorMessage()).startsWith(MESSAGE); + } + + @Test + void shouldLogError() { + var logCaptor = LogCaptor.forClass(PostfachService.class); + + service.handleSendMail(COMMAND_ID, mail); + + verify(service).proceedWithErrorException(eq(COMMAND_ID), any(PostfachException.class)); + assertThat(logCaptor.getLogEvents().get(0).getLevel()).isEqualTo(LogLevel.ERROR.name()); + assertThat(logCaptor.getLogEvents().get(0).getMessage()).startsWith(MESSAGE); + } + + @Test + void shouldReturnResponse() { + var response = service.handleSendMail(COMMAND_ID, mail); + + assertThat(response.isSentSuccessful()).isFalse(); + assertThat(response.getMessageCode()).isEqualTo(PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE); + } + } + + @DisplayName("OsiPostfachServerProcessException") + @Nested + class TestOsiPostfachServerProcessException { + + private final static String MESSAGE = "Postfach server returned false"; + + @Mock + private Logger logger; + + @BeforeEach + void mockService() { + doThrow(OsiPostfachServerProcessExceptionTestFactory.create()).when(postfachRemoteService).sendMessage(any()); + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + } + + @Test + void shouldPublishEvent() { + service.handleSendMail(COMMAND_ID, mail); + + verify(publisher).publishEvent(eventFailedCaptor.capture()); + assertThat(eventFailedCaptor.getValue().getSource()).isEqualTo(COMMAND_ID); + assertThat(eventFailedCaptor.getValue().getErrorMessage()).startsWith(MESSAGE); + } + + @Test + void shouldLogWarning() { + var logCaptor = LogCaptor.forClass(PostfachService.class); + + service.handleSendMail(COMMAND_ID, mail); + + verify(service).proceedwithWarnException(eq(COMMAND_ID), any(OsiPostfachServerProcessException.class)); + assertThat(logCaptor.getLogEvents().get(0).getLevel()).isEqualTo(LogLevel.WARN.name()); + assertThat(logCaptor.getLogEvents().get(0).getMessage()).startsWith(MESSAGE); + } + + @Test + void shouldReturnResponse() { + var response = service.handleSendMail(COMMAND_ID, mail); + + assertThat(response.isSentSuccessful()).isFalse(); + assertThat(response.getMessageCode()).isEqualTo(PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + } + } + } + + } + + @Nested + class TestDoSendMail { + @Test + void shouldCallPostfachRemoteService() { + service.doSendMail(PostfachNachrichtTestFactory.create()); + + verify(postfachRemoteService).sendMessage(any()); + } + + @Nested + class WithoutRemoteService { + @InjectMocks + private PostfachService service; + + @Test + void shouldThrowNotConfiguredException() { + var nachricht = PostfachNachrichtTestFactory.create(); + + assertThatExceptionOfType(NotConfiguredException.class).isThrownBy(() -> service.doSendMail(nachricht)); + + verify(postfachRemoteService, never()).sendMessage(any()); + } + } + + } + + @Nested + class TestIsPostfachConfigured { + + @Test + void shouldReturnTrue() { + assertThat(service.isPostfachConfigured()).isTrue(); + } + } + + @Nested + class TestGetPostfachs { + + private Postfach postfach = PostfachTestFactory.create(); + + @Test + void shouldCallBuildPostfach() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + service.getPostfachs(); + + verify(service).buildPostfach(postfachRemoteService); + } + + @Test + void shouldReturnPostfachs() { + doReturn(postfach).when(service).buildPostfach(any()); + + var result = service.getPostfachs(); + + assertThat(result).containsOnly(postfach); + } + + @Test + void shouldReturnEmptyStream() { + doReturn(false).when(service).isPostfachConfigured(); + + var result = service.getPostfachs(); + + assertThat(result).isEmpty(); + } + + @Nested + class TestBuildPostfach { + + @Test + void shouldSetPostfachType() { + when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); + + var result = service.buildPostfach(postfachRemoteService); + + assertThat(result.getType()).isEqualTo(PostfachTestFactory.POSTFACH_TYPE); + } + + @Test + void shouldSetIsReplyAllowed() { + doReturn(true).when(service).isReplyAllowed(any()); + + var result = service.buildPostfach(postfachRemoteService); + + assertThat(result.isReplyAllowed()).isTrue(); + } + } + + @Nested + class TestIsReplyAllowed { + + @Test + void shouldAllowWithAntragsraum() { + doReturn(true).when(service).isPostfachWithAntragsraum(postfachRemoteService); + + var result = service.isReplyAllowed(postfachRemoteService); + + assertThat(result).isTrue(); + } + + @Test + void shouldAllowWithPostfach() { + doReturn(false).when(service).isPostfachWithAntragsraum(postfachRemoteService); + when(postfachRemoteService.isReplyAllowed()).thenReturn(true); + + var result = service.isReplyAllowed(postfachRemoteService); + + assertThat(result).isTrue(); + } + + @Test + void shouldNotAllow() { + doReturn(false).when(service).isPostfachWithAntragsraum(postfachRemoteService); + + var result = service.isReplyAllowed(postfachRemoteService); + + assertThat(result).isFalse(); + } + } + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachTestFactory.java new file mode 100644 index 0000000..94c458e --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachTestFactory.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach; + +import de.ozgcloud.nachrichten.postfach.Postfach.PostfachBuilder; + +public class PostfachTestFactory { + + public static final String POSTFACH_TYPE = "postfachType"; + + public static final boolean REPLY_ALLOWED = true; + + public static Postfach create() { + return createBuilder().build(); + } + + public static PostfachBuilder createBuilder() { + return Postfach.builder() + .type(POSTFACH_TYPE) + .isReplyAllowed(REPLY_ALLOWED); + } +} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponseTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponseTestFactory.java similarity index 86% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponseTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponseTestFactory.java index 9ec6483..257b308 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/SendPostfachNachrichtResponseTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/SendPostfachNachrichtResponseTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; public class SendPostfachNachrichtResponseTestFactory { public static final boolean SENT_SUCCESSFUL = true; - public static final OsiPostfachMessageCode MESSAGE_CODE = OsiPostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE; + public static final PostfachMessageCode MESSAGE_CODE = PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE; public static SendPostfachNachrichtResponse create() { return createBuilder().build(); diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumServiceTest.java new file mode 100644 index 0000000..539c689 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/AntragsraumServiceTest.java @@ -0,0 +1,144 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +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 de.ozgcloud.nachrichten.NachrichtenManagerProperties; +import de.ozgcloud.nachrichten.postfach.PostfachException; +import de.ozgcloud.nachrichten.postfach.PostfachMessageCode; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +class AntragsraumServiceTest { + + @Spy + @InjectMocks + private AntragsraumService service; + + @Mock + private AntragsraumProperties properties; + @Mock + private NachrichtenManagerProperties nachrichtenManagerProperties; + @Mock + private InfomanagerRemoteService infomanagerRemoteService; + + @Nested + class TestGetAntragsraumUrl { + + private static final String URL = "url"; + + @Test + void shouldReturnUrl() { + when(properties.getUrl()).thenReturn(URL); + + var url = service.getAntragsraumUrl(); + + assertThat(url).isEqualTo(URL); + } + + } + + @Nested + class TestNotifyAntragsraum { + + private static final String NACHRICHTEN_MANAGER_URL = "nachrichtenManagerUrl"; + + private PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.create(); + + @Test + void shouldCallBuildInfomanagerNachricht() { + service.notifyAntragsraum(postfachNachricht); + + verify(service).builInfomanagerNachricht(postfachNachricht); + } + + @Test + void shouldCallInfoManagerRemoteService() { + var infomanagerNachricht = InfomanagerNachrichtTestFactory.create(); + doReturn(infomanagerNachricht).when(service).builInfomanagerNachricht(any()); + + service.notifyAntragsraum(postfachNachricht); + + verify(infomanagerRemoteService).sendNotification(infomanagerNachricht); + } + + @Test + void shouldThrowPostfachException() { + var causeException = new RuntimeException(); + when(infomanagerRemoteService.sendNotification(any())).thenThrow(causeException); + + var exception = assertThrows(PostfachException.class, () -> service.notifyAntragsraum(postfachNachricht)); + assertThat(exception.getMessageCode()).isEqualTo(PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + } + + @Nested + class TestBuildInfomanagerNachricht { + + @Test + void shouldSetNachrichtId() { + var infomanagerNachricht = buildInfomanagerNachricht(); + + assertThat(infomanagerNachricht.getNachrichtId()).isEqualTo(PostfachNachrichtTestFactory.ID); + } + + @Test + void shouldSetVorgangId() { + var infomanagerNachricht = buildInfomanagerNachricht(); + + assertThat(infomanagerNachricht.getVorgangId()).isEqualTo(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldSetPostfachId() { + var infomanagerNachricht = buildInfomanagerNachricht(); + + assertThat(infomanagerNachricht.getPostfachId()).isEqualTo(MessageTestFactory.POSTFACH_ID); + } + + @Test + void shouldSetNachrichtenManagerUrl() { + when(nachrichtenManagerProperties.getUrl()).thenReturn(NACHRICHTEN_MANAGER_URL); + + var infomanagerNachricht = buildInfomanagerNachricht(); + + assertThat(infomanagerNachricht.getNachrichtenManagerUrl()).isEqualTo(NACHRICHTEN_MANAGER_URL); + } + + private InfomanagerNachricht buildInfomanagerNachricht() { + return service.builInfomanagerNachricht(postfachNachricht); + } + } + } + +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtTestFactory.java new file mode 100644 index 0000000..41631e8 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerNachrichtTestFactory.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.nachrichten.postfach.antragsraum; + +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.antragsraum.InfomanagerNachricht.InfomanagerNachrichtBuilder; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +public class InfomanagerNachrichtTestFactory { + + public static final String NACHRICHTEN_MANAGER_URL = "nachrichten-manager"; + public static InfomanagerNachricht create() { + return createBuilder().build(); + } + + private static InfomanagerNachrichtBuilder createBuilder() { + return InfomanagerNachricht.builder() + .nachrichtId(PostfachNachrichtTestFactory.ID) + .vorgangId(MessageTestFactory.VORGANG_ID) + .postfachId(MessageTestFactory.POSTFACH_ID) + .nachrichtenManagerUrl(NACHRICHTEN_MANAGER_URL); + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteServiceTest.java new file mode 100644 index 0000000..60d5e66 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/antragsraum/InfomanagerRemoteServiceTest.java @@ -0,0 +1,116 @@ +/* + * 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.nachrichten.postfach.antragsraum; + +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 de.ozgcloud.info.nachricht.GrpcNachricht; +import de.ozgcloud.info.nachricht.GrpcNewNachrichtReply; +import de.ozgcloud.info.nachricht.GrpcNewNachrichtRequest; +import de.ozgcloud.info.nachricht.NachrichtServiceGrpc.NachrichtServiceBlockingStub; + +class InfomanagerRemoteServiceTest { + + @Spy + @InjectMocks + private InfomanagerRemoteService service; + + @Mock + private NachrichtServiceBlockingStub nachrichtServiceStub; + @Mock + private InfomanagerNachrichtMapper nachrichtMapper; + + @Nested + class TestSendNotification { + + private static final String INFO_MANAGER_STATUS = "status"; + + @Mock + private GrpcNewNachrichtRequest grpcRequest; + @Mock + private GrpcNewNachrichtReply grpcReply; + + @BeforeEach + void setup() { + doReturn(grpcRequest).when(service).buildNachrichtRequest(any()); + when(nachrichtServiceStub.saveNewNachricht(any())).thenReturn(grpcReply); + } + + @Test + void shouldCallGrpcClient() { + sendNotification(); + + verify(nachrichtServiceStub).saveNewNachricht(grpcRequest); + } + + @Test + void shouldReturnStatus() { + when(grpcReply.getStatus()).thenReturn(INFO_MANAGER_STATUS); + + var status = sendNotification(); + + assertThat(status).isEqualTo(INFO_MANAGER_STATUS); + } + + private String sendNotification() { + return service.sendNotification(InfomanagerNachrichtTestFactory.create()); + } + } + + @Nested + class TestBuildNachrichtRequest { + + @Mock + private GrpcNachricht grpcNachricht; + + @BeforeEach + void setup() { + when(nachrichtMapper.toGrpc(any())).thenReturn(grpcNachricht); + } + + @Test + void shouldCallMapper() { + var nachricht = InfomanagerNachrichtTestFactory.create(); + + service.buildNachrichtRequest(nachricht); + + verify(nachrichtMapper).toGrpc(nachricht); + } + + @Test + void shouldSetNachricht() { + var grpcRequest = service.buildNachrichtRequest(InfomanagerNachrichtTestFactory.create()); + + assertThat(grpcRequest.getNachricht()).isEqualTo(grpcNachricht); + } + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTestFactory.java new file mode 100644 index 0000000..cc86790 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTestFactory.java @@ -0,0 +1,49 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.ozgcloud.nachrichten.postfach.bayernid.Absender.AbsenderBuilder; + +public class AbsenderTestFactory { + public static final String POSTKORB_ID="28721c6f-b78f-4d5c-a048-19fd2fc429d2"; + public static final String NAME="test name"; + public static final String ANSCHRIFT="Niemalsgasse 5, 99999 Irgendwo Stadt"; + public static final String DIENST="Stadtverwaltung"; + public static final String MANDANT="Fürth"; + public static final String GEMEINDE_SCHLUESSEL="09563000"; + + public static Absender create(){ + return createBuilder().build(); + } + + public static AbsenderBuilder createBuilder(){ + return Absender.builder() + .postkorbId(POSTKORB_ID) + .name(NAME) + .anschrift(ANSCHRIFT) + .dienst(DIENST) + .mandant(MANDANT) + .gemeindeSchluessel(GEMEINDE_SCHLUESSEL); + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTypeTestFactory.java new file mode 100644 index 0000000..9eb5b05 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/AbsenderTypeTestFactory.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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.AbsenderType; +import lombok.val; + +public class AbsenderTypeTestFactory { + public static final String DIENST = "Stadtverwaltung"; + public static final String MANDANT = "Fürth"; + + public static AbsenderType create() { + val absenderType = new AbsenderType(); + absenderType.setDienst(DIENST); + absenderType.setMandant(MANDANT); + return absenderType; + } + +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentServiceTest.java new file mode 100644 index 0000000..a92cda9 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentServiceTest.java @@ -0,0 +1,179 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static de.ozgcloud.nachrichten.postfach.bayernid.BayernIdAttachmentTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 com.mongodb.client.gridfs.model.GridFSFile; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.BinaryFileService; +import de.ozgcloud.nachrichten.postfach.FileId; + +class BayernIdAttachmentServiceTest { + + private static final FileId FILE_ID = FileId.from("42"); + + @InjectMocks + @Spy + private BayernIdAttachmentService bayernIdAttachmentService; + + @Mock + private BinaryFileService fileService; + + @Mock + private GridFSFile gridFsfile; + + @Mock + private Document metadata; + + @Nested + class TestLoadingAttachment { + + @BeforeEach + void init() { + when(gridFsfile.getMetadata()).thenReturn(metadata); + when(fileService.getFile(any())).thenReturn(gridFsfile); + } + + @Test + void shouldCallGetFile() { + when(fileService.getUploadedFileStream(any())).thenReturn(new ByteArrayInputStream(CONTENT)); + + bayernIdAttachmentService.getMessageAttachment(FILE_ID); + + verify(fileService).getFile(FILE_ID); + } + + @Test + void shouldCallGetAttachmentContent() { + when(fileService.getUploadedFileStream(any())).thenReturn(new ByteArrayInputStream(CONTENT)); + + bayernIdAttachmentService.getMessageAttachment(FILE_ID); + + verify(bayernIdAttachmentService).getMessageAttachment(FILE_ID); + } + + @Test + void shouldCallBuildBayernIdAttachment() { + var contentStream = getContentStream(); + doReturn(contentStream).when(bayernIdAttachmentService).getAttachmentContentStream(any()); + + bayernIdAttachmentService.getMessageAttachment(FILE_ID); + + verify(bayernIdAttachmentService).buildBayernIdAttachment(metadata, contentStream); + } + + } + + @Nested + class TestLoadAttachmentError { + + @Test + @DisplayName("should throw TechnicalException if attachment not found") + void shouldThrowException() { + when(fileService.getFile(any())).thenReturn(null); + + assertThrows(TechnicalException.class, () -> bayernIdAttachmentService.getMessageAttachment(FILE_ID)); + } + + @Test + @DisplayName("should throw TechnicalException if metadata is null") + void shouldThrowExceptionIfNoMetadata() { + when(fileService.getFile(any())).thenReturn(gridFsfile); + when(gridFsfile.getMetadata()).thenReturn(null); + + assertThrows(TechnicalException.class, () -> bayernIdAttachmentService.getMessageAttachment(FILE_ID)); + } + } + + @Nested + class TestBuildBayernIdAttachment { + + @BeforeEach + void setup() { + when(metadata.getString(BayernIdAttachmentService.NAME_KEY)).thenReturn(BayernIdAttachmentTestFactory.FILENAME); + when(metadata.getString(BayernIdAttachmentService.CONTENT_TYPE_KEY)).thenReturn(BayernIdAttachmentTestFactory.CONTENT_TYPE); + } + + @Test + void shouldSetFileName() { + var attachment = buildBayernIdAttachment(); + + assertThat(attachment.getFileName()).isEqualTo(BayernIdAttachmentTestFactory.FILENAME); + } + + @Test + void shouldSetContent() { + var attachment = buildBayernIdAttachment(); + + assertThat(attachment.getContent()).hasSameContentAs(new ByteArrayInputStream(CONTENT)); + } + + @Test + void shouldSetContentType() { + var attachment = buildBayernIdAttachment(); + + assertThat(attachment.getContentType()).isEqualTo(BayernIdAttachmentTestFactory.CONTENT_TYPE); + } + + private BayernIdAttachment buildBayernIdAttachment() { + return bayernIdAttachmentService.buildBayernIdAttachment(metadata, getContentStream()); + } + } + + @Nested + class TestLoadingAttachmentContent { + + @BeforeEach + void init() { + when(fileService.getUploadedFileStream(any())) + .thenReturn(new ByteArrayInputStream(CONTENT)); + } + + @Test + void shouldGetInputStream() { + InputStream input = bayernIdAttachmentService.getAttachmentContentStream(FILE_ID); + + assertThat(input).hasSameContentAs(getContentStream()); + } + + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentTestFactory.java new file mode 100644 index 0000000..428d417 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdAttachmentTestFactory.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.nachrichten.postfach.bayernid; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import de.ozgcloud.nachrichten.postfach.bayernid.BayernIdAttachment.BayernIdAttachmentBuilder; + +public class BayernIdAttachmentTestFactory { + + public final static String FILENAME = "test.txt"; + public final static String CONTENT_TYPE = "text/plain"; + public static final byte[] CONTENT = "test".getBytes(); + public static final long SIZE = 4L; + + public static BayernIdAttachment create() { + return createBuilder().build(); + } + + public static BayernIdAttachmentBuilder createBuilder() { + return BayernIdAttachment.builder() + .fileName(FILENAME) + .content(new ByteArrayInputStream(CONTENT)) + .contentType(CONTENT_TYPE); + } + + public static InputStream getContentStream() { + return new ByteArrayInputStream(CONTENT); + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapperTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapperTest.java new file mode 100644 index 0000000..2102d04 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachNachrichtMapperTest.java @@ -0,0 +1,295 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.Spy; + +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachmentMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcAttachments; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcBayernIdMessageMetadata; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +class BayernIdPostfachNachrichtMapperTest { + + @Spy + private BayernIdPostfachNachrichtMapper mapper = Mappers.getMapper(BayernIdPostfachNachrichtMapper.class); + + @Nested + class TestMapToSendBayernIdMessageMetadataRequest { + + private static final PostfachNachricht NACHRICHT = PostfachNachrichtTestFactory.create(); + private static final Absender ABSENDER = AbsenderTestFactory.create(); + + @Test + void shouldIgnoreAttachments() { + var request = mapper.toSendBayernIdMessageMetadataRequest(NACHRICHT, ABSENDER); + + assertThat(request.getAttachments()).isEqualTo(GrpcAttachments.getDefaultInstance()); + } + + @Test + void shouldCallToBayernIdMessageMetadata() { + mapper.toSendBayernIdMessageMetadataRequest(NACHRICHT, ABSENDER); + + verify(mapper).toBayernIdMessageMetadata(NACHRICHT, ABSENDER); + } + + @Nested + class TestMapToBayernIdMessageMetadata { + + @Test + void shouldSetMessageId() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getMessageId()).isEqualTo(MessageTestFactory.MESSAGE_ID); + } + + @Nested + class TestCreatedAt { + + @Test + void shouldCallConvertZonedDateTime() { + toMessageMetadata(); + + verify(mapper).convertZonedDateTime(PostfachNachrichtTestFactory.CREATED_AT); + } + + @Test + void shouldSetCreatedAt() { + doReturn(PostfachNachrichtTestFactory.CREATED_AT_STR).when(mapper).convertZonedDateTime(any()); + + var metadata = toMessageMetadata(); + + assertThat(metadata.getCreatedAt()).isEqualTo(PostfachNachrichtTestFactory.CREATED_AT_STR); + } + } + + @Test + void shouldSetSubject() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getSubject()).isEqualTo(MessageTestFactory.SUBJECT); + } + + @Test + void shouldSetStorkQaaLevel() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getStorkQaaLevel()).isEqualTo(BayernIdPostfachNachrichtMapper.MESSAGE_LEVEL); + } + + @Test + void shouldSetVorgangId() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getVorgangId()).isEqualTo(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldSetText() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getText()).isEqualTo(PostfachNachrichtTestFactory.MAIL_BODY); + } + + @Nested + class TestMapAbsender { + + @Test + void shouldSetName() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getAbsender().getName()).isEqualTo(AbsenderTestFactory.NAME); + } + + @Test + void shouldSetAnschrift() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getAbsender().getAnschrift()).isEqualTo(AbsenderTestFactory.ANSCHRIFT); + } + + @Test + void shouldSetDienst() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getAbsender().getDienst()).isEqualTo(AbsenderTestFactory.DIENST); + } + + @Test + void shouldSetMandant() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getAbsender().getMandant()).isEqualTo(AbsenderTestFactory.MANDANT); + } + + @Test + void shouldSetGemeindeschluessel() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getAbsender().getGemeindeschluessel()).isEqualTo(AbsenderTestFactory.GEMEINDE_SCHLUESSEL); + } + + } + + @Nested + class TestMapToEmpfaenger { + + @Test + void shouldSetPostkorbId() { + var metadata = toMessageMetadata(); + + assertThat(metadata.getEmpfaenger().getPostkorbId()).isEqualTo(MessageTestFactory.POSTFACH_ID); + } + } + + private GrpcBayernIdMessageMetadata toMessageMetadata() { + return mapper.toBayernIdMessageMetadata(NACHRICHT, ABSENDER); + } + } + } + + @Nested + class TestMapToSendBayernIdAttachmentsMetadata { + + private static final BayernIdAttachment ATTACHMENT = BayernIdAttachmentTestFactory.create(); + + @Test + void shouldIgnoreMessageMetadata() { + var request = toMessageRequest(); + + assertThat(request.getMessageMetadata()).isEqualTo(GrpcBayernIdMessageMetadata.getDefaultInstance()); + } + + @Test + void shouldIgnoreContent() { + var request = toMessageRequest(); + + assertThat(request.getAttachments().getContent()).isEmpty(); + } + + @Test + void shouldCallToAttachmentsMetadata() { + toMessageRequest(); + + verify(mapper).toAttachmentMetadata(ATTACHMENT); + } + + private GrpcSendBayernIdMessageRequest toMessageRequest() { + return mapper.toSendBayernIdAttachmentsMetadataRequest(ATTACHMENT); + } + } + + @Nested + class TestMapToAttachmentMetadata { + + @Test + void shouldSetFileName() { + var metadata = toMessageRequest(); + + assertThat(metadata.getFileName()).isEqualTo(BayernIdAttachmentTestFactory.FILENAME); + } + + @Test + void shouldSetFileType() { + var metadata = toMessageRequest(); + + assertThat(metadata.getFileType()).isEqualTo(BayernIdAttachmentTestFactory.CONTENT_TYPE); + } + + private GrpcAttachmentMetadata toMessageRequest() { + return mapper.toAttachmentMetadata(BayernIdAttachmentTestFactory.create()); + } + } + + @Nested + class TestMapToGregorianCalendar { + + @Test + void shouldReturnGregorianCalendar() { + var expectedDateTiem = "2024-02-14T23:29:25.000+01:00"; + var dateTiem = ZonedDateTime.of(2024, 2, 14, 23, 29, 25, 0, ZoneId.of("Europe/Berlin")); + + var calendar = mapper.convertZonedDateTime(dateTiem); + + assertThat(calendar).isEqualTo(expectedDateTiem); + } + } + + @Nested + class TestMapFromSendBayernIdMessageResponse { + + @Test + void shouldSetSuccess() { + var result = mapper.fromSendBayernIdMessageResponse(GrpcSendBayernIdMessageResponseTestFactory.create()); + + assertThat(result.isSuccess()).isTrue(); + } + + @Test + void shouldSetStatus() { + var result = mapper.fromSendBayernIdMessageResponse(GrpcSendBayernIdMessageResponseTestFactory.create()); + + assertThat(result.getStatus()).isEqualTo(GrpcSendBayernIdMessageResponseTestFactory.STATUS); + } + + @Test + void shouldSetMessage(){ + var result = mapper.fromSendBayernIdMessageResponse(GrpcSendBayernIdMessageResponseTestFactory.create()); + + assertThat(result.getMessage()).isEqualTo(GrpcSendBayernIdMessageResponseTestFactory.MESSAGE_TEXT); + } + } + + @Nested + class TestSkipNulls { + + @Test + void shouldNotSetNull() { + var bayernIdMessageMetadata = mapper.toBayernIdMessageMetadata(PostfachNachrichtTestFactory.createBuilder().messageId(null).build(), + AbsenderTestFactory.create()); + + assertThat(bayernIdMessageMetadata.getMessageId()).isEmpty(); + } + + @Test + void shouldReturnTrueIfNotNull() { + var result = mapper.nonNull("test"); + + assertThat(result).isTrue(); + } + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceTest.java new file mode 100644 index 0000000..fa21a62 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceTest.java @@ -0,0 +1,455 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.PostfachRuntimeException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.BayernIdProxyServiceGrpc; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import io.grpc.stub.CallStreamObserver; +import io.grpc.stub.StreamObserver; +import lombok.SneakyThrows; + +class BayernIdPostfachRemoteServiceTest { + + @Spy + @InjectMocks + private BayernIdPostfachRemoteService service; + + @Mock + private BayernIdProxyServiceGrpc.BayernIdProxyServiceStub bayernIdProxyServiceStub; + @Mock + private BayernIdProperties properties; + @Mock + private BayernIdPostfachResponseHandler responseHandler; + @Mock + private BayernIdPostfachNachrichtMapper mapper; + @Mock + private BayernIdAttachmentService attachmentService; + + @Nested + @DisplayName("Get all messages") + class TestGetAllMessages { + + @Test + void shouldThrowUnsupportedOperationException() { + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(service::getAllMessages); + } + } + + @Nested + @DisplayName("Delete messages") + class TestDeleteMessages { + + @Test + void shouldThrowUnsupportedOperationException() { + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> service.deleteMessage(StringUtils.EMPTY)); + } + } + + @Nested + @DisplayName("Send message") + class TestSendMessage { + + @Mock + private GrpcSendBayernIdMessageResponse grpcResponse; + @Mock + private MessageWithFilesSender messageWithFilesSender; + @Mock + private BayernIdResponse bayernIdResponse; + + @Nested + class TestSend { + + @BeforeEach + void setup() { + doReturn(grpcResponse).when(service).waitUntilTransferCompleted(any()); + } + + @Test + void shouldCallCreateMessageWithFileSender() { + sendMessage(); + + verify(service).createMessageWithFilesSender(any()); + } + + @Test + void shouldCallSend() { + doReturn(messageWithFilesSender).when(service).createMessageWithFilesSender(any()); + + sendMessage(); + + verify(messageWithFilesSender).send(); + } + + @Test + void shouldCallWaitForResults() { + var expectedSender = mock(MessageWithFilesSender.class); + when(messageWithFilesSender.send()).thenReturn(expectedSender); + doReturn(messageWithFilesSender).when(service).createMessageWithFilesSender(any()); + + sendMessage(); + + verify(service).waitUntilTransferCompleted(expectedSender); + } + + @Test + void shouldCallMaapper() { + sendMessage(); + + verify(mapper).fromSendBayernIdMessageResponse(grpcResponse); + } + + @Test + void shouldCallResponseHandler() { + when(mapper.fromSendBayernIdMessageResponse(any())).thenReturn(bayernIdResponse); + + sendMessage(); + + verify(responseHandler).handleResponse(bayernIdResponse); + } + } + + @Nested + class TestExceptionHandling { + + @Test + void shouldHandleExceptionWhenSending() { + var thrownException = new RuntimeException("Test"); + when(messageWithFilesSender.send()).thenThrow(thrownException); + doReturn(messageWithFilesSender).when(service).createMessageWithFilesSender(any()); + + assertThrows(PostfachRuntimeException.class, TestSendMessage.this::sendMessage); + } + + @Test + void shouldHandleExceptionWhenWaiting() { + var thrownException = new RuntimeException("Test"); + doThrow(thrownException).when(service).waitUntilTransferCompleted(any()); + + assertThrows(PostfachRuntimeException.class, TestSendMessage.this::sendMessage); + } + + @Test + void shouldPassBayernIdServerException() { + doReturn(grpcResponse).when(service).waitUntilTransferCompleted(any()); + var thrownException = new BayernIdServerException("Test"); + doThrow(thrownException).when(responseHandler).handleResponse(any()); + + var resultException = assertThrows(BayernIdServerException.class, TestSendMessage.this::sendMessage); + assertThat(resultException).isEqualTo(thrownException); + } + } + + private void sendMessage() { + service.sendMessage(PostfachNachrichtTestFactory.create()); + } + } + + @Nested + class TestCreateMessageWithFileSender { + + @Mock + private Function<StreamObserver<GrpcSendBayernIdMessageResponse>, CallStreamObserver<GrpcSendBayernIdMessageRequest>> streamObserverBuilder; + @Mock + private GrpcSendBayernIdMessageRequest metadataRequest; + @Mock + private Function<String, BayernIdAttachment> attachmentBuilder; + @Mock + private Function<BayernIdAttachment, GrpcSendBayernIdMessageRequest> attachmentMetadataMapper; + @Mock + private BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; + + @Test + void shouldSetStreamObserverBuilder() { + doReturn(streamObserverBuilder).when(service).buildCallStreamObserverBuilder(); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("reqObserverBuilder").isEqualTo(streamObserverBuilder); + } + + @Test + void shouldCallMessageMetadataMapper() { + var absender = AbsenderTestFactory.create(); + when(properties.getAbsender()).thenReturn(absender); + var nachricht = PostfachNachrichtTestFactory.create(); + + service.createMessageWithFilesSender(nachricht); + + verify(mapper).toSendBayernIdMessageMetadataRequest(nachricht, absender); + } + + @Test + void shouldSetMessageMetadata() { + when(mapper.toSendBayernIdMessageMetadataRequest(any(), any())).thenReturn(metadataRequest); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("messageMetadata").isEqualTo(metadataRequest); + } + + @Test + void shouldSetAttachmentIds() { + var nachricht = PostfachNachrichtTestFactory.create(); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("attachmentIds").isEqualTo(nachricht.getAttachments()); + } + + @Test + void shouldSetAttachmentBuilder() { + doReturn(attachmentBuilder).when(service).buildAttachmentBuilder(); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("toAttachment").isEqualTo(attachmentBuilder); + } + + @Test + void shouldSetAttachmentMetadataBuilder() { + doReturn(attachmentMetadataMapper).when(service).buildAttachmentMetadataMapper(); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("attachmentMetadataMapper").isEqualTo(attachmentMetadataMapper); + } + + @Test + void shouldSetChunkBuilder() { + doReturn(chunkBuilder).when(service).buildChunkRequest(); + + var sender = createMessageWithFilesSender(); + + assertThat(sender).extracting("chunkBuilder").isEqualTo(chunkBuilder); + } + + private MessageWithFilesSender createMessageWithFilesSender() { + return service.createMessageWithFilesSender(PostfachNachrichtTestFactory.create()); + } + } + + @Nested + class TestBuildCallStreamObserverBuilder { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + @Mock + private StreamObserver<GrpcSendBayernIdMessageResponse> responseObserver; + + @Test + void shouldCallSendMessageAsStream() { + service.buildCallStreamObserverBuilder().apply(responseObserver); + + verify(bayernIdProxyServiceStub).sendMessageAsStream(responseObserver); + } + + @Test + void shouldReturnRequestObserver() { + when(bayernIdProxyServiceStub.sendMessageAsStream(any())).thenReturn(requestObserver); + + var result = service.buildCallStreamObserverBuilder().apply(responseObserver); + + assertThat(result).isEqualTo(requestObserver); + } + } + + @Nested + class TestBuildAttachmentBuilder { + + @Captor + private ArgumentCaptor<FileId> attachmentIdCaptor; + + @Test + void shouldCallGetMessageAttachment (){ + var attachmentId = "test"; + + service.buildAttachmentBuilder().apply(attachmentId); + + verify(attachmentService).getMessageAttachment(attachmentIdCaptor.capture()); + assertThat(attachmentIdCaptor.getValue()).extracting(FileId::toString).isEqualTo(attachmentId); + } + + @Test + void shouldReturnAttachment() { + var attachment = BayernIdAttachmentTestFactory.create(); + when(attachmentService.getMessageAttachment(any())).thenReturn(attachment); + + var result = service.buildAttachmentBuilder().apply(StringUtils.EMPTY); + + assertThat(result).isEqualTo(attachment); + } + } + + @Nested + class TestBuildChunkRequest { + + @Captor + private ArgumentCaptor<byte[]> bytesCaptor; + @Captor + private ArgumentCaptor<Integer> lengthCaptor; + + @Test + void shouldReturnRequest() { + var bytes = new byte[] { 1, 2, 3 }; + var length = 3; + + var result = service.buildChunkRequest().apply(bytes, length); + + assertThat(result.getAttachments().getContent().toByteArray()).isEqualTo(bytes); + } + } + + @Nested + class TestBuildAttachmentMetadataMapper { + + private static final BayernIdAttachment ATTACHMENT = BayernIdAttachmentTestFactory.create(); + + @Mock + private GrpcSendBayernIdMessageRequest attachmentMetadataRequest; + + @Test + void shouldCallMapper() { + service.buildAttachmentMetadataMapper().apply(ATTACHMENT); + + verify(mapper).toSendBayernIdAttachmentsMetadataRequest(ATTACHMENT); + } + + @Test + void shouldReturnResult() { + when(mapper.toSendBayernIdAttachmentsMetadataRequest(any())).thenReturn(attachmentMetadataRequest); + + var result = service.buildAttachmentMetadataMapper().apply(ATTACHMENT); + + assertThat(result).isEqualTo(attachmentMetadataRequest); + } + } + + @Nested + class TestWaitUntilTransferCompleted { + + @Mock + private MessageWithFilesSender sender; + @Mock + private GrpcSendBayernIdMessageResponse grpcResponse; + @Mock + private CompletableFuture<GrpcSendBayernIdMessageResponse> resultFuture; + + @BeforeEach + void setup() { + doReturn(resultFuture).when(sender).getResultFuture(); + } + + @Test + void shouldCallGet() { + service.waitUntilTransferCompleted(sender); + + verify(sender).getResultFuture(); + } + + @Test + @SneakyThrows + void shouldReturnResult() { + when(resultFuture.get(anyLong(), any())).thenReturn(grpcResponse); + + var result = service.waitUntilTransferCompleted(sender); + + assertThat(result).isEqualTo(grpcResponse); + } + + @SneakyThrows + @Test + void shouldHandleInterruptedException() { + var interruptedException = new InterruptedException(); + + when(resultFuture.get(anyLong(), any())).thenThrow(interruptedException); + + assertThrows(TechnicalException.class, () -> service.waitUntilTransferCompleted(sender)); + verify(sender).cancelOnError(interruptedException); + } + + @Test + @SneakyThrows + void shouldHandleTimeout() { + when(resultFuture.get(anyLong(), any())).thenThrow(new TimeoutException()); + + assertThrows(TechnicalException.class, () -> service.waitUntilTransferCompleted(sender)); + verify(sender).cancelOnTimeout(); + } + + @Test + @SneakyThrows + void shouldHandleExecutionException() { + var executionException = new ExecutionException(new RuntimeException()); + when(resultFuture.get(anyLong(), any())).thenThrow(executionException); + + assertThrows(TechnicalException.class, () -> service.waitUntilTransferCompleted(sender)); + verify(sender).cancelOnTimeout(); + } + + } + + @Nested + class TestGetPostfach { + + @Test + void shouldHasTyp() { + var postfachType = service.getPostfachType(); + + assertThat(postfachType).isEqualTo(BayernIdPostfachRemoteService.POSTFACH_TYPE); + } + + @Test + void shouldSetReplyNotAllowed() { + var isReplyAllowed = service.isReplyAllowed(); + + assertThat(isReplyAllowed).isFalse(); + } + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandlerTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandlerTest.java new file mode 100644 index 0000000..8e9fcf8 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachResponseHandlerTest.java @@ -0,0 +1,66 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.InjectMocks; + +class BayernIdPostfachResponseHandlerTest { + + @InjectMocks + private BayernIdPostfachResponseHandler handler; + + @Nested + @DisplayName("Test successful Postfachserver response") + class TestSuccessfulPostfachServerResponse { + + @Test + void shouldNotThrowAnyException() { + assertThatCode(() -> handler.handleResponse(BayernIdResponseTestFactory.create())).doesNotThrowAnyException(); + } + } + + @Nested + @DisplayName("Test faulty Postfachserver response ") + class TestFaultyPostfachserverResponse { + + @DisplayName("Fehler im OK.KOMM-Schema") + @ParameterizedTest(name = "when response status: {0}") + @EnumSource(value = MailSendingResponseStatus.class, mode = EnumSource.Mode.EXCLUDE, names = { "SUCCESS" }) + void shouldThrowPostfachBadRequestExceptionForSchluessel(MailSendingResponseStatus responseStatus) { + var bayernIdResponse = BayernIdResponseTestFactory.createBuilder().success(false).status(responseStatus.getSchluessel()).build(); + + var exception = Assertions.assertThrows(BayernIdServerException.class, () -> handler.handleResponse(bayernIdResponse)); + assertThat(exception.getMessage()).startsWith("9006 / %s / %s".formatted(responseStatus.getSchluessel(), responseStatus.getMessage())); + } + + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPropertiesITCase.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPropertiesITCase.java new file mode 100644 index 0000000..b0268ff --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPropertiesITCase.java @@ -0,0 +1,111 @@ +/* + * 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.nachrichten.postfach.bayernid; + +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +import de.ozgcloud.common.test.ITCase; + +@SpringBootTest(classes = { BayernIdProperties.class }) +@ITCase +class BayernIdPropertiesITCase { + + private static final String NAME = "test name"; + + @TestPropertySource(properties = { + "ozgcloud.bayernid.enabled=true", + "ozgcloud.bayernid.absender.postkorbId=28721c6f-b78f-4d5c-a048-19fd2fc429d2", + "ozgcloud.bayernid.absender.name=test name", + "ozgcloud.bayernid.absender.anschrift=Niemalsgasse 5, 99999 Irgendwo Stadt", + "ozgcloud.bayernid.absender.dienst=Stadtverwaltung", + "ozgcloud.bayernid.absender.mandant=Fürth", + "ozgcloud.bayernid.absender.gemeindeSchluessel=09563000", + }) + @DisplayName("Test loading bayernid configuration") + @Nested + class TestLoadingConfiguration { + + // TODO remove access data + private static final String POSTKORBID = "28721c6f-b78f-4d5c-a048-19fd2fc429d2"; + private static final String DIENST = "Stadtverwaltung"; + private static final String ANSCHRIFT = "Niemalsgasse 5, 99999 Irgendwo Stadt"; + private static final String PASSWORD = ""; + private static final String RESOURCE_PATH = "bayernid.p12"; + private static final String MANDANT = "Fürth"; + private static final String GEMEINDE_SCHLUESSEL = "09563000"; + + @Autowired + private BayernIdProperties properties; + + @Test + void shouldHaveProperties() { + assertThat(properties).isNotNull(); + } + + @Test + void shouldHaveAbsender() { + assertThat(properties.getAbsender()) + .isNotNull() + .usingRecursiveComparison() + .isEqualTo(Absender.builder() + .anschrift(ANSCHRIFT) + .dienst(DIENST) + .name(NAME) + .mandant(MANDANT) + .gemeindeSchluessel(GEMEINDE_SCHLUESSEL) + .postkorbId(POSTKORBID).build()); + } + + } + + @TestPropertySource(properties = { "ozgcloud.other=test name" }) + @DisplayName("Test loading application context without bayerid properties") + @Nested + class TestLoadingOtherConfiguration { + + @Value("${ozgcloud.other}") + private String testValue; + + @Autowired(required = false) + private BayernIdProperties properties; + + @Test + void shouldLoadTestProperty() { + assertThat(testValue).isEqualTo(NAME); + } + + @Test + void shouldNotLoadBayernIdProperties() { + assertThat(properties).isNull(); + } + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponseTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponseTestFactory.java new file mode 100644 index 0000000..54f6a07 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdResponseTestFactory.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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.BspQuittung; +import de.akdb.egov.bsp.nachrichten.SchluesseltabelleType; +import de.ozgcloud.nachrichten.postfach.bayernid.BayernIdResponse.BayernIdResponseBuilder; + +public class BayernIdResponseTestFactory { + public static final String ERGAENZENE_HINWEISE = "ergaenzenderHinweis"; + + public static BayernIdResponse create() { + return createBuilder().build(); + } + + public static BayernIdResponseBuilder createBuilder() { + return BayernIdResponse.builder() + .success(true) + .status("0") + .message(ERGAENZENE_HINWEISE); + } + +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BspNachrichtTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BspNachrichtTestFactory.java new file mode 100644 index 0000000..34b723d --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BspNachrichtTestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.BspNachricht; +import de.akdb.egov.bsp.nachrichten.NachrichtenKopfType; +import lombok.val; + +public class BspNachrichtTestFactory { + public static final NachrichtenKopfType NACHRICHTEN_KOPF_TYPE = NachrichtenKopfTypeTestFactory.create(); + + public static BspNachricht create() { + val bspNachricht = new BspNachricht(); + bspNachricht.setNachrichtenKopf(NACHRICHTEN_KOPF_TYPE); + return bspNachricht; + } + +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/EmpfaengerTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/EmpfaengerTypeTestFactory.java new file mode 100644 index 0000000..a0f8dd8 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/EmpfaengerTypeTestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.util.UUID; + +import de.akdb.egov.bsp.nachrichten.EmpfaengerType; +import lombok.val; + +public class EmpfaengerTypeTestFactory { + public static final String POSTKORB_ID = UUID.randomUUID().toString(); + + public static EmpfaengerType create() { + val empfaengerType = new EmpfaengerType(); + empfaengerType.setPostkorbId(POSTKORB_ID); + return empfaengerType; + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSenderTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSenderTest.java new file mode 100644 index 0000000..75536d8 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSenderTest.java @@ -0,0 +1,214 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.InputStream; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.test.util.ReflectionTestUtils; + +import de.ozgcloud.nachrichten.postfach.bayernid.FileSender.StreamReader; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import io.grpc.stub.CallStreamObserver; +import lombok.SneakyThrows; + +class FileSenderTest { + + private FileSender fileSender; + + @Mock + private BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + @Mock + private GrpcSendBayernIdMessageRequest metadata; + @Mock + private InputStream inputStream; + + @BeforeEach + void setup() { + fileSender = spy(new FileSender(chunkBuilder, requestObserver, metadata, inputStream)); + } + + @Nested + class TestSend { + + @Test + void shouldCallSendMetadata() { + fileSender.send(); + + verify(fileSender).sendMetadata(); + } + + @Test + void shouldCallSendNextChunk() { + when(requestObserver.isReady()).thenReturn(true); + doAnswer(invocation -> { + ((AtomicBoolean) ReflectionTestUtils.getField(fileSender, "done")).set(true); + return null; + }).when(fileSender).sendNextChunk(); + + fileSender.send(); + + verify(fileSender).sendNextChunk(); + } + + @Test + void shouldNotCallSendNextChunkWhenDone() { + ((AtomicBoolean) ReflectionTestUtils.getField(fileSender, "done")).set(true); + + fileSender.send(); + + verify(fileSender, never()).sendNextChunk(); + } + + @Test + void shouldNotCallSendNextChunkWhenNotReady() { + fileSender.send(); + + verify(fileSender, never()).sendNextChunk(); + } + } + + @Nested + class TestSendMetadata { + + @Test + void shouldCallOnNextOnce() { + fileSender.sendMetadata(); + fileSender.sendMetadata(); + + verify(requestObserver).onNext(metadata); + } + + } + + @Nested + class TestSendNextChunk { + + @Test + void shouldCallSendChunk() { + var contentToSend = new byte[] { 1, 2, 3, 4, 5 }; + setContent(contentToSend); + + fileSender.sendNextChunk(); + + verify(fileSender).sendChunk(contentToSend, 5); + } + + @Test + void shouldReturnContentLength() { + var contentToSend = new byte[] { 1, 2, 3, 4, 5 }; + setContent(contentToSend); + + var length = fileSender.sendNextChunk(); + + assertThat(length).isEqualTo(contentToSend.length); + } + + @Test + void shouldCallEndTransfer() { + setContent(new byte[] {}); + + fileSender.sendNextChunk(); + + verify(fileSender).endTransfer(); + } + + @SneakyThrows + void setContent(byte[] contentToSend) { + var streamReader = getStreamReader(); + ReflectionTestUtils.setField(streamReader, "buffer", contentToSend); + when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(contentToSend.length); + } + + } + + @Nested + class TestEndTransfer { + + @Mock + private StreamReader streamReader; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(fileSender, "streamReader", streamReader); + } + + @Test + void shouldSetDone() { + fileSender.endTransfer(); + + var done = (AtomicBoolean) ReflectionTestUtils.getField(fileSender, "done"); + assertThat(done.get()).isTrue(); + } + + @Test + void shouldCloseStream() { + fileSender.endTransfer(); + + verify(streamReader).close(); + } + } + + @Nested + class TestSendChunk { + + @Mock + private GrpcSendBayernIdMessageRequest chunkRequest; + + private byte[] contentToSend = new byte[] { 1, 2, 3, 4, 5 }; + private int length = 5; + + + @Test + void shouldCallChunkBuilder() { + fileSender.sendChunk(contentToSend, length); + + verify(chunkBuilder).apply(contentToSend, length); + } + + @Test + void shouldCallOnNext() { + when(chunkBuilder.apply(any(), anyInt())).thenReturn(chunkRequest); + + fileSender.sendChunk(contentToSend, length); + + verify(requestObserver).onNext(chunkRequest); + } + + } + + StreamReader getStreamReader() { + return (StreamReader) ReflectionTestUtils.getField(fileSender, "streamReader"); + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FreiTextTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FreiTextTypeTestFactory.java new file mode 100644 index 0000000..91a86c3 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/FreiTextTypeTestFactory.java @@ -0,0 +1,38 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.FreiTextType; +import de.akdb.egov.bsp.nachrichten.SchluesseltabelleType; +import lombok.val; + +public class FreiTextTypeTestFactory { + public static final String MESSAGE_TEXT = "Test Nachricht\n\nHallo"; + + public FreiTextType create() { + val freiText = new FreiTextType(); + freiText.setText(MESSAGE_TEXT); + return freiText; + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/GrpcSendBayernIdMessageResponseTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/GrpcSendBayernIdMessageResponseTestFactory.java new file mode 100644 index 0000000..3aa0719 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/GrpcSendBayernIdMessageResponseTestFactory.java @@ -0,0 +1,43 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; + +public class GrpcSendBayernIdMessageResponseTestFactory { + + public static final String STATUS = "code"; + public static final String MESSAGE_TEXT = "messageText"; + + public static GrpcSendBayernIdMessageResponse create() { + return createBuilder().build(); + } + + public static GrpcSendBayernIdMessageResponse.Builder createBuilder() { + return GrpcSendBayernIdMessageResponse.newBuilder() + .setSuccess(true) + .setStatus(STATUS) + .setMessage(MESSAGE_TEXT); + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/IdentifikationNachrichtTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/IdentifikationNachrichtTypeTestFactory.java new file mode 100644 index 0000000..66ff238 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/IdentifikationNachrichtTypeTestFactory.java @@ -0,0 +1,59 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.time.Instant; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.UUID; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import de.akdb.egov.bsp.nachrichten.IdentifikationNachrichtType; +import de.akdb.egov.bsp.nachrichten.SchluesseltabelleType; +import lombok.val; + +class IdentifikationNachrichtTypeTestFactory { + public static final XMLGregorianCalendar ERSTELLUNGSZEITPUNKT = now(); + public static final String NACHRICHTEN_ID = UUID.randomUUID().toString(); + + private static XMLGregorianCalendar now() { + try { + val c = new GregorianCalendar(); + c.setTime(Date.from(Instant.now())); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(c); + } catch (DatatypeConfigurationException e) { + throw new RuntimeException(e); + } + } + + public static IdentifikationNachrichtType create() { + IdentifikationNachrichtType identifikationNachrichtType = new IdentifikationNachrichtType(); + identifikationNachrichtType.setNachrichtenId(NACHRICHTEN_ID); + identifikationNachrichtType.setErstellungszeitpunkt(ERSTELLUNGSZEITPUNKT); + return identifikationNachrichtType; + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatusTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatusTest.java new file mode 100644 index 0000000..e8d26d1 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MailSendingResponseStatusTest.java @@ -0,0 +1,41 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class MailSendingResponseStatusTest { + + @Test + void shouldCreateSuccessResult() { + assertThat(MailSendingResponseStatus.SUCCESS.getSchluessel()).isEqualTo("0"); + } + + @Test + void shouldCreateFromSchluessel() { + assertThat(MailSendingResponseStatus.fromSchluessel("20")).isEqualTo(MailSendingResponseStatus.ERROR_IN_MESSAGE_SCHEMA); + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java new file mode 100644 index 0000000..1efd3e3 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java @@ -0,0 +1,405 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.InputStream; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.test.util.ReflectionTestUtils; + +import de.ozgcloud.common.binaryfile.BinaryFileUploadStreamObserver; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageRequest; +import de.ozgcloud.nachrichten.postfach.bayernid.proxy.GrpcSendBayernIdMessageResponse; +import io.grpc.stub.CallStreamObserver; +import io.grpc.stub.StreamObserver; + +class MessageWithFilesSenderTest { + + private MessageWithFilesSender messageWithFilesSender; + + @Mock + private Function<StreamObserver<GrpcSendBayernIdMessageResponse>, CallStreamObserver<GrpcSendBayernIdMessageRequest>> reqObserverBuilder; + @Mock + private GrpcSendBayernIdMessageRequest messageMetadata; + @Mock + private List<String> attachmentIds; + @Mock + private Function<String, BayernIdAttachment> toAttachment; + @Mock + private Function<BayernIdAttachment, GrpcSendBayernIdMessageRequest> attachmentMetadataMapper; + @Mock + private BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; + + @BeforeEach + void setup() { + messageWithFilesSender = spy( + MessageWithFilesSender.builder().reqObserverBuilder(reqObserverBuilder).messageMetadata(messageMetadata).toAttachment(toAttachment) + .attachmentMetadataMapper(attachmentMetadataMapper).chunkBuilder(chunkBuilder).build()); + } + + @Nested + class TestSend { + + @Mock + private BinaryFileUploadStreamObserver<GrpcSendBayernIdMessageRequest, GrpcSendBayernIdMessageResponse> responseStreamObserver; + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @Test + void shouldReturnSameObject() { + var result = messageWithFilesSender.send(); + + assertThat(result).isSameAs(messageWithFilesSender); + } + + @Test + void shouldCallRequestObserverBuilder() { + try (var createMock = Mockito.mockStatic(BinaryFileUploadStreamObserver.class)) { + createMock.when(() -> BinaryFileUploadStreamObserver.create(any(), any())).thenReturn(responseStreamObserver); + + messageWithFilesSender.send(); + + verify(reqObserverBuilder).apply(responseStreamObserver); + } + } + + @Test + void shouldSetRequestStreamObserver() { + when(reqObserverBuilder.apply(any())).thenReturn(requestObserver); + + messageWithFilesSender.send(); + + assertThat(messageWithFilesSender).extracting("requestObserver").isSameAs(requestObserver); + } + } + + @Nested + class TestSendNext { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldCheckIfDone() { + doNothing().when(messageWithFilesSender).waitForObserver(); + + messageWithFilesSender.sendNext(); + + verify(messageWithFilesSender).waitForObserver(); + } + + @Test + void shouldRetrunIfDone() { + ((AtomicBoolean) ReflectionTestUtils.getField(messageWithFilesSender, "done")).set(true); + + messageWithFilesSender.sendNext(); + + verify(messageWithFilesSender, never()).waitForObserver(); + } + + @Test + void shouldCallSendMetadata() { + doNothing().when(messageWithFilesSender).waitForObserver(); + + messageWithFilesSender.sendNext(); + + verify(messageWithFilesSender).sendMetadata(); + } + + @Test + void shouldCallSendAttachments() { + doNothing().when(messageWithFilesSender).waitForObserver(); + + messageWithFilesSender.sendNext(); + + verify(messageWithFilesSender).sendAttachments(); + } + } + + @Nested + class TestSendMetadata { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldCallOnNextOnce() { + messageWithFilesSender.sendMetadata(); + messageWithFilesSender.sendMetadata(); + + verify(requestObserver).onNext(messageMetadata); + } + + } + + @Nested + class TestSendAttachments { + + private String attachmentId = "id1"; + + @Mock + private FileSender fileSender; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId)); + doNothing().when(messageWithFilesSender).completeRequest(); + } + + @Test + void shouldCallCreateFileSenders() { + doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + + messageWithFilesSender.sendAttachments(); + + verify(messageWithFilesSender).createFileSenders(); + } + + @Test + void shouldNotRecreateFileSenders() { + ReflectionTestUtils.setField(messageWithFilesSender, "fileSenders", List.of(fileSender)); + + messageWithFilesSender.sendAttachments(); + + verify(messageWithFilesSender, never()).createFileSenders(); + } + + @Test + void shouldCallSendOnFileSender() { + doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + + messageWithFilesSender.sendAttachments(); + + verify(fileSender).send(); + } + + @Test + void shouldCallCompleteRequest() { + doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + + messageWithFilesSender.sendAttachments(); + + verify(messageWithFilesSender).completeRequest(); + } + } + + @Nested + class TestCreateFileSenders { + + private String attachmentId = "id1"; + + @Mock + private FileSender fileSender; + + @BeforeEach + void setup() { + doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId)); + } + + @Test + void shouldCalToAttachment() { + messageWithFilesSender.createFileSenders(); + + verify(toAttachment).apply(attachmentId); + } + + @Test + void shouldCallBuildFileSender() { + messageWithFilesSender.createFileSenders(); + + verify(messageWithFilesSender).buildFileSender(any()); + } + + @Test + void shouldReturnFileSenders() { + var result = messageWithFilesSender.createFileSenders(); + + assertThat(result).containsExactly(fileSender); + } + } + + @Nested + class TestBuildFileSender { + + private String attachmentId = "id1"; + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + @Mock + private GrpcSendBayernIdMessageRequest attachmentMetadata; + + @Mock + private BayernIdAttachment attachment; + @Mock + private InputStream inputStream; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldSetChunkBuilder() { + var result = messageWithFilesSender.buildFileSender(attachment); + + assertThat(result).extracting("chunkBuilder").isSameAs(chunkBuilder); + } + + @Test + void shouldSetRequestObserver() { + var result = messageWithFilesSender.buildFileSender(attachment); + + assertThat(result).extracting("requestObserver").isSameAs(requestObserver); + } + + @Test + void shouldCallAttachmentMetadataMapper() { + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper); + + messageWithFilesSender.buildFileSender(attachment); + + verify(attachmentMetadataMapper).apply(attachment); + } + + @Test + void shouldSetAttachmentMetadata() { + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper); + when(attachmentMetadataMapper.apply(any())).thenReturn(attachmentMetadata); + + var result = messageWithFilesSender.buildFileSender(attachment); + + assertThat(result).extracting("metadata").isSameAs(attachmentMetadata); + } + + @Test + void shouldGetContent() { + messageWithFilesSender.buildFileSender(attachment); + + verify(attachment).getContent(); + } + } + + @Nested + class TestCompleteRequest { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldSetDone() { + messageWithFilesSender.completeRequest(); + + var done = (AtomicBoolean) ReflectionTestUtils.getField(messageWithFilesSender, "done"); + assertThat(done.get()).isTrue(); + } + + @Test + void shouldCallOnCompleted() { + messageWithFilesSender.completeRequest(); + + verify(requestObserver).onCompleted(); + } + } + + @Nested + class TestCancelOnTimeout { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldCallCancelOnRequestObserver() { + messageWithFilesSender.cancelOnTimeout(); + + verify(requestObserver).onError(any(TechnicalException.class)); + } + + @Test + void shouldCancelResultFuture() { + messageWithFilesSender.cancelOnTimeout(); + + assertThat(messageWithFilesSender.getResultFuture()).isCancelled(); + } + } + + @Nested + class TestCancelOnError { + + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + } + + @Test + void shouldCallCancelOnRequestObserver() { + var exception = new RuntimeException("test"); + messageWithFilesSender.cancelOnError(exception); + + verify(requestObserver).onError(exception); + } + + @Test + void shouldCancelResultFuture() { + messageWithFilesSender.cancelOnError(new TechnicalException("test")); + + assertThat(messageWithFilesSender.getResultFuture()).isCancelled(); + } + } +} \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenInhaltTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenInhaltTypeTestFactory.java new file mode 100644 index 0000000..0e1b28a --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenInhaltTypeTestFactory.java @@ -0,0 +1,37 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.NachrichtenInhaltType; +import lombok.val; + +public class NachrichtenInhaltTypeTestFactory { + public static final String BETREFF = "Test Nachricht"; + + public NachrichtenInhaltType create() { + val nachrichtenInhalt = new NachrichtenInhaltType(); + nachrichtenInhalt.setBetreff(BETREFF); + return nachrichtenInhalt; + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenKopfTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenKopfTypeTestFactory.java new file mode 100644 index 0000000..11cc84f --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/NachrichtenKopfTypeTestFactory.java @@ -0,0 +1,45 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import de.akdb.egov.bsp.nachrichten.AbsenderType; +import de.akdb.egov.bsp.nachrichten.EmpfaengerType; +import de.akdb.egov.bsp.nachrichten.IdentifikationNachrichtType; +import de.akdb.egov.bsp.nachrichten.NachrichtenKopfType; +import lombok.val; + +public class NachrichtenKopfTypeTestFactory { + public static final IdentifikationNachrichtType IDENTIFIKATION_NACHRICHT_TYPE = IdentifikationNachrichtTypeTestFactory.create(); + public static final AbsenderType ABSENDER_TYPE = AbsenderTypeTestFactory.create(); + public static final EmpfaengerType EMPFAENGER_TYPE = EmpfaengerTypeTestFactory.create(); + + public static NachrichtenKopfType create() { + val nachrichtenKopfType = new NachrichtenKopfType(); + nachrichtenKopfType.setIdentifikationNachricht(IDENTIFIKATION_NACHRICHT_TYPE); + nachrichtenKopfType.setAbsender(ABSENDER_TYPE); + nachrichtenKopfType.setEmpfaenger(EMPFAENGER_TYPE); + return nachrichtenKopfType; + } + +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/SendBspNachrichtNativeOutputTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/SendBspNachrichtNativeOutputTestFactory.java new file mode 100644 index 0000000..fdda90d --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/SendBspNachrichtNativeOutputTestFactory.java @@ -0,0 +1,38 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import akdb.bsp.postkorb.komm.webservice.SendBspNachrichtNativeOutput; +import lombok.val; + +public class SendBspNachrichtNativeOutputTestFactory { + + public static final String BSP_QUITTUNG = "quittung"; + + public static SendBspNachrichtNativeOutput create() { + val result = new SendBspNachrichtNativeOutput(); + result.setBspQuittung(BSP_QUITTUNG); + return result; + } +} diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/ZuVorgangTypeTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/ZuVorgangTypeTestFactory.java new file mode 100644 index 0000000..3f6b4ec --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/ZuVorgangTypeTestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import java.util.UUID; + +import de.akdb.egov.bsp.nachrichten.ZuVorgangType; +import lombok.val; + +public class ZuVorgangTypeTestFactory { + public static final String VORGANG_ID = UUID.randomUUID().toString(); + + public static ZuVorgangType create() { + val vorgang = new ZuVorgangType(); + vorgang.setVorgangsId(VORGANG_ID); + return vorgang; + } +} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/AttachmentServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java similarity index 71% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/AttachmentServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java index 7cd2df6..cc6ac5b 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/AttachmentServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -44,11 +44,14 @@ import org.mockito.Mock; import com.mongodb.client.gridfs.model.GridFSFile; -class AttachmentServiceTest { +import de.ozgcloud.nachrichten.postfach.BinaryFileService; +import de.ozgcloud.nachrichten.postfach.FileId; + +class MessageAttachmentServiceTest { private static final FileId FILE_ID = FileId.from("42"); @InjectMocks - private AttachmentService attachmentService; + private MessageAttachmentService messageAttachmentService; @Mock private BinaryFileService fileService; @@ -71,17 +74,18 @@ class AttachmentServiceTest { @Test void shouldHaveAttachmentWithFileName() { - MessageAttachment attachment = attachmentService.getMessageAttachment(FILE_ID); + MessageAttachment attachment = messageAttachmentService.getMessageAttachment(FILE_ID); assertThat(attachment.getFileName()).isEqualTo(MessageAttachmentTestFactory.FILENAME); } @Test void shouldHaveAttachmentContent() { - MessageAttachment attachment = attachmentService.getMessageAttachment(FILE_ID); + MessageAttachment attachment = messageAttachmentService.getMessageAttachment(FILE_ID); assertThat(attachment.getContent()).isEqualTo(MessageAttachmentTestFactory.CONTENT); } + } @Nested @@ -94,16 +98,34 @@ class AttachmentServiceTest { @Test void shouldGetInputStream() { - InputStream input = attachmentService.getAttachmentContentStream(FILE_ID); + InputStream input = messageAttachmentService.getAttachmentContentStream(FILE_ID); assertThat(input).isNotNull(); } @Test void shouldGetContent() throws IOException { - String input = attachmentService.getAttachmentContent(FILE_ID); + String input = messageAttachmentService.getAttachmentContent(FILE_ID); assertThat(input).isEqualTo(MessageAttachmentTestFactory.CONTENT); } } + + @Nested + class TestMapAttachmentFile { + + @Test + void shouldMapFileName() { + var attachmentFile = messageAttachmentService.mapAttachmentFile(MessageAttachmentTestFactory.create()); + + assertThat(attachmentFile.getName()).isEqualTo(MessageAttachmentTestFactory.FILENAME); + } + + @Test + void shouldMapContent() { + var attachmentFile = messageAttachmentService.mapAttachmentFile(MessageAttachmentTestFactory.create()); + + assertThat(attachmentFile.getContent()).hasContent(MessageAttachmentTestFactory.CONTENT); + } + } } diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageAttachmentTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentTestFactory.java similarity index 87% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageAttachmentTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentTestFactory.java index 97e9b57..42bb7d1 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageAttachmentTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; public class MessageAttachmentTestFactory { @@ -35,8 +35,6 @@ public class MessageAttachmentTestFactory { } public static MessageAttachment.MessageAttachmentBuilder createBuilder() { - return MessageAttachment.builder() - .fileName(FILENAME) - .content(CONTENT); + return MessageAttachment.builder().fileName(FILENAME).content(CONTENT); } } diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageJsonReplyTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageJsonReplyTestFactory.java new file mode 100644 index 0000000..ddffcdb --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageJsonReplyTestFactory.java @@ -0,0 +1,60 @@ +/* + * 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.nachrichten.postfach.osi; + +public class MessageJsonReplyTestFactory { + + private static final String REPLY_JSON_TMPL = """ + [{ + "messageId": "%s", + "nameIdentifier": "%s", + "body": "%s", + "isHtml": false, + "replyAction": %d, + "subject": "%s", + "sequenceNumber": "%s", + "eidasLevel": 1, + "isObligatory": true, + "attachments": [{ + "fileName": "%s", + "content": "%s" + }] + }]"""; + + public static String buildReplyJson() { + return buildReplyJson(MessageTestFactory.create(), MessageAttachmentTestFactory.create()); + } + + public static String buildReplyJson(Message msg, MessageAttachment attachement) { + return String.format(REPLY_JSON_TMPL, + msg.getMessageId(), + msg.getPostfachId(), + msg.getMailBody(), + msg.getReplyOption().toValue(), + msg.getSubject(), + msg.getVorgangId(), + attachement.getFileName(), + attachement.getContent()); + } +} diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageTestFactory.java similarity index 88% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageTestFactory.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageTestFactory.java index 25077cd..097b45e 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/MessageTestFactory.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import java.util.List; import java.util.UUID; -import de.itvsh.ozg.mail.postfach.Message.EidasLevel; -import de.itvsh.ozg.mail.postfach.Message.ReplyOption; +import de.ozgcloud.nachrichten.postfach.osi.Message.EidasLevel; public class MessageTestFactory { @@ -35,7 +34,7 @@ public class MessageTestFactory { public static final String POSTFACH_ID = UUID.randomUUID().toString(); public static final String VORGANG_ID = UUID.randomUUID().toString(); - public static final String MAIL_BODY = "BodyString"; + public static final String MAIL_BODY = "Body<br>String"; public static final boolean IS_HTML = false; public static final ReplyOption REPLY_OPTION = ReplyOption.MANDATORY; public static final String SUBJECT = "Test Subject"; diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapperTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapperTest.java new file mode 100644 index 0000000..85e811d --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachMessageMapperTest.java @@ -0,0 +1,200 @@ +/* + * 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.nachrichten.postfach.osi; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PostfachAddressTestFactory; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; + +class OsiPostfachMessageMapperTest { + + @InjectMocks + private OsiPostfachMessageMapper mapper = Mappers.getMapper(OsiPostfachMessageMapper.class); + @Mock + private MessageAttachmentService messageAttachmentService; + @Mock + private GrpcObjectMapper grpcObjectMapper; + + @DisplayName("To mail") + @Nested + class TestToNachricht { + + @Test + void shouldSetDirection() { + var mail = mapper.toPostfachNachricht(MessageTestFactory.create()); + + assertThat(mail.getDirection()).isEqualTo(Direction.IN); + } + + @Test + void shouldSetCreatedAt() { + var mail = mapper.toPostfachNachricht(MessageTestFactory.create()); + + assertThat(mail.getCreatedAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); + } + + @Test + void shouldIgnoreSentInformation() { + var mail = mapper.toPostfachNachricht(MessageTestFactory.create()); + + assertThat(mail.getSentAt()).isNull(); + assertThat(mail.getSentSuccessful()).isNull(); + } + + @Test + void shouldPersistAttachment() { + mapper.toPostfachNachricht(MessageTestFactory.create()); + + verify(messageAttachmentService).persistAttachment(MessageTestFactory.VORGANG_ID, MessageTestFactory.ATTACHMENTS.get(0)); + } + + @Test + void shouldSetPostfachAddress() { + var expectedPostfachAddress = PostfachAddressTestFactory.createBuilder().serviceKontoType(OsiPostfachRemoteService.POSTFACH_TYPE).build(); + + var mail = toMail(); + + assertThat(mail.getPostfachAddress()).usingRecursiveComparison().isEqualTo(expectedPostfachAddress); + } + + @Test + void shouldPreserveNewLineInBody() { + var bodyText = "line\nline"; + var mail = mapper.toPostfachNachricht(MessageTestFactory.createBuilder().mailBody(bodyText).build()); + + assertThat(mail.getMailBody()).isEqualTo(bodyText); + } + + @Test + void shouldRecodeAND() { + var mail = mapper.toPostfachNachricht(MessageTestFactory.createBuilder().mailBody("this&that").build()); + + assertThat(mail.getMailBody()).isEqualTo("this&that"); + } + + private PostfachNachricht toMail() { + return mapper.toPostfachNachricht(MessageTestFactory.create()); + } + } + + @DisplayName("To osi message") + @Nested + class TestToOsiMessage { + + @Test + void shouldCallAttachmentService() { + var fileId = FileId.from("42"); + + toOsiMessage(PostfachNachrichtTestFactory.createBuilder().attachments(List.of(fileId.toString())).build()); + + verify(messageAttachmentService).getMessageAttachment(fileId); + } + + @Test + void shouldMapFields() { + var message = toOsiMessage(PostfachNachrichtTestFactory.create()); + + assertThat(message.getSubject()).isEqualTo(MessageTestFactory.SUBJECT); + assertThat(message.getAttachments()).hasSize(1); + } + + @Test + void shouldMapMailBody() { + var message = toOsiMessage(PostfachNachrichtTestFactory.create()); + + assertThat(message.getMailBody()).isEqualTo(MessageTestFactory.MAIL_BODY); + } + + @Test + void shouldReplaceNewLineToHtml() { + var bodyText = "line\nline&"; + var message = toOsiMessage(PostfachNachrichtTestFactory.createBuilder().mailBody(bodyText).build()); + + assertThat(message.getMailBody()).isEqualTo("line<br>line&"); + } + + @DisplayName("build postfachId") + @Nested + class TestToPostfachId { + + @DisplayName("by existing postfachAddress") + @Nested + class TestWithExistingPostfachAddress { + + @Test + void shouldMapPostfachAddressToPostfachId() { + var message = toOsiMessage(PostfachNachrichtTestFactory.create()); + + assertThat(message.getPostfachId()).isEqualTo(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + } + } + + @DisplayName("by postfachId if postfachAddress not exists") + @Nested + class TestWithoutPostfachAddress { + + @Test + void shouldMapPostfachAddressToPostfachId() { + var message = toOsiMessage(PostfachNachrichtTestFactory.createBuilder().postfachAddress(null).build()); + + assertThat(message.getPostfachId()).isEqualTo(MessageTestFactory.POSTFACH_ID); + } + } + } + + private Message toOsiMessage(PostfachNachricht postfachNachricht) { + return mapper.toOsiMessage(postfachNachricht); + } + } + + @DisplayName("To HTML body") + @Nested + class TestToHTMLBody { + + @Test + void shouldNotContainNewlines() { + var body = mapper.replaceNewlines(MessageTestFactory.MAIL_BODY); + + assertThat(body).doesNotContain("\n"); + } + + } +} \ No newline at end of file diff --git a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceTest.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceTest.java similarity index 65% rename from mail-service/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceTest.java rename to nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceTest.java index 7d82d4f..d0a2666 100644 --- a/mail-service/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceTest.java +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,70 +21,57 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; -import static de.itvsh.ozg.mail.postfach.MessageTestFactory.*; +import static de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; import static org.springframework.test.web.client.response.MockRestResponseCreators.*; -import java.util.List; +import java.util.stream.Collectors; import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.core.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.ResponseActions; import org.springframework.web.client.RestTemplate; -class OsiPostfachServiceTest { +import de.ozgcloud.nachrichten.postfach.NotConfiguredException; +import de.ozgcloud.nachrichten.postfach.PostfachBadRequestException; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; - public static final String HEADER_API_KEY = "apikey"; - public static final String HEADER_API_REALM = "realm"; +class OsiPostfachRemoteServiceTest { private static final String TEST_URL = "https://testUrl.local"; private static final String TEST_API_KEY = "dummyApiKey"; private static final String TEST_API_REALM = "dummyApiRealm"; - private static final String REPLY_JSON_TMPL = """ - [{ - "messageId": "%s", - "nameIdentifier": "%s", - "body": "%s", - "isHtml": false, - "replyAction": %d, - "subject": "%s", - "sequenceNumber": "%s", - "eidasLevel": 1, - "isObligatory": true, - "attachments": [{ - "fileName": "%s", - "content": "%s" - }] - }]"""; - @InjectMocks - private OsiPostfachService service; + private OsiPostfachRemoteService service; @Mock - private AttachmentService attachmentService; + private OsiPostfachMessageMapper mapper; @Spy private RestTemplate restTemplate; + @Spy private OsiPostfachProperties properties = new OsiPostfachProperties(); { @@ -117,9 +104,11 @@ class OsiPostfachServiceTest { @Test void shouldFillMessage() { + when(mapper.toPostfachNachricht(any())).thenReturn(PostfachNachrichtTestFactory.create()); + var messages = service.getAllMessages(); - assertThat(messages).hasSize(1).first().usingRecursiveComparison().isEqualTo(MessageTestFactory.create()); + assertThat(messages).hasSize(1).first().usingRecursiveComparison().isEqualTo(PostfachNachrichtTestFactory.create()); } @Test @@ -131,16 +120,31 @@ class OsiPostfachServiceTest { @Test void shouldHaveAttachment() { - var messages = service.getAllMessages(); + var messages = Arrays.array(MessageTestFactory.create()); + doReturn(ResponseEntity.ok().body(messages)).when(restTemplate).exchange(TEST_URL, HttpMethod.GET, null, Message[].class); + when(mapper.toPostfachNachricht(messages[0])).thenReturn(PostfachNachrichtTestFactory.create()); + + var postfachNachrichten = service.getAllMessages(); - assertThat(messages).hasSize(1).first().extracting(Message::getAttachments, InstanceOfAssertFactories.LIST).hasSize(1) - .usingRecursiveComparison().isEqualTo(List.of(MessageAttachmentTestFactory.create())); + assertThat(postfachNachrichten).hasSize(1).first() + .extracting(PostfachNachricht::getAttachments, InstanceOfAssertFactories.LIST) + .hasSize(1) + .usingRecursiveComparison().isEqualTo(PostfachNachrichtTestFactory.ATTACHMENTS); + } + + @Test + void shouldCallMapper() { + prepareMockServer(); + + service.getAllMessages().collect(Collectors.toList()); + + verify(mapper).toPostfachNachricht(any()); } private void prepareMockServer() { mockServer.expect(ExpectedCount.once(), requestTo(TEST_URL)) .andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess(buildReplyJson(), MediaType.APPLICATION_JSON)); + .andRespond(withSuccess(MessageJsonReplyTestFactory.buildReplyJson(), MediaType.APPLICATION_JSON)); } } @@ -148,10 +152,7 @@ class OsiPostfachServiceTest { @Nested class TestSendMessage { - @Captor - private ArgumentCaptor<HttpEntity<Message>> httpEntityCaptor; - - private Message message = MessageTestFactory.create(); + private PostfachNachricht message = PostfachNachrichtTestFactory.create(); @Test void shouldCallRestTemplateExchange() { @@ -191,7 +192,16 @@ class OsiPostfachServiceTest { void shouldThrowBadRequestExceptionOnHttpClientError() { prepareMockServer().andRespond(withStatus(HttpStatus.BAD_REQUEST)); - assertThrows(OsiPostfachBadRequestException.class, () -> service.sendMessage(message)); + assertThrows(PostfachBadRequestException.class, () -> service.sendMessage(message)); + } + + @Test + void shouldCallMapper() { + prepareMockServer(); + + service.sendMessage(message); + + verify(mapper).toOsiMessage(any()); } @Nested @@ -219,37 +229,52 @@ class OsiPostfachServiceTest { @Test void shouldHaveVorgangIdAsSequenceNumber() { + var postfachNachricht = PostfachNachrichtTestFactory.create(); + when(mapper.toOsiMessage(postfachNachricht)).thenReturn(MessageTestFactory.create()); + prepareMockServer().andExpect(jsonPath("$.sequenceNumber").value(VORGANG_ID)); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(postfachNachricht); } @Test void shouldHavePostfachIdAsNameIdentifier() { + var postfachNachricht = PostfachNachrichtTestFactory.create(); + when(mapper.toOsiMessage(postfachNachricht)).thenReturn(MessageTestFactory.create()); + prepareMockServer().andExpect(jsonPath("$.nameIdentifier").value(POSTFACH_ID)); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(postfachNachricht); } @Test void shouldHaveSubject() { + var postfachNachricht = PostfachNachrichtTestFactory.create(); + when(mapper.toOsiMessage(postfachNachricht)).thenReturn(MessageTestFactory.create()); + prepareMockServer().andExpect(jsonPath("$.subject").value(SUBJECT)); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(postfachNachricht); } @Test void shouldHaveMailBodyAsBody() { + var postfachNachricht = PostfachNachrichtTestFactory.create(); + when(mapper.toOsiMessage(postfachNachricht)).thenReturn(MessageTestFactory.create()); + prepareMockServer().andExpect(jsonPath("$.body").value(MAIL_BODY)); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(postfachNachricht); } @Test void shouldHaveNumericReplyOptionAsReplyAction() { + var postfachNachricht = PostfachNachrichtTestFactory.create(); + when(mapper.toOsiMessage(postfachNachricht)).thenReturn(MessageTestFactory.create()); + prepareMockServer().andExpect(jsonPath("$.replyAction").value(REPLY_OPTION.toValue())); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(postfachNachricht); } } @@ -292,19 +317,21 @@ class OsiPostfachServiceTest { } } - static String buildReplyJson() { - return buildReplyJson(MessageTestFactory.create(), MessageAttachmentTestFactory.create()); - } + @Nested + class TestGetPostfach { + + @Test + void shouldHasTyp() { + var postfachType = service.getPostfachType(); + + assertThat(postfachType).isEqualTo(OsiPostfachRemoteService.POSTFACH_TYPE); + } + + @Test + void shouldAllowReplys(){ + var isReplyAllowed = service.isReplyAllowed(); - static String buildReplyJson(Message msg, MessageAttachment attachement) { - return String.format(REPLY_JSON_TMPL, - msg.getMessageId(), - msg.getPostfachId(), - msg.getMailBody(), - msg.getReplyOption().toValue(), - msg.getSubject(), - msg.getVorgangId(), - attachement.getFileName(), - attachement.getContent()); + assertThat(isReplyAllowed).isTrue(); + } } } \ No newline at end of file diff --git a/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessExceptionTestFactory.java b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessExceptionTestFactory.java new file mode 100644 index 0000000..94411f5 --- /dev/null +++ b/nachrichten-manager/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachServerProcessExceptionTestFactory.java @@ -0,0 +1,32 @@ +/* + * 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.nachrichten.postfach.osi; + +public class OsiPostfachServerProcessExceptionTestFactory { + + public static OsiPostfachServerProcessException create() { + return new OsiPostfachServerProcessException(); + } + +} diff --git a/nachrichten-manager/src/test/resources/BspQuittung.xml b/nachrichten-manager/src/test/resources/BspQuittung.xml new file mode 100644 index 0000000..5ef6f03 --- /dev/null +++ b/nachrichten-manager/src/test/resources/BspQuittung.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<ns2:BspQuittung + xmlns:ns2="http://www.akdb.de/egov/bsp/nachrichten" + xmlns:ns3="urn:akdb:bsp:postkorb:komm:webservice"> + <ns2:AnnahmeErfolgreich>true</ns2:AnnahmeErfolgreich> +</ns2:BspQuittung> diff --git a/nachrichten-manager/src/test/resources/BspQuittungError.xml b/nachrichten-manager/src/test/resources/BspQuittungError.xml new file mode 100644 index 0000000..e54e673 --- /dev/null +++ b/nachrichten-manager/src/test/resources/BspQuittungError.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<ns2:BspQuittung + xmlns:ns2="http://www.akdb.de/egov/bsp/nachrichten" + xmlns:ns3="urn:akdb:bsp:postkorb:komm:webservice"> + <ns2:AnnahmeErfolgreich>false</ns2:AnnahmeErfolgreich> + <ns2:ErgebnisStatus> + <ns2:Tabelle>9006</ns2:Tabelle> + <ns2:Schluessel>1</ns2:Schluessel> + </ns2:ErgebnisStatus> + <ns2:ErgaenzendeHinweise>Test error</ns2:ErgaenzendeHinweise> +</ns2:BspQuittung> diff --git a/pluto-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/nachrichten-manager/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 100% rename from pluto-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to nachrichten-manager/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension diff --git a/nachrichten-manager/src/test/resources/bayernid.p12 b/nachrichten-manager/src/test/resources/bayernid.p12 new file mode 100644 index 0000000000000000000000000000000000000000..fa82ce9007cc50831496073cdb03d8b6a92b5ee4 GIT binary patch literal 6349 zcmXqLk~qo4$ZXIg(Zt57)#lOmotKfFaY2(rF-wy~zCn{jwm}o?bQCGp4wfd?7K0|% z27@Nn8a8gIE*>sMrUgwbzYUsLz8h$=alwQcnGK{_M3!p?sR<gE^S*x5W)*a{xogRa zPoJ5X8BQ>;G_jmeShiixahKAKj)Ft)e?79=_3qXt3D&RLZ@=oaCCvRb`x(psV&U~w zFB8wGgx_|`cD(d+-5VWa>zbX$NxpL>R@_P8mWU6%FmqF7Xw9{jyQ@=@o~EBtNnBGq zp>L<qEl=sWbq(j<DOmC|M?Tq=m=%9TXtLs@#5=!S7;B`h9)?W5d8GJ~?D;mSw5GxZ zDbfAuE8agn?`3=M#z%|Q*YZCaCR}D{J7MtUfJUBYGh69I+m$XWkG;26o_d?JYw<4m zV+SvtKM=((|5WjYlKiFO=VISI-q>l1iiW-qwQc`zmA;|Q(d^8;xdr#46;8H2^GOx% zQdOvRR=RLu{turiGqxY*P>yU>w+@K-)ArFg>aECpt%Yu>iW|6_?o4sGvva+j^_u2h z-P+x6R+yPTnO2tneCm9Yq`Sp}t&5k&s_vTn>So%TQ`Oq(QJ?2<2`c1#n7eO7{>Ovg zimrXTayH0(HS?c9S9#3@Hs@)AOT=9Qd~P+F_ZiG=eLpwug6fx3wXv0lR$2L#_moW3 ziR9h5aN)Po-hUV073bSkFXG$bUtsR%G2yF-y#0#6;CVNne4O5Y>!$bYuiw{k+}UFL zP=CU)-UPm{t4ca!-%QGCE;0A0{k162Ddp>~U#6dUCyK1x6mgPg($?i2M|lgXirLz% z5Bb|S-{w9P`~D?Yf%lbYo2S+*3)j2y3hDZDs?XmOAC#lFCiIq*?xd%c=CV^Z_;_z< zNW04CAFRA<`}}r>%G)RH_uaLh&hhx)O`R3XB(KloQhcW*IJx_z3UhL5$*0mSC6Nbn z_Q(B--2Zer2jjp0d0TJsu=cmrFK+x5uMjdf``c=*Q_Wr64<<9e3JhUAAXdV^^q2Dg z>lUAORwmlNR=y|oTCbJM;kR$a?puwl>O$V19yT3de|GuIk^a&Lk9M+bd-p)7^7p)} z+gfhk{5^f2c(47LrR^uCeSGaAlD9b`E$ZgJfGUB>fh(Cg7aQ=Gtm)E!#?nzR<^0C9 zW&c-iXL;P2#_)K~S%qZ>D_?rM6wBUmxuMlFLm>O)CynQpr<Mhmc5Vz@<$GX9Y|B-( zf{O57S1su?WzQ}z(LN@8`N*OZw|`BoTH+*JW1#10bw{l-OY{%RC9ShrtJu`$9%)Lh z>Zotxoam5#{pX$9#uGkQ`#paOu^ra0-muz7eT{`%?k|gtH?OXX-1@B2%RXvecIQHc zLtmvGv>skxlTpmHCwN-y9Jy+%byhu5ahHB)X<agYpf^j(Gtq3G&!l>njETl`oO?Fp zRymf~Jj>WE+2Ys}BlJ^-FPM9QeciUzdp;J`9NRhZ;r;Mwm6whk)^IrCdpP>EeZ%H} zZ*ouW9bR`@V|8>`VRO){X3g)}D{X@pYM6;mifKRS!Y{S;jOH)q7x@bxhT9&GGA+BP zHqEB&Ku?p1){niMExXsrE}bAHF_ZIV1nX3eFD55{IQr+$-u5+IE<8JZ)$~Ps>t6q1 z=$p9zxae;!%WzJ!^s4&6U7Hv8a=fkb_;l-`XhiD11YQo+4-e+8^J0n66pmW^_~pTW zxvjJLzGNt@icxpJFf*_vzDR#ld(j&)wi(y%9XNZYTX%Zt$u0MD8;?58aJ(^LO7fI@ z)4nHuE}nA!#-)m*53T$i_V*Ol-7K(R@X?fR|DAop;M7)S_PMXNE}pTJ{rvTIvHW0L zN%<_pJOgETQOPN4D8?d^mXZ{6)?QWkq*<0hWbmGE=3?8*4crlmL=3IuEEwDwf*1lA ztQZs+Tp0ow92p`RbQwYzTp5BHLKqYnd>Pysd>P^y{28Jc+!^8-oEdT$@)=4QQVg1e z&cKagXIs!DwAY|XXeSdRgF%zfCWH(lN_or%Dvwtmmd>iniA(X>VZ7vH@WB?Dqy5t0 z^0=W%sABoK+(j-&c&a)?UWLxuvOAztC!)Cg^wEa}H_ug1C@-Amx`K6$++X?KSBr)3 zDZbN<=F^c?xcm6P)vb%Zf4)}Czjvy7nb}5VsmI!kbLAfzybb9t52}{_P%PYMe{5~k z{M;ms8@7&J+;^{klTP-zB&Dq(*8kexd)cjnlWLAQO#R0G{M6xptJj{@(3v#vdyt~X z;{%LaTlFp-y7{Cx=n3P`gAu2Wy|38jb=g;_#N|oJO=jhYBVm*F>=a?x#kTi(;hWI# zEFZ~$v&;1NMT<7)_bB`n;PY!`oq6_`ebR+XXSQ#;I>$NipjCo?i^TO=K5yrK+oZkQ z)x|SZ<;SJX?Sb`C6V4{azAoR$Gu_eEY7hI1ipif2uM9kXJHvpn>|X9FX34nXLzX|y z_}-fcxf&?fmYm%`>C0+vgFx%W!J$|4Y&?C>mYAl5)V>amkI=2#w0_Q(OLfK9dFDz@ zNo?_WA0K98%W`qUr_b@Z(-ys%Q+)o(gn~0G+m`6p@hwl={^aY*oRC*pmzJHkIW2OK zap#Ady>W*vTI)7%`tW)F?tt}&H(XEO`t`tsC09D7dBk<JEqsjGA4JIg*s;HKms`5M z)0Ii4K^$s3&QA@W`LOv`deWP=kSQf*EKh5icCbE^V%f%fM?7ze6?32@oAmM*sl1<l zKl#Sk^vpYQ|Mj~0%*!TbrMHFEl-N%?`}W_7<{rkgtHLKfS9Y4_XBj3oKc-UZO1gcc zd&HVOiwr`HID9NqBo8xHIzEY$OlrOIH(<`ZKY?3UPPO;0RSh=r+id+?-6+_2v#E-j zNrV4}Y_FFUd23u)lAo$(uy_ZCPDwa%B)Rv@Wu5}3``P#9O|%>Ke!JY(vvb3>Rnu*J zKkQch7p<mzq-J|lZ}LY=MP<v3#5cPRD1;p<FgyNs3+o2krYW7ATMo9q5k4Pm*teqM zsoh@1kFn(kS{B`3!mn5RvGCgkA9o$`<~7;tJ#4IhbUi+qzu}(i!T4Oi2P`>X1w}VK z7v8mcjb8l4cMpvk8h7*MNluL7vR^vi-@U*h^wd@t=X-pTJH#DkEuNox+V<%Su?zE* zU)`ymA#J(-i1_!JOQu~oU3D)kooU5dEtSP)oG({o&n~vP#aSP{+vS*7$8(FRdqNJp zd4KvBQ(L&d@T|Vzm4%k7e79~c?sPTkYdiAsW$a^*Yd*&`5*RA?+-Zw)+q(F=0q5J- zs%-zRsI+8F{k}au<IBy@$0Vg!%vSna@H8U*)3IoYzn=x}3QuQ?+dijHU9(Z@q;J|y z9*-~Ge-~KmYdv}B7RT%Jsd~XxkpnAEUHiG-@6U~Iz4I1ioH%#NEdGPQi=<`xE56;{ zr|?>ESx(<_jaPLywm7UP{Ov2T<9^&K_vcP;eH3PX5MI{!>!!q$Ltp<~y?P|!FW=%~ zJ=W+jowetp+b>oA;tvSSdSSZKLzpckv_UuI%8bIm%_<Fnp1ZSab03%;yDJ;w<h^12 zy+a)_rc=_m_$-@d|6a~2SMHEL|De+ISGz-76BCyQu>R-eK9w=`;G@fTe~4@OYM*Nq zkl`q>m{#zs=T5lM|Ic#K&%Uf)W7lbXOXS?UJ#E~Z?PjlHsCa5u+7{<qYxeHu1)(J~ z-j(QnTF;#4?Xly{x(g5b3Kh9#c>cL?@tJJ=YPHRi{h#jQUtKKd!6Xp<rsTBI*QjHM zR_19${JVYJaK_CiyL;tt8~$C)+4irwhQDXAs7asvE|qkV2Rb|UMJ!G<lQs;S_q5#D zTvm5Vm}kzX{gb8^n1oss2B)WQUGgqq!P3<_?<N)`UVL^j^Gtz#y{Zde>(&L#cV(u$ zTDsuCkB*kAotb%tWq0lGrigP#SLLxSbGRv5K4F^K`AyP?z7|w(n_^e+-CNam>7w|6 z)dh1d@>u3*E>KQc5nnUc@iN=Q@7JDP(n{o3^fgfAest66Sm~wCNwZIh>TESBsb60D z;=Wvn@B@Bs#gh+jO`CheFSq^Dgv!JRtXI>wK3&LtKVQ!62JfCCgM*v1Yi7IH$lEOq z)Xw>^W8sn`doC_i{B&otc}c{ttcE|w-5xF0YiV|FQ4#OFQ+&aRGi{^Uan(Zt-(ufM za5MO%W!6h<a^to+Z+6&9<NurxzvX5&`~M3Tf9~mM&x~;TvqVSANAe_Z_5NS)INP!= zzcbqMJHY%;LGSJD1|c=kw#;JE36}m*ks{XnrDmV{vdv)8wtcPa9+MWG&z-x6Csyd( ziO9acA!@u;t8e+|z6d<=x9a_Jlg@{Rn`eIiY^zor{renqKvLEAhEKJXDQu5_sEe_` zww|)8N@YrMw<Sw&+y$%aOCleg2;Z)>@z%aro7+V-l}neoITkMqndr;@`k0%4uFO0p zJ^lHAxa`svUOc7g-W0^UEbR&hTjVXj>5?D0i_{Jnu9mb_vM#FZy}`tL>!;2+0r$8+ z+YLYb46NDbt-OE9i$w=7p7r^?!$@!InrAt2;mjKv|0upZUuO5-$i%Xn;eXxKf{k__ zo934M%1gQT^6f?=pIxcB5`SecWNuHs9=>qfOWtP_%wu+Xrbu$<?QRfeR#=p@!pHc~ zfnPQ2kNcedbztst(_;yzPkDQNNr|%eEcmIpEK_?^&!S0x3NAj%w5xaJ-?#nQx?GFr z0TQ$BZD18(N|wp-pJ#FA?%Uges@m6iZfdg6tWRn@V0Ghyd~5Fl<qt<M+)EcfnKoxj zv_jBHL+;h0i`g&!R;)fB9(QW#%G{ELsc|8*KXdS;%A0*rmF0UVQa0aOGqiK(fdaO( z+pX(m&ez6lDW0apxg?>u=XA@o%R!O4C7+okXTN6kW9{NpztT3<!OeBDUZC%ztvLew z|FwEv?y8tHVKH~dUV(|fYyRuJR55jvk?RtVVEeL+ot5p@6~RTTw~9Rv)%wcQG&8sR zK>NX0SN^LxNo!rMZOr($t5WvUqB;5t4@p=ptNL#4)6ce*H8jFu%`?M2>u%&UPEuJM zeP&w63&uH&*Yf{x9C^B>!#aum#>^>Sk9tPCm@m4c)_#w-V7VU0_9>GjzPHpTnJF<W z`@3LSW3KUMTb}YOh2^^?fBXq;kovTj^X_RiOWw3t-FH1lO}3dtPZB?MyY*ELhZDmy z*)|Iv;mff}{TIr<b!9xX3Ve8=WrfHyiR1lDUp6-wztY~Uo2RQRx9=6tp&8m6r*Yl$ z-8<vz;_FY}S?1};JhX6D{yuHHPtx%ifk|PfXK3s@roV4WXMu6q3ZZu|Ju~ud9(@#_ z=%TATr=-#%-tMNrV~g{5Z29>9a$K1a^?Od_rQ0cy_iJC?x0ekG+4q~TaT9~YC5_!% znS}c`F4*XpASzX8CRALO5E3kDWcun!@ZX!^$*cTt#xDJHU+cW8OYI8_y-&F_H1iD; zeBNu^SP=Q*Q}2xHzSA{o9C+G_iZypE-0>|lzT^AbzpJ|yZp|wA%d|gDC-u;~D+W~y zl79b7a4-L4&3EqcVW*-irA&POPi-%pySUM!Qab76lCbdo&o4`>3S4vEk}h-bLS=c< z@{Rj9N2dlSoozWc=Xi6i>G>As-fven-|AtOGQSfc`9>ym=bXbbKQu!m3v*dgtj>OU zmhEG6Hu4YCp}&8-H!S>PU*z$xjnA>}cJ!&8JyCUEJYyGVomu*K|BI~qag&!fs+9-r zta8wJTbQutUisv{Blkjn%D>b;Hk);I-s;;NCps?*+%4j;usH8_tLf^cIXBpTC^D^_ ztF+3?y8fQI(rl*Bc6?dW{nvXu>C@`dI2PV<?4-z6^|-RV(|*|HTe++?4>wA?{_2_g zhbM>bzD&AsYo6HTwKJ_I|1xa3bV$?g|I0Ii%=5QY@0==jiMve8WWnsfPX=Guw6{cu z>$o3gTPppE!NLF0h1;?J&t!hQ-I*|<^Zf&TGw&CX%1o6rJw2tYyjTBt{qcgWXRX6p zFQH4P|6l7|nQDGxLU;$)Y@3UQB_Ais|I@tS9eh7%^<|-IrG0-NIVN2{-?Cp`wdhS} z?agc@Yi*%jk;_vp4$s^6@WZK#4-d>#J}B|L=jE}(mpI#1&w9l?U}f0)_yAMY*8ffG zf2_YJdN0<xyU9T6s)p-?klzy(Y(=<)xYy6~jCr+w<CC2M-&d=vneA=rQeb&8EyE_` z*2D>`r3$UOr4wg%PCfqBLGih__36^8Id?gqUXLs<6AGHqp?`Oh!>znizkj*xz9hP| ztZ{~NmEpP@$8rl3-X7hPeN5NPaZSIcS^J_K$;T2ZKPGhXuf1QUy8GlVW?8+<MM}2r z0*_bzS)Ja=SLAmmPu$t->kO^)FD=(<3#xW<99*KC`QG&UQ=RD2e{<rGa}=Knd?a!? z+fyKg|6rlkncaeCHnDBkxc86#Wnq5p^d$$?-8X*oD3w1fr+Zvn<feyH#Wn}A&q3Et z*1N9U{JU8&gm-;Gt^G6Cdq1u!HUx@!o+@7_ep4-`a6;gkL&fTU3JMSR2>v~@_e)a5 zp~cpFHd;7MJiPDvY;&u~NfI5c2W{VdoW1GroF4}Nywr1L{_Hk=^<+tRU=s7D*I^oY zIoFk^`P~&@x$~eZF}TO}{>4X`oGaE^=aw&$f9lJ%X_MRGzQ1R#ZvPY@Q1JOtz2w_j zkIqc95@F_;dnj`L{7?K#PDrcRxTl;pnUnOUT~+mMBkRe>*A5!Be2M+O(NQ(v^rzGh zHlgebjE#28|9*6(+Rg=z0tR9UACK)?V^n{*d4jy{tLqWx=32yRT&gv=!nNYqu9c51 zSq1sGvuB<V4XwHRv#BO=*YZF0(vjXr4XgJ)W;d-3Zam8TTh;33=^xpF2g|I!-Trbb zeEB7{ohj4#;>;puuGM6}8un0Sj!A;Z-`#9MNlGP_|0Sz9;(4X&)twK^BuqYcV#QOv zkf}%HHMjVmec^aRg7dSPa8BvPXKIt$xqP<Ogew)O>G-ZMC@|8<JhXlJ`Ig2QK^exh zMJvx%U4L8gIn`|P+3@)?7e5L7zj*ofia*_RxBt9ev6Zdr`x&)K&ZQ>WLg}?8TK|tN zuQ|=~Ch5h3%Elj2ev86IcCf7#v1y;+_b}Jw_vv<3sjWVoC%<0O*n0e&^t$+YVq9F? zJ7?@nUfHIae&~s+?{SaqI<=L4MM@ks%SsovcPCe#nJc}f_d^0>s*kw=_oU)y9||x2 zx!P_}=D9D7_3*kw>ttIa4+_s*b8zd~uQwNSf4y9mwDQL49Y<PAw&j~A-kPYo&E2_? z$JFHB490#ImWP2ejv6f!zkH_hlZwzu`*Z0YGq3MdElSxavXC?U-{t9DtJ-hReSXW< zJbzu}Y?DLp8eR&r{@X4vzxDc82e*5kMU!%B)C-SkoBi3pTH?*UON)gsU5N=zzjim! z-SCJ@_8P@09=AK@#Yk|?czsMHPjIP(o9&|7+QLI^k6T{|UFmncm@846aIS88u+PQC z*=$#gj3+OOJYewW$iaL=!!7~I5{o8{wcpihr50`wo3T6k(c8Yba0Z5lv*w)JceR0E zS~a|V=L!F|bMba_ymp;ld|#&jtD4!S8S^gJy=3D%!tv&#wAr~mSB>vab601VV6MN+ z#Nqsy`+e`VqlOGC^=rG=mi|>_KYT%c@sALdlXg-Hm#hB<PJOrXjIoY5%hJ+vY1_R0 zVecc3sqyCpTy&W({9(tgEdJs}3$Aq3`&>NsTj%7o<aM9lTiMUr&#uIfmEE^3!JGA) zsg1{XyY*lACLecM>$cm?p0jtZ_*{*qdalHe<xAe1nx&WCSLB-LrgmpfK`rOq?GfMP z{8I1nPq4chp`v(asn65)1->3lOo@IryeAg$u{8aAGU<Lneg6~#K90MMHsLxC&-7hL znm*s;X}8rWqXn9a6fV7uIxb$8JxO<}grzK_+!lc&u5T@8Ds*S8nIyr>qI7*{-`OWg zeX^-c8PAt_>MRa=x#0Hy^&eDO8+oG~*R?sxKb3!ZrS*Epu?6?MISQP`+SZ?t(E0JF zBk9(WH-`6wio%P6{2h*e_i;aet2rXc&CK#~%lb26D+SpWOlLARD`%X^xkP?_#P7EK zkM<UNt@t12{O`oowK1uSr2N+2O^H_xS2#Ake{byeEnCm++Om6ot_Y*&x=pKs#cSW1 zSM5KXX8f)5;?c7CQ@9^8Pit|A*Di0buXo(CRb%qZJO5{HwLX}~7*KJP<B#c$`+-pr zC4Zt+Cx$xp<}BQ>D|1mom!j2gRZ*KSN3Za2>HM)&-}CXOxFz~$OO{<SY7DArTCrm7 zq2QHnyUYG<7U=l&P>NqeSx%}@KXqcEpi$Rt`}ybM*q!(6wVb1{&+d#J({-c7it8u0 zaH>2go++54a4nc4I*Enh*#omU$ql;u(}nKO>74Fxo2T#F+kA$O25$Kxr(V(Xr!H}s zrHLGK|9@lhdg~O^$!`_J(*M*QnJfBx_iD3V*$K}|%+e-n%v-f=Yh3y=iBE1k3)^Qs z(XTz~d0vf4zroUTwvTT6%89%I=e9^$b1cobQ*!z-^)&BH?ebk#Yi>Wz{vi?An&_7z zWMF5YXu!$Fs?EpDB*n_WBC_|=0)w=*Udx@*zi=q&e4pVM_P~!t#D|Ml<;OLVKJ|B3 Tvzv}ZT5L>J)@Nd7oWKA8<KO^t literal 0 HcmV?d00001 diff --git a/pluto-utils/src/test/resources/junit-platform.properties b/nachrichten-manager/src/test/resources/junit-platform.properties similarity index 100% rename from pluto-utils/src/test/resources/junit-platform.properties rename to nachrichten-manager/src/test/resources/junit-platform.properties diff --git a/nachrichten-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/nachrichten-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/nachrichten-manager/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/notification-manager/lombok.config b/notification-manager/lombok.config index e2cecc9..81661f0 100644 --- a/notification-manager/lombok.config +++ b/notification-manager/lombok.config @@ -1,28 +1,30 @@ -# Copyright (C) 2022 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: +# 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 # -# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# 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. # -# 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. lombok.log.fieldName=LOG lombok.log.slf4j.flagUsage = ERROR lombok.log.log4j.flagUsage = ERROR lombok.data.flagUsage = ERROR lombok.nonNull.exceptionType = IllegalArgumentException -lombok.addLombokGeneratedAnnotation = true +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/notification-manager/pom.xml b/notification-manager/pom.xml index 3584bdc..f83ba66 100644 --- a/notification-manager/pom.xml +++ b/notification-manager/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,38 +24,44 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-parent</artifactId> - <version>1.2.1</version> - <relativePath /> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> + <relativePath/> </parent> - <groupId>de.itvsh.kop.notification</groupId> + <groupId>de.ozgcloud.notification</groupId> <artifactId>notification-manager</artifactId> - <name>KOP Notification Manager</name> - <version>1.0.0</version> + <version>2.4.0</version> + <name>OZG-Cloud Notification Manager</name> <properties> - <user-manager-interface.version>1.0.0</user-manager-interface.version> + <user-manager-interface.version>2.1.0</user-manager-interface.version> + <ozgcloud.license.version>1.6.0</ozgcloud.license.version> </properties> <dependencies> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-interface</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-utils</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>de.itvsh.kop.user</groupId> + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.user</groupId> <artifactId>user-manager-interface</artifactId> <version>${user-manager-interface.version}</version> <exclusions> @@ -99,8 +105,8 @@ <!-- Test --> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-utils</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> <version>${project.version}</version> <type>test-jar</type> <scope>test</scope> @@ -121,6 +127,33 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> + + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <mapping> + <config>SCRIPT_STYLE</config> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/README</exclude> + <exclude>src/test/resources/**</exclude> + <exclude>src/main/resources/**</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> + </plugin> </plugins> </build> -</project> \ No newline at end of file +</project> diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListener.java b/notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListener.java deleted file mode 100644 index ae86bb4..0000000 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListener.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.notification.antragsteller; - -import java.util.function.Predicate; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Component; - -import de.itvsh.kop.notification.vorgang.Vorgang; -import de.itvsh.kop.notification.vorgang.VorgangId; -import de.itvsh.kop.notification.vorgang.VorgangService; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; - -@Component -public class AntragstellerNotificationEventListener { - - static final String FS_FORMENGINE_NAME = "FormSolutions"; - private static final Predicate<Vorgang> SHOULD_SEND_NOTIFICATION = vorgang -> StringUtils.isNoneBlank(vorgang.getPostfachId()) - && StringUtils.equals(vorgang.getFormEngineName(), FS_FORMENGINE_NAME); - - @Autowired - private AntragstellerNotificationService service; - @Autowired - private VorgangService vorgangService; - - @EventListener - public void onVorgangCreated(VorgangCreatedEvent event) { - var vorgang = vorgangService.getVorgang(VorgangId.from(event.getSource())); - - sendIfRequired(vorgang); - } - - private void sendIfRequired(Vorgang vorgang) { - if (SHOULD_SEND_NOTIFICATION.test(vorgang)) { - service.sendNotification(vorgang); - } - } -} diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptor.java b/notification-manager/src/main/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptor.java similarity index 90% rename from notification-manager/src/main/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptor.java rename to notification-manager/src/main/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptor.java index a214882..0bdfa2d 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptor.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification; +package de.ozgcloud.notification; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; import java.util.UUID; @@ -31,7 +33,6 @@ import io.grpc.ClientCall; import io.grpc.ClientInterceptor; import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; import io.grpc.Metadata; -import io.grpc.Metadata.Key; import io.grpc.MethodDescriptor; public class NotificationManagerCallContextAttachingInterceptor implements ClientInterceptor { @@ -40,7 +41,7 @@ public class NotificationManagerCallContextAttachingInterceptor implements Clien static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin"; static final String KEY_REQUEST_ID = "REQUEST_ID-bin"; - public static final String NOTIFICATION_MANAGER_CLIENT_NAME = "KopNotificationManager"; + public static final String NOTIFICATION_MANAGER_CLIENT_NAME = "OzgCloud_NotificationManager"; static final String NOTIFICATION_MANAGER_SENDER_USER_ID = "system-notification_manager-new_vorgang"; // <A> = Request, <B> = Response @@ -78,9 +79,4 @@ public class NotificationManagerCallContextAttachingInterceptor implements Clien } - // TODO move to common grpc utils - public static Key<byte[]> createKeyOf(String key) { - return Key.of(key, Metadata.BINARY_BYTE_MARSHALLER); - } - } diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListener.java b/notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListener.java new file mode 100644 index 0000000..7ef8213 --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListener.java @@ -0,0 +1,93 @@ +/* + * 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.notification.antragsteller; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.notification.postfach.PostfachService; +import de.ozgcloud.notification.vorgang.Vorgang; +import de.ozgcloud.notification.vorgang.VorgangId; +import de.ozgcloud.notification.vorgang.VorgangService; +import lombok.extern.log4j.Log4j2; + +@Component +@Log4j2 +public class AntragstellerNotificationEventListener { + + static final String FS_FORMENGINE_NAME = "FormSolutions"; + static final String POSTFACH_NOT_CONFIGURED_MESSAGE = "Postfach is not configured. Antragsteller notifications will not be sent."; + private static final Predicate<Vorgang> EXISTS_POSTFACH_ID = vorgang -> StringUtils.isNoneBlank(vorgang.getPostfachId()); + private static final Predicate<Vorgang> EXISTS_POSTFACH_ADDRESS = vorgang -> Objects.nonNull(vorgang.getPostfachAddress()); + private static final Predicate<Vorgang> IS_FORMSOLUTIONS_FORM_ENGINE = vorgang -> StringUtils.equals(vorgang.getFormEngineName(), + FS_FORMENGINE_NAME); + private static final Predicate<Vorgang> SHOULD_SEND_NOTIFICATION = vorgang -> // + (EXISTS_POSTFACH_ID.test(vorgang) || EXISTS_POSTFACH_ADDRESS.test(vorgang)) && IS_FORMSOLUTIONS_FORM_ENGINE.test(vorgang); + + @Autowired + private AntragstellerNotificationService service; + @Autowired + private VorgangService vorgangService; + @Autowired + private PostfachService postfachService; + + private Optional<Boolean> isPostfachConfigured = Optional.empty(); + + @EventListener + public void onVorgangCreated(VorgangCreatedEvent event) { + if (isPostfachConfigured()) { + sendIfRequired(vorgangService.getVorgang(VorgangId.from(event.getSource()))); + } else { + LOG.debug(POSTFACH_NOT_CONFIGURED_MESSAGE); + } + } + + boolean isPostfachConfigured() { + return isPostfachConfigured.orElseGet(this::fetchIsPostfachConfigured); + } + + synchronized boolean fetchIsPostfachConfigured() { + return isPostfachConfigured.orElseGet(() -> { + var isConfigured = postfachService.isPostfachConfigured(); + if (!isConfigured) { + LOG.warn(POSTFACH_NOT_CONFIGURED_MESSAGE); + } + isPostfachConfigured = Optional.of(isConfigured); + return isConfigured; + }); + } + + private void sendIfRequired(Vorgang vorgang) { + if (SHOULD_SEND_NOTIFICATION.test(vorgang)) { + service.sendNotification(vorgang); + } + } +} diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationService.java b/notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationService.java similarity index 87% rename from notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationService.java index 82004c8..8f6bbb4 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.antragsteller; +package de.ozgcloud.notification.antragsteller; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -33,10 +33,10 @@ import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.kop.notification.command.CommandService; -import de.itvsh.kop.notification.postfach.PostfachNachricht; -import de.itvsh.kop.notification.vorgang.Vorgang; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.notification.command.CommandService; +import de.ozgcloud.notification.postfach.PostfachNachricht; +import de.ozgcloud.notification.vorgang.Vorgang; @Service class AntragstellerNotificationService { @@ -58,6 +58,7 @@ class AntragstellerNotificationService { return PostfachNachricht.builder() .vorgangId(vorgang.getId()) .postfachId(vorgang.getPostfachId()) + .postfachAddress(vorgang.getPostfachAddress()) .mailBody(formatMessage(vorgang)) .subject(formatSubject(vorgang)) .build(); diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/command/Command.java b/notification-manager/src/main/java/de/ozgcloud/notification/command/Command.java similarity index 88% rename from notification-manager/src/main/java/de/itvsh/kop/notification/command/Command.java rename to notification-manager/src/main/java/de/ozgcloud/notification/command/Command.java index a72e987..502bd85 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/command/Command.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/command/Command.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import java.util.Map; -import de.itvsh.kop.notification.vorgang.VorgangId; +import de.ozgcloud.notification.vorgang.VorgangId; import lombok.Builder; import lombok.Getter; diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandBody.java b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandBody.java similarity index 89% rename from notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandBody.java rename to notification-manager/src/main/java/de/ozgcloud/notification/command/CommandBody.java index e4df375..45446d1 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandBody.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; public interface CommandBody { diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandMapper.java b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandMapper.java similarity index 83% rename from notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandMapper.java rename to notification-manager/src/main/java/de/ozgcloud/notification/command/CommandMapper.java index 558c912..935f710 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandMapper.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; + +import java.util.Optional; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.notification.vorgang.VorgangId; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; @Mapper(uses = GrpcObjectMapper.class) interface CommandMapper { @@ -58,10 +61,9 @@ interface CommandMapper { @Mapping(target = "orderString", source = "order") GrpcCreateCommandRequest toGrpcRequest(Command command); - default String toString(de.itvsh.kop.notification.vorgang.VorgangId vorgangId) { - if (vorgangId == null) { - return null; - } - return vorgangId.toString(); + default String toString(VorgangId vorgangId) { + return Optional.ofNullable(vorgangId) + .map(VorgangId::toString) + .orElse(null); } } diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandRemoteService.java b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandRemoteService.java similarity index 83% rename from notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandRemoteService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/command/CommandRemoteService.java index 47831f9..43288ee 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandRemoteService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.kop.notification.NotificationManagerCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; import net.devh.boot.grpc.client.inject.GrpcClient; @Service diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandService.java b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandService.java similarity index 57% rename from notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/command/CommandService.java index f065857..e7541a0 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/command/CommandService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/command/CommandService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,24 +21,31 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; +import java.util.function.Predicate; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.kop.notification.command.Command.CommandOrder; -import de.itvsh.kop.notification.postfach.PostfachNachricht; +import de.ozgcloud.notification.command.Command.CommandOrder; +import de.ozgcloud.notification.postfach.PostfachAddress; +import de.ozgcloud.notification.postfach.PostfachAddressIdentifier; +import de.ozgcloud.notification.postfach.PostfachNachricht; +import de.ozgcloud.notification.postfach.StringBasedIdentifier; @Service("notificationCommandService") public class CommandService { + private static final Predicate<Entry<Object, Object>> IS_NOT_CLASS_KEY = entry -> !StringUtils.equals(entry.getKey().toString(), "class"); + @Autowired private CommandRemoteService commandRemoteService; @@ -60,9 +67,26 @@ public class CommandService { new BeanMap(nachricht).entrySet().stream() .filter(entry -> Objects.nonNull(entry.getValue())) - .filter(entry -> !StringUtils.equals(entry.getKey().toString(), "class")) - .forEach(entry -> result.put(entry.getKey().toString(), entry.getValue())); + .filter(IS_NOT_CLASS_KEY) + .forEach(entry -> result.put(entry.getKey().toString(), getValue(entry.getValue()))); return Collections.unmodifiableMap(result); } -} + + private Object getValue(Object value) { + if (value instanceof PostfachAddress postfachAddress) { + return buildPostfachAddressMap(postfachAddress); + } + return value; + } + + private Map<String, Object> buildPostfachAddressMap(PostfachAddress postfachAddress){ + return Map.of(PostfachAddress.TYPE_FIELD, postfachAddress.getType(), + PostfachAddress.VERSION_FIELD, postfachAddress.getVersion(), + PostfachAddress.IDENTIFIER_FIELD, buildPostfachAddressIdentifierMap(postfachAddress.getIdentifier())); + } + + private Map<String, Object> buildPostfachAddressIdentifierMap(PostfachAddressIdentifier identifier){ + return Map.of(StringBasedIdentifier.POSTFACH_ID_FIELD, ((StringBasedIdentifier) identifier).getPostfachId()); + } +} \ No newline at end of file diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRecipientMapper.java b/notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRecipientMapper.java similarity index 83% rename from notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRecipientMapper.java rename to notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRecipientMapper.java index bbb8b70..5ed8035 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRecipientMapper.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRecipientMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; + +import de.ozgcloud.nachrichten.email.GrpcRecipient; +import de.ozgcloud.notification.user.Recipient; -import de.itvsh.kop.notification.user.Recipient; -import de.itvsh.ozg.mail.email.GrpcRecipient; import org.mapstruct.Mapper; @Mapper diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRemoteService.java b/notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRemoteService.java similarity index 71% rename from notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRemoteService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRemoteService.java index 010c5c1..1044ac7 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/email/EmailRemoteService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/email/EmailRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; + +import java.util.List; -import de.itvsh.ozg.mail.email.EmailServiceGrpc.EmailServiceBlockingStub; -import de.itvsh.ozg.mail.email.GrpcRecipient; -import de.itvsh.ozg.mail.email.GrpcSendEmailRequest; -import net.devh.boot.grpc.client.inject.GrpcClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.List; +import de.ozgcloud.nachrichten.email.EmailServiceGrpc.EmailServiceBlockingStub; +import de.ozgcloud.nachrichten.email.GrpcRecipient; +import de.ozgcloud.nachrichten.email.GrpcSendEmailRequest; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import lombok.NonNull; +import net.devh.boot.grpc.client.inject.GrpcClient; @Service public class EmailRemoteService { @@ -41,9 +44,10 @@ public class EmailRemoteService { @Autowired private EmailRecipientMapper recipientMapper; - public void sendEmail(UserEmail email) { + public void sendEmail(@NonNull UserEmail email) { var grpcEmailRecipients = email.recipients().stream().map(recipientMapper::toGrpc).toList(); - emailServiceStub.sendEmail(buildRequest(grpcEmailRecipients, email.subject(), email.body())); + emailServiceStub.withInterceptors(new NotificationManagerCallContextAttachingInterceptor()) + .sendEmail(buildRequest(grpcEmailRecipients, email.subject(), email.body())); } private GrpcSendEmailRequest buildRequest(List<GrpcRecipient> grpcRecipients, String subject, String body) { diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/email/UserEmail.java b/notification-manager/src/main/java/de/ozgcloud/notification/email/UserEmail.java similarity index 87% rename from notification-manager/src/main/java/de/itvsh/kop/notification/email/UserEmail.java rename to notification-manager/src/main/java/de/ozgcloud/notification/email/UserEmail.java index 4d37fbd..302016d 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/email/UserEmail.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/email/UserEmail.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; -import de.itvsh.kop.notification.user.Recipient; +import de.ozgcloud.notification.user.Recipient; import lombok.Builder; import lombok.Singular; diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddress.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddress.java new file mode 100644 index 0000000..2fa6538 --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddress.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.notification.postfach; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class PostfachAddress { + + public static final String VERSION_FIELD = "version"; + public static final String TYPE_FIELD = "type"; + public static final String IDENTIFIER_FIELD = "identifier"; + + private String version; + private int type; + private PostfachAddressIdentifier identifier; +} \ No newline at end of file diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddressIdentifier.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddressIdentifier.java new file mode 100644 index 0000000..ce49e9f --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachAddressIdentifier.java @@ -0,0 +1,28 @@ +/* + * 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.notification.postfach; + +public interface PostfachAddressIdentifier { + +} diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/postfach/PostfachNachricht.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachNachricht.java similarity index 82% rename from notification-manager/src/main/java/de/itvsh/kop/notification/postfach/PostfachNachricht.java rename to notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachNachricht.java index eba6129..b72d7bb 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/postfach/PostfachNachricht.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachNachricht.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.postfach; +package de.ozgcloud.notification.postfach; -import de.itvsh.kop.notification.command.CommandBody; -import de.itvsh.kop.notification.vorgang.VorgangId; +import de.ozgcloud.notification.command.CommandBody; +import de.ozgcloud.notification.vorgang.VorgangId; import lombok.Builder; import lombok.Getter; @@ -34,6 +34,7 @@ public class PostfachNachricht implements CommandBody { static final String FIELD_VORGANG_ID = "vorgangId"; static final String FIELD_POSTFACH_ID = "postfachId"; + public static final String FIELD_POSTFACH_ADDRESS = "postfachAddress"; static final String FIELD_SUBJECT = "subject"; static final String FIELD_MESSAGE = "mailBody"; @@ -42,6 +43,7 @@ public class PostfachNachricht implements CommandBody { private VorgangId vorgangId; private String postfachId; + private PostfachAddress postfachAddress; private String subject; private String mailBody; diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachRemoteService.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachRemoteService.java new file mode 100644 index 0000000..138735e --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachRemoteService.java @@ -0,0 +1,50 @@ +/* + * 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.notification.postfach; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.nachrichten.postfach.GrpcIsPostfachConfiguredRequest; +import de.ozgcloud.nachrichten.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class PostfachRemoteService { + + @GrpcClient("pluto") + private PostfachServiceBlockingStub postfachServiceBlockingStub; + + public boolean isPostfachConfigured() { + return getPostfachServiceStub().isPostfachConfigured(buildGrpcRequest()).getIsConfigured(); + } + + GrpcIsPostfachConfiguredRequest buildGrpcRequest() { + return GrpcIsPostfachConfiguredRequest.newBuilder().build(); + } + + PostfachServiceBlockingStub getPostfachServiceStub() { + return postfachServiceBlockingStub.withInterceptors(new NotificationManagerCallContextAttachingInterceptor()); + } +} diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachService.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachService.java new file mode 100644 index 0000000..08c6f8a --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/PostfachService.java @@ -0,0 +1,38 @@ +/* + * 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.notification.postfach; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service("notificationPostfachService") +public class PostfachService { + + @Autowired + private PostfachRemoteService postfachRemoteService; + + public boolean isPostfachConfigured() { + return postfachRemoteService.isPostfachConfigured(); + } +} diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/postfach/StringBasedIdentifier.java b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/StringBasedIdentifier.java new file mode 100644 index 0000000..9f3df67 --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/postfach/StringBasedIdentifier.java @@ -0,0 +1,37 @@ +/* + * 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.notification.postfach; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class StringBasedIdentifier implements PostfachAddressIdentifier { + + public static final String POSTFACH_ID_FIELD = "postfachId"; + + private String postfachId; + +} \ No newline at end of file diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/user/Recipient.java b/notification-manager/src/main/java/de/ozgcloud/notification/user/Recipient.java similarity index 90% rename from notification-manager/src/main/java/de/itvsh/kop/notification/user/Recipient.java rename to notification-manager/src/main/java/de/ozgcloud/notification/user/Recipient.java index 9fd0df8..cacb560 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/user/Recipient.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/user/Recipient.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; import lombok.Builder; diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationEventListener.java b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationEventListener.java similarity index 71% rename from notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationEventListener.java rename to notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationEventListener.java index 4797dea..b0f7ac5 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationEventListener.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; - -import java.util.Objects; +package de.ozgcloud.notification.user; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; -import de.itvsh.kop.notification.vorgang.VorgangId; -import de.itvsh.kop.notification.vorgang.VorgangService; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.notification.vorgang.VorgangId; +import de.ozgcloud.notification.vorgang.VorgangService; @Component public class UserNotificationEventListener { @@ -44,10 +42,6 @@ public class UserNotificationEventListener { @EventListener public void onVorgangCreated(VorgangCreatedEvent event) { - var organisationsEinheitId = vorgangService.getVorgang(VorgangId.from(event.getSource())).getOrganisationseinheitenId(); - - if (Objects.nonNull(organisationsEinheitId)) { - userNotificationService.sendNotification(organisationsEinheitId); - } + userNotificationService.sendNotification(vorgangService.getVorgang(VorgangId.from(event.getSource()))); } } diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationService.java b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationService.java similarity index 62% rename from notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationService.java index 5fa3983..023c140 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserNotificationService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserNotificationService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; + +import static java.util.Objects.*; import java.util.List; @@ -29,14 +31,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import de.itvsh.kop.notification.email.EmailRemoteService; -import de.itvsh.kop.notification.email.UserEmail; +import de.ozgcloud.notification.email.EmailRemoteService; +import de.ozgcloud.notification.email.UserEmail; +import de.ozgcloud.notification.vorgang.Vorgang; import lombok.NonNull; @Service public class UserNotificationService { - public static final String MAIL_SUBJECT = "Neuer Vorgang"; + public static final String MAIL_SUBJECT_TEMPLATE = "Neuer Vorgang: %s"; public static final String MAIL_BODY = "Es ist ein neuer Vorgang im Allgemeinen Fachverfahren eingegangen."; @Autowired @@ -46,12 +49,14 @@ public class UserNotificationService { private UserRemoteService userRemoteService; @Async - public void sendNotification(@NonNull String organisationsEinheitId) { - var recipients = userRemoteService.getRecipients(organisationsEinheitId); - emailRemoteService.sendEmail(buildUserEmail(recipients)); + public void sendNotification(@NonNull Vorgang vorgang) { + if (nonNull(vorgang.getOrganisationseinheitenId())) { + var recipients = userRemoteService.getRecipients(vorgang.getOrganisationseinheitenId()); + emailRemoteService.sendEmail(buildUserEmail(recipients, MAIL_SUBJECT_TEMPLATE.formatted(vorgang.getVorgangName()))); + } } - private UserEmail buildUserEmail(List<Recipient> recipients) { - return UserEmail.builder().recipients(recipients).subject(MAIL_SUBJECT).body(MAIL_BODY).build(); + UserEmail buildUserEmail(List<Recipient> recipients, String subject) { + return UserEmail.builder().recipients(recipients).subject(subject).body(MAIL_BODY).build(); } } \ No newline at end of file diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRecipientMapper.java b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserRecipientMapper.java similarity index 86% rename from notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRecipientMapper.java rename to notification-manager/src/main/java/de/ozgcloud/notification/user/UserRecipientMapper.java index f9dda8b..9587eb4 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRecipientMapper.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserRecipientMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; -import de.itvsh.kop.user.recipient.GrpcRecipient; import org.mapstruct.Mapper; +import de.ozgcloud.user.recipient.GrpcRecipient; + @Mapper interface UserRecipientMapper { diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRemoteService.java b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserRemoteService.java similarity index 70% rename from notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRemoteService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/user/UserRemoteService.java index 908f103..8123bc6 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/user/UserRemoteService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/user/UserRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,27 +21,29 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.kop.user.grpc.recipient.GrpcFindRecipientRequest; -import de.itvsh.kop.user.grpc.recipient.RecipientServiceGrpc; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import de.ozgcloud.user.grpc.recipient.GrpcFindRecipientRequest; +import de.ozgcloud.user.grpc.recipient.RecipientServiceGrpc; import net.devh.boot.grpc.client.inject.GrpcClient; @Service public class UserRemoteService { @GrpcClient("user-manager") - private RecipientServiceGrpc.RecipientServiceBlockingStub recipientService; + private RecipientServiceGrpc.RecipientServiceBlockingStub stub; @Autowired private UserRecipientMapper mapper; public List<Recipient> getRecipients(String organisationseinheitId) { var request = GrpcFindRecipientRequest.newBuilder().setOrganisationsEinheitId(organisationseinheitId).build(); - return recipientService.findRecipientByOrganisationsEinheitId(request).getRecipientList().stream().map(mapper::fromGrpc).toList(); + return stub.withInterceptors(new NotificationManagerCallContextAttachingInterceptor()) + .findRecipientByOrganisationsEinheitId(request).getRecipientList().stream().map(mapper::fromGrpc).toList(); } } diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/Vorgang.java b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/Vorgang.java similarity index 84% rename from notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/Vorgang.java rename to notification-manager/src/main/java/de/ozgcloud/notification/vorgang/Vorgang.java index 90ad243..879bd3e 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/Vorgang.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/Vorgang.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; +import java.time.ZonedDateTime; + +import de.ozgcloud.notification.postfach.PostfachAddress; import lombok.Builder; import lombok.Getter; -import java.time.ZonedDateTime; - @Getter -@Builder +@Builder(toBuilder = true) public class Vorgang { private VorgangId id; @@ -42,4 +43,6 @@ public class Vorgang { private String postfachId; private String formEngineName; private String organisationseinheitenId; + + private PostfachAddress postfachAddress; } diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangId.java b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangId.java similarity index 87% rename from notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangId.java rename to notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangId.java index caa49c9..c659491 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangId.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangId.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; -import de.itvsh.kop.common.datatype.StringBasedValue; +import de.ozgcloud.common.datatype.StringBasedValue; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) diff --git a/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangMapper.java b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangMapper.java new file mode 100644 index 0000000..f138112 --- /dev/null +++ b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangMapper.java @@ -0,0 +1,79 @@ +/* + * 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.notification.vorgang; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; + +import de.ozgcloud.notification.postfach.PostfachAddress; +import de.ozgcloud.notification.postfach.PostfachAddressIdentifier; +import de.ozgcloud.notification.postfach.StringBasedIdentifier; +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangHead; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +interface VorgangMapper { + + @Mapping(target = "postfachId", source = "eingang.antragsteller.postfachId") + @Mapping(target = "vorgangName", source = "name") + @Mapping(target = "vorgangNummer", source = "nummer") + @Mapping(target = "organisationseinheitenId", source = "eingang.zustaendigeStelle.organisationseinheitenId") + @Mapping(target = "postfachAddress", expression = "java(fromPostfachAddress(vorgang))") + Vorgang fromGrpc(GrpcVorgangWithEingang vorgang); + + default PostfachAddress fromPostfachAddress(GrpcVorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getHeader()) + .map(GrpcVorgangHead::getServiceKonto) + .map(GrpcServiceKonto::getPostfachAddressesList) + .filter(list -> !list.isEmpty()) + .map(list -> list.get(0)) + .map(this::buildPostfachAddress) + .orElse(null); + } + + private PostfachAddress buildPostfachAddress(GrpcPostfachAddress postfachAddress) { + return PostfachAddress.builder() + .type(postfachAddress.getType()) + .version(postfachAddress.getVersion()) + .identifier(buildIdentifier(postfachAddress.getIdentifier())) + .build(); + } + + private PostfachAddressIdentifier buildIdentifier(GrpcObject identifier) { + var postfachId = identifier.getProperty(0).getValue(0); + return StringBasedIdentifier.builder().postfachId(postfachId).build(); + } + + default VorgangId fromString(String vorgangId) { + return Optional.ofNullable(vorgangId).map(VorgangId::from).orElse(null); + } +} diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangRemoteService.java b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangRemoteService.java similarity index 81% rename from notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangRemoteService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangRemoteService.java index 5822e8f..faee804 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangRemoteService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangRemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,20 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.kop.notification.NotificationManagerCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangRequest; -import de.itvsh.ozg.pluto.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; @Service class VorgangRemoteService { - @GrpcClient("pluto") + @GrpcClient("vorgang-manager") private VorgangServiceBlockingStub stub; @Autowired diff --git a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangService.java b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangService.java similarity index 91% rename from notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangService.java rename to notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangService.java index 03225a6..8b1d43a 100644 --- a/notification-manager/src/main/java/de/itvsh/kop/notification/vorgang/VorgangService.java +++ b/notification-manager/src/main/java/de/ozgcloud/notification/vorgang/VorgangService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/notification-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/notification-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..08abec6 --- /dev/null +++ b/notification-manager/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,20 @@ +net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcHealthServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListenerTest.java b/notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListenerTest.java deleted file mode 100644 index bc377c0..0000000 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationEventListenerTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.notification.antragsteller; - -import static org.mockito.ArgumentMatchers.*; -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 de.itvsh.kop.notification.vorgang.Vorgang; -import de.itvsh.kop.notification.vorgang.VorgangService; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; - -class AntragstellerNotificationEventListenerTest { - - @InjectMocks - private AntragstellerNotificationEventListener eventListener; - - @Mock - private AntragstellerNotificationService service; - @Mock - private VorgangService vorgangService; - - @Nested - class TestOnVorgangCreated { - - private static final VorgangCreatedEvent EVENT = new VorgangCreatedEvent(VorgangTestFactory.ID.toString()); - private static final Vorgang VORGANG = VorgangTestFactory.createBuilder() - .formEngineName(AntragstellerNotificationEventListener.FS_FORMENGINE_NAME).build(); - - @BeforeEach - void initMock() { - when(vorgangService.getVorgang(any())).thenReturn(VORGANG); - } - - @Test - void shouldLoadVorgang() { - eventListener.onVorgangCreated(EVENT); - - verify(vorgangService).getVorgang(VorgangTestFactory.ID); - } - - @Test - void shouldCallService() { - eventListener.onVorgangCreated(EVENT); - - verify(service).sendNotification(same(VORGANG)); - } - - @Test - void shouldNOTCallServiceOnMissingPostfach() { - when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.createBuilder().postfachId(null).build()); - - eventListener.onVorgangCreated(EVENT); - - verify(service, never()).sendNotification(any()); - } - - @Test - void shouldOnlyCallServiceForFormSolutions() { - when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.createBuilder().formEngineName("other").build()); - - eventListener.onVorgangCreated(EVENT); - - verify(service, never()).sendNotification(any()); - } - } -} diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptorTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptorTest.java similarity index 92% rename from notification-manager/src/test/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptorTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptorTest.java index 8984cc7..bc97278 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/NotificationManagerCallContextAttachingInterceptorTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/NotificationManagerCallContextAttachingInterceptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification; +package de.ozgcloud.notification; -import static de.itvsh.kop.notification.NotificationManagerCallContextAttachingInterceptor.*; +import static de.ozgcloud.common.grpc.GrpcUtil.*; +import static de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListenerTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListenerTest.java new file mode 100644 index 0000000..3d8bd53 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationEventListenerTest.java @@ -0,0 +1,238 @@ +/* + * 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.notification.antragsteller; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 org.springframework.test.util.ReflectionTestUtils; + +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.notification.postfach.PostfachService; +import de.ozgcloud.notification.vorgang.Vorgang; +import de.ozgcloud.notification.vorgang.VorgangService; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; +import lombok.SneakyThrows; + +class AntragstellerNotificationEventListenerTest { + + @Spy + @InjectMocks + private AntragstellerNotificationEventListener eventListener; + + @Mock + private AntragstellerNotificationService service; + @Mock + private VorgangService vorgangService; + @Mock + private PostfachService postfachService; + + @DisplayName("On vorgang created") + @Nested + class TestOnVorgangCreated { + + private static final VorgangCreatedEvent EVENT = new VorgangCreatedEvent(VorgangTestFactory.ID.toString()); + private static final Vorgang VORGANG = VorgangTestFactory.createBuilder() + .formEngineName(AntragstellerNotificationEventListener.FS_FORMENGINE_NAME).build(); + + @Test + void shouldLoadVorgang() { + when(postfachService.isPostfachConfigured()).thenReturn(true); + when(vorgangService.getVorgang(any())).thenReturn(VORGANG); + + onVorgangCreated(); + + verify(vorgangService).getVorgang(VorgangTestFactory.ID); + } + + @DisplayName("should not send notification when postfach is not configured") + @Test + void shouldNotSend() { + when(postfachService.isPostfachConfigured()).thenReturn(false); + + onVorgangCreated(); + + verify(vorgangService, never()).getVorgang(any()); + } + + @Nested + class TestIsPostfachConfigured { + + @Test + void shouldCallFetchIsPostfachService() { + eventListener.isPostfachConfigured(); + + verify(eventListener).fetchIsPostfachConfigured(); + } + + @Test + void shouldNotCallFetchIsPostfachService() { + ReflectionTestUtils.setField(eventListener, "isPostfachConfigured", Optional.of(true)); + + eventListener.isPostfachConfigured(); + + verify(eventListener, never()).fetchIsPostfachConfigured(); + } + + @Test + void shouldReturnValue() { + when(postfachService.isPostfachConfigured()).thenReturn(true); + + var isConfigured = eventListener.isPostfachConfigured(); + + assertThat(isConfigured).isTrue(); + } + + } + + @Nested + class TestFetchIsPostfachConfigured { + + @Test + void shouldCallRemoteService() { + eventListener.fetchIsPostfachConfigured(); + + verify(postfachService).isPostfachConfigured(); + } + + @Test + void shouldReturnValue() { + when(postfachService.isPostfachConfigured()).thenReturn(true); + + var isConfigured = eventListener.fetchIsPostfachConfigured(); + + assertThat(isConfigured).isTrue(); + } + + @Test + void shouldCallIsPostfachConfiguredOnce() { + fetchIsPostfachConfigured(); + + verify(postfachService).isPostfachConfigured(); + } + + @SneakyThrows + private void fetchIsPostfachConfigured() { + var executorService = Executors.newFixedThreadPool(5); + var countDownLatch = new CountDownLatch(3); + + IntStream.range(0, 3).forEach(i -> + executorService.submit(() -> { + eventListener.fetchIsPostfachConfigured(); + countDownLatch.countDown(); + }) + ); + + countDownLatch.await(); + } + } + + @DisplayName("send if required") + @Nested + class TestSendIfRequirest { + + @DisplayName("should not call service") + @Nested + class TestNotCallService { + + @BeforeEach + void setup() { + when(postfachService.isPostfachConfigured()).thenReturn(true); + } + + @Test + void onMissingPostfachIdAndPostfachAddress() { + when(vorgangService.getVorgang(any())).thenReturn(VORGANG.toBuilder().postfachId(null).postfachAddress(null).build()); + + onVorgangCreated(); + + verify(service, never()).sendNotification(any()); + } + + @Test + void forOtherThanFormSolutionsEngines() { + when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.createBuilder().formEngineName("other").build()); + + onVorgangCreated(); + + verify(service, never()).sendNotification(any()); + } + } + + @DisplayName("should call service") + @Nested + class TestCallService { + + @BeforeEach + void setup() { + when(postfachService.isPostfachConfigured()).thenReturn(true); + } + + @Test + void onExistingPostfachIdAndPostfachAddress() { + when(vorgangService.getVorgang(any())).thenReturn(VORGANG); + + onVorgangCreated(); + + verify(service).sendNotification(same(VORGANG)); + } + + @Test + void onExistingPostfachIdAndMissingPostfachAddress() { + when(vorgangService.getVorgang(any())).thenReturn(VORGANG.toBuilder().postfachAddress(null).build()); + + onVorgangCreated(); + + verify(service).sendNotification(any()); + } + + @Test + void onMissingPostfachIdAndExistingPostfachAddress() { + when(vorgangService.getVorgang(any())).thenReturn(VORGANG.toBuilder().postfachId(null).build()); + + onVorgangCreated(); + + verify(service).sendNotification(any()); + } + } + } + + private void onVorgangCreated() { + eventListener.onVorgangCreated(EVENT); + } + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationServiceTest.java similarity index 82% rename from notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationServiceTest.java index 122e14b..6f12a55 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/antragsteller/AntragstellerNotificationServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/antragsteller/AntragstellerNotificationServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.antragsteller; +package de.ozgcloud.notification.antragsteller; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -29,6 +29,7 @@ import static org.mockito.Mockito.*; import java.time.ZonedDateTime; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -37,10 +38,11 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.kop.notification.command.CommandService; -import de.itvsh.kop.notification.postfach.PostfachNachricht; -import de.itvsh.kop.notification.postfach.PostfachNachrichtTestFactory; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.notification.command.CommandService; +import de.ozgcloud.notification.postfach.PostfachAddressTestFactory; +import de.ozgcloud.notification.postfach.PostfachNachricht; +import de.ozgcloud.notification.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; class AntragstellerNotificationServiceTest { @@ -53,6 +55,7 @@ class AntragstellerNotificationServiceTest { @Captor private ArgumentCaptor<PostfachNachricht> nachrichtCaptor; + @DisplayName("Send notification") @Nested class TestSendNotification { @@ -96,6 +99,13 @@ class AntragstellerNotificationServiceTest { assertThat(nachricht.getPostfachId()).isEqualTo(VorgangTestFactory.POSTFACH_ID); } + + @Test + void shouldHavePostfachAddress() { + var nachricht = service.buildPostfachNachricht(VorgangTestFactory.create()); + + assertThat(nachricht.getPostfachAddress()).usingRecursiveComparison().isEqualTo(PostfachAddressTestFactory.create()); + } } @Nested diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandMapperTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandMapperTest.java similarity index 70% rename from notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandMapperTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/command/CommandMapperTest.java index d7c52cc..d3e08ef 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandMapperTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,18 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; 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 org.mockito.InjectMocks; import org.mockito.Spy; -import de.itvsh.kop.notification.postfach.PostfachNachrichtTestFactory; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.ozgcloud.notification.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.notification.vorgang.VorgangId; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; class CommandMapperTest { @@ -41,8 +43,10 @@ class CommandMapperTest { @Spy private GrpcObjectMapper objectMapper = Mappers.getMapper(GrpcObjectMapper.class); + @DisplayName("To grpc") @Nested class TestToGrpc { + @Test void shouldMapPostfachNachrichtCommand() { var mapped = mapper.toGrpcRequest(CommandTestFactory.createBuilder().body(PostfachNachrichtTestFactory.createAsMap()).build()); @@ -51,6 +55,24 @@ class CommandMapperTest { .ignoringFields("bodyObj_", "memoizedHashCode") .isEqualTo(GrpcCreateCommandRequestTestFactory.create()); } + + @DisplayName("to string") + @Nested + class TestToString { + + @Test + void shouldReturnValue() { + var vorgangId = mapper.toString(VorgangId.from("testId")); + + assertThat(vorgangId).isEqualTo("testId"); + } + + @Test + void shouldReturnNull() { + var vorgangId = mapper.toString(null); + + assertThat(vorgangId).isNull(); + } + } } - -} +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandRemoteServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandRemoteServiceTest.java similarity index 90% rename from notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandRemoteServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/command/CommandRemoteServiceTest.java index 67e040e..a1412eb 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandRemoteServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandRemoteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -33,7 +33,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; class CommandRemoteServiceTest { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandServiceTest.java similarity index 88% rename from notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/command/CommandServiceTest.java index f130b47..201bb62 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,19 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import org.junit.jupiter.api.DisplayName; 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 de.itvsh.kop.notification.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.notification.postfach.PostfachNachrichtTestFactory; class CommandServiceTest { @@ -43,6 +44,7 @@ class CommandServiceTest { @Mock private CommandRemoteService remoteService; + @DisplayName("Create send postfachNachricht command") @Nested class TestCreateSendPostfachNachrichtCommnad { @Test @@ -63,6 +65,7 @@ class CommandServiceTest { } } + @DisplayName("To map") @Nested class TestToMap { @@ -80,5 +83,4 @@ class CommandServiceTest { assertThat(map).doesNotContainKey("class"); } } - -} +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandTestFactory.java similarity index 84% rename from notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/command/CommandTestFactory.java index a13ac16..a775943 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/command/CommandTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/command/CommandTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; import java.util.Map; import java.util.UUID; -import de.itvsh.kop.notification.command.Command.CommandOrder; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.notification.command.Command.CommandOrder; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; public class CommandTestFactory { + public static final String ID = UUID.randomUUID().toString(); + public static final String RELATION_ID = UUID.randomUUID().toString(); public static final CommandOrder ORDER = CommandOrder.SEND_POSTFACH_NACHRICHT; diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/command/GrpcCreateCommandRequestTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/command/GrpcCreateCommandRequestTestFactory.java similarity index 82% rename from notification-manager/src/test/java/de/itvsh/kop/notification/command/GrpcCreateCommandRequestTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/command/GrpcCreateCommandRequestTestFactory.java index b39c287..679063f 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/command/GrpcCreateCommandRequestTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/command/GrpcCreateCommandRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.command; +package de.ozgcloud.notification.command; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectTestFactory; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; public class GrpcCreateCommandRequestTestFactory { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRecipientMapperTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRecipientMapperTest.java similarity index 89% rename from notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRecipientMapperTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRecipientMapperTest.java index d42ad91..a07d0da 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRecipientMapperTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRecipientMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; -import de.itvsh.kop.notification.user.RecipientTestFactory; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; import static org.assertj.core.api.Assertions.*; +import de.ozgcloud.notification.user.RecipientTestFactory; + class EmailRecipientMapperTest { private EmailRecipientMapper mapper = Mappers.getMapper(EmailRecipientMapper.class); diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRemoteServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRemoteServiceTest.java similarity index 65% rename from notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRemoteServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRemoteServiceTest.java index 73a4bdd..5e69a97 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/email/EmailRemoteServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/email/EmailRemoteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; -import de.itvsh.kop.notification.user.RecipientTestFactory; -import de.itvsh.ozg.mail.email.EmailServiceGrpc.EmailServiceBlockingStub; -import de.itvsh.ozg.mail.email.GrpcRecipient; -import de.itvsh.ozg.mail.email.GrpcSendEmailRequest; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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.ArgumentCaptor; @@ -34,10 +35,10 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import de.ozgcloud.nachrichten.email.EmailServiceGrpc.EmailServiceBlockingStub; +import de.ozgcloud.nachrichten.email.GrpcRecipient; +import de.ozgcloud.nachrichten.email.GrpcSendEmailRequest; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; class EmailRemoteServiceTest { @@ -58,41 +59,41 @@ class EmailRemoteServiceTest { private final static GrpcRecipient GRPC_RECIPIENT = GrpcEmailRecipientTestFactory.create(); - @Test - void shouldCallEmailServiceOnlyOnce() { + @BeforeEach + void initTest() { when(recipientMapper.toGrpc(any())).thenReturn(GRPC_RECIPIENT); - var userEmail = UserEmailTestFactory.createBuilder().recipient(RecipientTestFactory.create()).build(); + when(emailStub.withInterceptors(any())).thenReturn(emailStub); + } - remoteService.sendEmail(userEmail); + @Test + void shouldCallEmailServiceOnlyOnce() { + remoteService.sendEmail(UserEmailTestFactory.create()); verify(emailStub, times(1)).sendEmail(any()); } @Test void shouldNotifyAllRecipients() { - when(recipientMapper.toGrpc(any())).thenReturn(GRPC_RECIPIENT); - var userEmail = UserEmailTestFactory.createBuilder().recipient(RecipientTestFactory.create()).build(); - - remoteService.sendEmail(userEmail); + remoteService.sendEmail(UserEmailTestFactory.create()); verify(emailStub).sendEmail(requestCaptor.capture()); - assertThat(requestCaptor.getValue().getRecipientsList()).hasSameSizeAs(userEmail.recipients()); + assertThat(requestCaptor.getValue().getRecipientsList()).hasSameSizeAs(UserEmailTestFactory.RECIPIENTS); } @Test void shouldConvertCorrectly() { - when(recipientMapper.toGrpc(any())).thenReturn(GRPC_RECIPIENT); - remoteService.sendEmail(UserEmailTestFactory.create()); verify(emailStub).sendEmail(requestCaptor.capture()); - var emailRecipient = requestCaptor.getValue().getRecipients(0); - assertThat(emailRecipient).usingRecursiveComparison().isEqualTo(GRPC_RECIPIENT); + assertThat(requestCaptor.getValue().getRecipientsList()).first().usingRecursiveComparison().isEqualTo(GRPC_RECIPIENT); } @Test - void shouldFailWhenRecipientsAreNull() { - assertThrows(NullPointerException.class, () -> remoteService.sendEmail(null)); + void shouldUseInterceptor() { + remoteService.sendEmail(UserEmailTestFactory.create()); + + verify(emailStub).withInterceptors(any(NotificationManagerCallContextAttachingInterceptor.class)); } + } } \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/email/GrpcEmailRecipientTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/email/GrpcEmailRecipientTestFactory.java similarity index 84% rename from notification-manager/src/test/java/de/itvsh/kop/notification/email/GrpcEmailRecipientTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/email/GrpcEmailRecipientTestFactory.java index 505fedc..9bf2806 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/email/GrpcEmailRecipientTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/email/GrpcEmailRecipientTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; +package de.ozgcloud.notification.email; -import de.itvsh.ozg.mail.email.GrpcRecipient; +import de.ozgcloud.nachrichten.email.GrpcRecipient; -import static de.itvsh.kop.notification.user.RecipientTestFactory.*; +import static de.ozgcloud.notification.user.RecipientTestFactory.*; public class GrpcEmailRecipientTestFactory { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/email/UserEmailTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/email/UserEmailTestFactory.java similarity index 71% rename from notification-manager/src/test/java/de/itvsh/kop/notification/email/UserEmailTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/email/UserEmailTestFactory.java index b1a8cc7..ea77432 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/email/UserEmailTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/email/UserEmailTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.email; - -import de.itvsh.kop.notification.email.UserEmail.UserEmailBuilder; -import de.itvsh.kop.notification.user.Recipient; -import de.itvsh.kop.notification.user.UserNotificationService; -import de.itvsh.kop.notification.user.RecipientTestFactory; +package de.ozgcloud.notification.email; import java.util.List; +import de.ozgcloud.notification.email.UserEmail.UserEmailBuilder; +import de.ozgcloud.notification.user.Recipient; +import de.ozgcloud.notification.user.RecipientTestFactory; +import de.ozgcloud.notification.user.UserNotificationService; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; + public class UserEmailTestFactory { public static final List<Recipient> RECIPIENTS = List.of(RecipientTestFactory.create()); @@ -41,7 +42,7 @@ public class UserEmailTestFactory { public static UserEmailBuilder createBuilder() { return UserEmail.builder() .recipients(RECIPIENTS) - .subject(UserNotificationService.MAIL_SUBJECT) + .subject(UserNotificationService.MAIL_SUBJECT_TEMPLATE.formatted(VorgangTestFactory.VORGANG_NAME)) .body(UserNotificationService.MAIL_BODY); } } diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/postfach/GrpcPostfachAddressTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/GrpcPostfachAddressTestFactory.java new file mode 100644 index 0000000..6a1948d --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/GrpcPostfachAddressTestFactory.java @@ -0,0 +1,50 @@ +/* + * 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.notification.postfach; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; + +public class GrpcPostfachAddressTestFactory { + + public static GrpcPostfachAddress create() { + return createBuilder().build(); + } + + public static GrpcPostfachAddress.Builder createBuilder() { + return GrpcPostfachAddress.newBuilder() + .setType(PostfachAddressTestFactory.TYPE) + .setIdentifier(createIdentifier()) + .setVersion(PostfachAddressTestFactory.VERSION); + } + public static GrpcObject createIdentifier() { + return GrpcObject.newBuilder() + .addProperty(GrpcProperty.newBuilder() + .setName(StringBasedIdentifier.POSTFACH_ID_FIELD) + .addValue(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build()) + .build(); + } +} diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachAddressTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachAddressTestFactory.java new file mode 100644 index 0000000..da03e96 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachAddressTestFactory.java @@ -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. + */ +package de.ozgcloud.notification.postfach; + +import java.util.UUID; + +public class PostfachAddressTestFactory { + + public final static int TYPE = 1; + public static final String STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE = UUID.randomUUID().toString(); + public final static StringBasedIdentifier IDENTIFIER = StringBasedIdentifier.builder().postfachId(STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build(); + public static final String VERSION = "1.0"; + + public static PostfachAddress create() { + return createBuilder().build(); + } + + public static PostfachAddress.PostfachAddressBuilder createBuilder() { + return PostfachAddress.builder() + .type(TYPE) + .identifier(IDENTIFIER) + .version(VERSION); + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/postfach/PostfachNachrichtTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachNachrichtTestFactory.java similarity index 69% rename from notification-manager/src/test/java/de/itvsh/kop/notification/postfach/PostfachNachrichtTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachNachrichtTestFactory.java index dfc94e7..457b9df 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/postfach/PostfachNachrichtTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachNachrichtTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.postfach; +package de.ozgcloud.notification.postfach; import java.util.Map; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; public class PostfachNachrichtTestFactory { @@ -40,6 +40,7 @@ public class PostfachNachrichtTestFactory { return PostfachNachricht.builder() .vorgangId(VorgangTestFactory.ID) .postfachId(VorgangTestFactory.POSTFACH_ID) + .postfachAddress(PostfachAddressTestFactory.create()) .mailBody(MESSAGE) .subject(SUBJECT); } @@ -48,10 +49,19 @@ public class PostfachNachrichtTestFactory { return Map.of( PostfachNachricht.FIELD_VORGANG_ID, VorgangTestFactory.ID, PostfachNachricht.FIELD_POSTFACH_ID, VorgangTestFactory.POSTFACH_ID, + PostfachNachricht.FIELD_POSTFACH_ADDRESS, createPostfachAddressMap(), PostfachNachricht.FIELD_SUBJECT, SUBJECT, PostfachNachricht.FIELD_MESSAGE, MESSAGE, PostfachNachricht.FIELD_REPLY_OPTION, PostfachNachricht.DEFAULT_REPLY_OPTION); - } - -} + + public static final Map<String, Object> createPostfachAddressMap(){ + return Map.of(PostfachAddress.TYPE_FIELD, PostfachAddressTestFactory.TYPE, + PostfachAddress.VERSION_FIELD, PostfachAddressTestFactory.VERSION, + PostfachAddress.IDENTIFIER_FIELD, createIdentifierMap()); + } + + public static final Map<String, Object> createIdentifierMap(){ + return Map.of(PostfachNachricht.FIELD_POSTFACH_ID, PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachRemoteServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachRemoteServiceTest.java new file mode 100644 index 0000000..121df7b --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachRemoteServiceTest.java @@ -0,0 +1,78 @@ +/* + * 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.notification.postfach; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.nachrichten.postfach.GrpcIsPostfachConfiguredResponse; +import de.ozgcloud.nachrichten.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub; + +class PostfachRemoteServiceTest { + + @Spy + @InjectMocks + private PostfachRemoteService postfachRemoteService; + + @Mock + private PostfachServiceBlockingStub blockingStub; + + private static final GrpcIsPostfachConfiguredResponse GRPC_POSTFACH_RESPONSE = GrpcIsPostfachConfiguredResponse.newBuilder().build(); + + @BeforeEach + void setup() { + when(blockingStub.withInterceptors(any())).thenReturn(blockingStub); + when(blockingStub.isPostfachConfigured(any())).thenReturn(GRPC_POSTFACH_RESPONSE); + } + + @Test + void shouldGetPostfachServiceStub() { + postfachRemoteService.isPostfachConfigured(); + + verify(postfachRemoteService).getPostfachServiceStub(); + } + + @Test + void shouldCallIsPostfachConfigured() { + postfachRemoteService.isPostfachConfigured(); + + verify(blockingStub).isPostfachConfigured(any()); + } + + @Test + void shouldReturnIsPostfachConfigured() { + var postfachResponse = GrpcIsPostfachConfiguredResponse.newBuilder().setIsConfigured(true).build(); + when(blockingStub.isPostfachConfigured(any())).thenReturn(postfachResponse); + + var isPostfachConfigured = postfachRemoteService.isPostfachConfigured(); + + assertTrue(isPostfachConfigured); + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachServiceTest.java new file mode 100644 index 0000000..828c280 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/postfach/PostfachServiceTest.java @@ -0,0 +1,55 @@ +/* + * 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.notification.postfach; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +class PostfachServiceTest { + + @InjectMocks + private PostfachService postfachService; + @Mock + private PostfachRemoteService postfachRemoteService; + + @Test + void shouldCallRemoteService() { + postfachService.isPostfachConfigured(); + + verify(postfachRemoteService).isPostfachConfigured(); + } + + @Test + void shouldReturnRemoteServiceResult() { + when(postfachRemoteService.isPostfachConfigured()).thenReturn(true); + + var result = postfachService.isPostfachConfigured(); + + assertTrue(result); + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcFindRecipientRequestTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcFindRecipientRequestTestFactory.java similarity index 85% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcFindRecipientRequestTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcFindRecipientRequestTestFactory.java index 544f762..d3ed411 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcFindRecipientRequestTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcFindRecipientRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; -import de.itvsh.kop.user.grpc.recipient.GrpcFindRecipientResponse; -import de.itvsh.kop.user.recipient.GrpcRecipient; +import de.ozgcloud.user.grpc.recipient.GrpcFindRecipientResponse; +import de.ozgcloud.user.recipient.GrpcRecipient; public class GrpcFindRecipientRequestTestFactory { @@ -37,4 +37,5 @@ public class GrpcFindRecipientRequestTestFactory { public static GrpcFindRecipientResponse.Builder createBuilder() { return GrpcFindRecipientResponse.newBuilder().addRecipient(GRPC_RECIPIENT); } + } diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcUserRecipientTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcUserRecipientTestFactory.java similarity index 89% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcUserRecipientTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcUserRecipientTestFactory.java index 6b9f9b0..44893ee 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/GrpcUserRecipientTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/GrpcUserRecipientTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; -import de.itvsh.kop.user.recipient.GrpcRecipient; +import de.ozgcloud.user.recipient.GrpcRecipient; public class GrpcUserRecipientTestFactory { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/RecipientTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/RecipientTestFactory.java similarity index 88% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/RecipientTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/RecipientTestFactory.java index 7e9a890..38d1da8 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/RecipientTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/RecipientTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; -import de.itvsh.kop.notification.user.Recipient.RecipientBuilder; +import de.ozgcloud.notification.user.Recipient.RecipientBuilder; public class RecipientTestFactory { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationEventListenerTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationEventListenerTest.java similarity index 71% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationEventListenerTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationEventListenerTest.java index 6599256..e7f3b62 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationEventListenerTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationEventListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -33,10 +33,10 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.kop.notification.vorgang.VorgangId; -import de.itvsh.kop.notification.vorgang.VorgangService; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.notification.vorgang.VorgangId; +import de.ozgcloud.notification.vorgang.VorgangService; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; class UserNotificationEventListenerTest { @@ -72,27 +72,14 @@ class UserNotificationEventListenerTest { @Test void shouldNotifyWithOrganisationeinheitIds() { - userNotificationEventListener.onVorgangCreated(EVENT); - - verify(userNotificationService).sendNotification(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); - } - } - - @DisplayName("with missing orgaId") - @Nested - class TestWithoutOrgaId { + var vorgang = VorgangTestFactory.create(); + when(vorgangService.getVorgang(any())).thenReturn(vorgang); - @BeforeEach - void initMock() { - when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.createBuilder().organisationseinheitenId(null).build()); - } - - @Test - void shouldNotCallNotificationService() { userNotificationEventListener.onVorgangCreated(EVENT); - verifyNoInteractions(userNotificationService); + verify(userNotificationService).sendNotification(vorgang); } } + } } \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationServiceTest.java similarity index 63% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationServiceTest.java index 0c2deb9..7ad5945 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserNotificationServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserNotificationServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -35,14 +35,17 @@ 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 de.itvsh.kop.notification.email.EmailRemoteService; -import de.itvsh.kop.notification.email.UserEmail; -import de.itvsh.kop.notification.email.UserEmailTestFactory; -import de.itvsh.kop.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.notification.email.EmailRemoteService; +import de.ozgcloud.notification.email.UserEmail; +import de.ozgcloud.notification.email.UserEmailTestFactory; +import de.ozgcloud.notification.vorgang.Vorgang; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; class UserNotificationServiceTest { + @Spy @InjectMocks private UserNotificationService service; @@ -67,16 +70,27 @@ class UserNotificationServiceTest { @Test void shouldGetRecipients() { - service.sendNotification(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); + service.sendNotification(VorgangTestFactory.create()); verify(userRemoteService).getRecipients(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); } @Test void shouldSendEmail() { - service.sendNotification(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); + var email = UserEmailTestFactory.create(); + doReturn(email).when(service).buildUserEmail(anyList(), anyString()); + + service.sendNotification(VorgangTestFactory.create()); + + verify(emailRemoteService).sendEmail(email); + } + + @Test + void shouldSetSubject() { + service.sendNotification(VorgangTestFactory.create()); + + verify(service).buildUserEmail(anyList(), eq("Neuer Vorgang: " + VorgangTestFactory.VORGANG_NAME)); - verify(emailRemoteService).sendEmail(UserEmailTestFactory.create()); } } @@ -84,26 +98,28 @@ class UserNotificationServiceTest { @Nested class TestWithInvalidOrgaId { - @Test - void shouldThrowIllegalArgumentException() { - assertThatThrownBy(() -> service.sendNotification(null)) - .isInstanceOf(IllegalArgumentException.class) - .withFailMessage("organisationsEinheitId cannot be null."); - } + private Vorgang vorgang = VorgangTestFactory.createBuilder().organisationseinheitenId(null).build(); @Test void shouldNotCallUserRemoteService() { - assertThatThrownBy(() -> service.sendNotification(null)); + service.sendNotification(vorgang); verify(userRemoteService, never()).getRecipients(anyString()); } @Test - void shouldNotCallEmailRemoteSErvie() { - assertThatThrownBy(() -> service.sendNotification(null)); + void shouldNotCallEmailRemoteServie() { + service.sendNotification(vorgang); verify(emailRemoteService, never()).sendEmail(any(UserEmail.class)); } } + + @Test + void shouldThrowExceptionWhenVorgangNull() { + assertThatThrownBy(() -> service.sendNotification(null)) + .withFailMessage("organisationsEinheitId cannot be null.") + .isInstanceOf(IllegalArgumentException.class); + } } } \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRecipientMapperTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserRecipientMapperTest.java similarity index 93% rename from notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRecipientMapperTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/user/UserRecipientMapperTest.java index 28000bc..3ab993e 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/user/UserRecipientMapperTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserRecipientMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.user; +package de.ozgcloud.notification.user; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/user/UserRemoteServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserRemoteServiceTest.java new file mode 100644 index 0000000..b441806 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/user/UserRemoteServiceTest.java @@ -0,0 +1,72 @@ +/* + * 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.notification.user; + +import static org.mockito.ArgumentMatchers.*; +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 de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import de.ozgcloud.notification.vorgang.VorgangTestFactory; +import de.ozgcloud.user.grpc.recipient.RecipientServiceGrpc.RecipientServiceBlockingStub; + +class UserRemoteServiceTest { + + @InjectMocks + private UserRemoteService remoteService; + + @Mock + private RecipientServiceBlockingStub stub; + @Mock + private UserRecipientMapper mapper; + + @Nested + class TestRequestRecipients { + + @BeforeEach + void initTest() { + when(stub.findRecipientByOrganisationsEinheitId(any())).thenReturn(GrpcFindRecipientRequestTestFactory.create()); + when(stub.withInterceptors(any())).thenReturn(stub); + } + + @Test + void shouldCallMapper() { + remoteService.getRecipients(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); + + verify(mapper).fromGrpc(GrpcFindRecipientRequestTestFactory.GRPC_RECIPIENT); + } + + @Test + void shouldUseInterceptor() { + remoteService.getRecipients(VorgangTestFactory.ORGANISATIONS_EINHEIT_ID); + + verify(stub).withInterceptors(any(NotificationManagerCallContextAttachingInterceptor.class)); + } + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcServiceKontoTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcServiceKontoTestFactory.java new file mode 100644 index 0000000..1ec7fef --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcServiceKontoTestFactory.java @@ -0,0 +1,42 @@ +/* + * 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.notification.vorgang; + +import de.ozgcloud.notification.postfach.GrpcPostfachAddressTestFactory; +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; + +public class GrpcServiceKontoTestFactory { + + public final static String TYPE = "OSI"; + + public static GrpcServiceKonto create() { + return createBuilder().build(); + } + + public static GrpcServiceKonto.Builder createBuilder() { + return GrpcServiceKonto.newBuilder() + .setType(TYPE) + .addPostfachAddresses(GrpcPostfachAddressTestFactory.create()); + } +} diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangHeadTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangHeadTestFactory.java new file mode 100644 index 0000000..a215a89 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangHeadTestFactory.java @@ -0,0 +1,38 @@ +/* + * 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.notification.vorgang; + +import de.ozgcloud.vorgang.vorgang.GrpcVorgangHead; + +public class GrpcVorgangHeadTestFactory { + + public static GrpcVorgangHead create() { + return createBuilder().build(); + } + + public static GrpcVorgangHead.Builder createBuilder() { + return GrpcVorgangHead.newBuilder() + .setServiceKonto(GrpcServiceKontoTestFactory.create()); + } +} diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/GrpcVorgangTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangTestFactory.java similarity index 82% rename from notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/GrpcVorgangTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangTestFactory.java index f2213c2..964cc78 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/GrpcVorgangTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/GrpcVorgangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; -import de.itvsh.ozg.pluto.vorgang.GrpcAntragsteller; -import de.itvsh.ozg.pluto.vorgang.GrpcEingang; -import de.itvsh.ozg.pluto.vorgang.GrpcVorgangWithEingang; -import de.itvsh.ozg.pluto.vorgang.GrpcZustaendigeStelle; +import de.ozgcloud.vorgang.vorgang.GrpcAntragsteller; +import de.ozgcloud.vorgang.vorgang.GrpcEingang; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; +import de.ozgcloud.vorgang.vorgang.GrpcZustaendigeStelle; public class GrpcVorgangTestFactory { @@ -41,6 +41,7 @@ public class GrpcVorgangTestFactory { .setNummer(VorgangTestFactory.VORGANG_NUMMER) .setCreatedAt(VorgangTestFactory.CREATED_AT_STR) .setFormEngineName(VorgangTestFactory.FORM_ENGINE_NAME) + .setHeader(GrpcVorgangHeadTestFactory.create()) .setEingang(GrpcEingang.newBuilder() .setAntragsteller(GrpcAntragsteller.newBuilder() .setPostfachId(VorgangTestFactory.POSTFACH_ID) diff --git a/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangMapperTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangMapperTest.java new file mode 100644 index 0000000..060b5d6 --- /dev/null +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangMapperTest.java @@ -0,0 +1,73 @@ +/* + * 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.notification.vorgang; + +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.notification.postfach.PostfachAddressTestFactory; + +class VorgangMapperTest { + + private final VorgangMapper mapper = Mappers.getMapper(VorgangMapper.class); + + @DisplayName("From grpc") + @Nested + class TestFromGrpc { + + @Test + void shouldMapVorgang() { + var mapped = fromGrpc(); + + assertThat(mapped).usingRecursiveComparison().ignoringFields("postfachAddress").isEqualTo(VorgangTestFactory.create()); + } + + @DisplayName("postfachAddress") + @Nested + class TestPostfachAddress { + + @Test + void shouldMapIfServiceKontoExists() { + var mapped = fromGrpc(); + + assertThat(mapped.getPostfachAddress()).usingRecursiveComparison().isEqualTo(PostfachAddressTestFactory.create()); + } + + @Test + void shouldBeEmptyIfServiceKontoNotExists() { + var mapped = mapper.fromGrpc(GrpcVorgangTestFactory.createBuilder().clearHeader().build()); + + assertThat(mapped.getPostfachAddress()).isNull(); + } + } + + private Vorgang fromGrpc() { + return mapper.fromGrpc(GrpcVorgangTestFactory.create()); + } + } +} \ No newline at end of file diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangRemoteServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangRemoteServiceTest.java similarity index 85% rename from notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangRemoteServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangRemoteServiceTest.java index c781067..0d97898 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangRemoteServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangRemoteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -35,11 +35,11 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.kop.notification.NotificationManagerCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangRequest; -import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangResponse; -import de.itvsh.ozg.pluto.vorgang.GrpcVorgangWithEingang; -import de.itvsh.ozg.pluto.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import de.ozgcloud.notification.NotificationManagerCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangResponse; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; class VorgangRemoteServiceTest { diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangServiceTest.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangServiceTest.java similarity index 94% rename from notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangServiceTest.java rename to notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangServiceTest.java index 68ee393..9ef693c 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangServiceTest.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; diff --git a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangTestFactory.java b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangTestFactory.java similarity index 89% rename from notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangTestFactory.java rename to notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangTestFactory.java index c27f0f1..2492b43 100644 --- a/notification-manager/src/test/java/de/itvsh/kop/notification/vorgang/VorgangTestFactory.java +++ b/notification-manager/src/test/java/de/ozgcloud/notification/vorgang/VorgangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.notification.vorgang; +package de.ozgcloud.notification.vorgang; import java.time.ZonedDateTime; import java.util.UUID; +import de.ozgcloud.notification.postfach.PostfachAddressTestFactory; + public class VorgangTestFactory { public static final VorgangId ID = VorgangId.from(UUID.randomUUID().toString()); @@ -50,6 +52,7 @@ public class VorgangTestFactory { .vorgangNummer(VORGANG_NUMMER) .createdAt(CREATED_AT) .postfachId(POSTFACH_ID) + .postfachAddress(PostfachAddressTestFactory.create()) .formEngineName(FORM_ENGINE_NAME) .organisationseinheitenId(ORGANISATIONS_EINHEIT_ID); } diff --git a/pluto-interface/lombok.config b/pluto-interface/lombok.config deleted file mode 100644 index e2cecc9..0000000 --- a/pluto-interface/lombok.config +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2022 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. - -lombok.log.fieldName=LOG -lombok.log.slf4j.flagUsage = ERROR -lombok.log.log4j.flagUsage = ERROR -lombok.data.flagUsage = ERROR -lombok.nonNull.exceptionType = IllegalArgumentException -lombok.addLombokGeneratedAnnotation = true diff --git a/pluto-interface/src/main/protobuf/vorgangmodel.proto b/pluto-interface/src/main/protobuf/vorgangmodel.proto deleted file mode 100644 index b8e5ce4..0000000 --- a/pluto-interface/src/main/protobuf/vorgangmodel.proto +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.vorgang; - -import "clientattribute.model.proto"; - -option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.vorgang"; -option java_outer_classname = "VorgangModelProto"; - -message GrpcVorgangHeader { - string id = 1; - int64 version = 2; - string status = 3; - string name = 4; - string createdAt = 5; - string aktenzeichen = 6; - string assignedTo = 7; - string nummer = 8; - repeated de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute clientAttributes = 9; - string formEngineName = 15; -} - -message GrpcVorgangWithEingang { - string id = 1; - int64 version = 2; - string status = 3; - string name = 4; - string createdAt = 5; - string aktenzeichen = 6; - string assignedTo = 7; - string nummer = 8; - repeated de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute clientAttributes = 9; - - GrpcEingang eingang = 10; - string formEngineName = 15; -} - -message GrpcEingang { - string id = 1; - - GrpcEingangHeader header = 2; - GrpcAntragsteller antragsteller = 3; - GrpcZustaendigeStelle zustaendigeStelle = 4; - - GrpcFormData formData = 10; - - int32 numberOfAttachments = 11; - int32 numberOfRepresentations = 12; - - repeated GrpcIncomingFileGroup attachments = 20; - repeated GrpcIncomingFile representations = 21; -} - -message GrpcIncomingFileGroup { - string name = 1; - repeated GrpcIncomingFile files = 2; -} - -message GrpcIncomingFile { - string id = 1; - string vendorId = 2; - string name = 3; - string contentType = 4; - int64 size = 5; - bytes content = 6; -} - -message GrpcEingangHeader { - string requestId = 1; - string createdAt = 2; - string formId = 3; - string formName = 4; - string sender = 5; - string customer = 6 [deprecated=true]; - string customerId = 7 [deprecated=true]; - string client = 8 [deprecated=true]; - string clientId = 9 [deprecated=true]; - string formEngineName = 10; -} - -message GrpcAntragsteller { - string anrede = 1; - string nachname = 2; - string vorname = 3; - string geburtsdatum = 4; - string geburtsort = 5; - string geburtsname = 6; - string email = 7; - string telefon = 8; - string strasse = 9; - string hausnummer = 10; - string plz = 11; - string ort = 12; - string postfachId = 13; - - GrpcFormData otherData = 30; -} - -message GrpcFormData { - repeated GrpcFormField field = 1; - repeated GrpcSubForm form = 2; -} - -message GrpcFormField { - string name = 1; - string value = 2; -} - -message GrpcSubForm { - string title = 1; - repeated GrpcFormField field = 2; - repeated GrpcSubForm subForm = 3; -} - -message GrpcZustaendigeStelle { - string organisationseinheitenId = 1; - string email = 2; - string bezeichnung = 3; -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListener.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListener.java deleted file mode 100644 index 00a7f8f..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListener.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.attached_item; - -import java.util.function.Predicate; - -import javax.validation.ValidationException; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Component; - -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; -import de.itvsh.ozg.pluto.command.Order; - -@Component -class VorgangAttachedItemEventListener { - - private static final String IS_CREATE_ITEM_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemEventListener).IS_CREATE_ITEM_ORDER.test(event.getSource())}"; - private static final String IS_UPDATE_ITEM_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemEventListener).IS_UPDATE_ITEM_ORDER.test(event.getSource())}"; - private static final String IS_PATCH_ITEM_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemEventListener).IS_PATCH_ITEM_ORDER.test(event.getSource())}"; - - public static final Predicate<Command> IS_CREATE_ITEM_ORDER = command -> Order.CREATE_ATTACHED_ITEM.isMeant(command.getOrder()); - public static final Predicate<Command> IS_UPDATE_ITEM_ORDER = command -> Order.UPDATE_ATTACHED_ITEM.isMeant(command.getOrder()); - public static final Predicate<Command> IS_PATCH_ITEM_ORDER = command -> Order.PATCH_ATTACHED_ITEM.isMeant(command.getOrder()); - - @Autowired - private VorgangAttachedItemService service; - @Autowired - private VorgangAttachedItemMapper mapper; - - @EventListener(condition = IS_CREATE_ITEM_ORDER_CONDITION) - public void createItem(CommandCreatedEvent event) { - var command = event.getSource(); - validateCreateCommand(command); - - var item = mapper.fill(command.getBodyObject()); - service.create(command.getId(), item.toBuilder().id(null).version(0).build()); - } - - private void validateCreateCommand(Command command) { - if (!StringUtils.equals(command.getRelationId(), command.getVorgangId())) { - throw new ValidationException("Command invalid creation command: vorgangId and relationId must be equals"); - } - - } - - @EventListener(condition = IS_UPDATE_ITEM_ORDER_CONDITION) - public void updateItem(CommandCreatedEvent event) { - var command = event.getSource(); - var item = mapper.fill(command.getBodyObject()) - .toBuilder().id(command.getRelationId()).version(command.getRelationVersion()).build(); - - service.update(command.getId(), item); - } - - @EventListener(condition = IS_PATCH_ITEM_ORDER_CONDITION) - public void patchItem(CommandCreatedEvent event) { - var command = event.getSource(); - var item = mapper.fill(command.getBodyObject()); - - service.patch(command, item.getItem()); - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandService.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandService.java deleted file mode 100644 index 061a090..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandService.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.command; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URLConnection; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Base64; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.stream.Stream; - -import javax.activation.MimetypesFileTypeMap; - -import org.apache.http.entity.ContentType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.mail.postfach.MessageAttachment; -import de.itvsh.ozg.mail.postfach.PersistPostfachMailService; -import de.itvsh.ozg.mail.postfach.PostfachMail; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemMapper; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemService; -import de.itvsh.ozg.pluto.files.FileService; -import de.itvsh.ozg.pluto.files.OzgFile; -import de.itvsh.ozg.pluto.files.UploadedFilesReference; -import lombok.extern.log4j.Log4j2; - -/** - * @deprecated Temporally replacement for using GRPC Api by MailService - */ -@Deprecated -@Service -@Log4j2 -class PersistPostfachMailByCommandService implements PersistPostfachMailService { - - static final String CLIENT = "MailService"; - static final String ITEM_NAME = "PostfachMail"; - static final String ATTACHMENT_NAME = "PostfachAttachment"; - - @Autowired - private CommandService service; - @Autowired - private VorgangAttachedItemService attachedItemService; - @Autowired - private FileService fileService; - - @Override - public void persistMail(Optional<String> userId, PostfachMail mail) { - service.createCommand(CreateCommandRequest.builder() - .callContext(buildCallContext(userId)) - .vorgangId(mail.getVorgangId()) - .relationId(mail.getVorgangId()).relationVersion(-1L) - .order(Order.CREATE_ATTACHED_ITEM.name()) - .bodyObject(buildItem(mail)) - .build()); - } - - private CallContext buildCallContext(Optional<String> userId) { - var builder = CallContext.builder(); - userId.map(id -> User.builder().id(id).build()).ifPresent(builder::user); - - return builder.build(); - } - - private Map<String, Object> buildItem(PostfachMail mail) { - return Map.of( - VorgangAttachedItemMapper.PROPERTY_CLIENT, CLIENT, - VorgangAttachedItemMapper.PROPERTY_VORGANG_ID, mail.getVorgangId(), - VorgangAttachedItemMapper.PROPERTY_ITEM_NAME, ITEM_NAME, - VorgangAttachedItemMapper.PROPERTY_ITEM, buildMailMap(mail)); - - } - - Map<String, Object> buildMailMap(PostfachMail mail) { - Map<String, Object> result = new HashMap<>(Map.of( - PostfachMail.FIELD_VORGANG_ID, mail.getVorgangId(), - PostfachMail.FIELD_POSTFACH_ID, mail.getPostfachId(), - PostfachMail.FIELD_CREATED_AT, mail.getCreatedAt().format(DateTimeFormatter.ISO_DATE_TIME), - PostfachMail.FIELD_DIRECTION, mail.getDirection().name(), - PostfachMail.FIELD_REPLY_OPTION, mail.getReplyOption().name(), - PostfachMail.FIELD_SUBJECT, mail.getSubject(), - PostfachMail.FIELD_MAIL_BODY, mail.getMailBody(), - PostfachMail.FIELD_ATTACHMENTS, mail.getAttachments())); - - putIfNonNull(result, PostfachMail.FIELD_MESSAGE_ID, mail.getMessageId()); - putIfNonNull(result, PostfachMail.FIELD_CREATED_BY, mail.getCreatedBy()); - putIfNonNull(result, PostfachMail.FIELD_SENT_SUCCESSFUL, mail.getSentSuccessful()); - putIfNonNull(result, PostfachMail.FIELD_MESSAGE_CODE, mail.getMessageCode()); - putDateIfNonNull(result, PostfachMail.FIELD_SENT_AT, mail.getSentAt()); - - return Collections.unmodifiableMap(result); - } - - private Map<String, Object> putIfNonNull(Map<String, Object> mapIn, String key, Object value) { - if (Objects.nonNull(value)) { - mapIn.put(key, value); - } - return mapIn; - } - - private Map<String, Object> putDateIfNonNull(Map<String, Object> mapIn, String key, Object value) { - if (Objects.nonNull(value)) { - mapIn.put(key, ((ZonedDateTime) value).format(DateTimeFormatter.ISO_DATE_TIME)); - } - return mapIn; - } - - @Override - public Optional<Map<String, Object>> findById(String postfachNachrichtId) { - return attachedItemService.findById(postfachNachrichtId).map(VorgangAttachedItem::getItem); - } - - @Override - public Stream<Map<String, Object>> findByVorgangAsMap(String vorgangId) { - return attachedItemService.find(vorgangId, Optional.of(CLIENT), Optional.of(ITEM_NAME)).map(VorgangAttachedItem::getItem); - } - - @Override - public void patch(String postfachNachrichtId, Map<String, Object> propertyMap) { - attachedItemService.forcePatch(postfachNachrichtId, propertyMap); - } - - @Override - public Map<String, Object> getById(String postfachNachrichtId) { - return attachedItemService.getById(postfachNachrichtId).getItem(); - } - - @Override - public String persistAttachment(String vorgangId, MessageAttachment attachment) { - var decContent = Base64.getDecoder().decode(attachment.getContent()); - var contentType = getTypeByFile(attachment.getFileName(), attachment.getContent()); - - try { - return fileService.uploadFileStream( - createUploadedFilesReference(vorgangId), - createOzgFile(attachment, contentType, decContent.length), - Optional.empty(), - new ByteArrayInputStream(decContent)).get(10, TimeUnit.MINUTES).toString(); - } catch (ExecutionException | TimeoutException e) { - throw new TechnicalException(e.getMessage(), e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new TechnicalException(e.getMessage(), e); - } - } - - UploadedFilesReference createUploadedFilesReference(String vorgangId) { - return UploadedFilesReference.builder().vorgangId(vorgangId).client(CLIENT).name(ATTACHMENT_NAME).build(); - } - - OzgFile createOzgFile(MessageAttachment attachment, String contentType, long size) { - return OzgFile.builder().name(attachment.getFileName()).contentType(contentType).size(size).build(); - } - - String getTypeByFile(String fileName, String content) { - var fileNameMap = URLConnection.getFileNameMap(); - - return Optional.ofNullable(fileNameMap.getContentTypeFor(fileName)).orElseGet(() -> getTypeByContent(fileName, content)); - } - - private String getTypeByContent(String fileName, String content) { - try { - return Optional.ofNullable(URLConnection.guessContentTypeFromStream(new ByteArrayInputStream(content.getBytes()))) - .orElseGet(() -> getByMimeTypes(fileName)); - } catch (IOException e) { - LOG.warn("IO-Exception while guessing content type", e); - } - return ContentType.APPLICATION_OCTET_STREAM.toString(); - } - - // uses map file: src/main/resources/mime.types - private String getByMimeTypes(String fileName) { - MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap(); - - return fileTypeMap.getContentType(fileName); - } - -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/StatusOrder.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/StatusOrder.java deleted file mode 100644 index 945ac43..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/StatusOrder.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.command; - -import java.util.Optional; - -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@AllArgsConstructor -@NoArgsConstructor -enum StatusOrder { - - VORGANG_ANNEHMEN(VorgangService::annehmen), - VORGANG_VERWERFEN(VorgangService::verwerfen), - VORGANG_ZURUECKHOLEN(VorgangService::setStatusNeu), - VORGANG_BEARBEITEN(VorgangService::bearbeiten), - VORGANG_BESCHEIDEN(VorgangService::bescheiden), - VORGANG_ZURUECKSTELLEN(VorgangService::annehmen), - VORGANG_ABSCHLIESSEN(VorgangService::abschliessen), - VORGANG_WIEDEREROEFFNEN(VorgangService::wiedereroeffnen), - - REDIRECT_VORGANG, - - ASSIGN_USER, - - FORWARD_SUCCESSFULL, - FORWARD_FAILED, - - SEND_POSTFACH_MAIL, - RESEND_POSTFACH_MAIL, - - CREATE_ATTACHED_ITEM, - UPDATE_ATTACHED_ITEM; - - interface OrderMethod { - Vorgang executeOrder(VorgangService service, Command command); - } - - private OrderMethod method; - - /** @deprecated please implement event/listener */ - @Deprecated - static Optional<OrderMethod> getOrderMethod(String order) { - try { - return Optional.ofNullable(StatusOrder.valueOf(order).method); - } catch (IllegalArgumentException e) { - return Optional.empty(); - } - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.java deleted file mode 100644 index 0f6a553..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-01-21 13:57:00 OZG-2047", order = "M000", author = "jreese", runAlways = false) -public class M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing { // NOSONAR - static final String FORM_ID_BAULASTENAUSKUNFT = "baulastenauskunft/baulastenaufkunft"; - static final String ORGANISATIONSEINHEITEN_ID = "248240886"; - static final String CUSTOMER_ID = "nordfriesland"; - private static final String ZUSTAENDIGESTELLE_FIELD = "eingangs.0.zustaendigeStelle"; - private static final String ZUSTAENDIGESTELLE_ORGANISATIONSEINHEITEN_ID_FIELD = "eingangs.0.zustaendigeStelle.organisationseinheitenId"; - private static final String CUSTOMER_ID_FIELD = "eingangs.0.header.customerId"; - private static final String FORM_ID_FIELD = "eingangs.0.header.formId"; - private static final String COLLECTION_NAME = "vorgang"; - - @Execution - public void migrationMethod(MongoTemplate template) { - Update update = new Update(); - update.set(ZUSTAENDIGESTELLE_ORGANISATIONSEINHEITEN_ID_FIELD, ORGANISATIONSEINHEITEN_ID); - - Query query = new Query(Criteria - .where(ZUSTAENDIGESTELLE_FIELD) - .exists(false) - .and(CUSTOMER_ID_FIELD).is(CUSTOMER_ID) - .and(FORM_ID_FIELD).is(FORM_ID_BAULASTENAUSKUNFT)); - - template.updateMulti(query, update, COLLECTION_NAME); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFs.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFs.java deleted file mode 100644 index 298e1ac..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFs.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.Objects; - -import org.bson.BsonObjectId; -import org.bson.Document; -import org.bson.types.Binary; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import com.mongodb.MongoServerException; -import com.mongodb.client.gridfs.GridFSBucket; -import com.mongodb.client.gridfs.GridFSBuckets; -import com.mongodb.client.gridfs.model.GridFSUploadOptions; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@ChangeUnit(id = "2022-03-08 10:03:00 OZG-2259", order = "M001", author = "jreese", runAlways = false) -public class M001_MigrateMailServiceAttachmentsToGridFs { // NOSONAR - - private static final String ATTACHED_ITEM = "item"; - static final String ATTACHED_ITEM_COLLECTION = "vorgangAttachedItem"; - private static final String CONTENT_FIELD = "content"; - static final String BINARY_FILE_COLLECTION = "binaryFile"; - static final String GRID_FS_FILE_COLLECTION = "fs.files"; - private static final String CREATED_BY = "createdBy"; - private static final String CREATED_AT = "createdAt"; - private static final String FILE_FIELD_NAME = "field"; - private static final String FILE_FIELD = "file"; - static final String OBJECT_ID = "_id"; - - static final String CLIENT = "client"; - static final String CLIENT_VALUE = "MailService"; - static final String CONTENT_TYPE = "contentType"; - static final String FIELD_NAME = "fieldName"; - static final String FILE_NAME = "name"; - static final String VORGANG_ID = "vorgangId"; - - @Execution - public void migrationMethod(final MongoTemplate template) { - var attachedItems = findAttachedItems(template); - var gridFsBucket = getGridFsBucket(template); - - attachedItems.stream() - .flatMap(attachedItem -> getAttachmentIds(attachedItem).stream()) - .forEach(attachment -> doMigration(template, gridFsBucket, attachment)); - } - - private List<Document> findAttachedItems(MongoTemplate template) { - return template.find(Query.query(Criteria.where(CLIENT).is(CLIENT_VALUE)), Document.class, ATTACHED_ITEM_COLLECTION); - } - - private GridFSBucket getGridFsBucket(MongoTemplate template) { - return GridFSBuckets.create(template.getDb()); - } - - @SuppressWarnings("unchecked") - private List<String> getAttachmentIds(Document attachedItem) { - return (List<String>) attachedItem.get(ATTACHED_ITEM, Document.class).get("attachments"); - } - - private void doMigration(final MongoTemplate template, GridFSBucket gridFs, String attachment) { - var gridFsFile = getFileFromGridFs(attachment, template); - if (Objects.isNull(gridFsFile)) { - var file = getFile(attachment, template); - if (Objects.nonNull(file)) { - try { - storeToGridFs(gridFs, file); - } catch (MongoServerException | IOException e) { - LOG.error("Error migrating Attachment id " + attachment, e); - throw new MigrationException("Error migrating Attachment with id " + attachment, e); - } - } - } - } - - private Document getFile(String fileId, MongoTemplate template) { - return template.findOne(Query.query(Criteria.where(OBJECT_ID).is(fileId)), Document.class, BINARY_FILE_COLLECTION); - } - - private Document getFileFromGridFs(String fileId, MongoTemplate template) { - return template.findOne(Query.query(Criteria.where(OBJECT_ID).is(fileId)), Document.class, GRID_FS_FILE_COLLECTION); - } - - void storeToGridFs(GridFSBucket gridFsBucket, Document entry) throws IOException { - var file = entry.get(FILE_FIELD, Document.class); - byte[] convertedContent = convertContent(file); - try (var fileContentInputStream = new ByteArrayInputStream(convertedContent)) { - gridFsBucket.uploadFromStream( - createObjectId(entry), - createFilePath(entry, file), - fileContentInputStream, - createGridFsUploadOptions(entry, file)); - - } - } - - @SuppressWarnings("unchecked") - byte[] convertContent(Document file) { - var content = (List<Binary>) file.get(CONTENT_FIELD); - List<byte[]> allData = content.stream().map(Binary::getData).toList(); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - allData.forEach(t -> { - try { - out.write(t); - } catch (IOException e) { - throw new MigrationException("Error converting data", e); - } - }); - return out.toByteArray(); - } - - private BsonObjectId createObjectId(Document entry) { - return new BsonObjectId(entry.getObjectId(OBJECT_ID)); - } - - private String createFilePath(Document entry, Document file) { - return String.format("%s/%s/%s/%s", - entry.getString(VORGANG_ID), - entry.getString(CLIENT), - entry.getString(FILE_FIELD_NAME), - file.getString(FILE_NAME)); - } - - private GridFSUploadOptions createGridFsUploadOptions(Document entry, Document file) { - var uploadOptions = new GridFSUploadOptions(); - uploadOptions.metadata(createMetaData(entry, file)); - return uploadOptions; - } - - private Document createMetaData(Document entry, Document file) { - var metadata = new Document(); - metadata.append(VORGANG_ID, entry.get(VORGANG_ID)); - metadata.append(CLIENT, entry.get(CLIENT)); - metadata.append(FIELD_NAME, entry.get(FILE_FIELD_NAME)); - metadata.append(CONTENT_TYPE, file.get(CONTENT_TYPE)); - metadata.append(FILE_NAME, file.get(FILE_NAME)); - metadata.append(CREATED_BY, entry.get(CREATED_BY)); - metadata.append(CREATED_AT, entry.get(CREATED_AT)); - return metadata; - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs.java deleted file mode 100644 index 5cadda5..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.List; -import java.util.Objects; - -import org.bson.Document; -import org.bson.types.Binary; -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import com.mongodb.MongoServerException; -import com.mongodb.client.gridfs.GridFSBucket; -import com.mongodb.client.gridfs.GridFSBuckets; -import com.mongodb.client.gridfs.model.GridFSUploadOptions; - -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -//@ChangeUnit(id = "2022-04-29 14:45:00 OZG-2093", order = "M003", author = "jreese", runAlways = false) -public class M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs { // NOSONAR - - private static final String ATTACHMENTS_FIELD = "attachments"; - private static final String REPRESENTATIONS_FIELD = "representations"; - private static final String CONTENT_FIELD = "content"; - private static final String CREATED_BY = "createdBy"; - private static final String CREATED_AT = "createdAt"; - private static final String EINGANGS_FIELD = "eingangs"; - private static final String EINGANGS_ATTACHMENTS_FIELD = EINGANGS_FIELD + "." + ATTACHMENTS_FIELD; - private static final String FILES_FIELD = "files"; - - static final String CLIENT = "client"; - static final String CLIENT_VALUE = "eingangManager"; - static final String CONTENT_TYPE = "contentType"; - static final String FILE_FIELD_NAME = "fieldName"; - static final String ATTACHMENT_FIELD_NAME_VALUE = "vorgangAttachment"; - static final String REPRESENTATION_FIELD_NAME_VALUE = "vorgangRepresentation"; - static final String FILE_NAME = "name"; - static final String GRID_FS_FILE_COLLECTION = "fs.files"; - static final String GRISFS_FILE_NAME_FIELD = "filename"; - static final String OBJECT_ID = "_id"; - static final String VORGANG_ID = "vorgangId"; - static final String VORGANG_COLLECTION = "vorgang"; - - @Execution - public void migrationMethod(final MongoTemplate template) { - var vorgangs = findVorgangsWithAttachments(template); - var gridFsBucket = getGridFsBucket(template); - - vorgangs.forEach(vorgang -> { - getAttachments(vorgang).stream().flatMap(attachment -> getFiles(attachment).stream()) - .filter(Objects::nonNull) - .forEach(file -> doMigration(template, gridFsBucket, file, vorgang, ATTACHMENT_FIELD_NAME_VALUE)); - getRepresentations(vorgang).stream() - .forEach(file -> doMigration(template, gridFsBucket, file, vorgang, REPRESENTATION_FIELD_NAME_VALUE)); - }); - } - - private List<Document> findVorgangsWithAttachments(MongoTemplate template) { - return template.find(Query.query(Criteria.where(EINGANGS_ATTACHMENTS_FIELD).exists(Boolean.TRUE)), Document.class, VORGANG_COLLECTION); - } - - private GridFSBucket getGridFsBucket(MongoTemplate template) { - return GridFSBuckets.create(template.getDb()); - } - - private List<Document> getAttachments(Document vorgang) { - return vorgang.getList(EINGANGS_FIELD, Document.class).get(0).getList(ATTACHMENTS_FIELD, Document.class); - } - - private List<Document> getRepresentations(Document vorgang) { - return vorgang.getList(EINGANGS_FIELD, Document.class).get(0).getList(REPRESENTATIONS_FIELD, Document.class); - } - - private List<Document> getFiles(Document attachment) { - return attachment.getList(FILES_FIELD, Document.class); - } - - private void doMigration(final MongoTemplate template, GridFSBucket gridFs, Document file, Document vorgang, String fieldValue) { - final String vorgangId = vorgang.getObjectId(OBJECT_ID).toString(); - file.put(CREATED_AT, vorgang.getDate(CREATED_AT)); - var existingGridFsFile = getFileFromGridFsById(file.getString(OBJECT_ID), template); - if (Objects.isNull(existingGridFsFile)) { - try { - var objectId = storeToGridFs(gridFs, file, vorgangId, fieldValue); - updateMigratedFile(template, file, objectId, vorgang); - } catch (MongoServerException | IOException e) { - LOG.error("Error migrating attachment {}", file, e); - throw new IllegalStateException(e.getMessage(), e); - } - } - } - - private Document getFileFromGridFsById(String id, MongoTemplate template) { - return template.findOne(Query.query(Criteria.where(OBJECT_ID).is(id)), Document.class, GRID_FS_FILE_COLLECTION); - } - - ObjectId storeToGridFs(GridFSBucket gridFsBucket, Document file, String vorgangId, String fieldValue) throws IOException { - byte[] content = ((Binary) file.get(CONTENT_FIELD)).getData(); - try (var fileContentInputStream = new ByteArrayInputStream(content)) { - return gridFsBucket.uploadFromStream( - createFilePath(vorgangId, file, fieldValue), - fileContentInputStream, - createGridFsUploadOptions(file, vorgangId, fieldValue)); - - } - } - - void updateMigratedFile(MongoTemplate template, Document file, ObjectId id, Document vorgang) { - file.put(OBJECT_ID, id.toHexString()); - - template.save(vorgang, VORGANG_COLLECTION); - } - - private String createFilePath(String vorgangId, Document file, String fieldValue) { - return String.format("%s/%s/%s/%s", - vorgangId, - CLIENT_VALUE, - fieldValue, - file.getString(FILE_NAME)); - } - - private GridFSUploadOptions createGridFsUploadOptions(Document file, String vorgangId, String fieldValue) { - var uploadOptions = new GridFSUploadOptions(); - uploadOptions.metadata(createMetaData(file, vorgangId, fieldValue)); - return uploadOptions; - } - - private Document createMetaData(Document file, String vorgangId, String fieldValue) { - var metadata = new Document(); - metadata.append(VORGANG_ID, vorgangId); - metadata.append(CLIENT, CLIENT_VALUE); - metadata.append(FILE_FIELD_NAME, fieldValue); - metadata.append(CONTENT_TYPE, file.get(CONTENT_TYPE)); - metadata.append(FILE_NAME, file.get(FILE_NAME)); - metadata.append(CREATED_BY, file.get(CREATED_BY)); - metadata.append(CREATED_AT, file.get(CREATED_AT)); - return metadata; - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagen.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagen.java deleted file mode 100644 index a84416e..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagen.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.bson.Document; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-04-29 11:00:00 OZG-1918 OZG-2476", order = "M004", author = "jreese", runAlways = false) -public class M004_RemoveWiedervorlagen { // NOSONAR - static final String BINARY_FILE_COLLECTION = "binaryFile"; - static final String FIELD_KEY = "field"; - static final String FIELD_KEY_VALUE = "wiedervorlageAttachment"; - static final String WIEDERVORLAGES_FIELD_KEY = "wiedervorlages"; - static final String VORGANG_COLLECTION = "vorgang"; - static final String VORGANG_ID = "_id"; - - @Execution - public void migrationMethod(final MongoTemplate template) { - deleteWiedervorlageAttachments(template); - deleteWiedervorlagen(template); - } - - private void deleteWiedervorlageAttachments(final MongoTemplate template) { - var query = new Query(Criteria.where(FIELD_KEY).is(FIELD_KEY_VALUE)); - - template.remove(query, BINARY_FILE_COLLECTION); - } - - private void deleteWiedervorlagen(MongoTemplate template) { - var query = new Query(Criteria.where(WIEDERVORLAGES_FIELD_KEY).exists(true)); - var vorgangs = template.find(query, Document.class, VORGANG_COLLECTION); - - vorgangs.forEach(vorgangDoc -> { - var update = new Update(); - update.unset(WIEDERVORLAGES_FIELD_KEY); - var updateQuery = new Query(Criteria.where(VORGANG_ID).is(vorgangDoc.getObjectId(VORGANG_ID))); - template.updateMulti(updateQuery, update, VORGANG_COLLECTION); - }); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgang.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgang.java deleted file mode 100644 index e8f6ef8..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgang.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.springframework.data.mongodb.core.MongoTemplate; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-04-29 12:08:00 OZG-2232", order = "M005", author = "tobr", runAlways = false) -public class M005_CreateIndexesInVorgang { // NOSONAR - - @Execution - public void createIndexes(MongoTemplate template) { - createIndexWithoutStatus(template); - createIndexWithStatus(template); - } - - void createIndexWithStatus(MongoTemplate template) { - var createIndexCommand = """ - { - "createIndexes": "vorgang", - "indexes": [{ - "key": { - "inCreation": 1, - "eingangs.zustaendigeStelle.organisationseinheitenId": 1, - "status": 1 - "createdAt": 1, - }, - "name": "inCreation_orgaId_status_createdAt" - }] - } """; - - template.executeCommand(createIndexCommand); - } - - void createIndexWithoutStatus(MongoTemplate template) { - var createIndexCommand = """ - { - "createIndexes": "vorgang", - "indexes": [{ - "key": { - "inCreation": 1, - "eingangs.zustaendigeStelle.organisationseinheitenId": 1, - "createdAt": 1, - }, - "name": "inCreation_orgaId_createdAt" - }] - } """; - - template.executeCommand(createIndexCommand); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentar.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentar.java deleted file mode 100644 index 45a20e2..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentar.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.Date; -import java.util.List; -import java.util.Objects; - -import org.bson.Document; -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-05-24 15:45:00 OZG-1523", order = "M006", author = "mkuester", runAlways = true) -public class M006_MigrateKommentar {// NOSONAR - - private static final String VORGANG_COLLECTION = "vorgang"; - private static final String VORGANG_KOMMENTAR_FIELD = "kommentars"; - - private static final String VORGANG_ID_FIELD = "vorgangId"; - private static final String ATTACHED_ITEM_CLIENT_FIELD = "client"; - public static final String ATTACHED_ITEM_CLIENT = "Goofy"; - private static final String ATTACHED_ITEM_VERSION_FIELD = "version"; - public static final int ATTACHED_ITEM_VERSION = 0; - private static final String ATTACHED_ITEM_ITEM_NAME_FIELD = "itemName"; - public static final String ATTACHED_ITEM_ITEM_NAME = "Kommentar"; - private static final String ATTACHED_ITEM_ITEM_FIELD = "item"; - - private static final String KOMMENTAR_CREATED_AT_FIELD = "createdAt"; - private static final String KOMMENTAR_ID_FIELD = "id"; - - private static final String VORGANG_ATTACHED_ITEM_COLLECTION = "vorgangAttachedItem"; - - private static final String ID = "_id"; - - @Execution - public void migrationMethod(MongoTemplate template) { - var vorgaenge = template.findAll(Document.class, VORGANG_COLLECTION); - vorgaenge.forEach(vorgang -> migrateVorgang(template, vorgang)); - } - - private void migrateVorgang(MongoTemplate template, Document vorgang) { - var kommentare = vorgang.getList(VORGANG_KOMMENTAR_FIELD, Document.class); - if (Objects.nonNull(kommentare)) { - kommentare.forEach(kommentar -> migrateKommentar(template, vorgang.getObjectId(ID), kommentar)); - } - } - - private void migrateKommentar(MongoTemplate template, ObjectId vorgangId, Document kommentar) { - List<Document> existing = template.find(new Query(Criteria.where(ATTACHED_ITEM_ITEM_FIELD + "._id").is(kommentar.getString("_id"))), - Document.class, - VORGANG_ATTACHED_ITEM_COLLECTION); - if (existing.isEmpty()) { - var kommentarAttachedItem = createVorgangAttachedItem(vorgangId, kommentar); - - template.save(kommentarAttachedItem, VORGANG_ATTACHED_ITEM_COLLECTION); - } - } - - private Document createVorgangAttachedItem(ObjectId vorgangId, Document kommentar) { - var kommentarAsAttachedItem = new Document(); - kommentarAsAttachedItem.put(VORGANG_ID_FIELD, vorgangId.toHexString()); - kommentarAsAttachedItem.put(ATTACHED_ITEM_VERSION_FIELD, ATTACHED_ITEM_VERSION); - kommentarAsAttachedItem.put(ATTACHED_ITEM_CLIENT_FIELD, ATTACHED_ITEM_CLIENT); - kommentarAsAttachedItem.put(ATTACHED_ITEM_ITEM_NAME_FIELD, ATTACHED_ITEM_ITEM_NAME); - kommentarAsAttachedItem.put(ATTACHED_ITEM_ITEM_FIELD, buildItem(kommentar)); - - return kommentarAsAttachedItem; - } - - private Document buildItem(Document kommentar) { - var attachedItemKommentar = kommentar; - attachedItemKommentar.remove(KOMMENTAR_ID_FIELD); - attachedItemKommentar.remove(VORGANG_ID_FIELD); - attachedItemKommentar.put(KOMMENTAR_CREATED_AT_FIELD, convertDate(kommentar.get(KOMMENTAR_CREATED_AT_FIELD))); - - return attachedItemKommentar; - } - - private String convertDate(Object dateValue) { - return ZonedDateTime.ofInstant(((Date) dateValue).toInstant(), ZoneId.of("UTC")).toString(); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.java deleted file mode 100644 index 0e07116..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.bson.Document; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.util.CloseableIterator; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-06-30 12:55:00 OZG-2566", order = "M007", author = "mkuester", runAlways = true) -public class M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands { // NOSONAR - - static final String COMMAND_COLLECTION = "command"; - - static final String CONSIDERED_ORDER = "UPDATE_ATTACHED_ITEM"; - - private static final String ORDER_FIELD = "order"; - private static final String RELATION_ID_FIELD = "relationId"; - private static final String BODY_OBJECT_FIELD = "bodyObject"; - private static final String ITEM_FIELD = "item"; - private static final String ID_FIELD = "id"; - - private static final String BODY_OBJECT_ITEM_ID_FIELD = "bodyObject.item.id"; - - private MongoTemplate template; - - @Execution - public void migrationMethod(MongoTemplate template) { - this.template = template; - - try (var commands = getCommands(template)) { - commands.stream().forEach(this::migrateCommand); - } - } - - CloseableIterator<Document> getCommands(MongoTemplate template) { - return template.stream(createSearchQuery(), Document.class, COMMAND_COLLECTION); - } - - private Query createSearchQuery() { - return new Query(Criteria.where(ORDER_FIELD).is(CONSIDERED_ORDER) - .andOperator(Criteria.where(BODY_OBJECT_ITEM_ID_FIELD).exists(true) - .andOperator(createNeCriteria(RELATION_ID_FIELD, BODY_OBJECT_ITEM_ID_FIELD)))); - } - - private Criteria createNeCriteria(String field, String fieldToCompare) { - return new Criteria() { - @Override - public Document getCriteriaObject() { - Document obj = new Document(); - obj.put("$where", "this." + field + " != this." + fieldToCompare); - return obj; - } - }; - } - - private void migrateCommand(Document command) { - command.put(RELATION_ID_FIELD, getItemId(command)); - - template.save(command, COMMAND_COLLECTION); - } - - private Object getItemId(Document command) { - var bodyObject = (Document) command.get(BODY_OBJECT_FIELD); - var item = (Document) bodyObject.get(ITEM_FIELD); - - return item.get(ID_FIELD); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContent.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContent.java deleted file mode 100644 index 9a0b78a..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContent.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; -import org.springframework.data.mongodb.core.query.UpdateDefinition; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-07-06 13:10:00 OZG-2690", order = "M009", author = "jreese", runAlways = true) -public class M009_RemoveAttachmentContent {// NOSONAR - - private static final String COLLECTION = "vorgang"; - private static final String CONTENT_FIELD = "content"; - private static final String ATTACHMENTS_FIELD = "attachments"; - private static final String EINGANGS_FIELD = "eingangs"; - private static final String FILES_FIELD = "files"; - private static final String EINGANGS_ATTACHMENTS_FILES_FIELD = String.format("%s.%s.%s", EINGANGS_FIELD, ATTACHMENTS_FIELD, - FILES_FIELD); - private static final String EINGANGS_ATTACHMENTS_FILES_CONTENT_FIELD = EINGANGS_ATTACHMENTS_FILES_FIELD + "." + CONTENT_FIELD; - - @Execution - public void migrationMethod(MongoTemplate template) { - template.updateMulti(findVorgangsAttachmentContentQuery(), unsetContent(), COLLECTION); - } - - Query findVorgangsAttachmentContentQuery() { - return Query.query(Criteria.where(EINGANGS_ATTACHMENTS_FILES_CONTENT_FIELD).exists(Boolean.TRUE)); - } - - private UpdateDefinition unsetContent() { - return new Update().unset("eingangs.$[].attachments.$[].files.$[].content"); - - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationContent.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationContent.java deleted file mode 100644 index 1b49cef..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationContent.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; -import org.springframework.data.mongodb.core.query.UpdateDefinition; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-07-08 11:20:00 OZG-2690", order = "M010", author = "jreese", runAlways = true) -public class M010_RemoveRepresentationContent {// NOSONAR - - private static final String COLLECTION = "vorgang"; - private static final String CONTENT_FIELD = "content"; - private static final String REPRESENTATIONS_FIELD = "representations"; - private static final String EINGANGS_FIELD = "eingangs"; - private static final String EINGANGS_REPRESENTATIONS_FIELD = EINGANGS_FIELD + "." + REPRESENTATIONS_FIELD; - private static final String EINGANGS_REPRESENTATIONS_CONTENT_FIELD = EINGANGS_REPRESENTATIONS_FIELD + "." + CONTENT_FIELD; - - @Execution - public void migrationMethod(MongoTemplate template) { - template.updateMulti(findVorgangsAttachmentContentQuery(), unsetContent(), COLLECTION); - } - - Query findVorgangsAttachmentContentQuery() { - return Query.query(Criteria.where(EINGANGS_REPRESENTATIONS_CONTENT_FIELD).exists(Boolean.TRUE)); - } - - private UpdateDefinition unsetContent() { - return new Update().unset("eingangs.$[].representations.$[].content"); - - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAlias.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAlias.java deleted file mode 100644 index a99baf8..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAlias.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.core.query.Query.query; - -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; -import org.springframework.data.mongodb.core.query.UpdateDefinition; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; - -@ChangeUnit(id = "2022-08-01 15:23:00 OZG-2750", order = "M011", author = "tobr", runAlways = true) -public class M011_FixTypeAlias {// NOSONAR - - static final String TYPEKEY_ATTRIBUTE = "_class"; - - static final String COMMAND_TYPE_ALIAS = "Command"; - static final String VORGANG_TYPE_ALIAS = "Vorgang"; - static final String ITEM_TYPE_ALIAS = "VorgangAttachedItem"; - static final String ATTRIBUTE_TYPE_ALIAS = "ClientAttribute"; - - static final String CLIENT_NAME_NACHRICHTEN_MANAGER = "KopNachrichtenManager"; - static final String CLIENT_NAME_ALLGEMEINES_FV = "Goofy"; - - static final String ATTRIBUTES_FIELD_PATH_TEMPLATE = "clientAttributes.%s.%s._class"; - - @Execution - public void doMigration(MongoTemplate template) { - migrateCommands(template); - migrateVorgangs(template); - migrateVorgangAttachedItems(template); - migrateClientAttributes(template); - } - - void migrateCommands(MongoTemplate template) { - template.updateMulti(buildQuery(), buildUpdate(COMMAND_TYPE_ALIAS), "command"); - } - - void migrateVorgangs(MongoTemplate template) { - template.updateMulti(buildQuery(), buildUpdate(VORGANG_TYPE_ALIAS), "vorgang"); - } - - void migrateVorgangAttachedItems(MongoTemplate template) { - template.updateMulti(buildQuery(), buildUpdate(ITEM_TYPE_ALIAS), "vorgangAttachedItem"); - } - - private UpdateDefinition buildUpdate(String typeAlias) { - return new Update().set(TYPEKEY_ATTRIBUTE, typeAlias); - } - - Query buildQuery() { - return query(where(TYPEKEY_ATTRIBUTE).regex("pluto")); - } - - void migrateClientAttributes(MongoTemplate template) { - migrateClientAttribute(CLIENT_NAME_NACHRICHTEN_MANAGER, "hasPostfachNachricht", template); - migrateClientAttribute(CLIENT_NAME_NACHRICHTEN_MANAGER, "hasNewPostfachNachricht", template); - migrateClientAttribute(CLIENT_NAME_ALLGEMEINES_FV, "nextWiedervorlageFrist", template); - } - - void migrateClientAttribute(String clientName, String attributeName, MongoTemplate template) { - var fieldPath = String.format(ATTRIBUTES_FIELD_PATH_TEMPLATE, clientName, attributeName); - - template.updateMulti(buildQueryForAttributes(fieldPath), buildUpdateForAttributes(fieldPath), "vorgang"); - } - - private UpdateDefinition buildUpdateForAttributes(String fieldPath) { - return new Update().set(fieldPath, ATTRIBUTE_TYPE_ALIAS); - } - - Query buildQueryForAttributes(String fieldPath) { - return query(where(fieldPath).regex("pluto")); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } - -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserId.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserId.java deleted file mode 100644 index b2c2676..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserId.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.Objects; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import org.bson.Document; -import org.springframework.core.env.Environment; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import io.mongock.api.annotations.ChangeUnit; -import io.mongock.api.annotations.Execution; -import io.mongock.api.annotations.RollbackExecution; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@ChangeUnit(id = "2022-09-06 10:45:00 OZG-2737", order = "M012", author = "maku", runAlways = true) -public class M012_MigrationUserId {// NOSONAR - - private static final String KOP_USERMANAGER_URL_KEY = "kop.usermanager.url"; - private static final String SYSTEM_USER_PREFIX = "system"; - - static final String COLLECTION_VORGANG_NAME = "vorgang"; - static final String ASSIGNED_TO_FIELD = "assignedTo"; - - static final String COLLECTION_COMMAND_NAME = "command"; - - static final String CREATED_BY_FIELD = "createdBy"; - - static final String COLLECTION_VORGANG_ATTACHED_ITEM_NAME = "vorgangAttachedItem"; - static final String VORGANG_ATTACHED_ITEM_ITEM_FIELD = "item"; - static final String VORGANG_ATTACHED_ITEM_CREATED_BY_FIELD = VORGANG_ATTACHED_ITEM_ITEM_FIELD + "." + CREATED_BY_FIELD; - - static final Pattern UUID_PATTERN = Pattern.compile("-"); - - private MongoTemplate template; - - private RestTemplate restTemplate = new RestTemplate(); - - private String userManagerUrlTemplate; - - @Execution - public void doMigration(MongoTemplate template, Environment environment) { - var userManagerUrl = environment.getProperty(KOP_USERMANAGER_URL_KEY); - - if (Objects.nonNull(userManagerUrl)) { - this.template = template; - this.userManagerUrlTemplate = userManagerUrl + "/%s"; - - migrate(); - } else { - logUrlIsNotConfigured(); - } - } - - private void migrate() { - migrateAssignedTo(); - migrateCommandCreatedBy(); - migrateVorgangAttachedItemCreatedBy(); - } - - void migrateAssignedTo() { - findVorgangWithFilledAssignedTo().forEach(this::updateAssignedTo); - } - - private Stream<Document> findVorgangWithFilledAssignedTo() { - return template.stream(createFindVorgangWithFilledAssignedToQuery(), Document.class, COLLECTION_VORGANG_NAME).stream(); - } - - Query createFindVorgangWithFilledAssignedToQuery() { - return Query.query(Criteria.where(ASSIGNED_TO_FIELD).exists(Boolean.TRUE) - .andOperator(Criteria.where(ASSIGNED_TO_FIELD).regex(UUID_PATTERN))); - } - - private void updateAssignedTo(Document vorgang) { - getNewInternalId(vorgang.getString(ASSIGNED_TO_FIELD)).ifPresent(newId -> doUpdateAssignedTo(vorgang, newId)); - } - - private void doUpdateAssignedTo(Document vorgang, String newId) { - vorgang.put(ASSIGNED_TO_FIELD, newId); - - template.save(vorgang, COLLECTION_VORGANG_NAME); - } - - void migrateCommandCreatedBy() { - findCommandWithCreateBy().forEach(this::updateCreatedBy); - } - - private Stream<Document> findCommandWithCreateBy() { - return template.stream(createFindCommandWithCreatedByQuery(), Document.class, COLLECTION_COMMAND_NAME).stream(); - } - - Query createFindCommandWithCreatedByQuery() { - return Query.query(Criteria.where(CREATED_BY_FIELD).exists(Boolean.TRUE) - .andOperator(Criteria.where(CREATED_BY_FIELD).regex(UUID_PATTERN))); - } - - private void updateCreatedBy(Document command) { - getNewInternalId(command.getString(CREATED_BY_FIELD)).ifPresent(newId -> doUpdateCreatedBy(command, newId)); - } - - private void doUpdateCreatedBy(Document command, String newId) { - command.put(CREATED_BY_FIELD, newId); - - template.save(command, COLLECTION_COMMAND_NAME); - } - - void migrateVorgangAttachedItemCreatedBy() { - findVorgangAttachedItemWithCreatedBy().forEach(this::updateVorgangAttachedItemCreatedBy); - } - - private Stream<Document> findVorgangAttachedItemWithCreatedBy() { - return template.stream(createFindVorgangAttachedItemdWithCreatedByQuery(), Document.class, COLLECTION_VORGANG_ATTACHED_ITEM_NAME).stream(); - } - - Query createFindVorgangAttachedItemdWithCreatedByQuery() { - return Query.query(Criteria.where(VORGANG_ATTACHED_ITEM_CREATED_BY_FIELD).exists(Boolean.TRUE) - .andOperator(Criteria.where(VORGANG_ATTACHED_ITEM_CREATED_BY_FIELD).regex(UUID_PATTERN))); - } - - private void updateVorgangAttachedItemCreatedBy(Document vorgangAttachedItem) { - var itemCreatedBy = ((Document) vorgangAttachedItem.get(VORGANG_ATTACHED_ITEM_ITEM_FIELD)).getString(CREATED_BY_FIELD); - - getNewInternalId(itemCreatedBy).ifPresent(newId -> doUpdateVorgangAttachedItemCreatedBy(vorgangAttachedItem, newId)); - } - - private void doUpdateVorgangAttachedItemCreatedBy(Document vorgangAttachedItem, String newId) { - var item = (Document) vorgangAttachedItem.get(VORGANG_ATTACHED_ITEM_ITEM_FIELD); - item.put(CREATED_BY_FIELD, newId); - vorgangAttachedItem.put(VORGANG_ATTACHED_ITEM_ITEM_FIELD, item); - - template.save(vorgangAttachedItem, COLLECTION_VORGANG_ATTACHED_ITEM_NAME); - } - - private Optional<String> getNewInternalId(String currentId) { - if (currentId.startsWith(SYSTEM_USER_PREFIX)) { - return Optional.empty(); - } - - try { - return Optional.of(getInternalId(currentId)); - } catch (HttpClientErrorException e) { - if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) { - logNotFoundException(e, currentId); - } else { - logHttpException(e, currentId); - } - return Optional.empty(); - - } catch (Exception e) { - logException(e, currentId); - return Optional.empty(); - } - } - - String getInternalId(String currentId) { - return restTemplate.getForEntity(String.format(userManagerUrlTemplate, currentId), String.class).getBody(); - } - - void logNotFoundException(HttpClientErrorException e, String currentId) { - LOG.info(String.format("No matching user found by id %s- proceed without migration.", currentId), e); - } - - void logHttpException(HttpClientErrorException e, String currentId) { - LOG.warn(String.format("Http Error %s while fetching internal id for external id %s. Proceeding with next user id", - e.getStatusCode().name(), currentId), e); - } - - void logException(Exception e, String currentId) { - LOG.error(String.format("Error while fetching internal id for external id %s. Proceeding with next user id", currentId), e); - } - - void logUrlIsNotConfigured() { - LOG.warn("UserManager url is not configured - user migration not started."); - } - - @RollbackExecution - public void rollback() { - // kein rollback implementiert - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImpl.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImpl.java deleted file mode 100644 index 093f964..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImpl.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.search; - -import static de.itvsh.ozg.pluto.common.search.IndexedVorgang.*; -import static org.elasticsearch.index.query.AbstractQueryBuilder.*; -import static org.elasticsearch.index.query.QueryBuilders.*; - -import java.util.Arrays; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.elasticsearch.index.query.BoolQueryBuilder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.support.PageableExecutionUtils; -import org.springframework.stereotype.Repository; - -import de.itvsh.ozg.pluto.vorgang.VorgangHeader; - -@Repository -class SearchVorgangCustomRepositoryImpl implements SearchVorgangCustomRepostitory { - private static final String JOIN_AND = " AND "; - private static final String WILDCARD_PATTERN = "(*%s*)"; - private static final String KEYWORD = ".keyword"; - private static final float HALF_BOOST = 0.5f; - private static final float DOUBLE_BOOST = 2f; - - static final Map<String, Float> FIELD_MAP = Map.of( - FIELD_NAME, HALF_BOOST, - FIELD_VORGANG_NUMMER, DOUBLE_BOOST, - FIELD_AKTENZEICHEN, DOUBLE_BOOST, - FIELD_ANTRAGSTELLER_NAME, DEFAULT_BOOST, - FIELD_ANTRAGSTELLTER_VORNAME, DEFAULT_BOOST); - - @Autowired - private ElasticsearchOperations elasticsearchOperations; - - @Autowired - private IndexedVorgangMapper mapper; - - @Override - public Page<VorgangHeader> searchBy(SearchRequest request) { - var pageable = PageRequest.of(request.getOffSet(), request.getLimit()); - var searchQuery = createQuery(request, pageable); - - var result = elasticsearchOperations.search(searchQuery, IndexedVorgang.class); - var mappedResult = result.get().map(SearchHit::getContent).map(mapper::toVorgangHeader).toList(); - - return PageableExecutionUtils.getPage(mappedResult, pageable, result::getTotalHits); - } - - NativeSearchQuery createQuery(SearchRequest request, PageRequest pageable) { - NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder(); - - setFilter(request, searchQueryBuilder); - - var queryString = Arrays.stream(request.getQuery().strip().split(StringUtils.SPACE)).map( - WILDCARD_PATTERN::formatted).collect(Collectors.joining(JOIN_AND)); - - searchQueryBuilder.withQuery(queryStringQuery(queryString).fields(SearchVorgangCustomRepositoryImpl.FIELD_MAP)); - - return searchQueryBuilder.withPageable(pageable).build(); - } - - private void setFilter(SearchRequest request, NativeSearchQueryBuilder searchQueryBuilder) { - var query = boolQuery(); - - if (request.isFilterByOrganisationseinheitIds()) { - addByOrganisationseinheitIdsFilters(request, query); - } else if (CollectionUtils.isNotEmpty(request.getStatus())) { - query.must(termsQuery(FIELD_STATUS + KEYWORD, request.getStatus())); - } - - searchQueryBuilder.withFilter(query); - } - - private void addByOrganisationseinheitIdsFilters(SearchRequest request, BoolQueryBuilder query) { - query.must(termsQuery(FIELD_ORGANISATIONSEINHEITEN_ID, request.getOrganisationseinheitIds())); - - if (CollectionUtils.isNotEmpty(request.getStatus())) { - query.must(termsQuery(FIELD_STATUS + KEYWORD, request.getStatus())); - } - - if (StringUtils.isNotEmpty(request.getAssignedTo())) { - query.must(termsQuery(FIELD_ASSIGNED_TO + KEYWORD, request.getAssignedTo())); - } - } -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyRepository.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyRepository.java deleted file mode 100644 index 7a63c57..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyRepository.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.security; - -import java.util.Arrays; -import java.util.Collection; - -import org.bson.Document; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.aggregation.Aggregation; -import org.springframework.data.mongodb.core.aggregation.AggregationOperation; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.stereotype.Repository; - -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.vorgang.Vorgang; - -@Repository -class PolicyRepository { - - private static final String VORANG_ID_AS_OBJECT_ID_FIELD = """ - {"$addFields" : {"vorgangObjecId" : {"$toObjectId": "$vorgangId"}}} - """; - private static final String VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD = """ - {"$addFields" : {"vorgangObjecId" : {"$toObjectId": "$metadata.vorgangId"}}} - """; - private static final AggregationOperation ADD_VORGANG_OBJECT_ID_FIELD = context -> org.bson.Document.parse(VORANG_ID_AS_OBJECT_ID_FIELD); - - private static final AggregationOperation ADD_VORGANG_FROM_FILE = context -> org.bson.Document.parse(VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD); - - @Autowired - private MongoTemplate template; - - public boolean existsByCommandId(String commandId, Collection<String> organisationEinheitenIds) { - return evaluateAggregation(buildAggregation(commandId, organisationEinheitenIds, ADD_VORGANG_OBJECT_ID_FIELD), Command.class); - } - - public boolean existsByVorgangAttachedItem(String vorgangAttachedItemId, Collection<String> organisationEinheitenIds) { - return evaluateAggregation(buildAggregation(vorgangAttachedItemId, organisationEinheitenIds, ADD_VORGANG_OBJECT_ID_FIELD), - VorgangAttachedItem.class); - } - - public boolean existsByFileId(String fileId, Collection<String> organisationEinheitenIds) { - return evaluateAggregation(buildAggregation(fileId, organisationEinheitenIds, ADD_VORGANG_FROM_FILE), Document.class, "fs.files"); - } - - private Aggregation buildAggregation(String objectId, Collection<String> organisationEinheitenIds, AggregationOperation operation) { - return Aggregation.newAggregation(Arrays.asList( - matchId(objectId), - operation, - lookupVorgang(), - matchOrganisationEinheitenId(organisationEinheitenIds))); - } - - private boolean evaluateAggregation(Aggregation aggregation, Class<?> givenCollectionClass) { - var foundResult = template.aggregate(aggregation, givenCollectionClass, givenCollectionClass).getMappedResults(); - - return !foundResult.isEmpty(); - } - - private boolean evaluateAggregation(Aggregation aggregation, Class<?> givenCollectionClass, String collectionName) { - var foundResult = template.aggregate(aggregation, collectionName, givenCollectionClass).getMappedResults(); - - return !foundResult.isEmpty(); - } - - private AggregationOperation matchId(String id) { - return Aggregation.match(new Criteria(Vorgang.MONGODB_FIELDNAME_ID).is(id)); - } - - private AggregationOperation lookupVorgang() { - return Aggregation.lookup(Vorgang.COLLECTION_NAME, "vorgangObjecId", "_id", "vorgang"); - } - - private AggregationOperation matchOrganisationEinheitenId(Collection<String> organisationEinheitenIds) { - return Aggregation.match(Criteria.where("vorgang." + Vorgang.FIELD_ORGANISATIONSEINHEIT).in(organisationEinheitenIds)); - } -} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListener.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListener.java deleted file mode 100644 index e1d9b99..0000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListener.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.vorgang; - -import java.util.function.Predicate; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Component; - -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; -import de.itvsh.ozg.pluto.command.Order; -import de.itvsh.ozg.pluto.vorgang.redirect.VorgangForwardFailedEvent; -import de.itvsh.ozg.pluto.vorgang.redirect.VorgangRedirectedEvent; - -@Component -public class VorgangEventListener { - - private static final String IS_ASSIGN_COMMAND_CONDITION = "{T(de.itvsh.ozg.pluto.vorgang.VorgangEventListener).IS_ASSIGN_COMMAND.test(event.getSource())}"; - - public static final Predicate<Command> IS_ASSIGN_COMMAND = command -> Order.ASSIGN_USER.isMeant(command.getOrder()); - - @Autowired - private VorgangService service; - - @EventListener - public void updateStatus(VorgangRedirectedEvent event) { - service.setStatusToWeitergeleitet(event.getSource()); - } - - @EventListener - public void updateStatus(VorgangForwardFailedEvent event) { - service.setStatusToInBearbeitung(event.getSource(), event.getVorgangId()); - } - - @EventListener(condition = IS_ASSIGN_COMMAND_CONDITION) - public void assignToUser(CommandCreatedEvent event) { - service.assignToUser(event.getSource()); - } -} \ No newline at end of file diff --git a/pluto-server/src/main/resources/application-dev.yml b/pluto-server/src/main/resources/application-dev.yml deleted file mode 100644 index 3ca673c..0000000 --- a/pluto-server/src/main/resources/application-dev.yml +++ /dev/null @@ -1,11 +0,0 @@ -spring: - mail: - properties: - "[mail.smtp.starttls.enable]": true - -pluto: - redirect: - mail-from: ea@ozg-sh.de -kop: - notification: - mail-from: ea@ozg-sh.de diff --git a/pluto-server/src/main/resources/application-e2e.yml b/pluto-server/src/main/resources/application-e2e.yml deleted file mode 100644 index f7b0b5a..0000000 --- a/pluto-server/src/main/resources/application-e2e.yml +++ /dev/null @@ -1,12 +0,0 @@ -kop: - osi: - postfach: - scheduler: - enabled: false - proxyapi: - url: mockedForE2E - key: mockedForE2E - realm: mockedForE2E - -mongock: - enabled: false \ No newline at end of file diff --git a/pluto-server/src/main/resources/application-local.yml b/pluto-server/src/main/resources/application-local.yml deleted file mode 100644 index d5fe0c6..0000000 --- a/pluto-server/src/main/resources/application-local.yml +++ /dev/null @@ -1,54 +0,0 @@ -logging: - level: - root: WARN, - "[de.itvsh]": INFO - "[org.elasticsearch.client]": WARN - config: classpath:log4j2-local.xml - -server: - port: 8085 - -management: - server.port: 8083 - health: - elasticsearch: - enabled: false - endpoint: - health: - show-details: always - -spring: - data: - mongodb: - database: pluto-local - mail: - properties: - "[mail.smtp.starttls.enable]": true - elasticsearch: - uris: http://localhost:9200 - -pluto: - redirect: - mail-from: ea@ozg-sh.de - -kop: - osi: - postfach: - scheduler: - enabled: false - fixedDelay: 10000 - proxyapi: - url: https://postfach.serviceportal-stage.schleswig-holstein.de/ApiProxy/V1/Message - realm: urn:osp:names:realm:stage:sh - elasticsearch: - initEnabled: true - index: test-index - notification: - mail-from: ea@ozg-sh.de - usermanager: - url: http://localhost:9092/migration/user - -aktenzeichen: de.itvsh.ozg.pluto.vorgang.AktenzeichenProviderEA - -mongock: - transactionEnabled: false diff --git a/pluto-server/src/main/resources/application-prod.yml b/pluto-server/src/main/resources/application-prod.yml deleted file mode 100644 index 68af29d..0000000 --- a/pluto-server/src/main/resources/application-prod.yml +++ /dev/null @@ -1,6 +0,0 @@ -spring: - mail: - port: 25 - -kop: - production: true diff --git a/pluto-server/src/main/resources/application-test.yml b/pluto-server/src/main/resources/application-test.yml deleted file mode 100644 index a7bacd5..0000000 --- a/pluto-server/src/main/resources/application-test.yml +++ /dev/null @@ -1,8 +0,0 @@ -spring: - mail: - properties: - "[mail.smtp.starttls.enable]": true - -pluto: - redirect: - mail-from: ea@ozg-sh.de diff --git a/pluto-server/src/main/resources/application-withdevdb.yml b/pluto-server/src/main/resources/application-withdevdb.yml deleted file mode 100644 index 30ce9f0..0000000 --- a/pluto-server/src/main/resources/application-withdevdb.yml +++ /dev/null @@ -1,4 +0,0 @@ -spring: - data: - mongodb: - database: pluto-database diff --git a/pluto-server/src/main/resources/banner.txt b/pluto-server/src/main/resources/banner.txt deleted file mode 100644 index 1df2e8a..0000000 --- a/pluto-server/src/main/resources/banner.txt +++ /dev/null @@ -1,5 +0,0 @@ - ___ _ _ _ _____ ___ -| _ \| | | | | ||_ _| / _ \ -| _/| |__ | |_| | | | | (_) | -|_| |____| \___/ |_| \___/ -${spring-boot.version} ${application.version} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepositoryITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepositoryITCase.java deleted file mode 100644 index 483c50b..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepositoryITCase.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.attached_item; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoOperations; - -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; - -@DataITCase -class VorgangAttachedItemRepositoryITCase { - - @Autowired - private VorgangAttachedItemRepository repository; - @Autowired - private MongoOperations mongoOperations; - - private VorgangAttachedItem persistedItem; - - @BeforeEach - void prepareDatabase() { - mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); - } - - @DisplayName("Find by") - @Nested - class TestFindBy { - - @BeforeEach - void init() { - persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); - } - - @Nested - class VorgangIdAndClientAndItemName { - - @Test - void shouldReturnResult() { - var loadedItems = repository.findByVorgangIdAndClientAndItemName(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.CLIENT, - VorgangAttachedItemTestFactory.ITEM_NAME); - - assertThat(loadedItems).hasSize(1); - } - } - - @Nested - class VorgangIdAndClient { - - @Test - void shouldReturnResult() { - var loadedItems = repository.findByVorgangIdAndClient(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.CLIENT); - - assertThat(loadedItems).hasSize(1); - } - } - - @Nested - class VorgangIdAndItemName { - - @Test - void shouldReturnResult() { - var loadedItems = repository.findByVorgangIdAndItemName(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.ITEM_NAME); - - assertThat(loadedItems).hasSize(1); - } - } - - @Nested - class VorgangId { - - @Test - void shouldReturnResult() { - var loadedItems = repository.findByVorgangId(VorgangTestFactory.ID); - - assertThat(loadedItems).hasSize(1); - } - } - } - - @Nested - class TestPatch { - - @BeforeEach - void prepareDatabase() { - mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); - - persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); - } - - @Test - void shouldUpdateFieldValue() { - repository.patch(persistedItem.getId(), persistedItem.getVersion(), buildPatchMap()); - - var loaded = findVorgangAttachedItem(); - assertThat(loaded).isNotNull(); - assertThat(loaded.getItem()).containsOnly( - entry("dontTouch", 600), - entry(VorgangAttachedItemTestFactory.ITEM_FIELD_NAME, VorgangAttachedItemTestFactory.ITEM_FIELD_STRING_VALUE)); - } - - @Test - void shouldIncreaseVersion() { - repository.patch(persistedItem.getId(), persistedItem.getVersion(), buildPatchMap()); - - var loaded = findVorgangAttachedItem(); - assertThat(loaded).isNotNull(); - assertThat(loaded.getVersion()).isEqualTo(persistedItem.getVersion() + 1); - } - - @Test - void shouldNotUpdateOnWrongVersion() { - repository.patch(persistedItem.getId(), 42, buildPatchMap()); - - var loaded = findVorgangAttachedItem(); - - assertThat(loaded).usingRecursiveComparison().isEqualTo(persistedItem); - } - - private Map<String, Object> buildPatchMap() { - return Map.of("dontTouch", 600); - } - } - - private VorgangAttachedItem findVorgangAttachedItem() { - return mongoOperations.findById(persistedItem.getId(), VorgangAttachedItem.class); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandRepositoryITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandRepositoryITCase.java deleted file mode 100644 index cad79be..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandRepositoryITCase.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.command; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Collections; -import java.util.Optional; -import java.util.UUID; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoOperations; - -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; - -@DataITCase -class CommandRepositoryITCase { - - @Autowired - private CommandRepository repository; - @Autowired - private MongoOperations mongoOperations; - - @BeforeEach - void clearDB() { - mongoOperations.dropCollection(Command.class); - } - - @Nested - class TestSave { - - @Test - void shouldSave() { - repository.save(CommandTestFactory.create()); - - verifyCommandExists(CommandTestFactory.ID); - } - - @Test - void shouldGenerateIdOnSave() { - Command command = repository.save(CommandTestFactory.createBuilder().id(null).build()); - - verifyCommandExists(command.getId()); - } - - private void verifyCommandExists(String id) { - Command command = mongoOperations.findById(id, Command.class); - - assertThat(command).isNotNull(); - assertThat(command.getId()).isEqualTo(id); - } - } - - @Nested - class TestGetById { - - private final String ADDITIONAL_COMMAND_ID = UUID.randomUUID().toString(); - - @BeforeEach - void persistAdditionalCommandToVorgang() { - mongoOperations.save(CommandTestFactory.create()); - } - - @Test - void shouldFindCommand() { - verifyCommandExists(CommandTestFactory.ID); - } - - @Test - void shouldFindAdditionalCommand() { - mongoOperations.save(CommandTestFactory.createBuilder().id(ADDITIONAL_COMMAND_ID).build()); - - verifyCommandExists(ADDITIONAL_COMMAND_ID); - } - - private void verifyCommandExists(String id) { - Optional<Command> command = repository.getById(id); - - assertThat(command).isPresent(); - assertThat(command.get().getId()).isEqualTo(id); - } - } - - @Nested - class TestUpdateCommandStatus { - - @BeforeEach - void persistVorgangWithCommand() { - repository.save(CommandTestFactory.create()); - } - - @ParameterizedTest - @EnumSource(CommandStatus.class) - void shouldUpdateCommandStatus(CommandStatus status) { - repository.updateCommandStatus(CommandTestFactory.ID, status); - - Optional<Command> command = repository.getById(CommandTestFactory.ID); - - assertThat(command).isPresent(); - assertThat(command.get().getStatus()).isEqualTo(status); - } - } - - @Nested - class TestUpdateCommandStatusAndVersion { - - @BeforeEach - void persistVorgangWithCommand() { - repository.save(CommandTestFactory.create()); - } - - @ParameterizedTest - @EnumSource(CommandStatus.class) - void shouldUpdateCommandStatus(CommandStatus status) { - repository.updateCommandStatusAndVersion(CommandTestFactory.ID, status, 78L); - - Optional<Command> command = repository.getById(CommandTestFactory.ID); - - assertThat(command).isPresent(); - assertThat(command.get().getRelationVersion()).isEqualTo(78L); - assertThat(command.get().getStatus()).isEqualTo(status); - } - } - - @Nested - class TestGetPendingCommands { - - @BeforeEach - void persistCommand() { - repository.save(CommandTestFactory.create()); - repository.save(CommandTestFactory.createBuilder().id(null).vorgangId(VorgangTestFactory.ID).status(CommandStatus.FINISHED).build()); - } - - @Test - void shouldReturnPendingCommand() { - var result = repository.getPendingCommands(VorgangTestFactory.ID); - - assertThat(result).hasSize(1); - assertThat(result.get(0).getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); - assertThat(result.get(0).getStatus()).isEqualTo(CommandStatus.PENDING); - } - } - - @Nested - class TestFindCommands { - - @Test - void shouldReturnCommandByVorgang() { - repository.save(CommandTestFactory.create()); - - var commands = repository.findCommands(VorgangTestFactory.ID, Collections.emptyList(), Optional.empty()); - - assertThat(commands).hasSize(1); - } - - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationIdMigrationITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationIdMigrationITCase.java deleted file mode 100644 index 1338410..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M000_AddOrganisationIdMigrationITCase.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; - -import java.util.List; - -import org.bson.Document; -import org.bson.types.ObjectId; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M000_AddOrganisationIdMigrationITCase { - - private final M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing migrator = new M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing(); - - @Autowired - private MongoTemplate template; - - private Document vorgangToMigrate; - private Document vorgangNotToMigrate; - - @BeforeEach - public void init() { - template.dropCollection(MigrationDbTestUtils.VORGANG_COLLECTION); - - vorgangNotToMigrate = template.save(MigrationVorgangTestFactory.create(), MigrationDbTestUtils.VORGANG_COLLECTION); - vorgangToMigrate = template.save(createVorgangToMigrate(), MigrationDbTestUtils.VORGANG_COLLECTION); - } - - private Document createVorgangToMigrate() { - var eingangHeader = MigrationEingangHeaderTestFactory.create(); - eingangHeader.put(MigrationEingangHeaderTestFactory.FIELD_CUSTOMER_ID, - M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.CUSTOMER_ID); - eingangHeader.put(MigrationEingangHeaderTestFactory.FIELD_FORM_ID, - M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.FORM_ID_BAULASTENAUSKUNFT); - - var eingang = MigrationEingangTestFactory.create(); - eingang.put(MigrationEingangTestFactory.FIELD_HEADER, eingangHeader); - eingang.remove(MigrationEingangTestFactory.FIELD_ZUSTAENDIDGESTELLE); - - var vorgang = MigrationVorgangTestFactory.create(); - vorgang.put(MigrationVorgangTestFactory.FIELD_EINGANGS, List.of(eingang)); - - return vorgang; - } - - @Test - void shouldMigrate() { - migrator.migrationMethod(template); - - var organisationseinheitenId = getOrganisationeinheitenId(getVorgang(MigrationTestUtils.getObjectId(vorgangToMigrate))); - assertThat(organisationseinheitenId).isEqualTo(M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.ORGANISATIONSEINHEITEN_ID); - } - - @Test - void shoulNotMigrate() { - migrator.migrationMethod(template); - - var organisationseinheitenId = getOrganisationeinheitenId(getVorgang(MigrationTestUtils.getObjectId(vorgangNotToMigrate))); - assertThat(organisationseinheitenId).isNotEqualTo(M000_AddOrganisationseinheitenIdForNordfrieslandWhenMissing.ORGANISATIONSEINHEITEN_ID); - } - - private Object getOrganisationeinheitenId(Document vorgang) { - return getZustaendigeStelle(vorgang).get(MigrationZustaendigeStelleTestFactory.FIELD_ORGANISATIONSEINHEITEN_ID); - } - - private Document getZustaendigeStelle(Document vorgang) { - return (Document) MigrationTestUtils.getList(vorgang, MigrationVorgangTestFactory.FIELD_EINGANGS).get(0) - .get(MigrationEingangTestFactory.FIELD_ZUSTAENDIDGESTELLE); - } - - private Document getVorgang(ObjectId vorgangId) { - return MigrationDbTestUtils.getVorgang(template, vorgangId); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsITCase.java deleted file mode 100644 index 6b0dd6e..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M001_MigrateMailServiceAttachmentsToGridFsITCase.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.gridfs.GridFsTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M001_MigrateMailServiceAttachmentsToGridFsITCase { - - @Spy - private M001_MigrateMailServiceAttachmentsToGridFs migrator = new M001_MigrateMailServiceAttachmentsToGridFs(); - - @Autowired - private MongoTemplate template; - @Autowired - private GridFsTemplate gridFsTemplate; - - private Document binaryFileToMigrate; - private Document binaryFileNotToMigrate; - - @BeforeEach - public void init() { - template.dropCollection(MigrationDbTestUtils.BINARY_FILE_COLLECTION); - template.dropCollection(MigrationDbTestUtils.GRID_FS_FILES_COLLECTION); - template.dropCollection(MigrationDbTestUtils.GRID_FS_CHUNKS_COLLECTION); - - binaryFileToMigrate = MigrationDbTestUtils.saveBinaryFile(template, MigrationBinaryFileTestFactory.create()); - binaryFileNotToMigrate = MigrationDbTestUtils.saveBinaryFile(template, MigrationBinaryFileTestFactory.create()); - - saveVorgangAttachedItem(); - } - - private void saveVorgangAttachedItem() { - var vorgangAttachedItem = MigrationVorgangAttachedItemTestFactory.create(); - vorgangAttachedItem.put(MigrationVorgangAttachedItemTestFactory.FIELD_ITEM, - Map.of("attachments", List.of(MigrationTestUtils.getObjectId(binaryFileToMigrate).toString()))); - - MigrationDbTestUtils.saveVorgangAttachedItem(template, vorgangAttachedItem); - } - - @Test - void shouldHaveFilePath() { - migrate(); - - var expectedPath = String.format("%s/%s/%s/%s", - MigrationBinaryFileTestFactory.VORGANG_ID, - MigrationBinaryFileTestFactory.CLIENT, - MigrationBinaryFileTestFactory.FIELD, MigrationIncomingFileTestFactory.NAME); - - var gridFsFile = MigrationDbTestUtils.getGridFsFile(gridFsTemplate, MigrationTestUtils.getObjectId(binaryFileToMigrate)); - assertThat(gridFsFile.getFilename()).isEqualTo(expectedPath); - } - - @Test - void shouldHaveMetadata() { - migrate(); - - var gridFsFile = MigrationDbTestUtils.getGridFsFile(gridFsTemplate, MigrationTestUtils.getObjectId(binaryFileToMigrate)); - var metadata = gridFsFile.getMetadata(); - assertThat(metadata.getString(MigrationGridFSFileTestFactory.FIELD_CLIENT)) - .isEqualTo(MigrationBinaryFileTestFactory.CLIENT); - assertThat(metadata.getString(MigrationGridFSFileTestFactory.FIELD_VORGANG_ID)).isEqualTo(MigrationBinaryFileTestFactory.VORGANG_ID); - assertThat(metadata.getString(MigrationGridFSFileTestFactory.FIELD_FIELD_NAME)).isEqualTo(MigrationBinaryFileTestFactory.FIELD); - assertThat(metadata.getString(MigrationGridFSFileTestFactory.FIELD_CONTENT_TYPE)) - .isEqualTo(MigrationIncomingFileTestFactory.CONTENT_TYPE); - assertThat(metadata.getString(MigrationGridFSFileTestFactory.FIELD_NAME)).isEqualTo(MigrationIncomingFileTestFactory.NAME); - } - - @Test - void shouldHaveContent() throws IOException { - migrate(); - - var gridFsResource = MigrationDbTestUtils.getGridFsResource(gridFsTemplate, MigrationTestUtils.getObjectId(binaryFileToMigrate)); - assertThat(gridFsResource.getContent().readAllBytes()).isEqualTo(MigrationIncomingFileTestFactory.CONTENT); - } - - @Test - void shouldNotHaveBeenMigrated() { - migrate(); - - var binaryFileId = MigrationTestUtils.getObjectId(binaryFileNotToMigrate).toString(); - var binaryFile = MigrationDbTestUtils.getBinaryFile(template, binaryFileId); - assertThat(MigrationTestUtils.getObjectId(binaryFile)).hasToString(binaryFileId); - } - - @Test - void shouldNotStopOnExceptionWhenMigrationASecondTime() { - migrate(); - - assertThatNoException().isThrownBy(this::migrate); - } - - @Test - void shouldThrowException() throws IOException { - doThrow(new IOException("Test")).when(migrator).storeToGridFs(any(), any()); - - assertThatThrownBy(this::migrate).isInstanceOf(RuntimeException.class); - } - - private void migrate() { - migrator.migrationMethod(template); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangsITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangsITCase.java deleted file mode 100644 index 1d840e8..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangsITCase.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; - -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M002_SetInCreationFalseForAllVorgangsITCase { // NOSONAR - - private final M002_SetInCreationFalseForAllVorgangs migrator = new M002_SetInCreationFalseForAllVorgangs(); - - @Autowired - private MongoTemplate template; - - private Document vorgangNotToMigrate; - private Document vorgangToMigrate; - - @BeforeEach - public void init() { - MigrationDbTestUtils.dropVorgangCollection(template); - - vorgangNotToMigrate = MigrationDbTestUtils.saveVorgang(template, createVorgangNotToMigrate()); - vorgangToMigrate = MigrationDbTestUtils.saveVorgang(template, createVorgangToMigrate()); - } - - private Document createVorgangNotToMigrate() { - var vorgang = MigrationVorgangTestFactory.create(); - vorgang.put(MigrationVorgangTestFactory.FIELD_IN_CREATION, true); - - return vorgang; - } - - private Document createVorgangToMigrate() { - var vorgang = MigrationVorgangTestFactory.create(); - vorgang.remove(MigrationVorgangTestFactory.FIELD_IN_CREATION); - - return vorgang; - } - - @Test - void shouldMigrate() { - migrator.migrationMethod(template); - - var vorgangDocument = MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgangToMigrate)); - - assertThat(vorgangDocument).containsEntry(MigrationVorgangTestFactory.FIELD_IN_CREATION, Boolean.FALSE); - } - - @Test - void shoulNotMigrate() { - migrator.migrationMethod(template); - - var vorgangDocument = MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgangNotToMigrate)); - - assertThat(vorgangDocument).containsEntry(MigrationVorgangTestFactory.FIELD_IN_CREATION, Boolean.TRUE); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFsITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFsITCase.java deleted file mode 100644 index 0b8c6a6..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M003_MigrateVorgangAttachmentsAndRepresentationsToGridFsITCase.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static de.itvsh.ozg.pluto.common.migration.M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs.*; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.io.IOException; - -import org.apache.commons.lang3.StringUtils; -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.gridfs.GridFsTemplate; - -import com.mongodb.client.gridfs.model.GridFSFile; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M003_MigrateVorgangAttachmentsAndRepresentationsToGridFsITCase {// NOSONAR - - @Spy - private M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs migrator = new M003_MigrateVorgangAttachmentsAndRepresentationsToGridFs(); - @Autowired - private MongoTemplate template; - @Autowired - private GridFsTemplate gridFsTemplate; - - private Document vorgang; - - @BeforeEach - void init() { - template.dropCollection(MigrationDbTestUtils.GRID_FS_FILES_COLLECTION); - template.dropCollection(MigrationDbTestUtils.GRID_FS_CHUNKS_COLLECTION); - template.dropCollection(MigrationDbTestUtils.VORGANG_COLLECTION); - - vorgang = MigrationDbTestUtils.saveVorgang(template, MigrationVorgangTestFactory.create()); - } - - @Test - void shouldNotStopOnExceptionWhenMigrationASecondTime() { - doMigration(); - - doMigration(); - - assertThatNoException().isThrownBy(this::doMigration); - } - - @Test - void shouldThrowException() throws IOException { - doThrow(new IOException("Test Migration Exception")).when(migrator).storeToGridFs(any(), any(), any(), any()); - - assertThatThrownBy(this::doMigration).isInstanceOf(IllegalStateException.class); - } - - @Nested - class TestAttachmentMigration { - - @Nested - class TestFirstAttachmentFile { - - private final static String NAME = MigrationAttachmentTestFactory.ATTACHMENT_FILE_NAME; - - @Test - void shouldKeepDataInVorgangAttachment() { - doMigration(); - - var attachment = getAttachment(getIdOfCreatedGridFsFile(ATTACHMENT_FIELD_NAME_VALUE, NAME)); - assertThat(attachment.getString(MigrationIncomingFileTestFactory.FIELD_CONTENT_TYPE)) - .isEqualTo(MigrationIncomingFileTestFactory.CONTENT_TYPE); - assertThat(attachment.getString(MigrationIncomingFileTestFactory.FIELD_NAME)).isEqualTo(NAME); - assertThat(attachment.getLong(MigrationIncomingFileTestFactory.FIELD_SIZE)).isEqualTo(MigrationIncomingFileTestFactory.SIZE); - } - - @Test - void shouldUpdateAttachmentFileId() { - doMigration(); - - var gridFsFileId = getIdOfCreatedGridFsFile(ATTACHMENT_FIELD_NAME_VALUE, NAME); - var attachment = getAttachment(gridFsFileId); - assertThat(gridFsFileId).isEqualTo(attachment.getString(OBJECT_ID)); - } - - @Nested - class TestCreatedGridFs { - - @Test - void shouldHaveAttachmentFilePath() { - doMigration(); - - var expectedFilename = buildAttachmentFilename(NAME); - var migratedFilename = getGridFsFile(expectedFilename).getFilename(); - assertThat(migratedFilename).isEqualTo(expectedFilename); - } - - @Test - void shouldHaveGridFsFileMetadata() { - doMigration(); - - var gridFsFile = getGridFsFile(buildAttachmentFilename(NAME)); - var metadata = gridFsFile.getMetadata(); - assertThat(metadata.getString(CLIENT)).isEqualTo(CLIENT_VALUE); - assertThat(metadata.getString(VORGANG_ID)).isEqualTo(MigrationTestUtils.getObjectId(vorgang).toHexString()); - assertThat(metadata.getString(FILE_FIELD_NAME)).isEqualTo(ATTACHMENT_FIELD_NAME_VALUE); - } - - @Test - void shouldHaveAttachmentContent() throws IOException { - doMigration(); - - var gridFsFileContent = getGridFsFileContent(getGridFsFile(buildAttachmentFilename(NAME))); - assertThat(gridFsFileContent).isEqualTo(MigrationIncomingFileTestFactory.CONTENT); - } - } - } - - @Nested - class TestSecondAttachmentFile { - - private final static String NAME = MigrationAttachmentTestFactory.ATTACHMENT_FILE_NAME2; - - @Test - void shouldKeepDataInVorgang() { - doMigration(); - - var attachment = getAttachment(getIdOfCreatedGridFsFile(ATTACHMENT_FIELD_NAME_VALUE, NAME)); - assertThat(attachment.getString(MigrationIncomingFileTestFactory.FIELD_CONTENT_TYPE)) - .isEqualTo(MigrationIncomingFileTestFactory.CONTENT_TYPE); - assertThat(attachment.getString(MigrationIncomingFileTestFactory.FIELD_NAME)).isEqualTo(NAME); - assertThat(attachment.getLong(MigrationIncomingFileTestFactory.FIELD_SIZE)).isEqualTo(MigrationIncomingFileTestFactory.SIZE); - } - - @Test - void shouldUpdateAttachmentFileId() { - doMigration(); - - var gridFsFileId = getIdOfCreatedGridFsFile(ATTACHMENT_FIELD_NAME_VALUE, NAME); - var attachment = getAttachment(gridFsFileId); - assertThat(gridFsFileId).isEqualTo(attachment.getString(OBJECT_ID).toString()); - } - - @Nested - class TestCreatedGridFs { - - @Test - void shouldHaveAttachmentFilePath() { - doMigration(); - - var expectedFilename = buildAttachmentFilename(NAME); - var gridFsFile = getGridFsFile(expectedFilename); - var migratedFilename = gridFsFile.getFilename(); - assertThat(migratedFilename).isEqualTo(expectedFilename); - } - - @Test - void shouldHaveGridFsFileMetadata() { - doMigration(); - - var gridFsFileMetadata = getGridFsFile(buildAttachmentFilename(NAME)).getMetadata(); - assertThat(gridFsFileMetadata.getString(CLIENT)).isEqualTo(CLIENT_VALUE); - assertThat(gridFsFileMetadata.getString(VORGANG_ID)).isEqualTo(MigrationTestUtils.getObjectId(vorgang).toHexString()); - assertThat(gridFsFileMetadata.getString(FILE_FIELD_NAME)).isEqualTo(ATTACHMENT_FIELD_NAME_VALUE); - } - - @Test - void shouldHaveAttachmentContent() throws IOException { - doMigration(); - - var gridFsFileContent = getGridFsFileContent(getGridFsFile(buildAttachmentFilename(NAME))); - assertThat(gridFsFileContent).isEqualTo(MigrationIncomingFileTestFactory.CONTENT); - } - } - } - - private Document getAttachment(String gridFsFileId) { - var attachments = getVorgang().getList(MigrationVorgangTestFactory.FIELD_EINGANGS, Document.class).get(0) - .getList(MigrationEingangTestFactory.FIELD_ATTACHMENTS, Document.class); - return attachments.stream() - .flatMap(oneattachment -> oneattachment.getList("files", Document.class).stream()) - .filter(attachmentFile -> StringUtils.equals(attachmentFile.getString(OBJECT_ID), gridFsFileId)) - .toList().get(0); - } - } - - @Nested - class TestRepresentationMigration { - - private final static String NAME = MigrationIncomingFileTestFactory.NAME; - - @Test - void shouldKeepDataInVorgang() { - doMigration(); - - var representation = getRepresentation(getVorgang(), getIdOfCreatedGridFsFile()); - assertThat(representation.getString(MigrationIncomingFileTestFactory.FIELD_CONTENT_TYPE)) - .isEqualTo(MigrationIncomingFileTestFactory.CONTENT_TYPE); - assertThat(representation.getString(MigrationIncomingFileTestFactory.FIELD_NAME)).isEqualTo(NAME); - assertThat(representation.getLong(MigrationIncomingFileTestFactory.FIELD_SIZE)).isEqualTo(MigrationIncomingFileTestFactory.SIZE); - } - - @Test - void shouldUpdateRepresentationFileId() { - doMigration(); - - var gridFsFileId = getIdOfCreatedGridFsFile(); - var representation = getRepresentation(getVorgang(), gridFsFileId); - assertThat(gridFsFileId).isEqualTo(representation.getString(OBJECT_ID)); - } - - private String getIdOfCreatedGridFsFile() { - var gridFsFile = getGridFsFile(buildRepresentationFilename()); - var gridFsFileId = gridFsFile.getId().asObjectId().getValue().toHexString(); - return gridFsFileId; - } - - @Nested - class TestCreatedGridFs { - - @Test - void shouldHaveRepresentationFilePath() { - doMigration(); - - var expectedFilename = buildRepresentationFilename(); - var gridFsFile = getGridFsFile(buildRepresentationFilename()); - var migratedFilename = gridFsFile.getFilename(); - assertThat(migratedFilename).isEqualTo(expectedFilename); - } - - @Test - void shouldSetGridFsFileMetadata() { - doMigration(); - - var gridFsFile = getGridFsFile(buildRepresentationFilename()); - var metadata = gridFsFile.getMetadata(); - assertThat(metadata.getString(CLIENT)).isEqualTo(CLIENT_VALUE); - assertThat(metadata.getString(VORGANG_ID)).isEqualTo(MigrationTestUtils.getObjectId(vorgang).toHexString()); - assertThat(metadata.getString(FILE_FIELD_NAME)).isEqualTo(REPRESENTATION_FIELD_NAME_VALUE); - } - - @Test - void shouldHaveRepresentationContent() throws IOException { - doMigration(); - - var gridFsFileContent = getGridFsFileContent(getGridFsFile(buildRepresentationFilename())); - assertThat(gridFsFileContent).isEqualTo(MigrationIncomingFileTestFactory.CONTENT); - } - } - - private Document getRepresentation(Document vorgang, String gridFsFileId) { - var representations = vorgang.getList(MigrationVorgangTestFactory.FIELD_EINGANGS, Document.class).get(0) - .getList(MigrationEingangTestFactory.FIELD_REPRESENTATIONS, Document.class); - return representations.stream() - .filter(representationFile -> StringUtils.equals(representationFile.getString(OBJECT_ID), gridFsFileId)) - .toList().get(0); - } - - private String buildRepresentationFilename() { - return buildFilename(REPRESENTATION_FIELD_NAME_VALUE, NAME); - } - } - - private byte[] getGridFsFileContent(GridFSFile gridFsFile) throws IOException { - return gridFsTemplate.getResource(gridFsFile).getContent().readAllBytes(); - } - - private Document getVorgang() { - return MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgang)); - } - - private String buildFilename(String fieldValue, String name) { - return String.format("%s/%s/%s/%s", - MigrationTestUtils.getObjectId(vorgang).toHexString(), - CLIENT_VALUE, - fieldValue, - name); - } - - private GridFSFile getGridFsFile(String filename) { - return MigrationDbTestUtils.getGridFsFile(gridFsTemplate, filename); - } - - private String getIdOfCreatedGridFsFile(String fieldName, String name) { - var filename = buildFilename(fieldName, name); - return getGridFsFile(filename).getId().asObjectId().getValue().toHexString(); - } - - private String buildAttachmentFilename(String name) { - return buildFilename(ATTACHMENT_FIELD_NAME_VALUE, name); - } - - private void doMigration() { - migrator.migrationMethod(template); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagenITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagenITCase.java deleted file mode 100644 index 95b6a0c..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M004_RemoveWiedervorlagenITCase.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static de.itvsh.ozg.pluto.common.migration.M004_RemoveWiedervorlagen.*; -import static org.assertj.core.api.Assertions.*; - -import java.util.List; - -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M004_RemoveWiedervorlagenITCase {// NOSONAR - - private static final String OTHER_FIELD_ID_VALUE = "postfachNachrichtAttachment"; - - @Spy - private M004_RemoveWiedervorlagen migrator = new M004_RemoveWiedervorlagen(); - - @Autowired - private MongoTemplate template; - - private Document vorgang; - - @BeforeEach - public void init() { - MigrationDbTestUtils.dropBinaryFileCollection(template); - MigrationDbTestUtils.dropVorgangCollection(template); - - vorgang = MigrationDbTestUtils.saveVorgang(template, createVorgangWithWiedervorlage()); - - MigrationDbTestUtils.saveBinaryFile(template, createBinaryFile(FIELD_KEY_VALUE)); - MigrationDbTestUtils.saveBinaryFile(template, createBinaryFile(OTHER_FIELD_ID_VALUE)); - } - - private Document createVorgangWithWiedervorlage() { - var vorgang = MigrationVorgangTestFactory.create(); - vorgang.put(MigrationVorgangTestFactory.FIELD_WIEDERVORLAGES, List.of(MigrationWiedervorlageTestFactory.create())); - return vorgang; - } - - private Document createBinaryFile(String fieldValue) { - var binaryFileDoc = MigrationBinaryFileTestFactory.create(); - binaryFileDoc.put(MigrationBinaryFileTestFactory.FIELD_VORGANG_ID, MigrationTestUtils.getObjectId(vorgang).toHexString()); - binaryFileDoc.put(MigrationBinaryFileTestFactory.FIELD_CLIENT, "goofy"); - binaryFileDoc.put(MigrationBinaryFileTestFactory.FIELD_FIELD, fieldValue); - - return binaryFileDoc; - } - - @Test - void shouldRemoveWiedervorlageAttachment() { - migrate(); - - var wiedervorlageAttachments = findBinaryFile(FIELD_KEY_VALUE); - assertThat(wiedervorlageAttachments).isEmpty(); - } - - @Test - void shouldRemoveWiedervorlages() { - migrate(); - - var migratedVorgang = MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgang)); - assertThat(migratedVorgang.get(WIEDERVORLAGES_FIELD_KEY)).isNull(); - } - - @Test - void shouldNotRemovePostfachNachrichtAttachment() { - migrate(); - - var postfachNachrichtAttachments = findBinaryFile(OTHER_FIELD_ID_VALUE); - assertThat(postfachNachrichtAttachments).isNotEmpty(); - - } - - private void migrate() { - migrator.migrationMethod(template); - } - - private List<Document> findBinaryFile(String fieldValue) { - return MigrationDbTestUtils.findBinaryFile(template, new Query(Criteria.where(FIELD_KEY).is(fieldValue))); - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgangITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgangITCase.java deleted file mode 100644 index ac795a9..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M005_CreateIndexesInVorgangITCase.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M005_CreateIndexesInVorgangITCase { - - @InjectMocks - private M005_CreateIndexesInVorgang migration; - - @Autowired - private MongoTemplate template; - - @BeforeEach - void clearDb() { - template.indexOps(MigrationDbTestUtils.VORGANG_COLLECTION).dropAllIndexes(); - } - - @Test - void shouldCreateIndexes() { - migration.createIndexes(template); - - var indexInfos = template.indexOps(MigrationDbTestUtils.VORGANG_COLLECTION).getIndexInfo(); - assertThat(indexInfos).hasSize(3); - } - - @Nested - class TestCreateIndexWithoutStatus { - @Test - void shouldCreateIndex() { - migration.createIndexWithoutStatus(template); - - var indexInfos = template.indexOps(MigrationDbTestUtils.VORGANG_COLLECTION).getIndexInfo(); - assertThat(indexInfos).hasSize(2); - } - } - - @Nested - class TestCreateIndexWithStatus { - @Test - void shouldCreateIndex() { - migration.createIndexWithStatus(template); - - var indexInfos = template.indexOps(MigrationDbTestUtils.VORGANG_COLLECTION).getIndexInfo(); - assertThat(indexInfos).hasSize(2); - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentarITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentarITCase.java deleted file mode 100644 index 4423425..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M006_MigrateKommentarITCase.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; - -import java.util.List; - -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M006_MigrateKommentarITCase { - - @Spy - private M006_MigrateKommentar migrator = new M006_MigrateKommentar(); - - @Autowired - private MongoTemplate template; - - private Document savedVorgang; - - @BeforeEach - void initKommentar() { - MigrationDbTestUtils.dropVorgangCollection(template); - MigrationDbTestUtils.dropVorgangAttachedItemCollection(template); - - var vorgang = MigrationVorgangTestFactory.create(); - vorgang.put(MigrationVorgangTestFactory.FIELD_KOMMENTARS, List.of(MigrationKommentarTestFactory.create())); - savedVorgang = MigrationDbTestUtils.saveVorgang(template, vorgang); - } - - @DisplayName("Migrate Kommentare") - @Nested - class TestMigrateKommentar { - - @Nested - class CreateAttachedItem { - - @Test - void shouldExists() { - migrator.migrationMethod(template); - - var kommentarAsAttachedItem = getKommentare(); - - assertThat(kommentarAsAttachedItem).isNotEmpty().hasSize(1); - } - - @Test - void shouldContainsData() { - migrator.migrationMethod(template); - - var kommentarAsAttachedItem = getKommentare().get(0); - - assertThat(kommentarAsAttachedItem) - .containsEntry(MigrationVorgangAttachedItemTestFactory.FIELD_ITEM_NAME, M006_MigrateKommentar.ATTACHED_ITEM_ITEM_NAME) - .containsEntry(MigrationVorgangAttachedItemTestFactory.FIELD_CLIENT, M006_MigrateKommentar.ATTACHED_ITEM_CLIENT) - .containsEntry(MigrationVorgangAttachedItemTestFactory.VERSION_FIELD, M006_MigrateKommentar.ATTACHED_ITEM_VERSION); - } - - @Test - void shouldContainsItemData() { - migrator.migrationMethod(template); - - var kommentarAsAttachedItem = getKommentare().get(0); - var item = (Document) kommentarAsAttachedItem.get(MigrationVorgangAttachedItemTestFactory.FIELD_ITEM); - - assertThat(item) - .containsEntry(MigrationKommentarTestFactory.CREATED_AT_FIELD, MigrationKommentarTestFactory.CREATED_AT_STR) - .containsEntry(MigrationKommentarTestFactory.CREATED_BY_FIELD, MigrationKommentarTestFactory.CREATED_BY) - .containsEntry(MigrationKommentarTestFactory.TEXT_FIELD, MigrationKommentarTestFactory.TEXT); - } - - @Test - void shouldNotMigrateTwice() { - migrator.migrationMethod(template); - - migrator.migrationMethod(template); - - assertThat(getKommentare()).hasSize(1); - - } - - private List<Document> getKommentare() { - return MigrationDbTestUtils.getVorgangAttachedItem(template, "itemName", "Kommentar"); - } - } - - @Nested - class DataAtVorgang { - - @Test - void shouldStillExists() { - migrator.migrationMethod(template); - - var kommentarAtVorgang = getKommentare(); - - assertThat(kommentarAtVorgang).isNotEmpty().hasSize(1); - } - - @Test - void shouldKeptData() { - migrator.migrationMethod(template); - - var kommentarAtVorgang = getKommentare().get(0); - - assertThat(kommentarAtVorgang).usingRecursiveComparison().isEqualTo(MigrationKommentarTestFactory.create()); - } - - private List<Document> getKommentare() { - var vorgang = MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(savedVorgang)); - return MigrationTestUtils.getList(vorgang, MigrationVorgangTestFactory.FIELD_KOMMENTARS); - } - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommandsITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommandsITCase.java deleted file mode 100644 index 59bf2ed..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommandsITCase.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.UUID; - -import org.bson.Document; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommandsITCase { - - private final M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands migrator = new M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands(); - - @Autowired - private MigrationDbTestUtils dbTestUtils; - @Autowired - private MongoTemplate template; - - private Document kommentarCommandToUpdate; - private Document wiedervorlageCommandToUpdate; - private Document doNotMigrateCommandByWrongOrder; - private Document doNotMigrateCommandByValidRelationId; - - @BeforeEach - void initDatabase() { - dbTestUtils.dropCommandCollection(); - - kommentarCommandToUpdate = dbTestUtils.saveCommand(M007_MigrationTestFactory.createCommandWithKommentarAsBody()); - wiedervorlageCommandToUpdate = dbTestUtils.saveCommand(M007_MigrationTestFactory.createCommandWithWiedervorlageAsBody()); - - doNotMigrateCommandByWrongOrder = dbTestUtils.saveCommand(M007_MigrationTestFactory.createCommandWithWrongOrder()); - doNotMigrateCommandByValidRelationId = dbTestUtils.saveCommand(M007_MigrationTestFactory.createCommandWithValidRelationId()); - } - - @DisplayName("Migrate relationId") - @Nested - class TestMigrateRelationId { - - @Test - void shouldFindAllConsidered() { - var commands = migrator.getCommands(template).stream().toList(); - - assertThat(commands).hasSize(2); - } - - @DisplayName("should not update relation id") - @Nested - class TestNotUpdateRelationid { - - @DisplayName("on not considered order") - @Test - void onOtherOrderCommands() { - migrator.migrationMethod(template); - - var migratedCommand = reloadCommand(doNotMigrateCommandByWrongOrder); - assertThat(migratedCommand).containsEntry( - M007_MigrationTestFactory.COMMAND_RELATION_ID_FIELD, M007_MigrationTestFactory.COMMAND_RELATION_ID); - } - - @DisplayName("on valid relation id") - @Test - void onfValidRelationId() { - migrator.migrationMethod(template); - - var migratedCommand = reloadCommand(doNotMigrateCommandByValidRelationId); - assertThat(migratedCommand).containsEntry( - M007_MigrationTestFactory.COMMAND_RELATION_ID_FIELD, M007_MigrationTestFactory.WIEDERVORLAGE_ID); - } - } - - @DisplayName("of edit kommentar command") - @Nested - class TestEditKommentarCommand { - - @Test - void shouldSetItemIdAsRelationId() { - migrator.migrationMethod(template); - - var migratedCommand = reloadCommand(kommentarCommandToUpdate); - assertThat(migratedCommand).containsEntry( - M007_MigrationTestFactory.COMMAND_RELATION_ID_FIELD, M007_MigrationTestFactory.KOMMENTAR_ID); - } - } - - @DisplayName("of update wiedervorlage command") - @Nested - class TestUpdateWiedervorlageCommand { - - @Test - void shouldSetItemIdAsRelationId() { - migrator.migrationMethod(template); - - var migratedCommand = reloadCommand(wiedervorlageCommandToUpdate); - assertThat(migratedCommand).containsEntry( - M007_MigrationTestFactory.COMMAND_RELATION_ID_FIELD, M007_MigrationTestFactory.WIEDERVORLAGE_ID); - } - } - - private Document reloadCommand(Document commandToReload) { - return dbTestUtils.getCommand(MigrationTestUtils.getObjectId(commandToReload)); - } - } - - private class M007_MigrationTestFactory { - - private static final String ID_FIELD = "id"; - - static final String KOMMENTAR_ID = UUID.randomUUID().toString(); - static final String WIEDERVORLAGE_ID = UUID.randomUUID().toString(); - - private static final String ITEM_FIELD = "item"; - - private static final String ITEM_NAME_FIELD = "itemName"; - private static final String ITEM_NAME_WIEDERVORLAGE = "Wiedervorlage"; - private static final String ITEM_NAME_KOMMENTAR = "Kommentar"; - - static final String COMMAND_RELATION_ID_FIELD = "relationId"; - static final String COMMAND_RELATION_ID = UUID.randomUUID().toString(); - - private static final String COMMAND_RELATION_VERSION_FIELD = "relationVersion"; - private static final int COMMAND_RELATION_VERSION = 42; - - private static final String COMMAND_BODY_OBJECT_FIELD = "bodyObject"; - - private static final String COMMAND_ORDER_FIELD = "order"; - - public static Document createCommandWithKommentarAsBody() { - return createCommandWithBody(createKommentar()); - } - - private static Document createKommentar() { - var item = new Document(); - item.put(ID_FIELD, KOMMENTAR_ID); - - var vorgangAttachedItem = new Document(); - vorgangAttachedItem.put(ITEM_NAME_FIELD, ITEM_NAME_KOMMENTAR); - vorgangAttachedItem.put(ITEM_FIELD, item); - - return vorgangAttachedItem; - } - - public static Document createCommandWithWiedervorlageAsBody() { - return createCommandWithBody(createWiedervorlage()); - } - - private static Document createWiedervorlage() { - var item = new Document(); - item.put(ID_FIELD, WIEDERVORLAGE_ID); - - var vorgangAttachedItem = new Document(); - vorgangAttachedItem.put(ITEM_NAME_FIELD, ITEM_NAME_WIEDERVORLAGE); - vorgangAttachedItem.put(ITEM_FIELD, item); - - return vorgangAttachedItem; - } - - private static Document createCommandWithBody(Document bodyObject) { - var command = createCommand(); - command.put(COMMAND_RELATION_ID_FIELD, COMMAND_RELATION_ID); - command.put(COMMAND_ORDER_FIELD, M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.CONSIDERED_ORDER); - command.put(COMMAND_BODY_OBJECT_FIELD, bodyObject); - - return command; - } - - public static Document createCommandWithValidRelationId() { - var command = createCommand(); - command.put(COMMAND_RELATION_ID_FIELD, WIEDERVORLAGE_ID); - command.put(COMMAND_BODY_OBJECT_FIELD, createWiedervorlage()); - command.put(COMMAND_ORDER_FIELD, M007_MigrateRelationIdOnUpdateVorgangAttachedItemCommands.CONSIDERED_ORDER); - - return command; - } - - public static Document createCommandWithWrongOrder() { - var command = createCommand(); - command.put(COMMAND_RELATION_ID_FIELD, COMMAND_RELATION_ID); - command.put(COMMAND_ORDER_FIELD, "ANY_ORDER"); - - return command; - } - - private static Document createCommand() { - var command = new Document(); - command.put(COMMAND_RELATION_VERSION_FIELD, COMMAND_RELATION_VERSION); - command.put(COMMAND_BODY_OBJECT_FIELD, new Document()); - - return command; - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollectionITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollectionITCase.java deleted file mode 100644 index fdf50e3..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollectionITCase.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M008_DropBinaryFilesCollectionITCase { - - private M008_DropBinaryFilesCollection migrator = new M008_DropBinaryFilesCollection(); - - @Autowired - private MongoTemplate template; - - @BeforeEach - void initDatabase() { - template.dropCollection(MigrationDbTestUtils.BINARY_FILE_COLLECTION); - template.dropCollection(MigrationDbTestUtils.VORGANG_COLLECTION); - - template.createCollection(MigrationDbTestUtils.BINARY_FILE_COLLECTION); - template.createCollection(MigrationDbTestUtils.VORGANG_COLLECTION); - } - - @DisplayName("Test dropping binaryFile collection") - @Nested - class TestDropCollection { - @Test - void shouldDropCollection() { - migrator.migrationMethod(template); - - assertThat(template.collectionExists(MigrationDbTestUtils.BINARY_FILE_COLLECTION)).isFalse(); - } - - @Test - void shouldNotDropVorgangCollection() { - migrator.migrationMethod(template); - - assertThat(template.collectionExists(MigrationDbTestUtils.VORGANG_COLLECTION)).isTrue(); - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContentITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContentITCase.java deleted file mode 100644 index 39efcb9..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M009_RemoveAttachmentContentITCase.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static de.itvsh.ozg.pluto.common.migration.MigrationAttachmentTestFactory.*; -import static de.itvsh.ozg.pluto.common.migration.MigrationEingangTestFactory.*; -import static de.itvsh.ozg.pluto.common.migration.MigrationIncomingFileTestFactory.*; -import static de.itvsh.ozg.pluto.common.migration.MigrationVorgangTestFactory.*; -import static org.assertj.core.api.Assertions.*; - -import java.util.List; - -import org.bson.Document; -import org.bson.types.Binary; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M009_RemoveAttachmentContentITCase { - - private M009_RemoveAttachmentContent migrator = new M009_RemoveAttachmentContent(); - - @Autowired - private MongoTemplate template; - - private Document savedVorgang1; - private Document savedVorgang2; - - @BeforeEach - void initDatabase() { - MigrationDbTestUtils.dropVorgangCollection(template); - - savedVorgang1 = MigrationDbTestUtils.saveVorgang(template, TestFactory.create(true)); - savedVorgang2 = MigrationDbTestUtils.saveVorgang(template, TestFactory.create(false)); - } - - @DisplayName("Test removing attachment content") - @Nested - class TestRemoveAttachmentContent { - @Test - void shouldRemoveAttachmentContent() { - migrator.migrationMethod(template); - - assertThat(getFirstAttachment(savedVorgang1)).doesNotContainKey("content"); - } - - @Test - void shouldNotTouchVorgangWithoutAttachmentContent() { - migrator.migrationMethod(template); - - assertThat(getVorgang(savedVorgang2)).usingRecursiveComparison().isEqualTo(savedVorgang2); - } - } - - private Document getVorgang(Document vorgang) { - return MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgang)); - } - - private Document getFirstAttachment(Document vorgang) { - var attachments = getVorgang(vorgang).getList(MigrationVorgangTestFactory.FIELD_EINGANGS, Document.class).get(0) - .getList(MigrationEingangTestFactory.FIELD_ATTACHMENTS, Document.class); - - return attachments.get(0).getList("files", Document.class).get(0); - } - - class TestFactory { - static Document create(boolean withContent) { - var vorgang = new Document(); - vorgang.put(FIELD_EINGANGS, List.of(createEingang(withContent))); - return vorgang; - } - - static Document createEingang(boolean withContent) { - var eingang = new Document(); - eingang.put(FIELD_ATTACHMENTS, List.of(createFileGroup(withContent))); - eingang.put(FIELD_NUMBER_OF_ATTACHMENTS, 1); - - return eingang; - } - - private static Document createFileGroup(boolean withContent) { - var incomingFileGroup = new Document(); - incomingFileGroup.put(FIELD_FILES, List.of(createFile(withContent))); - - return incomingFileGroup; - } - - static Document createFile(boolean withContent) { - var file = new Document(); - - file.put(FIELD_CONTENT_TYPE, CONTENT_TYPE); - file.put(FIELD_SIZE, SIZE); - if (withContent) { - file.put(FIELD_CONTENT, new Binary(CONTENT)); - } - - return file; - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationsContentITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationsContentITCase.java deleted file mode 100644 index cfbeb69..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M010_RemoveRepresentationsContentITCase.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static de.itvsh.ozg.pluto.common.migration.MigrationEingangTestFactory.*; -import static de.itvsh.ozg.pluto.common.migration.MigrationIncomingFileTestFactory.*; -import static de.itvsh.ozg.pluto.common.migration.MigrationVorgangTestFactory.*; -import static org.assertj.core.api.Assertions.*; - -import java.util.HashMap; -import java.util.List; - -import org.bson.Document; -import org.bson.types.Binary; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M010_RemoveRepresentationsContentITCase { - - private M010_RemoveRepresentationContent migrator = new M010_RemoveRepresentationContent(); - - @Autowired - private MongoTemplate template; - - private Document savedVorgang1; - private Document savedVorgang2; - - @BeforeEach - void initDatabase() { - MigrationDbTestUtils.dropVorgangCollection(template); - - savedVorgang1 = MigrationDbTestUtils.saveVorgang(template, TestFactory.create(true)); - savedVorgang2 = MigrationDbTestUtils.saveVorgang(template, TestFactory.create(false)); - } - - @DisplayName("Test removing representation content") - @Nested - class TestRemoveRepresentationContent { - @Test - void shouldRemoveRepresentationContent() { - migrator.migrationMethod(template); - - assertThat(getRepresentation(savedVorgang1)).doesNotContainKey("content"); - } - - @Test - void shouldNotTouchVorgangWithoutRepresentationContent() { - migrator.migrationMethod(template); - - assertThat(getVorgang(savedVorgang2)).usingRecursiveComparison().isEqualTo(savedVorgang2); - } - } - - private Document getVorgang(Document vorgang) { - return MigrationDbTestUtils.getVorgang(template, MigrationTestUtils.getObjectId(vorgang)); - } - - private Document getRepresentation(Document vorgang) { - var eingangs = getVorgang(vorgang).getList(FIELD_EINGANGS, Document.class); - var representations = eingangs.get(0).getList(FIELD_REPRESENTATIONS, Document.class); - return representations.get(0); - } - - class TestFactory { - static Document create(boolean withContent) { - var vorgang = new Document(); - vorgang.put(FIELD_EINGANGS, List.of(createEingang(withContent))); - return vorgang; - } - - static Document createEingang(boolean withContent) { - var eingang = new Document(); - eingang.put(FIELD_REPRESENTATIONS, List.of(createFile(withContent))); - eingang.put(FIELD_NUMBER_OF_REPRESENTATIONS, 1); - eingang.put(FIELD_FORMDATA, new HashMap<String, Object>()); - - return eingang; - } - - static Document createFile(boolean withContent) { - var file = new Document(); - - file.put(FIELD_CONTENT_TYPE, CONTENT_TYPE); - file.put(FIELD_SIZE, SIZE); - if (withContent) { - file.put(FIELD_CONTENT, new Binary(CONTENT)); - } - - return file; - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAliasITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAliasITCase.java deleted file mode 100644 index 1da1024..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M011_FixTypeAliasITCase.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; - -import org.bson.Document; -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.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M011_FixTypeAliasITCase { - - @Spy - @InjectMocks - private M011_FixTypeAlias migration; - - @Autowired - private MongoTemplate template; - - @BeforeEach - void clearDatabase() { - template.dropCollection(MigrationDbTestUtils.COMMAND_COLLECTION); - template.dropCollection(MigrationDbTestUtils.VORGANG_COLLECTION); - template.dropCollection(MigrationDbTestUtils.VORGANG_ATTACHED_ITEM_COLLECTION); - } - - @Test - void shouldCallMigrateCommands() { - migration.doMigration(template); - - verify(migration).migrateCommands(any()); - } - - @Test - void shouldCallMigrateVorgangs() { - migration.doMigration(template); - - verify(migration).migrateVorgangs(any()); - } - - @Test - void shouldCallMigrateItems() { - migration.doMigration(template); - - verify(migration).migrateVorgangAttachedItems(template); - } - - @Test - void shouldCallMigrateAttributes() { - migration.doMigration(template); - - verify(migration).migrateClientAttributes(template); - } - - @Nested - class TestMigrationOfCommands { - - @BeforeEach - void persistCommand() { - template.save(buildDocument("de.itvsh.ozg.pluto.command.Command"), MigrationDbTestUtils.COMMAND_COLLECTION); - template.save(buildDocument("de.itvsh.ozg.pluto.command.PersistedCommand"), MigrationDbTestUtils.COMMAND_COLLECTION); - - assertThat(getCommands()).isNotEmpty().allMatch(doc -> doc.containsKey("_class")); - } - - @Test - void shouldUpdateTypeAttributeKey() { - migration.migrateCommands(template); - - assertThat(getCommands()).isNotEmpty() - .allMatch(doc -> Objects.equals(doc.getString(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), M011_FixTypeAlias.COMMAND_TYPE_ALIAS)); - } - - @Test - void shouldMatchNothingAfterMigration() { - migration.migrateCommands(template); - - assertThat(template.count(migration.buildQuery(), MigrationDbTestUtils.COMMAND_COLLECTION)).isZero(); - } - - private List<Document> getCommands() { - return template.findAll(Document.class, MigrationDbTestUtils.COMMAND_COLLECTION); - } - - } - - @Nested - class TestMigrateVorgangs { - @BeforeEach - void persistVorgang() { - template.save(buildDocument("de.itvsh.ozg.pluto.vorgang.Vorgang"), MigrationDbTestUtils.VORGANG_COLLECTION); - } - - @Test - void shouldUpdateTypeAttributeKey() { - migration.migrateVorgangs(template); - - assertThat(getVorgangs()).isNotEmpty() - .allMatch(doc -> Objects.equals(doc.getString(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), M011_FixTypeAlias.VORGANG_TYPE_ALIAS)); - } - - @Test - void shouldMatchNothingAfterMigration() { - migration.migrateVorgangs(template); - - assertThat(template.count(migration.buildQuery(), MigrationDbTestUtils.VORGANG_COLLECTION)).isZero(); - } - - private List<Document> getVorgangs() { - return template.findAll(Document.class, MigrationDbTestUtils.VORGANG_COLLECTION); - } - } - - @Nested - class TestMigrateVorgangAttachedItems { - @BeforeEach - void persistItem() { - template.save(buildDocument("de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem"), - MigrationDbTestUtils.VORGANG_ATTACHED_ITEM_COLLECTION); - } - - @Test - void shouldUpdateTypeAttributeKey() { - migration.migrateVorgangAttachedItems(template); - - assertThat(getItems()).isNotEmpty() - .allMatch(doc -> Objects.equals(doc.getString(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), M011_FixTypeAlias.ITEM_TYPE_ALIAS)); - } - - @Test - void shouldMatchNothingAfterMigration() { - migration.migrateVorgangAttachedItems(template); - - assertThat(template.count(migration.buildQuery(), MigrationDbTestUtils.VORGANG_ATTACHED_ITEM_COLLECTION)).isZero(); - } - - private List<Document> getItems() { - return template.findAll(Document.class, MigrationDbTestUtils.VORGANG_ATTACHED_ITEM_COLLECTION); - } - } - - private Document buildDocument(String typeKeyValue) { - var doc = new Document(); - doc.put(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE, typeKeyValue); - return doc; - } - - @Nested - class TestMigrateClientAttributes { - - private static final String FIELD_CLIENT_ATTRIBUTES = "clientAttributes"; - private static final String FIELD_CLIENT_NAME = "KopNachrichtenManager"; - private static final String FIELD_ATTRIBUTE_NAME_HASNACHRICHT = "hasPostfachNachricht"; - private static final String FIELD_ATTRIBUTE_NAME_NEWNACHRICHT = "hasNewPostfachNachricht"; - private static final String FIELD_ATTRIBUTE_NAME_WIEDERVORLAGE = "nextWiedervorlageFrist"; - - @BeforeEach - void persistAttribute() { - template.save(buildVorgangWithAttribute(), MigrationDbTestUtils.VORGANG_COLLECTION); - } - - @Test - void shouldUpdateTypeAttributeKeys() { - migration.migrateClientAttributes(template); - - assertThat(getClientAttributes()).isNotEmpty().allMatch(this::areTypeAliasMigrated); - } - - @Test - void shouldMatchNothingAfterMigration() { - migration.migrateClientAttributes(template); - - assertThat(countMatch("hasPostfachNachricht")).isZero(); - assertThat(countMatch("hasNewPostfachNachricht")).isZero(); - } - - @Test - void shouldUpdateForGoofyAsClient() { - template.save(buildVorgangWithWiedervorlageAttribute(), MigrationDbTestUtils.VORGANG_COLLECTION); - - migration.migrateClientAttributes(template); - - assertThat(getClientAttributes("Goofy")).isNotEmpty().allMatch(doc -> Objects.equals( - ((Document) doc.get(FIELD_ATTRIBUTE_NAME_WIEDERVORLAGE)).get(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), - M011_FixTypeAlias.ATTRIBUTE_TYPE_ALIAS)); - } - - private long countMatch(String attributeName) { - String fieldPathTemplate = "clientAttributes.KopNachrichtenManager.%s._class"; - - return template.count(migration.buildQueryForAttributes(String.format(fieldPathTemplate, attributeName)), - MigrationDbTestUtils.VORGANG_COLLECTION); - } - - private boolean areTypeAliasMigrated(Document attributesDoc) { - var hasNachrichtDoc = (Document) attributesDoc.get(FIELD_ATTRIBUTE_NAME_HASNACHRICHT); - var hasNewNachrichtDoc = (Document) attributesDoc.get(FIELD_ATTRIBUTE_NAME_NEWNACHRICHT); - - return Objects.equals(hasNachrichtDoc.get(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), M011_FixTypeAlias.ATTRIBUTE_TYPE_ALIAS) - && Objects.equals(hasNewNachrichtDoc.get(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE), M011_FixTypeAlias.ATTRIBUTE_TYPE_ALIAS); - } - - private Stream<Document> getClientAttributes() { - return getClientAttributes(FIELD_CLIENT_NAME); - } - - private Stream<Document> getClientAttributes(String clientName) { - var vorgangs = template.findAll(Document.class, MigrationDbTestUtils.VORGANG_COLLECTION); - return vorgangs.stream() - .map(vorgangDoc -> (Document) vorgangDoc.get(FIELD_CLIENT_ATTRIBUTES)) - .map(attributesDoc -> (Document) attributesDoc.get(clientName)) - .filter(Objects::nonNull); - } - - private Document buildVorgangWithWiedervorlageAttribute() { - var doc = new Document(); - - var attributes = new Document(); - doc.put(FIELD_CLIENT_ATTRIBUTES, attributes); - - var nachrichtenManager = new Document(); - attributes.put("Goofy", nachrichtenManager); - - var hasNachricht = new Document(); - hasNachricht.put(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE, "de.itvsh.ozg.pluto.clientattribute.ClientAttribute"); - nachrichtenManager.put(FIELD_ATTRIBUTE_NAME_WIEDERVORLAGE, hasNachricht); - - return doc; - } - - private Document buildVorgangWithAttribute() { - var doc = new Document(); - - var attributes = new Document(); - doc.put(FIELD_CLIENT_ATTRIBUTES, attributes); - - var nachrichtenManager = new Document(); - attributes.put(FIELD_CLIENT_NAME, nachrichtenManager); - - var hasNachricht = new Document(); - hasNachricht.put(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE, "de.itvsh.ozg.pluto.clientattribute.ClientAttribute"); - nachrichtenManager.put(FIELD_ATTRIBUTE_NAME_HASNACHRICHT, hasNachricht); - - var hasNewNachricht = new Document(); - hasNewNachricht.put(M011_FixTypeAlias.TYPEKEY_ATTRIBUTE, "de.itvsh.ozg.pluto.clientattribute.ClientAttribute"); - nachrichtenManager.put(FIELD_ATTRIBUTE_NAME_NEWNACHRICHT, hasNewNachricht); - - return doc; - } - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserIdITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserIdITCase.java deleted file mode 100644 index b4a94d0..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/M012_MigrationUserIdITCase.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.util.List; -import java.util.UUID; - -import org.bson.Document; -import org.bson.types.ObjectId; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.core.env.Environment; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import de.itvsh.kop.common.test.DataITCase; - -@DataITCase -class M012_MigrationUserIdITCase { - - private final static String USER_MANAGER_URL = "userManagerUrlForTest"; - - @SpyBean - private M012_MigrationUserId migration; - - @Autowired - private MigrationDbTestUtils dbUtils; - - @Autowired - private MongoTemplate template; - - @Mock - private RestTemplate restTemplate; - - @DisplayName("Migrate") - @Nested - class TestMigration { - - @Mock - private Environment env; - - @BeforeEach - void init() { - ReflectionTestUtils.setField(migration, "restTemplate", restTemplate); - } - - @Test - void shouldInitMigration() { - when(env.getProperty(anyString())).thenReturn(USER_MANAGER_URL); - - migration.doMigration(template, env); - - verify(migration, never()).logUrlIsNotConfigured(); - } - - @Test - void shouldNotInitMigration() { - migration.doMigration(template, env); - - verify(migration).logUrlIsNotConfigured(); - } - - @DisplayName("vorgang assignedTo") - @Nested - class TestMigrateAssignedTo { - - private final static String ASSIGNED_TO = UUID.randomUUID().toString(); - private final static String NEW_ASSIGNED_TO = new ObjectId().toHexString(); - - private Document vorgang; - - @BeforeEach - void init() { - dbUtils.dropVorgangCollection(); - - vorgang = dbUtils.saveVorgang(createVorgangWithAssignedTo()); - } - - @SuppressWarnings("unchecked") - @Test - void shouldMigrateOnValidResponse() { - ResponseEntity<Object> response = mock(ResponseEntity.class); - when(response.getBody()).thenReturn(NEW_ASSIGNED_TO); - when(restTemplate.getForEntity(anyString(), any())).thenReturn(response); - - migrateAssignedTo(); - - assertThat(loadVorgang()).containsEntry(M012_MigrationUserId.ASSIGNED_TO_FIELD, NEW_ASSIGNED_TO); - } - - @DisplayName("on exception") - @Nested - class TestOnException { - - @Test - void shouldProceed() { - mockHttpNotFound(); - - migrateAssignedTo(); - - assertThat(loadVorgang()).containsEntry(M012_MigrationUserId.ASSIGNED_TO_FIELD, ASSIGNED_TO); - } - - @Test - void shouldLogOnHttpNotFound() { - mockHttpNotFound(); - - migrateAssignedTo(); - - verify(migration).logNotFoundException(any(), any()); - } - - @Test - void shouldLogOnHttpError() { - mockHttpError(); - - migrateAssignedTo(); - - verify(migration).logHttpException(any(), any()); - } - } - - private void migrateAssignedTo() { - migration.migrateAssignedTo(); - } - - private Document loadVorgang() { - return dbUtils.getVorgang(MigrationTestUtils.getObjectId(vorgang)); - } - - @DisplayName("find all vorgaenge with assignedTo field filled") - @Nested - class TestFindVorgangWithFilledAssignedTo { - - @BeforeEach - void mock() { - dbUtils.dropVorgangCollection(); - dbUtils.dropVorgangAttachedItemCollection(); - } - - @Test - void shouldFindWithOldAssignedToData() { - dbUtils.saveVorgang(createVorgangWithAssignedTo()); - - var vorgaenge = findVorgang(); - - assertThat(vorgaenge).hasSize(1); - assertThat(vorgaenge.get(0)).containsEntry(M012_MigrationUserId.ASSIGNED_TO_FIELD, ASSIGNED_TO); - } - - @Test - void shouldReturnEmptyListOnNewAssignedToData() { - dbUtils.saveVorgang(new Document(M012_MigrationUserId.ASSIGNED_TO_FIELD, NEW_ASSIGNED_TO)); - - var vorgaenge = findVorgang(); - - assertThat(vorgaenge).isEmpty(); - } - - private List<Document> findVorgang() { - return template.find(migration.createFindVorgangWithFilledAssignedToQuery(), Document.class, - M012_MigrationUserId.COLLECTION_VORGANG_NAME); - } - } - - private Document createVorgangWithAssignedTo() { - return new Document(M012_MigrationUserId.ASSIGNED_TO_FIELD, ASSIGNED_TO); - } - } - - @DisplayName("command createdBy") - @Nested - class TestMigrateCreatedBy { - - private final static String CREATED_BY = UUID.randomUUID().toString(); - private final static String NEW_CREATED_BY = new ObjectId().toHexString(); - - private Document command; - - @BeforeEach - void init() { - dbUtils.dropCommandCollection(); - - command = dbUtils.saveCommand(createCommandWithCreatedBy()); - } - - @SuppressWarnings("unchecked") - @Test - void shouldMigrateOnValidResponse() { - ResponseEntity<Object> response = mock(ResponseEntity.class); - when(response.getBody()).thenReturn(NEW_CREATED_BY); - when(restTemplate.getForEntity(anyString(), any())).thenReturn(response); - - migrateCreatedBy(); - - assertThat(loadCommand()).containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, NEW_CREATED_BY); - } - - @DisplayName("on exception") - @Nested - class TestOnException { - @Test - void shouldProceed() { - mockHttpNotFound(); - - migrateCreatedBy(); - - assertThat(loadCommand()).containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, CREATED_BY); - } - - @Test - void shouldLogOnNotFound() { - mockHttpNotFound(); - - migrateCreatedBy(); - - verify(migration).logNotFoundException(any(), any()); - } - - @Test - void shouldLogOnHttpError() { - mockHttpError(); - - migrateCreatedBy(); - - verify(migration).logHttpException(any(), any()); - } - } - - private void migrateCreatedBy() { - migration.migrateCommandCreatedBy(); - } - - private Document loadCommand() { - return dbUtils.getCommand(MigrationTestUtils.getObjectId(command)); - } - - @DisplayName("find all commands with createdBy field filled") - @Nested - class TestFindCommandWithFilledCreatedBy { - - @BeforeEach - void mock() { - dbUtils.dropCommandCollection(); - } - - @Test - void shouldFindWithOldCreatedByData() { - dbUtils.saveCommand(createCommandWithCreatedBy()); - - var commands = findCommand(); - - assertThat(commands).hasSize(1); - assertThat(commands.get(0)).containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, CREATED_BY); - } - - @Test - void shouldReturnEmptyListOnNewCreatedByData() { - dbUtils.saveVorgang(new Document(M012_MigrationUserId.CREATED_BY_FIELD, NEW_CREATED_BY)); - - var commands = findCommand(); - - assertThat(commands).isEmpty(); - } - - private List<Document> findCommand() { - return template.find(migration.createFindCommandWithCreatedByQuery(), Document.class, - M012_MigrationUserId.COLLECTION_COMMAND_NAME); - } - } - - private static Document createCommandWithCreatedBy() { - return new Document(M012_MigrationUserId.CREATED_BY_FIELD, CREATED_BY); - } - } - - @DisplayName("vorgangAttachedItem createdBy") - @Nested - class TestAttachedItemCreatedBy { - - private static final String SYSTEM_NOTIFICATION_MANAGER_NEW_VORGANG = "system-notification_manager-new_vorgang"; - private final static String CREATED_BY = UUID.randomUUID().toString(); - private final static String NEW_CREATED_BY = new ObjectId().toHexString(); - - private Document vorganAttachedItem; - - @BeforeEach - void init() { - dbUtils.dropVorgangAttachedItemCollection(); - - vorganAttachedItem = dbUtils.saveVorgangAttachedItem(createVorgangAttachedItemWithCreatedBy(CREATED_BY)); - } - - @Test - void shouldMigrateOnValidResponse() { - doReturn(NEW_CREATED_BY).when(migration).getInternalId(anyString()); - - migrateVorgangAttachedItemCreatedBy(); - - assertThat(((Document) loadVorgangAttachedItem().get(M012_MigrationUserId.VORGANG_ATTACHED_ITEM_ITEM_FIELD))) - .containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, NEW_CREATED_BY); - } - - @Test - void shouldNotMigrateOnSystemUser() { - dbUtils.dropVorgangAttachedItemCollection(); - vorganAttachedItem = dbUtils - .saveVorgangAttachedItem(createVorgangAttachedItemWithCreatedBy(SYSTEM_NOTIFICATION_MANAGER_NEW_VORGANG)); - - migrateVorgangAttachedItemCreatedBy(); - - verify(migration, never()).getInternalId(any()); - } - - @DisplayName("on exception") - @Nested - class TestOnException { - @Test - void shouldProceedOnNotFound() { - mockHttpNotFound(); - - migrateVorgangAttachedItemCreatedBy(); - - assertThat((Document) loadVorgangAttachedItem().get(M012_MigrationUserId.VORGANG_ATTACHED_ITEM_ITEM_FIELD)) - .containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, CREATED_BY); - } - - @Test - void shouldLogOnNotFound() { - mockHttpNotFound(); - - migrateVorgangAttachedItemCreatedBy(); - - verify(migration).logNotFoundException(any(), any()); - } - - @Test - void shouldLogOnHttpError() { - mockHttpError(); - - migrateVorgangAttachedItemCreatedBy(); - - verify(migration).logHttpException(any(), any()); - } - } - - private void migrateVorgangAttachedItemCreatedBy() { - migration.migrateVorgangAttachedItemCreatedBy(); - } - - private Document loadVorgangAttachedItem() { - return dbUtils.getVorgangAttachedItem(MigrationTestUtils.getObjectId(vorganAttachedItem)); - } - - @DisplayName("find all vorgangAttachedItem with createdBy field filled") - @Nested - class TestFindVorgangAttachedItemWithFilledCreatedBy { - - @BeforeEach - void mock() { - dbUtils.dropVorgangAttachedItemCollection(); - } - - @Test - void shouldFindWithOldCreatedByData() { - dbUtils.saveVorgangAttachedItem(createVorgangAttachedItemWithCreatedBy(CREATED_BY)); - - var vorgangAttachedItems = findVorgangAttachedItem(); - - assertThat(vorgangAttachedItems).hasSize(1); - assertThat(((Document) vorgangAttachedItems.get(0).get(M012_MigrationUserId.VORGANG_ATTACHED_ITEM_ITEM_FIELD))) - .containsEntry(M012_MigrationUserId.CREATED_BY_FIELD, CREATED_BY); - } - - @Test - void shouldReturnEmptyListOnNewCreatedByData() { - dbUtils.saveVorgangAttachedItem(new Document(M012_MigrationUserId.VORGANG_ATTACHED_ITEM_ITEM_FIELD, - new Document(M012_MigrationUserId.CREATED_BY_FIELD, NEW_CREATED_BY))); - - var vorgangAttachedItems = findVorgangAttachedItem(); - - assertThat(vorgangAttachedItems).isEmpty(); - } - - private List<Document> findVorgangAttachedItem() { - return template.find(migration.createFindVorgangAttachedItemdWithCreatedByQuery(), Document.class, - M012_MigrationUserId.COLLECTION_VORGANG_ATTACHED_ITEM_NAME); - } - } - - private static Document createVorgangAttachedItemWithCreatedBy(String createdById) { - return new Document(M012_MigrationUserId.VORGANG_ATTACHED_ITEM_ITEM_FIELD, - new Document(M012_MigrationUserId.CREATED_BY_FIELD, createdById)); - } - } - } - - private void mockHttpNotFound() { - when(restTemplate.getForEntity(anyString(), any())).thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)); - } - - private void mockHttpError() { - when(restTemplate.getForEntity(anyString(), any())).thenThrow(new HttpClientErrorException(HttpStatus.BAD_GATEWAY)); - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationAttachmentTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationAttachmentTestFactory.java deleted file mode 100644 index acd5b0c..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationAttachmentTestFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.List; -import java.util.UUID; - -import org.bson.Document; - -import com.thedeanda.lorem.LoremIpsum; - -class MigrationAttachmentTestFactory { - - static final String FIELD_NAME = "name"; - static final String NAME = LoremIpsum.getInstance().getName(); - - static final String FIELD_FILES = "files"; - - static final String ATTACHMENT_FILE_ID = UUID.randomUUID().toString(); - static final String ATTACHMENT_FILE_NAME = LoremIpsum.getInstance().getName(); - - static final String ATTACHMENT_FILE_ID2 = UUID.randomUUID().toString(); - static final String ATTACHMENT_FILE_NAME2 = LoremIpsum.getInstance().getName(); - - static Document create() { - var incomingFileGroup = new Document(); - incomingFileGroup.put(FIELD_NAME, NAME); - incomingFileGroup.put(FIELD_FILES, List.of( - createAttachment(ATTACHMENT_FILE_ID, ATTACHMENT_FILE_NAME), - createAttachment(ATTACHMENT_FILE_ID2, ATTACHMENT_FILE_NAME2))); - - return incomingFileGroup; - } - - private static Document createAttachment(String id, String name) { - var attachmentFile = MigrationIncomingFileTestFactory.create(); - attachmentFile.remove(MigrationIncomingFileTestFactory.FIELD_ID); - attachmentFile.put(MigrationIncomingFileTestFactory.FIELD_ID, id); - attachmentFile.remove(MigrationIncomingFileTestFactory.FIELD_NAME); - attachmentFile.put(MigrationIncomingFileTestFactory.FIELD_NAME, name); - return attachmentFile; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationBinaryFileTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationBinaryFileTestFactory.java deleted file mode 100644 index f276a27..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationBinaryFileTestFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.List; - -import org.bson.Document; -import org.bson.types.Binary; -import org.bson.types.ObjectId; - -class MigrationBinaryFileTestFactory { - - public final static String FIELD_VORGANG_ID = "vorgangId"; - public final static String VORGANG_ID = new ObjectId().toHexString(); - - public final static String FIELD_CLIENT = "client"; - public final static String CLIENT = "MailService"; - - public final static String FIELD_FIELD = "field"; - public final static String FIELD = "files"; - - public final static String FIELD_FILE = "file"; - - public static Document create() { - var binaryFileDoc = new Document(); - binaryFileDoc.put(FIELD_VORGANG_ID, VORGANG_ID); - binaryFileDoc.put(FIELD_CLIENT, CLIENT); - binaryFileDoc.put(FIELD_FIELD, FIELD); - binaryFileDoc.put(FIELD_FILE, createFile()); - - return binaryFileDoc; - } - - public static Document createFile() { - var file = MigrationIncomingFileTestFactory.create(); - file.put(MigrationIncomingFileTestFactory.FIELD_CONTENT, List.of(new Binary(MigrationIncomingFileTestFactory.CONTENT))); - - return file; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationDbTestUtils.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationDbTestUtils.java deleted file mode 100644 index fb75cde..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationDbTestUtils.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.List; - -import org.bson.Document; -import org.bson.types.ObjectId; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.gridfs.GridFsResource; -import org.springframework.data.mongodb.gridfs.GridFsTemplate; -import org.springframework.stereotype.Component; - -import com.mongodb.client.gridfs.model.GridFSFile; - -@Component -class MigrationDbTestUtils { - - public static final String COMMAND_COLLECTION = "command"; - public static final String VORGANG_COLLECTION = "vorgang"; - public static final String VORGANG_ATTACHED_ITEM_COLLECTION = "vorgangAttachedItem"; - public static final String BINARY_FILE_COLLECTION = "binaryFile"; - - public static final String GRID_FS_CHUNKS_COLLECTION = "fs.chunk"; - public static final String GRID_FS_FILES_COLLECTION = "fs.files"; - - @Autowired - private MongoTemplate template; - - public Document saveCommand(Document doc) { - return template.save(doc, COMMAND_COLLECTION); - } - - public Document getCommand(ObjectId id) { - return template.findById(id, Document.class, COMMAND_COLLECTION); - } - - public void dropCommandCollection() { - template.dropCollection(COMMAND_COLLECTION); - } - - public void dropVorgangCollection() { - template.dropCollection(VORGANG_COLLECTION); - } - - public Document getVorgang(ObjectId id) { - return template.findById(id, Document.class, VORGANG_COLLECTION); - } - - public Document saveVorgang(Document doc) { - return template.save(doc, VORGANG_COLLECTION); - } - - public Document saveVorgangAttachedItem(Document doc) { - return template.save(doc, VORGANG_ATTACHED_ITEM_COLLECTION); - } - - public Document getVorgangAttachedItem(ObjectId id) { - return template.findById(id, Document.class, VORGANG_ATTACHED_ITEM_COLLECTION); - } - - public void dropVorgangAttachedItemCollection() { - template.dropCollection(VORGANG_ATTACHED_ITEM_COLLECTION); - } - - /** - * @param template - * - * @deprecated Inject MigrationDbTestUtils and use {@link #saveVorgang()} - * instead. - */ - @Deprecated - public static Document saveVorgang(MongoTemplate template, Document doc) { - return template.save(doc, VORGANG_COLLECTION); - } - - /** - * @param template - * - * @deprecated Inject MigrationDbTestUtils and use - * {@link #saveVorgangAttachedItem()} instead. - */ - public static Document saveVorgangAttachedItem(MongoTemplate template, Document doc) { - return template.save(doc, VORGANG_ATTACHED_ITEM_COLLECTION); - } - - public static Document getBinaryFile(MongoTemplate template, String id) { - return template.findById(id, Document.class, BINARY_FILE_COLLECTION); - } - - public static List<Document> findBinaryFile(MongoTemplate template, Query query) { - return template.find(query, Document.class, BINARY_FILE_COLLECTION); - } - - public static Document saveBinaryFile(MongoTemplate template, Document doc) { - return template.save(doc, BINARY_FILE_COLLECTION); - } - - /** - * @param template - * - * @deprecated Inject MigrationDbTestUtils and use {@link #getVorgang()} - * instead. - */ - @Deprecated - public static Document getVorgang(MongoTemplate template, ObjectId id) { - return template.findById(id, Document.class, MigrationDbTestUtils.VORGANG_COLLECTION); - } - - public static List<Document> getVorgangAttachedItem(MongoTemplate template, String fieldKey, String fieldValue) { - return template.find(new Query(Criteria.where(fieldKey).is(fieldValue)), Document.class, VORGANG_ATTACHED_ITEM_COLLECTION); - } - - public static void dropBinaryFileCollection(MongoTemplate template) { - template.dropCollection(BINARY_FILE_COLLECTION); - } - - /** - * @param template - * - * @deprecated Inject MigrationDbTestUtils and use - * {@link #dropVorgangCollection()} instead. - */ - @Deprecated - public static void dropVorgangCollection(MongoTemplate template) { - template.dropCollection(VORGANG_COLLECTION); - } - - /** - * @param template - * - * @deprecated Inject MigrationDbTestUtils and use - * {@link #dropVorgangAttachedItemCollection()} instead. - */ - @Deprecated - public static void dropVorgangAttachedItemCollection(MongoTemplate template) { - template.dropCollection(VORGANG_ATTACHED_ITEM_COLLECTION); - } - - public static GridFsResource getGridFsResource(GridFsTemplate template, ObjectId id) { - return template.getResource(getGridFsFile(template, id)); - } - - public static GridFSFile getGridFsFile(GridFsTemplate template, ObjectId id) { - return template.findOne(Query.query(Criteria.where(MigrationTestUtils.FIELD_OBJECT_ID).is(id))); - } - - public static GridFSFile getGridFsFile(GridFsTemplate template, String filename) { - return template.findOne(Query.query(Criteria.where(MigrationGridFSFileTestFactory.FIELD_FILE_NAME).is(filename))); - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangHeaderTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangHeaderTestFactory.java deleted file mode 100644 index b40f167..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangHeaderTestFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.UUID; - -import org.bson.Document; - -import com.thedeanda.lorem.LoremIpsum; - -class MigrationEingangHeaderTestFactory { - - public static final String FIELD_REQUEST_ID = "requestId"; - public static final String REQUEST_ID = UUID.randomUUID().toString(); - - public static final String FIELD_CREATED_AT = "createdAt"; - public static final String CREATED_AT_STR = "2021-01-10T10:30:00Z"; - - public static final String FIELD_FORM_NAME = "formName"; - public static final String FORM_NAME = LoremIpsum.getInstance().getWords(10); - - public static final String FIELD_FORM_ID = "formId"; - public static final String FORM_ID = FORM_NAME; - - public static final String FIELD_SENDER = "sender"; - private static final String SENDER = LoremIpsum.getInstance().getWords(2); - - public static final String FIELD_CUSTOMER = "customer"; - private static final String CUSTOMER = LoremIpsum.getInstance().getWords(2); - - public static final String FIELD_CUSTOMER_ID = "customerId"; - private static final String CUSTOMER_ID = UUID.randomUUID().toString(); - - public static final String FIELD_CLIENT = "client"; - private static final String CLIENT = LoremIpsum.getInstance().getWords(2); - - public static final String FIELD_CLIENT_ID = "clientId"; - public static final String CLIENT_ID = UUID.randomUUID().toString(); - - public static Document create() { - var eingangHeader = new Document(); - eingangHeader.put(FIELD_REQUEST_ID, REQUEST_ID); - eingangHeader.put(FIELD_CREATED_AT, CREATED_AT_STR); - eingangHeader.put(FIELD_FORM_NAME, FORM_NAME); - eingangHeader.put(FIELD_FORM_ID, FORM_ID); - eingangHeader.put(FIELD_SENDER, SENDER); - eingangHeader.put(FIELD_CUSTOMER, CUSTOMER); - eingangHeader.put(FIELD_CUSTOMER_ID, CUSTOMER_ID); - eingangHeader.put(FIELD_CLIENT, CLIENT); - eingangHeader.put(FIELD_CLIENT_ID, CLIENT_ID); - - return eingangHeader; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangTestFactory.java deleted file mode 100644 index 7a091c2..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationEingangTestFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - -import org.bson.Document; - -class MigrationEingangTestFactory { - - static final String FIELD_ID = "_id"; - static final String ID = UUID.randomUUID().toString(); - - static final String FIELD_HEADER = "header"; - static final String FIELD_ANTRAGSTELLER = "antragsteller"; - static final String FIELD_ZUSTAENDIDGESTELLE = "zustaendigeStelle"; - static final String FIELD_REPRESENTATIONS = "representations"; - static final String FIELD_NUMBER_OF_REPRESENTATIONS = "numberOfRepresentations"; - static final String FIELD_ATTACHMENTS = "attachments"; - static final String FIELD_NUMBER_OF_ATTACHMENTS = "numberOfAttachments"; - static final String FIELD_FORMDATA = "formData"; - - static Document create() { - var eingang = new Document(); - eingang.put(FIELD_ID, ID); - eingang.put(FIELD_HEADER, MigrationEingangHeaderTestFactory.create()); - eingang.put(FIELD_ANTRAGSTELLER, new Document()); - eingang.put(FIELD_ZUSTAENDIDGESTELLE, MigrationZustaendigeStelleTestFactory.create()); - eingang.put(FIELD_ATTACHMENTS, List.of(MigrationAttachmentTestFactory.create())); - eingang.put(FIELD_NUMBER_OF_ATTACHMENTS, 2); - eingang.put(FIELD_REPRESENTATIONS, List.of(MigrationIncomingFileTestFactory.create())); - eingang.put(FIELD_NUMBER_OF_REPRESENTATIONS, 1); - eingang.put(FIELD_FORMDATA, new HashMap<String, Object>()); - - return eingang; - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationGridFSFileTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationGridFSFileTestFactory.java deleted file mode 100644 index 65664f0..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationGridFSFileTestFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -class MigrationGridFSFileTestFactory { - - public final static String FIELD_CLIENT = "client"; - public final static String FIELD_VORGANG_ID = "vorgangId"; - public final static String FIELD_FIELD_NAME = "fieldName"; - public final static String FIELD_CONTENT_TYPE = "contentType"; - public final static String FIELD_NAME = "name"; - public final static String FIELD_FILE_NAME = "filename"; -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationIncomingFileTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationIncomingFileTestFactory.java deleted file mode 100644 index b4917ce..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationIncomingFileTestFactory.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.io.IOException; -import java.io.InputStream; - -import org.bson.Document; -import org.bson.types.Binary; -import org.bson.types.ObjectId; - -import de.itvsh.kop.common.test.TestUtils; - -class MigrationIncomingFileTestFactory { - - static final String FIELD_ID = "_id"; - static final String ID = new ObjectId().toHexString(); - - static final String FIELD_NAME = "name"; - static final String NAME = "TestDoc.docx"; - - static final String FIELD_CONTENT_TYPE = "contentType"; - static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; - - static final String FIELD_SIZE = "size"; - static final long SIZE; - - static final String FIELD_CONTENT = "content"; - static final byte[] CONTENT; - - static { - CONTENT = initContent(); - SIZE = CONTENT.length; - } - - private static byte[] initContent() { - try (InputStream in = TestUtils.loadFile(NAME)) { - byte[] fileData = new byte[in.available()]; - in.read(fileData); - - return fileData; - } catch (IOException e) { - throw new IllegalStateException("Error reading test file " + NAME); - } - } - - static Document create() { - var incomingFile = new Document(); - incomingFile.put(FIELD_ID, ID); - incomingFile.put(FIELD_NAME, NAME); - incomingFile.put(FIELD_CONTENT_TYPE, CONTENT_TYPE); - incomingFile.put(FIELD_SIZE, SIZE); - incomingFile.put(FIELD_CONTENT, new Binary(CONTENT)); - - return incomingFile; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationKommentarTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationKommentarTestFactory.java deleted file mode 100644 index 10c902c..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationKommentarTestFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.Date; -import java.util.UUID; - -import org.bson.Document; - -import com.thedeanda.lorem.LoremIpsum; - -public class MigrationKommentarTestFactory { - - public static final String ID_FIELD = "id"; - - public static final String VORGANG_ID_FIELD = "vorgangId"; - public static final String VORGANG_ID = UUID.randomUUID().toString(); - - public static final String CREATED_AT_FIELD = "createdAt"; - public static final Date CREATED_AT = new Date(); - public static final String CREATED_AT_STR = ZonedDateTime.ofInstant(CREATED_AT.toInstant(), ZoneId.of("UTC")).toString(); - - public static final String CREATED_BY_FIELD = "createdBy"; - public static final String CREATED_BY = UUID.randomUUID().toString(); - - public static final String TEXT_FIELD = "text"; - public static final String TEXT = LoremIpsum.getInstance().getWords(20); - - public static Document create() { - var kommentar = new Document(); - kommentar.put(VORGANG_ID_FIELD, VORGANG_ID); - kommentar.put(CREATED_AT_FIELD, CREATED_AT); - kommentar.put(CREATED_BY_FIELD, CREATED_BY); - kommentar.put(TEXT_FIELD, TEXT); - - return kommentar; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangAttachedItemTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangAttachedItemTestFactory.java deleted file mode 100644 index b2619fb..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangAttachedItemTestFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.Collections; - -import org.bson.Document; - -class MigrationVorgangAttachedItemTestFactory { - - public final static String FIELD_CLIENT = "client"; - public final static String CLIENT = "MailService"; - - public final static String FIELD_ITEM_NAME = "itemName"; - public final static String ITEM_NAME = "files"; - - public final static String FIELD_ITEM = "item"; - - public final static String VERSION_FIELD = "version"; - public final static int VERSION = 0; - - public static Document create() { - var vorgangAttachedItem = new Document(); - vorgangAttachedItem.put(FIELD_CLIENT, CLIENT); - vorgangAttachedItem.put(FIELD_ITEM_NAME, ITEM_NAME); - vorgangAttachedItem.put(VERSION_FIELD, VERSION); - vorgangAttachedItem.put(FIELD_ITEM, Collections.emptyMap()); - - return vorgangAttachedItem; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangTestFactory.java deleted file mode 100644 index 8c7622a..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationVorgangTestFactory.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.List; - -import org.bson.Document; - -class MigrationVorgangTestFactory { - - static final String FIELD_NAME = "name"; - static final String NAME = "Test Vorgang"; - - static final String FIELD_NUMMER = "nummer"; - static final String NUMMER = "2342454345654"; - - static final String FIELD_STATUS = "status"; - static final String STATUS = "NEU"; - - static final String FIELD_VERSION = "version"; - static final String VERSION = "0"; - - static final String FIELD_EINGANGS = "eingangs"; - - static final String FIELD_FORWARDINGS = "forwardings"; - - static final String FIELD_IN_CREATION = "inCreation"; - static final boolean IN_CREATION = false; - - static final String FIELD_WIEDERVORLAGES = "wiedervorlages"; - - static final String FIELD_KOMMENTARS = "kommentars"; - - static Document create() { - var vorgang = new Document(); - vorgang.put(FIELD_NAME, NAME); - vorgang.put(FIELD_NUMMER, NUMMER); - vorgang.put(FIELD_STATUS, STATUS); - vorgang.put(FIELD_VERSION, VERSION); - vorgang.put(FIELD_EINGANGS, List.of(MigrationEingangTestFactory.create())); - vorgang.put(FIELD_FORWARDINGS, new Document()); - vorgang.put(FIELD_IN_CREATION, IN_CREATION); - - return vorgang; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationWiedervorlageTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationWiedervorlageTestFactory.java deleted file mode 100644 index d041df5..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationWiedervorlageTestFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import java.util.Collections; - -import org.bson.Document; - -import com.thedeanda.lorem.LoremIpsum; - -public class MigrationWiedervorlageTestFactory { - - public final static String FIELD_BETREFF = "betreff"; - public final static String BETREFF = LoremIpsum.getInstance().getWords(2); - - public final static String FIELD_BESCHREIBUNG = "beschreibung"; - public final static String BESCHREIBUNG = LoremIpsum.getInstance().getWords(3); - - public final static String FIELD_ATTACHMENTS = "attachments"; - - public static Document create() { - var wiedervorlage = new Document(); - wiedervorlage.put(FIELD_BETREFF, BETREFF); - wiedervorlage.put(FIELD_BESCHREIBUNG, BESCHREIBUNG); - wiedervorlage.put(FIELD_ATTACHMENTS, Collections.emptyList()); - - return wiedervorlage; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationZustaendigeStelleTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationZustaendigeStelleTestFactory.java deleted file mode 100644 index f0cdf39..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationZustaendigeStelleTestFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.migration; - -import org.bson.Document; - -class MigrationZustaendigeStelleTestFactory { - - public static final String FIELD_ORGANISATIONSEINHEITEN_ID = "organisationseinheitenId"; - public static final String ORGANISATIONSEINHEIT_ID = "08150815"; - - public static final String FIELD_EMAIL = "email"; - public static final String EMAIL = "hase@loewenkaefig.de"; - - static Document create() { - var zustaendigeStelle = new Document(); - zustaendigeStelle.put(FIELD_ORGANISATIONSEINHEITEN_ID, ORGANISATIONSEINHEIT_ID); - zustaendigeStelle.put(FIELD_EMAIL, EMAIL); - - return zustaendigeStelle; - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchRequestTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchRequestTestFactory.java deleted file mode 100644 index bd812f6..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchRequestTestFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.search; - -import org.elasticsearch.core.List; - -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequestTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; - -class SearchRequestTestFactory { - static final int LIMIT = FindVorgangRequestTestFactory.LIMIT; - static final int OFFSET = FindVorgangRequestTestFactory.OFFSET; - - static final String QUERY = "vors"; - static final String ORGANISATIONSEINHEIT_ID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID; - static final boolean FILTER_BY_ORGANISATIONSEINHEIT_ID = true; - static final String ASSIGNED_TO = UserTestFactory.ID; - - static SearchRequest create() { - return createBuilder().build(); - } - - static SearchRequest.SearchRequestBuilder createBuilder() { - return SearchRequest.builder() - .limit(LIMIT) - .offSet(OFFSET) - .query(QUERY) - .filterByOrganisationseinheitIds(FILTER_BY_ORGANISATIONSEINHEIT_ID) - .assignedTo(ASSIGNED_TO) - .organisationseinheitIds(List.of(ORGANISATIONSEINHEIT_ID)); - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceITCase.java deleted file mode 100644 index 12ea40e..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceITCase.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.search; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.Optional; -import java.util.UUID; - -import org.bson.types.ObjectId; -import org.elasticsearch.core.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; - -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandService; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.FilterCriteriaTestFactory; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequestTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; - -@SearchITCase -public class SearchServiceITCase { - @Autowired - private SearchService searchService; - - @Autowired - private SearchVorgangRepostitory repostitory; - - @Autowired - private ElasticsearchOperations elasticsearchOperations; - - @MockBean - private CommandService commandService; - - @Nested - class TestAddVorgang { - @BeforeEach - void init() { - elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); - } - - @Test - void shouldAdd() throws IOException { - searchService.addVorgang(VorgangTestFactory.create()); - - Iterable<IndexedVorgang> vorgangs = repostitory.findAll(); - assertThat(vorgangs).isNotEmpty(); - } - } - - @Nested - class TestUpdateVorgang { - @BeforeEach - void init() { - Command cmd = CommandTestFactory.createBuilder().build(); - when(commandService.findCommand(CommandTestFactory.ID)).thenReturn(Optional.of(cmd)); - - elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); - - searchService.addVorgang(VorgangTestFactory.create()); - } - - @Test - void shouldUpdate() throws IOException { - var vorgang = VorgangTestFactory.createBuilder().status(Status.ABGESCHLOSSEN).build(); - searchService.updateVorgang(vorgang); - - Iterable<IndexedVorgang> vorgangs = repostitory.findAll(); - assertThat(vorgangs).isNotEmpty().hasSize(1); - assertThat(vorgangs.iterator().next().getStatus()).isEqualTo(Status.ABGESCHLOSSEN.name()); - } - } - - @Nested - class TestSearchVorgang { - @BeforeEach - void init() { - elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); - - searchService.addVorgang(VorgangTestFactory.create()); - searchService.addVorgang(VorgangTestFactory.createBuilder().id(new ObjectId().toHexString()).aktenzeichen("test") - .assignedTo(UUID.randomUUID().toString()).build()); - searchService.addVorgang(VorgangTestFactory.createBuilder().id(new ObjectId().toHexString()).aktenzeichen("vors").build()); - searchService.addVorgang(VorgangTestFactory.createBuilder().id(new ObjectId().toHexString()).aktenzeichen("vOrsi").build()); - - elasticsearchOperations.indexOps(IndexCoordinates.of("other-test")).delete(); - elasticsearchOperations.indexOps(IndexCoordinates.of("other-test")).create(); - elasticsearchOperations.save(IndexedVorgangTestFactory.create(), IndexCoordinates.of("other-test")); - } - - @Nested - class filteredByOrganisationseinheitenId { - @Test - void shouldFindByAktenzeichen() { - var res = searchService.find(FindVorgangRequestTestFactory.createBuilder() - .searchBy("vors") - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().assignedTo(null).build()) - .build()); - - assertThat(res).hasSize(2); - } - - @Test - void shouldFindByAntragstellerName() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().assignedTo(null).build()) - .build()); - - assertThat(res).hasSize(4); - } - - @Test - void shouldFindByAntragstellerNameAndAktenzeichen() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME + " tes") - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().assignedTo(null).build()) - .build()); - - assertThat(res).hasSize(1); - } - - @Test - void shouldFindByAntragstellerNameAndereOrganisationEinheitId() { - searchService - .addVorgang( - VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); - - var res = searchService.find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME).filterBy( - FilterCriteriaTestFactory.createBuilder() - .clearOrganisationseinheitIds() - .organisationseinheitIds(List.of("12345678")) - .clearStatus().build()) - .build()); - - assertThat(res).hasSize(1); - } - - @Test - void shouldDoPageination() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) - .limit(2) - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().build()) - .build()); - - assertThat(res).hasSize(2); - assertThat(res.getTotalPages()).isEqualTo(2); - } - } - - @Nested - class filteredForStatus { - @Test - void shouldFindByAntragstellerName() { - searchService - .addVorgang( - VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); - - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) - .filterBy(FilterCriteriaTestFactory.createBuilder().filterByOrganisationseinheitenId(false).build()) - .build()); - - assertThat(res).hasSize(5); - } - } - - @Nested - class filteredForStatusAndOrganisationEinheitId { - @BeforeEach - void init() { - searchService - .addVorgang( - VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); - searchService - .addVorgang(VorgangTestFactory.createBuilder().status(Status.ANGENOMMEN).id(UUID.randomUUID().toString()).build()); - } - - @Test - void shouldFindByAktenzeichen() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy("test") - .filterBy(FilterCriteriaTestFactory.createBuilder().assignedTo(null).build()) - .build()); - - assertThat(res).hasSize(1); - } - - @Test - void shouldFindByAntragstellerName() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) - .filterBy(FilterCriteriaTestFactory.createBuilder().assignedTo(null).build()) - .build()); - - assertThat(res).hasSize(4); - } - } - - @Nested - class filteredForAssignedToAndOrganisationEinheitId { - @BeforeEach - void init() { - searchService - .addVorgang( - VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); - } - - @Test - void shouldFindByAntragstellerName() { - var res = searchService - .find(FindVorgangRequestTestFactory.createBuilder() - .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().assignedTo(UserTestFactory.ID).build()) - .build()); - - assertThat(res).hasSize(3); - } - } - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImplTest.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImplTest.java deleted file mode 100644 index 5fc54e1..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepositoryImplTest.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.common.search; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import org.elasticsearch.core.List; -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.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; - -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangHeader; -import de.itvsh.ozg.pluto.vorgang.VorgangHeaderTestFactory; - -class SearchVorgangCustomRepositoryImplTest { - @InjectMocks - private SearchVorgangCustomRepositoryImpl searchRepostitory; - - @Mock - private IndexedVorgangMapper mapper; - - @Mock - private SearchProperties properties; - - @Mock - private ElasticsearchOperations operations; - - @Nested - class TestSearch { - - @Mock - private SearchHits<IndexedVorgang> searchHits; - @Mock - private SearchHit<IndexedVorgang> searchHit; - - @BeforeEach - void init() { - when(searchHit.getContent()).thenReturn(IndexedVorgangTestFactory.create()); - when(searchHits.get()).thenReturn(List.of(searchHit).stream()); - when(operations.search(any(NativeSearchQuery.class), eq(IndexedVorgang.class))).thenReturn(searchHits); - } - - @Test - void shouldCallSearch() { - searchRepostitory.searchBy(SearchRequestTestFactory.create()); - - verify(mapper, atLeastOnce()).toVorgangHeader(any()); - verify(operations).search(any(NativeSearchQuery.class), eq(IndexedVorgang.class)); - } - - @Test - void shouldMapResult() { - when(mapper.toVorgangHeader(any())).thenReturn(VorgangHeaderTestFactory.create()); - - var res = searchRepostitory.searchBy(SearchRequestTestFactory.create()); - - assertThat(res).isNotEmpty().hasAtLeastOneElementOfType(VorgangHeader.class); - } - } - - @Nested - class TestQuery { - @Test - void shouldHavePaging() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getPageable()).isNotNull(); - assertThat(query.getPageable().getOffset()).isZero(); - assertThat(query.getPageable().getPageSize()).isEqualTo(SearchRequestTestFactory.LIMIT); - assertThat(query.getPageable().getSort()).isEqualTo(Sort.unsorted()); - } - - @Test - void shouldHaveFieldsWithWights() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getQuery()).isNotNull(); - assertThat(query.getQuery()).asString().contains("aktenzeichen^2.0"); - assertThat(query.getQuery()).asString().contains("antragstellerName^1.0"); - assertThat(query.getQuery()).asString().contains("antragstellerVorname^1.0"); - assertThat(query.getQuery()).asString().contains("vorgangName^0.5"); - assertThat(query.getQuery()).asString().contains("vorgangNummer^2.0"); - } - - @Test - void shouldHaveSimpleQuery() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getQuery()).asString().contains("\"query\" : \"(*vors*)\""); - } - - @Test - void shouldHaveQuery() { - var request = SearchRequestTestFactory.createBuilder().query("vors test").build(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getQuery()).asString().contains("\"query\" : \"(*vors*) AND (*test*)\""); - } - - @Nested - class forRolePoststelle { - @Test - void shouldHaveStatusFilterOnly() { - var request = SearchRequestTestFactory.createBuilder().filterByOrganisationseinheitIds(false).organisationseinheitIds(null) - .status(List.of(Status.ABGESCHLOSSEN.name())) - .build(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getFilter()).isNotNull(); - assertThat(query.getFilter()).asString().contains("status"); - assertThat(query.getFilter()).asString().contains(Status.ABGESCHLOSSEN.name()); - assertThat(query.getFilter()).asString().doesNotContain("organisationseinheitenId"); - } - - @Test - void shouldHaveOrganisationseinheitenIdFilterOnly() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getFilter()).isNotNull(); - assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); - assertThat(query.getFilter()).asString().contains(SearchRequestTestFactory.ORGANISATIONSEINHEIT_ID); - } - - @Test - void shouldHaveOrganisationseinheitenAndStatusFilter() { - var request = SearchRequestTestFactory.createBuilder().status(List.of(Status.ABGESCHLOSSEN.name())).build(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getFilter()).isNotNull(); - assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); - assertThat(query.getFilter()).asString().contains(SearchRequestTestFactory.ORGANISATIONSEINHEIT_ID); - assertThat(query.getFilter()).asString().contains("status"); - assertThat(query.getFilter()).asString().contains(Status.ABGESCHLOSSEN.name()); - } - } - - @Nested - class forOtherRoles { - @Test - void shouldHaveOrganisationseinheitenIdFilter() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getFilter()).isNotNull(); - assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); - assertThat(query.getFilter()).asString().contains(SearchRequestTestFactory.ORGANISATIONSEINHEIT_ID); - } - - @Test - void shouldHaveAssignedToFilter() { - var request = SearchRequestTestFactory.create(); - var query = searchRepostitory.createQuery(request, PageRequest.of(request.getOffSet(), request.getLimit())); - - assertThat(query.getFilter()).isNotNull(); - assertThat(query.getFilter()).asString().contains("assignedTo"); - assertThat(query.getFilter()).asString().contains(SearchRequestTestFactory.ASSIGNED_TO); - } - } - } -} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapperTest.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapperTest.java deleted file mode 100644 index 96f020d..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapperTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.vorgang; - -import static org.assertj.core.api.Assertions.*; - -import org.apache.commons.lang3.StringUtils; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; - -class EingangHeaderMapperTest { - - private EingangHeaderMapper mapper = Mappers.getMapper(EingangHeaderMapper.class); - - @Nested - class TestFromGrpc { - - @Test - void shouldMapDateStrToZonedDateTime() { - GrpcEingangHeader grpcEingangHeader = GrpcEingangHeaderTestFactory.create(); - - var eingang = mapper.fromGrpc(grpcEingangHeader); - - assertThat(eingang.getCreatedAt()).isEqualTo(GrpcEingangHeaderTestFactory.CREATED_AT); - } - - @Test - void shouldMapAllFields() { - var mapped = mapper.fromGrpc(GrpcEingangHeaderTestFactory.create()); - - assertThat(mapped).usingRecursiveComparison().isEqualTo(EingangHeaderTestFactory.create()); - } - } - - @Nested - class TestToGrpc { - - @Test - void shouldMapZonedDateTimeToDateStr() { - EingangHeader plutoEingangHeader = EingangHeaderTestFactory.create(); - - var eingangHeader = mapper.toGrpc(plutoEingangHeader); - - assertThat(eingangHeader.getCreatedAt()).isEqualTo(EingangHeaderTestFactory.CREATED_AT_STR); - } - - @Test - void shouldProceedWithEmptyValues() { - EingangHeader plutoEingangHeader = EingangHeaderTestFactory.createBuilder().createdAt(null).build(); - - var eingangHeader = mapper.toGrpc(plutoEingangHeader); - - assertThat(eingangHeader.getCreatedAt()).isEqualTo(StringUtils.EMPTY); - } - - } -} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceITCase.java deleted file mode 100644 index 1eb03fa..0000000 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceITCase.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.ozg.pluto.vorgang; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.util.Optional; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.mongodb.core.MongoOperations; -import org.springframework.security.test.context.support.WithMockUser; - -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandService; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; - -@DataITCase -@WithMockUser -class VorgangServiceITCase { - - @Autowired - private VorgangService vorgangService; - - @Autowired - private VorgangRepository repository; - - @Autowired - private MongoOperations mongoOperations; - - @MockBean - private CommandService commandService; - - @Nested - class TestVorgangUpdateStatus { - - private Vorgang persistedVorgang; - private Command command; - - @BeforeEach - void persistVorgang() { - mongoOperations.dropCollection(Vorgang.class); - persistedVorgang = repository.save(VorgangTestFactory.create()); - - command = CommandTestFactory.createBuilder().relationId(persistedVorgang.getId()).relationVersion(persistedVorgang.getVersion()).build(); - when(commandService.findCommand(any())).thenReturn(Optional.of(command)); - } - - @Test - void annehmenShouldUpdateStatusAndVersion() { - - vorgangService.annehmen(command); - - Optional<Vorgang> vorgang = repository.findById(persistedVorgang.getId()); - - assertThat(vorgang.get().getStatus()).isEqualTo(Status.ANGENOMMEN); - assertThat(vorgang.get().getVersion()).isEqualTo(persistedVorgang.getVersion() + 1); - } - - @Test - void verwerfenShouldUpdateStatusAndVersion() { - - vorgangService.verwerfen(command); - - Optional<Vorgang> vorgang = repository.findById(persistedVorgang.getId()); - - assertThat(vorgang.get().getStatus()).isEqualTo(Status.VERWORFEN); - assertThat(vorgang.get().getVersion()).isEqualTo(persistedVorgang.getVersion() + 1); - } - - @Test - void bescheidenShouldUpdateStatusAndVersion() { - - vorgangService.bescheiden(command); - - Optional<Vorgang> vorgang = repository.findById(persistedVorgang.getId()); - - assertThat(vorgang.get().getStatus()).isEqualTo(Status.BESCHIEDEN); - assertThat(vorgang.get().getVersion()).isEqualTo(persistedVorgang.getVersion() + 1); - } - - @Test - void wiedereroeffnenShouldUpdateStatusAndVersion() { - - vorgangService.wiedereroeffnen(command); - - Optional<Vorgang> vorgang = repository.findById(persistedVorgang.getId()); - - assertThat(vorgang.get().getStatus()).isEqualTo(Status.IN_BEARBEITUNG); - assertThat(vorgang.get().getVersion()).isEqualTo(persistedVorgang.getVersion() + 1); - } - } -} \ No newline at end of file diff --git a/pluto-server/src/test/resources/application-itcase.yml b/pluto-server/src/test/resources/application-itcase.yml deleted file mode 100644 index 8af9c9e..0000000 --- a/pluto-server/src/test/resources/application-itcase.yml +++ /dev/null @@ -1,26 +0,0 @@ -logging: - level: - ROOT: ERROR, - '[org.springframework]': ERROR - '[org.springframework.data.mongodb.core]': WARN - '[de.itvsh]': WARN - config: classpath:log4j2-local.xml - -grpc: - server: - port: -1 - -aktenzeichen: de.itvsh.ozg.pluto.vorgang.AktenzeichenProviderEA - -kop: - osi: - postfach: - proxyapi: - url: http://localhost/ApiProxy/V1/Message - key: 1234 - realm: test-realm - notification: - mail-from: test@local.host - -mongock: - enabled: false \ No newline at end of file diff --git a/pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapper.java b/pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapper.java deleted file mode 100644 index 4fb8122..0000000 --- a/pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapper.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.pluto.common.grpc; - -import java.time.LocalDate; -import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.mapstruct.Mapper; - -import de.itvsh.kop.common.datatype.StringBasedValue; -import de.itvsh.ozg.pluto.common.GrpcObject; -import de.itvsh.ozg.pluto.common.GrpcProperty; -import de.itvsh.ozg.pluto.common.GrpcSubObject; - -@Mapper -public interface GrpcObjectMapper { - - default GrpcObject fromMap(Map<String, Object> map) { - return GrpcObject.newBuilder() - .addAllProperty(mapToAllProperties(map)) - .addAllSubObject(mapToSubObjects(map)) - .build(); - } - - @SuppressWarnings("unchecked") - default List<GrpcSubObject> mapToSubObjects(Map<String, Object> propertyMap) { - return propertyMap.entrySet().stream() - .filter(entry -> entry.getValue() instanceof Map) - .map(entry -> buildSubObject(entry.getKey(), (Map<String, Object>) entry.getValue())) - .toList(); - } - - default GrpcSubObject buildSubObject(String name, Map<String, Object> map) { - return GrpcSubObject.newBuilder().setName(name) - .addAllProperty(mapToAllProperties(map)) - .addAllSubObject(mapToSubObjects(map)).build(); - } - - // FIXME den filter ausbauen - dadurch gehen unbemerkt properties verloren - default List<GrpcProperty> mapToAllProperties(Map<String, Object> propertyMap) { - return propertyMap.entrySet().stream().filter(this::isPropertyType) - .map(entry -> mapToProperty(entry.getKey(), entry.getValue())) - .toList(); - } - - default GrpcProperty mapToProperty(String name, Object value) { - // TODO nicht auf 'List' sondern auf 'Collection' prüfen - if (value instanceof List<?> valueList) { - return GrpcProperty.newBuilder().setName(name).addAllValue(valueList.stream().map(String::valueOf).toList()) - .build(); - } - return GrpcProperty.newBuilder().setName(name).addValue(value.toString()).build(); - } - - default boolean isPropertyType(Entry<String, Object> entry) { - return entry.getValue() instanceof String - || entry.getValue() instanceof Integer - || entry.getValue() instanceof Long - || entry.getValue() instanceof ZonedDateTime - || entry.getValue() instanceof LocalDate - || entry.getValue() instanceof StringBasedValue - || entry.getValue() instanceof Boolean - || entry.getValue() instanceof List; - } - - default Map<String, Object> mapFromGrpc(GrpcObject bodyObject) { - var map = new HashMap<String, Object>(); - bodyObject.getPropertyList().stream().forEach(property -> mapProperty(map, property)); - bodyObject.getSubObjectList().stream().forEach(subObject -> map.put(subObject.getName(), mapSubObject(subObject))); - - return map; - } - - private Map<String, Object> mapSubObject(GrpcSubObject object) { - var map = new HashMap<String, Object>(); - object.getPropertyList().stream().forEach(property -> mapProperty(map, property)); - object.getSubObjectList().stream().forEach(subObject -> map.put(subObject.getName(), mapSubObject(subObject))); - - return map; - } - - private void mapProperty(HashMap<String, Object> map, GrpcProperty property) { - if (property.getValueCount() == 1) { - map.put(property.getName(), String.valueOf(property.getValue(0))); - } else if (property.getValueCount() > 1) { - map.put(property.getName(), property.getValueList().stream().map(String::valueOf).toList()); - } - } -} \ No newline at end of file diff --git a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapperTest.java b/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapperTest.java deleted file mode 100644 index 4ca5773..0000000 --- a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapperTest.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.pluto.common.grpc; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import de.itvsh.ozg.pluto.vorgang.GrpcFormData; -import de.itvsh.ozg.pluto.vorgang.GrpcFormField; -import de.itvsh.ozg.pluto.vorgang.GrpcSubForm; - -class GrpcFormDataMapperTest { - - @InjectMocks - private GrpcFormDataMapper MAPPER_INSTANCE = Mappers.getMapper(GrpcFormDataMapper.class); - - @Mock - private GrpcFormDataMapper grpcFormDataMapper; - - @BeforeEach - void mockMapperReturnValues() { - lenient().when(grpcFormDataMapper.mapToFormData(anyMap())) - .thenReturn(GrpcFormData.newBuilder().addField(GrpcFormFieldTestFactory.create()).build()); - } - - @Nested - class TestSimpleValueMapping { - - @Test - void shouldHaveField() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", "value")); - - assertThat(formData.getFieldList()).hasSize(1); - } - - @Test - void shouldNotHaveSubForms() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", "value")); - - assertThat(formData.getFormList()).isEmpty(); - } - - @Test - void shouldHaveNameField() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", "value")); - - assertThat(formData.getField(0).getName()).isEqualTo("key"); - assertThat(formData.getField(0).getValue()).isEqualTo("value"); - } - } - - @Nested - class TestSubFormMapping { - - @Test - void shouldHaveSubForm() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", Map.of("subKey", "value"))); - - assertThat(formData.getFormList()).hasSize(1); - } - - @Test - void shouldNotHaveFields() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", Map.of("subKey", "value"))); - - assertThat(formData.getFieldList()).isEmpty(); - } - - @Test - void shouldHaveSubFormField() { - - GrpcFormData formData = MAPPER_INSTANCE.mapToFormData(Map.of("key", Map.of("subKey", "value"))); - - assertThat(formData.getForm(0).getFieldList()).hasSize(1); - assertThat(formData.getForm(0).getTitle()).isEqualTo("key"); - assertThat(formData.getForm(0).getField(0).getName()).isEqualTo("subKey"); - assertThat(formData.getForm(0).getField(0).getValue()).isEqualTo("value"); - } - } - - @DisplayName("Mapped SubFormField") - @Nested - class TestSubFormFieldMapping { - - private final GrpcSubForm subForm = GrpcSubFormTestFactory.create(); - - @Test - void shouldContainField() { - var mapped = MAPPER_INSTANCE.mapSubFormFields(subForm.getFieldList()); - - assertThat(mapped).containsKey(GrpcSubFormTestFactory.FIELD_NAME); - } - - @Test - void shouldContainValue() { - var mapped = MAPPER_INSTANCE.mapSubFormFields(subForm.getFieldList()); - - assertThat(mapped).containsEntry(GrpcSubFormTestFactory.FIELD_NAME, GrpcSubFormTestFactory.FIELD_VALUE); - } - - @Nested - class TestCombiner { - @Test - void missingInMap2ShouldContainValue() { - Map<String, Object> map1 = Map.of("TEST", "VALUE1"); - Map<String, Object> map2 = Map.of(); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", "VALUE1"); - } - - @Test - void missingInMap1ShouldContainValue() { - Map<String, Object> map1 = new HashMap<>(); - Map<String, Object> map2 = Map.of("TEST", "VALUE1"); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", "VALUE1"); - } - - @Test - void inBothMapShouldCombineToList() { - Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); - Map<String, Object> map2 = Map.of("TEST", "VALUE2"); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); - } - - @Test - void listInMap2ShouldStayAList() { - Map<String, Object> map1 = Map.of("TEST", List.of("VALUE1", "VALUE2")); - Map<String, Object> map2 = Map.of(); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); - } - - @Test - void valueInMap1ShouldBeAddedToList() { - Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); - Map<String, Object> map2 = Map.of("TEST", List.of("VALUE2", "VALUE3")); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3")); - } - - @Test - void valueInMap2ShouldBeAddedToList() { - Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); - Map<String, Object> map2 = Map.of("TEST", "VALUE3"); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3")); - } - - @Test - void listInMap1ShouldStayAList() { - Map<String, Object> map1 = new HashMap<>(); - Map<String, Object> map2 = Map.of("TEST", List.of("VALUE1", "VALUE2")); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); - } - - @Test - void listInBothMapsShouldByCombined() { - Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); - Map<String, Object> map2 = Map.of("TEST", List.of("VALUE3", "VALUE4")); - - var combined = MAPPER_INSTANCE.combiner(map1, map2); - - assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3", "VALUE4")); - } - } - } - - @Nested - class TestMapStringListsToFields { - - @Test - void emptyMapShouldNotBeMapped() { - - List<GrpcFormField> fields = MAPPER_INSTANCE.mapStringListsToFields(Collections.emptyMap()); - - assertThat(fields).isEmpty(); - } - - @Test - void simpleValueShouldNotBeMapped() { - - List<GrpcFormField> fields = MAPPER_INSTANCE.mapStringListsToFields(Map.of("a", "b")); - - assertThat(fields).isEmpty(); - } - - @Test - void listObjectValuesShouldBeMapped() { - - List<GrpcFormField> fields = MAPPER_INSTANCE.mapStringListsToFields(Map.of("key", List.of("value1", "value2"))); - - assertThat(fields).hasSize(2); - assertThat(fields.get(0).getName()).isEqualTo("key"); - assertThat(fields.get(0).getValue()).isEqualTo("value1"); - - assertThat(fields.get(1).getName()).isEqualTo("key"); - assertThat(fields.get(1).getValue()).isEqualTo("value2"); - } - } - - @Nested - class TestMapObjectListsToFields { - - @Test - void simpleValueShouldNotBeMapped() { - - List<GrpcSubForm> fields = MAPPER_INSTANCE.mapObjectListsToFields(Map.of("a", "b")); - - assertThat(fields).isEmpty(); - } - - @Test - void listOfSimpleValueShouldNotBeMapped() { - - List<GrpcSubForm> fields = MAPPER_INSTANCE.mapObjectListsToFields(Map.of("a", List.of("l1", "l2"))); - - assertThat(fields).isEmpty(); - } - - @Test - void listOfObjectsShouldBeMappedToSubForms() { - - List<GrpcSubForm> fields = MAPPER_INSTANCE - .mapObjectListsToFields(Map.of("key", List.of(Collections.emptyMap(), Collections.emptyMap()))); - - assertThat(fields).hasSize(2); - } - - @Test - void listOfObjectsShouldMappedToSubFormTitle() { - - List<GrpcSubForm> fields = MAPPER_INSTANCE - .mapObjectListsToFields(Map.of("key", List.of(Collections.emptyMap(), Collections.emptyMap()))); - - assertThat(fields.get(0).getTitle()).isEqualTo("key"); - assertThat(fields.get(1).getTitle()).isEqualTo("key"); - } - - @Test - void listOfObjectsShouldBeMapped() { - - List<GrpcSubForm> fields = MAPPER_INSTANCE - .mapObjectListsToFields(Map.of("key", List.of(Map.of("a1", "a2")))); - - assertThat(fields.get(0).getFieldCount()).isEqualTo(1); - assertThat(fields.get(0).getField(0).getName()).isEqualTo("a1"); - assertThat(fields.get(0).getField(0).getValue()).isEqualTo("a2"); - } - - @Test - void doubleNestedListObjectValuesShouldBeMapped() { - GrpcFormData formData = MAPPER_INSTANCE - .mapToFormData(Map.of("key1", Map.of("key2", List.of("value1", "value2")))); - - assertThat(formData.getForm(0).getFieldCount()).isEqualTo(2); - } - - @Test - void multipleNestedListObjectValuesShouldBeMapped() { - GrpcFormData formData = MAPPER_INSTANCE - .mapToFormData(Map.of("key1", Map.of("key2", Map.of("key3", List.of("value1", "value2"))))); - - assertThat(formData.getForm(0).getSubForm(0).getFieldCount()).isEqualTo(2); - } - } - - @Nested - class TestMapListOfMixedValuesInFormData { - - @Test - void shouldMapListOfStrings() { - - GrpcFormData formData = MAPPER_INSTANCE - .mapToFormData(Map.of("key", List.of("value1", "value2", Map.of("internKey1", "internValue1")))); - - assertThat(formData.getFieldCount()).isEqualTo(2); - assertThat(formData.getFormCount()).isEqualTo(1); - } - } -} diff --git a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapperTest.java b/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapperTest.java deleted file mode 100644 index 87ec689..0000000 --- a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectMapperTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.pluto.common.grpc; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Map; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; - -import de.itvsh.ozg.pluto.common.GrpcObject; - -class GrpcObjectMapperTest { - - private final GrpcObjectMapper mapper = Mappers.getMapper(GrpcObjectMapper.class); - - @Test - void shouldMapStringMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.STRING_MAP); - - assertThat(grpcObject).isNotNull(); - assertThat(grpcObject.getPropertyCount()).isEqualTo(1); - assertThat(grpcObject.getProperty(0).getName()).isEqualTo(GrpcObjectTestFactory.PROPERTY_NAME); - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_NAME_VALUE); - } - - @Test - void shouldMapLongMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.LONG_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_LONG_VALUE.toString()); - } - - @Test - void shouldMapIntegerMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.INTEGER_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_INT_VALUE.toString()); - } - - @Test - void shouldMapBooleanMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.BOOLEAN_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_BOOLEAN_VALUE.toString()); - } - - @Test - void shouldMapLocalDateMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.LOCAL_DATE_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_LOCAL_DATE_VALUE.toString()); - } - - @Test - void shouldMapZonedDateTimeMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.ZONED_DATE_TIME_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_ZONED_DATE_TIME_VALUE.toString()); - } - - @Test - void shouldMapFileIdMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.FILE_ID_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_FILE_ID_VALUE.toString()); - } - - @Test - void shouldMapFileIdListMapToGrpc() { - var grpcObject = mapper.fromMap(GrpcObjectTestFactory.FILE_ID_LIST_MAP); - - assertThat(getFirstValueOfFirstProperty(grpcObject)).isEqualTo(GrpcObjectTestFactory.PROPERTY_FILE_ID_VALUE.toString()); - assertThat(grpcObject.getProperty(0).getValue(1)).isEqualTo(GrpcObjectTestFactory.PROPERTY_FILE_ID_VALUE.toString()); - } - - private String getFirstValueOfFirstProperty(GrpcObject grpcObject) { - return grpcObject.getProperty(0).getValue(0); - } - - @Nested - class TestMapFromGrpcObject { - - private final GrpcObject grpcObject = GrpcObjectTestFactory.create(); - - @Nested - class Property { - - @Test - void shouldPutAsEntryInMap() { - var map = mapFromGrpc(); - - assertThat(map).contains(GrpcObjectTestFactory.PROPERTY_AS_MAP_ENTRY); - } - } - - @Nested - class SubObject { - - @Test - void shouldPutNameAsKeyInMap() { - var map = mapFromGrpc(); - - assertThat(map).containsKey(GrpcObjectTestFactory.SUB_OBJECT_NAME); - } - - @Test - void shouldPutPropertyAsValueInMap() { - var map = mapFromGrpc(); - - assertThat(getSubObjectMap(map, GrpcObjectTestFactory.SUB_OBJECT_NAME)).contains(GrpcObjectTestFactory.PROPERTY_AS_MAP_ENTRY); - } - - @Nested - class WithSubObject { - - @Test - void shouldPutNameAsKeyInSubObjectMap() { - var map = mapFromGrpc(); - - assertThat(getSubObjectMap(map, GrpcObjectTestFactory.SUB_OBJECT_NAME)) - .containsKey(GrpcObjectTestFactory.SUB_OBJECT_NAME_OF_SUB_OBJECT); - } - - @Test - void shouldPutPropertyAsValueInSubObjectMap() { - var map = mapFromGrpc(); - - assertThat(getSubObjectMap(getSubObjectMap(map, GrpcObjectTestFactory.SUB_OBJECT_NAME), - GrpcObjectTestFactory.SUB_OBJECT_NAME_OF_SUB_OBJECT)).contains(GrpcObjectTestFactory.PROPERTY_AS_MAP_ENTRY); - } - } - - @SuppressWarnings("unchecked") - private Map<String, Object> getSubObjectMap(Map<String, Object> map, String key) { - return (Map<String, Object>) map.get(key); - } - } - - private Map<String, Object> mapFromGrpc() { - return mapper.mapFromGrpc(grpcObject); - } - } -} diff --git a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectTestFactory.java b/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectTestFactory.java deleted file mode 100644 index 9e0f770..0000000 --- a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcObjectTestFactory.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.pluto.common.grpc; - -import java.time.LocalDate; -import java.time.ZonedDateTime; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import com.thedeanda.lorem.LoremIpsum; - -import de.itvsh.kop.common.binaryfile.FileId; -import de.itvsh.ozg.pluto.common.GrpcObject; -import de.itvsh.ozg.pluto.common.GrpcProperty; -import de.itvsh.ozg.pluto.common.GrpcSubObject; - -public class GrpcObjectTestFactory { - - public static final String PROPERTY_NAME = "propertyName"; - public static final String PROPERTY_NAME_VALUE = "propertyNameValue"; - - public static final Integer PROPERTY_INT_VALUE = Integer.MAX_VALUE; - - public static final Long PROPERTY_LONG_VALUE = 42L; - - public static final Boolean PROPERTY_BOOLEAN_VALUE = Boolean.TRUE; - - public static final Date PROPERTY_DATE_VALUE = new Date(); - - public static final LocalDate PROPERTY_LOCAL_DATE_VALUE = LocalDate.now(); - - public static final ZonedDateTime PROPERTY_ZONED_DATE_TIME_VALUE = ZonedDateTime.now(); - - public static final FileId PROPERTY_FILE_ID_VALUE = FileId.createNew(); - - public static final List<FileId> PROPERTY_FILE_ID_LIST_VALUE = List.of(PROPERTY_FILE_ID_VALUE, PROPERTY_FILE_ID_VALUE); - public static final Map<String, Object> STRING_MAP = Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE); - public static final Map<String, Object> INTEGER_MAP = Map.of(PROPERTY_NAME, PROPERTY_INT_VALUE); - public static final Map<String, Object> LONG_MAP = Map.of(PROPERTY_NAME, PROPERTY_LONG_VALUE); - public static final Map<String, Object> BOOLEAN_MAP = Map.of(PROPERTY_NAME, PROPERTY_BOOLEAN_VALUE); - public static final Map<String, Object> DATE_MAP = Map.of(PROPERTY_NAME, PROPERTY_DATE_VALUE); - public static final Map<String, Object> LOCAL_DATE_MAP = Map.of(PROPERTY_NAME, PROPERTY_LOCAL_DATE_VALUE); - public static final Map<String, Object> ZONED_DATE_TIME_MAP = Map.of(PROPERTY_NAME, PROPERTY_ZONED_DATE_TIME_VALUE); - public static final Map<String, Object> FILE_ID_MAP = Map.of(PROPERTY_NAME, PROPERTY_FILE_ID_VALUE); - public static final Map<String, Object> FILE_ID_LIST_MAP = Map.of(PROPERTY_NAME, PROPERTY_FILE_ID_LIST_VALUE); - - public static final String SUB_OBJECT_NAME = LoremIpsum.getInstance().getWords(1); - public static final String SUB_OBJECT_NAME_OF_SUB_OBJECT = LoremIpsum.getInstance().getWords(1); - public static final Map.Entry<String, Object> PROPERTY_AS_MAP_ENTRY = Map.entry(PROPERTY_NAME, PROPERTY_NAME_VALUE); - - public static GrpcObject create() { - return createBuilder().build(); - } - - public static GrpcObject.Builder createBuilder() { - return GrpcObject.newBuilder() - .addProperty(GrpcProperty.newBuilder().setName(PROPERTY_NAME).addValue(PROPERTY_NAME_VALUE).build()) - .addSubObject(GrpcSubObject.newBuilder() - .setName(SUB_OBJECT_NAME) - .addProperty(GrpcProperty.newBuilder().setName(PROPERTY_NAME).addValue(PROPERTY_NAME_VALUE).build()) - .addSubObject(GrpcSubObject.newBuilder() - .setName(SUB_OBJECT_NAME_OF_SUB_OBJECT) - .addProperty(GrpcProperty.newBuilder().setName(PROPERTY_NAME).addValue(PROPERTY_NAME_VALUE).build())) - .build()); - } - - public static GrpcObject fromStringMap(Map<String, String> map) { - var builder = GrpcObject.newBuilder(); - map.entrySet().forEach(entry -> builder.addProperty( - GrpcProperty.newBuilder().setName(entry.getKey()).addValue(entry.getValue()).build()) - .build()); - return builder.build(); - } -} \ No newline at end of file diff --git a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcSubFormTestFactory.java b/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcSubFormTestFactory.java deleted file mode 100644 index 987dfc0..0000000 --- a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcSubFormTestFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2022 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.itvsh.kop.pluto.common.grpc; - -import de.itvsh.ozg.pluto.vorgang.GrpcFormField; -import de.itvsh.ozg.pluto.vorgang.GrpcSubForm; - -public class GrpcSubFormTestFactory { - - public static final String TITLE = "kontakt"; - - public static final String FIELD_NAME = "name"; - public static final String FIELD_VALUE = "Thea"; - - public static final String SUBFORM_NAME = "kontakt"; - public static final String SUBFORM_FIELD_NAME = "E-Mail"; - public static final String SUBFORM_FIELD_VALUE = "thea@mailinator.de"; - - public static GrpcSubForm create() { - return createBuilder().build(); - } - - public static GrpcSubForm.Builder createBuilder() { - return GrpcSubForm.newBuilder() - .setTitle(TITLE) - .addField(GrpcFormField.newBuilder().setName(FIELD_NAME).setValue(FIELD_VALUE).build()) - .addSubForm(GrpcSubForm.newBuilder().setTitle(SUBFORM_NAME).addField( - GrpcFormField.newBuilder().setName(SUBFORM_FIELD_NAME).setValue(SUBFORM_FIELD_VALUE).build())); - } -} \ No newline at end of file diff --git a/pom.xml b/pom.xml index d665701..de22050 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,25 +24,66 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>de.itvsh.ozg</groupId> - <artifactId>pluto</artifactId> - <version>1.0.0</version> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager</artifactId> + <version>2.4.0</version> - <name>Pluto Parent</name> + <name>OZG-Cloud Vorgang Manager</name> <packaging>pom</packaging> + <properties> + <ozgcloud.license.version>1.6.0</ozgcloud.license.version> + </properties> + <modules> - <module>pluto-interface</module> - <module>pluto-server</module> - <module>mail-service</module> - <module>pluto-utils</module> + <module>vorgang-manager-interface</module> + <module>vorgang-manager-server</module> + <module>nachrichten-manager</module> + <module>vorgang-manager-utils</module> <module>notification-manager</module> + <module>vorgang-manager-command</module> + <module>bescheid-manager</module> + <module>vorgang-manager-base</module> + <module>nachrichten-bayernid-proxy</module> </modules> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <version>4.1</version> + <configuration> + <mapping> + <config>SCRIPT_STYLE</config> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/README</exclude> + <exclude>src/test/resources/**</exclude> + <exclude>src/main/resources/**</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </pluginManagement> + </build> + <distributionManagement> <repository> <id>ozg-nexus</id> @@ -56,4 +97,3 @@ </snapshotRepository> </distributionManagement> </project> - \ No newline at end of file diff --git a/release-erstellen.sh b/release-erstellen.sh new file mode 100755 index 0000000..6d07a59 --- /dev/null +++ b/release-erstellen.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# 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. +# + + +if [ "$#" -ne 1 ]; then + echo "Aufruf: release-erstellen.sh JA" + echo "Als Parameter bitte 'JA' eintragen zur Sicherheit" + exit 1 +fi + + +## alle -SNAPSHOT in pom.xmls entfernen +SED_PARAMS="-i" +if [[ "$OSTYPE" =~ ^darwin ]]; then + SED_PARAMS="$SED_PARAMS '' -e" +fi +find . -name pom.xml -exec sed $SED_PARAMS 's/-SNAPSHOT//g' {} + + +## release version auslesen +NEWVERSION=$(xmlstarlet sel -N w="http://maven.apache.org/POM/4.0.0" -t -v '//w:project/w:version' -n pom.xml) + +echo +echo "NEXT STEPS:" +echo "***********" +echo "Änderungen prüfen" +echo "git commit -a -m 'release version "$NEWVERSION"'" +echo "git push" +echo "git tag "$NEWVERSION +echo "git push --tags" diff --git a/release-startdev.sh b/release-startdev.sh new file mode 100755 index 0000000..a229763 --- /dev/null +++ b/release-startdev.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# 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. +# + + +#set -x + +if [ "$#" -ne 1 ]; then + echo "Aufruf: ozg-release-startdev.sh NEWVERSION" + exit 1 +fi + +NEWVERSION=$1 + +echo + +# pom.xml:main -> project.version setzen +# projectname/pom.xml:parent -> project.parent.version setzen +# projectname/pom.xml:parent,main -> project.parent.version und project.version setzen +# +PROJECTS="pom.xml:main + vorgang-manager-server/pom.xml:main + vorgang-manager-interface/pom.xml:main + vorgang-manager-utils/pom.xml:main + nachrichten-manager/pom.xml:main + notification-manager/pom.xml:main + vorgang-manager-command/pom.xml:main + vorgang-manager-base/pom.xml:main + bescheid-manger/pom.xml:main + " + +for PROJECT in $PROJECTS; +do + POMFILE=$(echo $PROJECT | cut -d':' -f1) + ACTIONS=$(echo $PROJECT | cut -d':' -f2) + + ## Auf SNAPSHOT Versionen testen + if fgrep -q "SNAPSHOT" $POMFILE; then + RED='\033[0;31m' + NC='\033[0m' + echo "${RED}ERROR: Datei "$POMFILE" enthält noch SNAPSHOT Versionen, das sollte hier nicht passieren.${NC}" + exit 1 + fi +echo $ACTIONS + ## Versionen setzen + if [[ $ACTIONS == "main" ]] ; then + xmlstarlet ed --pf -L -N w="http://maven.apache.org/POM/4.0.0" -u '//w:project/w:version' -v $NEWVERSION $POMFILE + fi + + if [[ $ACTIONS == "parent" ]]; then + xmlstarlet ed --pf -L -N w="http://maven.apache.org/POM/4.0.0" -u '//w:project/w:parent/w:version' -v $NEWVERSION $POMFILE + fi +done + + + +echo +echo "NEXT STEPS:" +echo "***********" +echo "Änderungen prüfen" +echo "git commit -a -m 'start development "$NEWVERSION"'" +echo "git push" + diff --git a/run_helm_test.sh b/run_helm_test.sh new file mode 100755 index 0000000..83200aa --- /dev/null +++ b/run_helm_test.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# +# 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. +# + + +set -e +set -x + +helm template ./src/main/helm/ -f src/test/helm-linter-values.yaml +helm lint -f src/test/helm-linter-values.yaml ./src/main/helm/ +cd src/main/helm && helm unittest -f '../../test/helm/**/*test.yaml' . + diff --git a/src/main/helm/Chart.yaml b/src/main/helm/Chart.yaml new file mode 100644 index 0000000..f7a9cfa --- /dev/null +++ b/src/main/helm/Chart.yaml @@ -0,0 +1,30 @@ +# +# 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. +# + +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Vorgang-Manager +name: vorgang-manager +version: 0.0.0-MANAGED-BY-JENKINS +icon: https://simpleicons.org/icons/helm.svg diff --git a/src/main/helm/README.md b/src/main/helm/README.md new file mode 100644 index 0000000..409f1dc --- /dev/null +++ b/src/main/helm/README.md @@ -0,0 +1,41 @@ +# Vorgang-Manager + +Das helm chart zur Installation des Vorgang-Managers. + +## FAQ + +### Benutzung beliebiger environment Werte + +In jedem der Projekte kann man beliebige weitere environments setzen. Dazu muss man in der jeweiligen values.yaml unter env.customList ein name value Paar setzen: + +```yaml +env: + customList: + - name: Dinge + value: true + - name: ... + value: ... +``` + +Um beispielsweise dem Spring eine Variable zu übergeben ``mongock.enabled=false`` kann man Folgendes konfigurieren: + +```yaml +env: + customList: + - name: mongock_enabled + value: "false" +``` + +### Nutzen einer externen MongoDB + +Möchte man Vorgang-Manager mit einer externen MongoDB verbinden, so muss unter `Datenbank` die +`Nutze externe Datenbank` Checkbox gesetzt sein und im Namespace muss sich ein Opaque Secret mit +Namen `vorgang-manager-database-spring` befinden. + +In dem Secret müssen folgende Felder vorhanden sein. + +```yaml +spring_data_mongodb_authentication-database: <authentication-database> # sollte admin sein +spring_data_mongodb_database: KOP_DB_SH_<Bezeichner in upper-case> +spring_data_mongodb_uri: mongodb://KOP_User_SH_<Bezeichner in upper-case>:<Password>@<IP-DB-1>:<PORT-DB-1>,<IP-DB-2>:<PORT-DB-2>,<IP-DB-3>:<PORT-DB-3>/<authentication-database>?ssl=false +``` \ No newline at end of file diff --git a/src/main/helm/templates/_helpers.tpl b/src/main/helm/templates/_helpers.tpl new file mode 100644 index 0000000..4ff4bae --- /dev/null +++ b/src/main/helm/templates/_helpers.tpl @@ -0,0 +1,99 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* Namespace */}} +{{- define "app.namespace" -}} +{{- if gt (len (.Release.Namespace)) 63 -}} +{{- fail (printf ".Release.Namespace %s ist zu lang (max. 63 Zeichen)" .Release.Namespace) -}} +{{- end -}} +{{ printf "%s" .Release.Namespace }} +{{- end -}} + +{{/* Chart: Name + Version */}} +{{- define "app.chart" -}} +{{- if gt (len (printf "%s-%s" .Chart.Name .Chart.Version)) 63 -}} +{{- fail (printf ".Chart.Name-.Chart.Version %s-%s ist zu lang (max. 63 Zeichen)" .Chart.Name .Chart.Version) -}} +{{- end -}} +{{ printf "%s-%s" .Chart.Name .Chart.Version }} +{{- end -}} + +{{/* Managed-by -> On Helm, this value is always Helm */}} +{{- define "app.managedBy" -}} +{{- if gt (len (.Release.Service)) 63 -}} +{{- fail (printf ".Release.Service %s ist zu lang (max. 63 Zeichen)" .Release.Service) -}} +{{- end -}} +{{ printf "%s" .Release.Service }} +{{- end -}} + +{{/* Default Labels: Helm recommended best-practice labels https://helm.sh/docs/chart_best_practices/labels/ */}} +{{- define "app.defaultLabels" }} +app.kubernetes.io/instance: vorgang-manager +app.kubernetes.io/managed-by: {{ include "app.managedBy" . }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ include "app.namespace" . }} +app.kubernetes.io/part-of: ozgcloud +app.kubernetes.io/version: {{ .Chart.Version }} +helm.sh/chart: {{ include "app.chart" . }} +{{- end -}} + +{{- define "app.matchLabels" }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ include "app.namespace" . }} +{{- end -}} + +{{- define "app.imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} + +{{- define "app.envSpringProfiles" }} +{{- if (.Values.env).overrideSpringProfiles -}} +{{ printf "%s" (.Values.env).overrideSpringProfiles }} +{{- else -}} +{{ printf "oc, %s" (include "app.ozgcloudEnvironment" . ) }} +{{- end -}} +{{- end -}} + +{{- define "app.ozgcloudEnvironment" -}} +{{- required "ozgcloud.environment muss angegeben sein" (.Values.ozgcloud).environment -}} +{{- end -}} + +{{- define "app.vorgangManagerDatabase" -}} +{{- if (.Values.database).databaseName -}} +{{ .Values.database.databaseName }} +{{- else -}} +{{ printf "vorgang-manager-database" }} +{{- end -}} +{{- end -}} + +{{- define "app.grpc_client_user-manager_address" -}} +{{ printf "%s.%s:9000" .Values.usermanagerName .Release.Namespace }} +{{- end -}} + +{{- define "app.ozgcloud_migration_user-manager_address" -}} +{{ printf "http://%s.%s:8080/migration/user" .Values.usermanagerName .Release.Namespace }} +{{- end -}} + +{{- define "app.ozgcloud_vorgangmanager_address" -}} +{{ printf "dns://%s.%s:9090" .Values.vorgangmanagerName .Release.Namespace }} +{{- end -}} + +{{- define "app.databaseTlsCert" -}} +{{- if ((.Values.database).tls).secretName -}} +{{ .Values.database.tls.secretName }} +{{- else -}} +{{ printf "ozg-mongodb-tls-cert" }} +{{- end -}} +{{- end -}} + +{{- define "app.databaseSecretName" -}} +{{- if (.Values.database).secretName -}} +{{ .Values.database.secretName }} +{{- else -}} +{{ printf "ozg-mongodb-admin-vorgang-manager-user" }} +{{- end -}} +{{- end -}} + +{{- define "app.serviceAccountName" -}} +{{ printf "%s" ( (.Values.serviceAccount).name | default "vorgang-manager-service-account" ) }} +{{- end -}} \ No newline at end of file diff --git a/src/main/helm/templates/configmap_bindings_type.yaml b/src/main/helm/templates/configmap_bindings_type.yaml new file mode 100644 index 0000000..102f45f --- /dev/null +++ b/src/main/helm/templates/configmap_bindings_type.yaml @@ -0,0 +1,32 @@ +# +# 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. +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: bindings-type + namespace: {{ include "app.namespace" . }} +data: + type: | + ca-certificates \ No newline at end of file diff --git a/src/main/helm/templates/deployment.yaml b/src/main/helm/templates/deployment.yaml new file mode 100644 index 0000000..a5df086 --- /dev/null +++ b/src/main/helm/templates/deployment.yaml @@ -0,0 +1,333 @@ +# +# 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. +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} +spec: + progressDeadlineSeconds: 600 + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "app.matchLabels" . | indent 6 }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + {{- include "app.defaultLabels" . | indent 8 }} + component: vorgang-manager + spec: + {{- if (.Values.serviceAccount).create }} + serviceAccountName: {{ include "app.serviceAccountName" . }} + {{- end }} + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ .Release.Name }} + containers: + - env: + - name: SERVICE_BINDING_ROOT + value: "/bindings" + - name: spring_profiles_active + value: {{ include "app.envSpringProfiles" . }} + - name: ozgcloud_nachrichten-manager_url + value: {{ include "app.ozgcloud_vorgangmanager_address" . }} + {{- if .Values.env.ozgcloudAktenzeichen.enabled }} + - name: ozgcloud_aktenzeichen + value: {{ .Values.env.ozgcloudAktenzeichen.value | default "de.ozgcloud.vorgang.vorgang.AktenzeichenProviderEA" }} + {{- end }} + {{- if (.Values.ozgcloudProxyApi).url }} + - name: ozgcloud_osi_postfach_proxyapi_url + value: {{ .Values.ozgcloudProxyApi.url }} + {{- end }} + {{- if (.Values.ozgcloudProxyApi).realm }} + - name: ozgcloud_osi_postfach_proxyapi_realm + value: {{ .Values.ozgcloudProxyApi.realm }} + {{- end }} + - name: ozgcloud_osi_postfach_scheduler_enabled + value: "{{ ((.Values.ozgcloudProxyApi).scheduler).enabled | default false }}" + - name: ozgcloud_osi_postfach_scheduler_fixedDelay + value: "{{ ((.Values.ozgcloudProxyApi).scheduler).fixedDelay | default 300000 }}" + {{- if ((.Values.osipostfach).httpproxy).enabled }} + - name: ozgcloud_osi_postfach_http-proxy_host + value: {{ .Values.osipostfach.httpproxy.host }} + - name: ozgcloud_osi_postfach_http-proxy_port + value: "{{ .Values.osipostfach.httpproxy.port }}" + - name: ozgcloud_osi_postfach_http-proxy_authenticationRequired + value: "{{ .Values.osipostfach.httpproxy.auth.required }}" + {{- if .Values.osipostfach.httpproxy.auth.required }} + - name: ozgcloud_osi_postfach_http-proxy_username + value: {{ .Values.osipostfach.httpproxy.auth.username }} + - name: ozgcloud_osi_postfach_http-proxy_password + value: {{ .Values.osipostfach.httpproxy.auth.password }} + {{- end }} + {{- end }} + {{- if (.Values.rabbitmq).enabled }} + - name: spring_rabbitmq_username + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: username + optional: false + - name: spring_rabbitmq_password + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: password + optional: false + {{- end }} + {{- if (.Values.elasticsearch).enabled }} + - name: ozgcloud_elasticsearch_address + valueFrom: + secretKeyRef: + name: {{ coalesce .Values.elasticsearch.secretName "elasticsearch-credentials" }} + key: address + optional: false + - name: ozgcloud_elasticsearch_username + valueFrom: + secretKeyRef: + name: {{ coalesce .Values.elasticsearch.secretName "elasticsearch-credentials" }} + key: username + optional: false + - name: ozgcloud_elasticsearch_password + valueFrom: + secretKeyRef: + name: {{ coalesce .Values.elasticsearch.secretName "elasticsearch-credentials" }} + key: password + optional: false + - name: ozgcloud_elasticsearch_index + valueFrom: + secretKeyRef: + name: {{ coalesce .Values.elasticsearch.secretName "elasticsearch-credentials" }} + key: index + optional: false + - name: spring_ssl_bundle_pem_es-root-ca_truststore_certificate + value: "/bindings/ca-certificates/es-root-ca.pem" + {{- end }} + {{- with (.Values.env).customList }} +{{ toYaml . | indent 10 }} + {{- end }} + - name: grpc_client_user-manager_address + value: {{ include "app.grpc_client_user-manager_address" . }} + - name: grpc_client_user-manager_negotiationType + value: {{ (.Values.userManager).grpcClientNegotiationType | default "TLS" }} + - name: grpc_client_info-manager_address + value: {{ ((.Values.ozgcloud).infoManager).address }} + + - name: ozgcloud_user-manager_url + value: {{ include "app.ozgcloud_migration_user-manager_address" . }} + - name: ozgcloud_zufi-manager_address + value: {{ .Values.zufiManager.address }} + {{- if not (.Values.database).useExternal }} + - name: spring_data_mongodb_uri + valueFrom: + secretKeyRef: + name: {{ include "app.databaseSecretName" . }} + key: connectionString.standardSrv + optional: false + - name: spring_data_mongodb_database + value: {{ include "app.vorgangManagerDatabase" . }} + {{- end }} + + {{- if ((.Values.ozgcloud).bayernid).enabled }} + - name: ozgcloud_bayernid_enabled + value: {{ quote .Values.ozgcloud.bayernid.enabled }} + - name: grpc_client_bayern-id_address + value: {{ quote (required "ozgcloud.bayernid.proxy.address must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).proxy).address) }} + - name: grpc_client_bayern-id_negotiationType + value: {{ (((.Values.ozgcloud).bayernid).proxy).negotiationType | default "PLAINTEXT" }} + - name: ozgcloud_bayernid_absender_name + value: {{ quote (required "ozgcloud.bayernid.absender.name must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).absender).name) }} + - name: ozgcloud_bayernid_absender_anschrift + value: {{ quote (required "ozgcloud.bayernid.absender.anschrift must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).absender).anschrift) }} + - name: ozgcloud_bayernid_absender_dienst + value: {{ quote (required "ozgcloud.bayernid.absender.dienst must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).absender).dienst) }} + - name: ozgcloud_bayernid_absender_mandant + value: {{ quote (required "ozgcloud.bayernid.absender.mandant must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).absender).mandant) }} + - name: ozgcloud_bayernid_absender_gemeindeSchluessel + value: {{ quote (required "ozgcloud.bayernid.absender.gemeindeSchluessel must be set if ozgcloud.bayernid is enabled" (((.Values.ozgcloud).bayernid).absender).gemeindeSchluessel) }} + {{- end }} + + + {{- if (.Values.ozgcloud).processors}} + {{- range $processor_index, $processor := (.Values.ozgcloud).processors }} + - name: ozgcloud_processors_{{ $processor_index }}_address + value: {{ $processor.address }} + - name: ozgcloud_processors_{{ $processor_index }}_name + value: {{ $processor.name }} + {{- if ($processor).forms}} + {{- range $form_index, $form := ($processor).forms }} + - name: ozgcloud_processors_{{ $processor_index }}_forms_{{ $form_index }}_formEngineName + value: {{ $form.formEngineName }} + - name: ozgcloud_processors_{{ $processor_index }}_forms_{{ $form_index }}_formId + value: {{ $form.formId }} + {{- end }} + {{- end}} + {{- end }} + {{- end}} + {{- if or (.Values.database).useExternal (.Values.ozgcloudProxyApi).apikey }} + envFrom: + {{- if (.Values.database).useExternal }} + - secretRef: + name: vorgang-manager-database-spring + {{- end }} + {{- if (.Values.ozgcloudProxyApi).apikey }} + - secretRef: + name: vorgang-manager-ozgcloud-proxyapi + {{- end }} + {{- end }} + image: "{{ .Values.image.repo }}/{{ .Values.image.name }}:{{ coalesce (.Values.image).tag "latest" }}" + imagePullPolicy: Always + name: vorgang-manager + ports: + - containerPort: 9090 + name: grpc-9090 + protocol: TCP + - containerPort: 8081 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + startupProbe: + httpGet: + path: /actuator/health/readiness + port: 8081 + scheme: HTTP + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + {{- if .Values.enableLivenessProbe }} + livenessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/liveness + port: 8081 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + {{- end }} + resources: + {{- with .Values.resources }} +{{ toYaml . | indent 10 }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: true + {{- with (.Values.securityContext).runAsUser }} + runAsUser: {{ . }} + {{- end }} + {{- with (.Values.securityContext).runAsGroup }} + runAsGroup: {{ . }} + {{- end }} + {{- with (.Values.securityContext).capabilities }} + capabilities: +{{ toYaml . | indent 12 }} + {{- end }} + stdin: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + tty: true + volumeMounts: + - name: bindings + mountPath: "/bindings/ca-certificates/type" + subPath: type + readOnly: true + {{- if (.Values.elasticsearch).enabled }} + - name: es-root-ca + mountPath: "/bindings/ca-certificates/es-root-ca.pem" + subPath: ca.crt + readOnly: true + {{- end }} + - name: mongodb-root-ca + mountPath: "/bindings/ca-certificates/mongodb-root-ca.pem" + subPath: ca.crt + readOnly: true + {{- if not .Values.disableUserManagerGrpcTls }} + - name: user-manager-tls-certificate + mountPath: "/bindings/ca-certificates/user-manager-tls-ca.pem" + subPath: ca.crt + readOnly: true + {{- end }} + volumes: + - name: bindings + configMap: + name: bindings-type + {{- if (.Values.elasticsearch).enabled }} + - name: es-root-ca + secret: + secretName: {{ .Values.elasticsearch.certificateSecretName }} + optional: false + {{- end }} + - name: mongodb-root-ca + secret: + secretName: {{ include "app.databaseTlsCert" . }} + optional: true + {{- if not .Values.disableUserManagerGrpcTls }} + - name: user-manager-tls-certificate + secret: + secretName: user-manager-tls-cert + {{- end }} + dnsConfig: {} + dnsPolicy: ClusterFirst + imagePullSecrets: + {{- if .Values.imagePullSecret }} + - name: {{ .Values.imagePullSecret }} + {{ else }} + - name: vorgang-manager-image-pull-secret + {{- end }} + restartPolicy: Always + {{- with .Values.hostAliases }} + hostAliases: +{{ toYaml . | indent 8 }} + {{- end }} + schedulerName: default-scheduler + {{- with .Values.podSecurityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: 30 diff --git a/src/main/helm/templates/elasticsearch_cr.yaml b/src/main/helm/templates/elasticsearch_cr.yaml new file mode 100644 index 0000000..251b7a3 --- /dev/null +++ b/src/main/helm/templates/elasticsearch_cr.yaml @@ -0,0 +1,31 @@ +# +# 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. +# + +{{- if and (not (.Values.elasticsearch).disableOzgCloudOperator) (.Values.elasticsearch).enabled }} +apiVersion: operator.ozgcloud.de/v1 +kind: OzgCloudElasticsearch +metadata: + name: vorgang-manager-elasticsearch-cr + namespace: {{ include "app.namespace" $ }} +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/image-pull-secret.yaml b/src/main/helm/templates/image-pull-secret.yaml new file mode 100644 index 0000000..d6bc5e3 --- /dev/null +++ b/src/main/helm/templates/image-pull-secret.yaml @@ -0,0 +1,34 @@ +# +# 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. +# + +{{- if not (.Values.imagePullSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: vorgang-manager-image-pull-secret + namespace: {{ include "app.namespace" . }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ include "app.imagePullSecret" . }} +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/network_policy.yaml b/src/main/helm/templates/network_policy.yaml new file mode 100644 index 0000000..d93becb --- /dev/null +++ b/src/main/helm/templates/network_policy.yaml @@ -0,0 +1,105 @@ +# +# 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. +# + +{{- if not (.Values.networkPolicy).disabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: network-policy-vorgang-manager + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + component: vorgang-manager + policyTypes: + - Ingress + - Egress + ingress: + - ports: + - port: 9090 + from: + - podSelector: + matchLabels: + component: alfa + - podSelector: + matchLabels: + ozg-component: eingangsadapter +{{- with (.Values.networkPolicy).additionalIngressConfig }} +{{ toYaml . | indent 2 }} +{{- end }} + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: elastic-system + podSelector: + matchLabels: + elasticsearch.k8s.elastic.co/cluster-name : ozg-search-cluster + ports: + - port: 9200 + protocol: TCP + - to: + - podSelector: + matchLabels: + component: ozgcloud-mongodb + ports: + - port: 27017 + protocol: TCP + - to: + - podSelector: + matchLabels: + component: user-manager + ports: + - port: 9000 + protocol: TCP +{{- if ((.Values.ozgcloud).bayernid).enabled }} + - to: + - podSelector: + matchLabels: + component: bayernid-proxy + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ required "ozgcloud.bayernid.proxy.namespace must be set if bayernid is enabled" (((.Values.ozgcloud).bayernid).proxy).namespace }} + ports: + - port: 9090 + protocol: TCP +{{- end }} + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ required "networkPolicy.dnsServerNamespace must be set" (.Values.networkPolicy).dnsServerNamespace }} + ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP +{{- with (.Values.networkPolicy).additionalEgressConfig }} +{{ toYaml . | indent 2 }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role.yaml b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role.yaml new file mode 100644 index 0000000..db4517b --- /dev/null +++ b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +{{- if and (not (.Values.elasticsearch).disableOzgCloudOperator) (.Values.elasticsearch).enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ozgcloud-elasticsearch-operator-secrets-read-role + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resourceNames: + - elasticsearch-credentials + - elasticsearch-certificate + resources: + - secrets + verbs: + - get + - list +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role_binding.yaml b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role_binding.yaml new file mode 100644 index 0000000..b9dae5c --- /dev/null +++ b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_read_role_binding.yaml @@ -0,0 +1,39 @@ +# +# 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. +# + +{{- if and (not (.Values.elasticsearch).disableOzgCloudOperator) (.Values.elasticsearch).enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ozgcloud-elasticsearch-operator-secrets-read-role-binding + namespace: {{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: ozgcloud-elasticsearch-operator-serviceaccount + namespace: {{ required "elasticsearch.operatorNamespace muss angegeben sein" .Values.elasticsearch.operatorNamespace }} +roleRef: + kind: Role + name: ozgcloud-elasticsearch-operator-secrets-read-role + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role.yaml b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role.yaml new file mode 100644 index 0000000..8a1d630 --- /dev/null +++ b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role.yaml @@ -0,0 +1,38 @@ +# +# 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. +# + +{{- if and (not (.Values.elasticsearch).disableOzgCloudOperator) (.Values.elasticsearch).enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ozgcloud-elasticsearch-operator-secrets-write-role-vorgang-manager + namespace: {{ include "app.namespace" $ }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - create +{{- end }} diff --git a/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role_binding.yaml b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role_binding.yaml new file mode 100644 index 0000000..899cae5 --- /dev/null +++ b/src/main/helm/templates/ozgcloud_elasticsearch_operator_secrets_write_role_binding.yaml @@ -0,0 +1,39 @@ +# +# 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. +# + +{{- if and (not (.Values.elasticsearch).disableOzgCloudOperator) (.Values.elasticsearch).enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ozgcloud-elasticsearch-operator-secrets-write-role-binding-vorgang-manager + namespace: {{ include "app.namespace" . }} +subjects: + - kind: ServiceAccount + name: ozgcloud-elasticsearch-operator-serviceaccount + namespace: {{ required "elasticsearch.operatorNamespace muss angegeben sein" .Values.elasticsearch.operatorNamespace }} +roleRef: + kind: Role + name: ozgcloud-elasticsearch-operator-secrets-write-role-vorgang-manager + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/rabbitmq_exchange.yaml b/src/main/helm/templates/rabbitmq_exchange.yaml new file mode 100644 index 0000000..c1e4831 --- /dev/null +++ b/src/main/helm/templates/rabbitmq_exchange.yaml @@ -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. +# + +{{- if (.Values.rabbitmq).enabled }} +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Exchange +metadata: + name: {{ include "app.namespace" . }} + namespace: {{ include "app.namespace" . }} +spec: + name: {{ include "app.namespace" . }}-exchange + type: direct + autoDelete: false + durable: true + rabbitmqClusterReference: + name: ozg-mq-cluster + namespace: rabbitmq-system +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/rabbitmq_permissions.yaml b/src/main/helm/templates/rabbitmq_permissions.yaml new file mode 100644 index 0000000..b336d01 --- /dev/null +++ b/src/main/helm/templates/rabbitmq_permissions.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +{{- if (.Values.rabbitmq).enabled }} +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Permission +metadata: + name: {{ include "app.namespace" . }} + namespace: {{ include "app.namespace" . }} +spec: + vhost: "/" + user: "{{ include "app.namespace" . }}" + permissions: + write: "{{ include "app.namespace" . }}-.*" + configure: ".*" + read: "{{ include "app.namespace" . }}-.*" + rabbitmqClusterReference: + name: ozg-mq-cluster + namespace: rabbitmq-system +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/rabbitmq_queue.yaml b/src/main/helm/templates/rabbitmq_queue.yaml new file mode 100644 index 0000000..609aacf --- /dev/null +++ b/src/main/helm/templates/rabbitmq_queue.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +{{- if (.Values.rabbitmq).enabled }} +{{- $tenant := .Values.prodEnv -}} +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Queue +metadata: + name: {{ include "app.namespace" . }} + namespace: {{ include "app.namespace" . }} +spec: + name: {{ include "app.namespace" . }}-queue + vhost: "/" + type: quorum + autoDelete: false + durable: true + rabbitmqClusterReference: + name: ozg-mq-cluster + namespace: rabbitmq-system +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/rabbitmq_secret.yaml b/src/main/helm/templates/rabbitmq_secret.yaml new file mode 100644 index 0000000..57ce287 --- /dev/null +++ b/src/main/helm/templates/rabbitmq_secret.yaml @@ -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. +# + +{{- if (.Values.rabbitmq).enabled }} +--- +{{- if not (lookup "v1" "Secret" .Release.Namespace "rabbitmq-credentials") }} +apiVersion: v1 +kind: Secret +metadata: + name: rabbitmq-credentials + namespace: {{ include "app.namespace" . }} + annotations: + "helm.sh/resource-policy": "keep" +type: Opaque +stringData: + password: {{ randAlphaNum 24 | b64enc }} + username: {{ include "app.namespace" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/rabbitmq_user.yaml b/src/main/helm/templates/rabbitmq_user.yaml new file mode 100644 index 0000000..d07a003 --- /dev/null +++ b/src/main/helm/templates/rabbitmq_user.yaml @@ -0,0 +1,38 @@ +# +# 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. +# + +{{- if (.Values.rabbitmq).enabled }} +--- +apiVersion: rabbitmq.com/v1beta1 +kind: User +metadata: + name: {{ include "app.namespace" . }} + namespace: {{ include "app.namespace" . }} +spec: + rabbitmqClusterReference: + name: ozg-mq-cluster + namespace: rabbitmq-system + importCredentialsSecret: + name: rabbitmq-credentials +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/secret_ozgcloud_proxyapi.yaml b/src/main/helm/templates/secret_ozgcloud_proxyapi.yaml new file mode 100644 index 0000000..85769f2 --- /dev/null +++ b/src/main/helm/templates/secret_ozgcloud_proxyapi.yaml @@ -0,0 +1,34 @@ +# +# 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. +# + +{{- if (.Values.ozgcloudProxyApi).apikey }} +apiVersion: v1 +kind: Secret +metadata: + name: vorgang-manager-ozgcloud-proxyapi + namespace: {{ .Release.Namespace }} +type: Opaque +data: + ozgcloud_osi_postfach_proxyapi_key: {{ (.Values.ozgcloudProxyApi).apikey | b64enc }} +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/service.yaml b/src/main/helm/templates/service.yaml new file mode 100644 index 0000000..ad49c6a --- /dev/null +++ b/src/main/helm/templates/service.yaml @@ -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. +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} + component: vorgang-manager-service +spec: + type: ClusterIP + ports: + - name: grpc-9090 + port: 9090 + protocol: TCP + - name: metrics + port: 8081 + protocol: TCP + selector: + {{- include "app.matchLabels" . | indent 4 }} + component: vorgang-manager diff --git a/src/main/helm/templates/service_account.yaml b/src/main/helm/templates/service_account.yaml new file mode 100644 index 0000000..3bac8e2 --- /dev/null +++ b/src/main/helm/templates/service_account.yaml @@ -0,0 +1,31 @@ +# +# 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. +# + +{{- if (.Values.serviceAccount).create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "app.serviceAccountName" . }} + namespace: {{ include "app.namespace" . }} +{{- end }} \ No newline at end of file diff --git a/src/main/helm/templates/service_monitor.yaml b/src/main/helm/templates/service_monitor.yaml new file mode 100644 index 0000000..9cb70ea --- /dev/null +++ b/src/main/helm/templates/service_monitor.yaml @@ -0,0 +1,43 @@ +# +# 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. +# + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} + component: vorgang-manager-service-monitor +spec: + endpoints: + - port: metrics + path: /actuator/prometheus + namespaceSelector: + matchNames: + - {{ include "app.namespace" . }} + selector: + matchLabels: + {{- include "app.matchLabels" . | indent 6 }} + component: vorgang-manager-service \ No newline at end of file diff --git a/src/main/helm/templates/tests/test-service-connection.yaml b/src/main/helm/templates/tests/test-service-connection.yaml new file mode 100644 index 0000000..036fa6f --- /dev/null +++ b/src/main/helm/templates/tests/test-service-connection.yaml @@ -0,0 +1,39 @@ +# +# 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. +# + +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-test-connection" + labels: + {{- include "app.defaultLabels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ .Release.Name }}:9090'] + restartPolicy: Never diff --git a/src/main/helm/values.yaml b/src/main/helm/values.yaml new file mode 100644 index 0000000..0d6d44c --- /dev/null +++ b/src/main/helm/values.yaml @@ -0,0 +1,64 @@ +# +# 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. +# + +cluster_env: "" + +baseUrl: test.sh.ozg-cloud.de + +replicaCount: 2 + +# ozgcloud: +# environment: dev + +image: + repo: docker.ozg-sh.de + name: vorgang-manager + tag: latest # [default: latest] + +env: +# overrideSpringProfiles: "oc,prod" + ozgcloudAktenzeichen: + enabled: false # [default: false] + value: de.ozgcloud.vorgang.vorgang.AktenzeichenProviderEA + # customList: # add name value pair for additional environments + # - name: Dinge + # value: true + +# customDatabaseCredentials: +# authenticationDatabase: admin +# database: sh-kiel-dev +# host: mongodb.sh-land +# password: +# username: sh-kiel-vorgang-manager-dev + + +vorgangmanagerName: vorgang-manager + +usermanagerName: user-manager + +zufiManager: + address: dns://zufi.zufi-manager:9090 + +elasticsearch: + certificateSecretName: elasticsearch-certificate diff --git a/src/test/helm-linter-values.yaml b/src/test/helm-linter-values.yaml new file mode 100644 index 0000000..097de84 --- /dev/null +++ b/src/test/helm-linter-values.yaml @@ -0,0 +1,31 @@ +# +# 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. +# + +ozgcloud: + environment: test + infoManager: + address: https://info-manager.my-wonderful-domain.local:9000 + +networkPolicy: + dnsServerNamespace: test-dns-namespace \ No newline at end of file diff --git a/src/test/helm/configmap_bindings_type_test.yaml b/src/test/helm/configmap_bindings_type_test.yaml new file mode 100644 index 0000000..1c592b4 --- /dev/null +++ b/src/test/helm/configmap_bindings_type_test.yaml @@ -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. +# + +suite: Certificate ConfigMap Binding +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/configmap_bindings_type.yaml +tests: + - it: validate configMap values + asserts: + - isKind: + of: ConfigMap + - equal: + path: metadata.name + value: bindings-type + - equal: + path: metadata.namespace + value: sh-helm-test + - equal: + path: data + value: + type: | + ca-certificates \ No newline at end of file diff --git a/src/test/helm/deployment_63_chars_test.yaml b/src/test/helm/deployment_63_chars_test.yaml new file mode 100644 index 0000000..3db76de --- /dev/null +++ b/src/test/helm/deployment_63_chars_test.yaml @@ -0,0 +1,57 @@ +# +# 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. +# + +suite: test deyploment less than 63 chars +release: + name: vorgang-manager + namespace: sh-helm-test + +chart: + name: vorgang-manager + +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + +tests: + - it: should fail on .Release.Namespace length longer than 63 characters + release: + namespace: test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 + asserts: + - failedTemplate: + errorMessage: .Release.Namespace test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 ist zu lang (max. 63 Zeichen) + - it: should not fail on .Release.Namespace length less than 63 characters + asserts: + - notFailedTemplate: {} + - it: should fail on .Chart.Name-.Chart.Version length longer than 63 characters + chart: + version: 1.0-test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 + asserts: + - failedTemplate: + errorMessage: .Chart.Name-.Chart.Version vorgang-manager-1.0-test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 ist zu lang (max. 63 Zeichen) + - it: should not fail on .Chart.Name-.Chart.Version length less than 63 characters + asserts: + - notFailedTemplate: {} \ No newline at end of file diff --git a/src/test/helm/deployment_bayernid_test.yaml b/src/test/helm/deployment_bayernid_test.yaml new file mode 100644 index 0000000..a3d32c9 --- /dev/null +++ b/src/test/helm/deployment_bayernid_test.yaml @@ -0,0 +1,183 @@ +# +# 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. +# + +suite: deployment bayernid +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev + bayernid: + enabled: true + proxy: + address: https://proxy.address.local + absender: + postkorbId: "postkorbId" + name: "name" + anschrift: "anschrift" + dienst: "dienst" + mandant: "mandant" + gemeindeSchluessel: "gemeindeSchluessel" +tests: + - it: should enable bayernid + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_enabled + value: "true" + + - it: should set absender name + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_absender_name + value: "name" + - it: should fail if absender name is not set + set: + ozgcloud: + bayernid: + absender: + name: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.absender.name must be set if ozgcloud.bayernid is enabled" + + - it: should set absender anschrift + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_absender_anschrift + value: "anschrift" + - it: should fail if absender anschrift is not set + set: + ozgcloud: + bayernid: + absender: + anschrift: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.absender.anschrift must be set if ozgcloud.bayernid is enabled" + + - it: should set absender dienst + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_absender_dienst + value: "dienst" + - it: should fail if absender dienst is not set + set: + ozgcloud: + bayernid: + absender: + dienst: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.absender.dienst must be set if ozgcloud.bayernid is enabled" + + - it: should set absender mandant + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_absender_mandant + value: "mandant" + - it: should fail if absender mandant is not set + set: + ozgcloud: + bayernid: + absender: + mandant: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.absender.mandant must be set if ozgcloud.bayernid is enabled" + + + - it: should contains absender gemeindeSchluessel + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_bayernid_absender_gemeindeSchluessel + value: "gemeindeSchluessel" + - it: should fail if absender gemeindeSchluessel is not set + set: + ozgcloud: + bayernid: + absender: + gemeindeSchluessel: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.absender.gemeindeSchluessel must be set if ozgcloud.bayernid is enabled" + + + - it: should set the bayernid proxy grpc address + set: + ozgcloud: + bayernid: + proxy: + address: https://bayernid-proxy.my-wonderful-domain.local:9000 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_bayern-id_address + value: https://bayernid-proxy.my-wonderful-domain.local:9000 + - it: should fail if bayernid proxy is enabled but proxy address is not configured + set: + ozgcloud: + bayernid: + proxy: + address: + asserts: + - failedTemplate: + errorMessage: "ozgcloud.bayernid.proxy.address must be set if ozgcloud.bayernid is enabled" + + - it: should set the bayernid proxy grpc negotiationType + set: + ozgcloud: + bayernid: + proxy: + negotiationType: NOT_DEFAULT + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_bayern-id_negotiationType + value: NOT_DEFAULT + - it: should set the bayernid proxy grpc default + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_bayern-id_negotiationType + value: PLAINTEXT \ No newline at end of file diff --git a/src/test/helm/deployment_bindings_test.yaml b/src/test/helm/deployment_bindings_test.yaml new file mode 100644 index 0000000..89d32dd --- /dev/null +++ b/src/test/helm/deployment_bindings_test.yaml @@ -0,0 +1,57 @@ +# +# 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. +# + +suite: deployment user-manager bindings +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: should have volumes + template: deployment.yaml + set: + usermanagerName: user-manager + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: user-manager-tls-certificate + mountPath: "/bindings/ca-certificates/user-manager-tls-ca.pem" + subPath: ca.crt + readOnly: true + - it: should have volume for user-manager-tls-certificate + template: deployment.yaml + set: + usermanagerName: user-manager + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: user-manager-tls-certificate + secret: + secretName: user-manager-tls-cert diff --git a/src/test/helm/deployment_container_security_context_test.yaml b/src/test/helm/deployment_container_security_context_test.yaml new file mode 100644 index 0000000..67deb14 --- /dev/null +++ b/src/test/helm/deployment_container_security_context_test.yaml @@ -0,0 +1,91 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check default values + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.runAsNonRoot + value: true + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsUser + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsGroup + - isNull: + path: spec.template.spec.containers[0].securityContext.capabilities + - isNull: + path: spec.template.spec.securityContext.fsGroup + - it: check runAsUser + set: + securityContext.runAsUser: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 1000 + - it: check runAsGroup + set: + securityContext.runAsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsGroup + value: 1000 + - it: check fsGroup + set: + podSecurityContext.fsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.securityContext.fsGroup + value: 1000 + - it: check capabilities + set: + securityContext: + capabilities: + drop: + - ALL + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.capabilities + value: + drop: + - ALL \ No newline at end of file diff --git a/src/test/helm/deployment_defaults_labels_test.yaml b/src/test/helm/deployment_defaults_labels_test.yaml new file mode 100644 index 0000000..048815c --- /dev/null +++ b/src/test/helm/deployment_defaults_labels_test.yaml @@ -0,0 +1,71 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml + - templates/service.yaml + - templates/service_monitor.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check default labels + asserts: + - equal: + path: metadata.labels["app.kubernetes.io/instance"] + value: vorgang-manager + - equal: + path: metadata.labels["app.kubernetes.io/name"] + value: vorgang-manager + - equal: + path: metadata.labels["app.kubernetes.io/part-of"] + value: ozgcloud + - equal: + path: metadata.labels["app.kubernetes.io/namespace"] + value: sh-helm-test + - it: check component label for deployment + templates: + - templates/deployment.yaml + asserts: + - equal: + path: spec.template.metadata.labels["component"] + value: vorgang-manager + - it: check component label for service + templates: + - templates/service.yaml + asserts: + - equal: + path: metadata.labels["component"] + value: vorgang-manager-service + - it: check component label for service monitor + templates: + - templates/service_monitor.yaml + asserts: + - equal: + path: metadata.labels["component"] + value: vorgang-manager-service-monitor \ No newline at end of file diff --git a/src/test/helm/deployment_env_test.yaml b/src/test/helm/deployment_env_test.yaml new file mode 100644 index 0000000..c681fa6 --- /dev/null +++ b/src/test/helm/deployment_env_test.yaml @@ -0,0 +1,122 @@ +# +# 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. +# + +suite: test environments +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check customList + template: deployment.yaml + set: + env.customList: + - name: my_test_environment_name + value: "A test value" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" + + - it: check customList test value is not set by default + template: deployment.yaml + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" + + - it: should have processor configuration + template: deployment.yaml + set: + ozgcloud: + environment: dev + processors: + - address: http://geil + name: processor_1 + forms: + - formEngineName: AFM + formId: odp_wahlhelfer/odp_wahlhelfer + - formEngineName: formEngineTest1 + formId: ID2 + - address: http://noch-geiler + name: processor_2 + forms: + - formEngineName: FormSolutions + formId: form-test + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_address + value: http://geil + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_name + value: processor_1 + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_forms_0_formEngineName + value: AFM + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_forms_0_formId + value: odp_wahlhelfer/odp_wahlhelfer + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_forms_1_formEngineName + value: formEngineTest1 + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_0_forms_1_formId + value: ID2 + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_1_address + value: http://noch-geiler + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_1_name + value: processor_2 + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_1_forms_0_formId + value: form-test + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_processors_1_forms_0_formEngineName + value: FormSolutions \ No newline at end of file diff --git a/src/test/helm/deployment_grpc_info_manager_address_test.yaml b/src/test/helm/deployment_grpc_info_manager_address_test.yaml new file mode 100644 index 0000000..1154207 --- /dev/null +++ b/src/test/helm/deployment_grpc_info_manager_address_test.yaml @@ -0,0 +1,43 @@ +# +# 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. +# + +suite: test info-manager address +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +tests: + - it: should set the grpc info-manager client address + set: + ozgcloud: + environment: dev + infoManager: + address: https://info-manager.my-wonderful-domain.local:9000 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_info-manager_address + value: https://info-manager.my-wonderful-domain.local:9000 diff --git a/src/test/helm/deployment_grpc_user_manager_address_test.yaml b/src/test/helm/deployment_grpc_user_manager_address_test.yaml new file mode 100644 index 0000000..00b11f9 --- /dev/null +++ b/src/test/helm/deployment_grpc_user_manager_address_test.yaml @@ -0,0 +1,63 @@ +# +# 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. +# + +suite: test user-manager address +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: should set the grpc user-manager client address + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_user-manager_address + value: user-manager.sh-helm-test:9000 + - it: should contain default user-manager grpc negotiationType tls + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_user-manager_negotiationType + value: TLS + - it: should contain user-manager grpc negotiationType plaintext + templates: + - templates/deployment.yaml + set: + userManager.grpcClientNegotiationType: PLAINTEXT + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: grpc_client_user-manager_negotiationType + value: PLAINTEXT \ No newline at end of file diff --git a/src/test/helm/deployment_host_aliases_test.yaml b/src/test/helm/deployment_host_aliases_test.yaml new file mode 100644 index 0000000..1e74b91 --- /dev/null +++ b/src/test/helm/deployment_host_aliases_test.yaml @@ -0,0 +1,53 @@ +# +# 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. +# + +suite: deployment host aliases +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: should not set hostAliases + asserts: + - isNull: + path: spec.template.spec.hostAliases + - it: should set hostAliases + set: + hostAliases: + - ip: "127.0.0.1" + hostname: + - "eins" + - "zwei" + asserts: + - contains: + path: spec.template.spec.hostAliases + content: + ip: "127.0.0.1" + hostname: + - "eins" + - "zwei" diff --git a/src/test/helm/deployment_imagepull_secret_test.yaml b/src/test/helm/deployment_imagepull_secret_test.yaml new file mode 100644 index 0000000..501eddd --- /dev/null +++ b/src/test/helm/deployment_imagepull_secret_test.yaml @@ -0,0 +1,50 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: should use default imagePull secret + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: vorgang-manager-image-pull-secret + - it: should set the imagePull secret + set: + imagePullSecret: image-pull-secret + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: image-pull-secret \ No newline at end of file diff --git a/src/test/helm/deployment_liveness_probe_test.yaml b/src/test/helm/deployment_liveness_probe_test.yaml new file mode 100644 index 0000000..c8bf126 --- /dev/null +++ b/src/test/helm/deployment_liveness_probe_test.yaml @@ -0,0 +1,56 @@ +# +# 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. +# + +suite: test deployment livenessProbe +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: livenessProbe should be disabled by default + template: deployment.yaml + asserts: + - notExists: + path: spec.template.spec.containers[0].livenessProbe + + - it: enable livenessProbe + template: deployment.yaml + set: + enableLivenessProbe: true + asserts: + - isSubset: + path: spec.template.spec.containers[0].livenessProbe + content: + failureThreshold: 3 + httpGet: + path: /actuator/health/liveness + port: 8081 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 diff --git a/src/test/helm/deployment_mongodb_test.yaml b/src/test/helm/deployment_mongodb_test.yaml new file mode 100644 index 0000000..882184d --- /dev/null +++ b/src/test/helm/deployment_mongodb_test.yaml @@ -0,0 +1,148 @@ +# +# 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. +# + +suite: deployment test mongodb environments +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check mongodb default env + template: deployment.yaml + release: + name: vorgang-manager + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_data_mongodb_uri + valueFrom: + secretKeyRef: + name: ozg-mongodb-admin-vorgang-manager-user + key: connectionString.standardSrv + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_data_mongodb_database + value: vorgang-manager-database + - contains: + path: spec.template.spec.volumes + content: + name: mongodb-root-ca + secret: + secretName: ozg-mongodb-tls-cert + optional: true + + - it: check external mongodb + template: deployment.yaml + release: + name: vorgang-manager + set: + database.useExternal: true + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: spring_data_mongodb_uri + valueFrom: + secretKeyRef: + name: vorgang-manager-database-admin-vorgang-manager-database-user + key: connectionString.standardSrv + optional: false + - isNull: + path: metadata.annotations + - contains: + path: spec.template.spec.containers[0].envFrom + content: + secretRef: + name: vorgang-manager-database-spring + + - it: check mongodb set secretname + template: deployment.yaml + release: + name: vorgang-manager + set: + database.secretName: secret-database-admin-vorgang-manager-user + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_data_mongodb_uri + valueFrom: + secretKeyRef: + name: secret-database-admin-vorgang-manager-user + key: connectionString.standardSrv + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_data_mongodb_database + value: vorgang-manager-database + + - it: check mongodb root ca mount + template: deployment.yaml + release: + name: vorgang-manager + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: mongodb-root-ca + mountPath: "/bindings/ca-certificates/mongodb-root-ca.pem" + subPath: ca.crt + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: mongodb-root-ca + secret: + secretName: ozg-mongodb-tls-cert + optional: true + + - it: check mongodb tls set tls cert name + template: deployment.yaml + release: + name: vorgang-manager + set: + database: + tls: + enabled: true + secretName: secret-tls-cert + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: mongodb-root-ca + mountPath: "/bindings/ca-certificates/mongodb-root-ca.pem" + subPath: ca.crt + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: mongodb-root-ca + secret: + secretName: secret-tls-cert + optional: true \ No newline at end of file diff --git a/src/test/helm/deployment_nachrichten_manager_address_test.yaml b/src/test/helm/deployment_nachrichten_manager_address_test.yaml new file mode 100644 index 0000000..4a81322 --- /dev/null +++ b/src/test/helm/deployment_nachrichten_manager_address_test.yaml @@ -0,0 +1,43 @@ +# +# 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. +# + +suite: test environments +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check if nachrichten-manager address is correct + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_nachrichten-manager_url + value: dns://vorgang-manager.sh-helm-test:9090 diff --git a/src/test/helm/deployment_rabbitmq_test.yaml b/src/test/helm/deployment_rabbitmq_test.yaml new file mode 100644 index 0000000..23113a6 --- /dev/null +++ b/src/test/helm/deployment_rabbitmq_test.yaml @@ -0,0 +1,98 @@ +# +# 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. +# + +suite: deployment test rabbitmq environments +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check rabbitmq spring env + template: deployment.yaml + set: + rabbitmq.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_username + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: username + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_password + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: password + optional: false + - it: check rabbitmq spring env is not set by default + template: deployment.yaml + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_username + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: username + optional: false + - notContains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_password + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: password + optional: false + - it: check rabbitmq spring env is not set + template: deployment.yaml + set: + rabbitmq.enabled: false + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_username + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: username + optional: false + - notContains: + path: spec.template.spec.containers[0].env + content: + name: spring_rabbitmq_password + valueFrom: + secretKeyRef: + name: rabbitmq-credentials + key: password + optional: false diff --git a/src/test/helm/deployment_resources_test.yaml b/src/test/helm/deployment_resources_test.yaml new file mode 100644 index 0000000..1538154 --- /dev/null +++ b/src/test/helm/deployment_resources_test.yaml @@ -0,0 +1,62 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: test resources + template: deployment.yaml + set: + resources: + limits: + cpu: 11m + memory: 22Mi + requests: + cpu: 33m + memory: 44Mi + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 11m + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 22Mi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 33m + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 44Mi + - it: no resources defined + template: deployment.yaml + asserts: + - isEmpty: + path: spec.template.spec.containers[0].resources + diff --git a/src/test/helm/deployment_service_account_test.yaml b/src/test/helm/deployment_service_account_test.yaml new file mode 100644 index 0000000..a3d515f --- /dev/null +++ b/src/test/helm/deployment_service_account_test.yaml @@ -0,0 +1,55 @@ +# +# 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. +# + +suite: deployment service account +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: should use service account with default name + set: + serviceAccount: + create: true + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: vorgang-manager-service-account + - it: should use service account with name + set: + serviceAccount: + create: true + name: helm-service-account + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: helm-service-account + - it: should use default service account + asserts: + - isNull: + path: spec.template.spec.serviceAccountName \ No newline at end of file diff --git a/src/test/helm/deployment_springProfile_test.yaml b/src/test/helm/deployment_springProfile_test.yaml new file mode 100644 index 0000000..eaffba2 --- /dev/null +++ b/src/test/helm/deployment_springProfile_test.yaml @@ -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. +# + +suite: test spring profiles +release: + name: vorgang-manager +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: is kind of Deployment + set: + env.overrideSpringProfiles: oc,stage,ea + templates: + - templates/deployment.yaml + asserts: + - isKind: + of: Deployment + - it: should override spring profiles + set: + env.overrideSpringProfiles: oc,stage,ea + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_profiles_active + value: oc,stage,ea + - it: should generate spring profiles + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_profiles_active + value: oc, dev \ No newline at end of file diff --git a/src/test/helm/deployment_test.yaml b/src/test/helm/deployment_test.yaml new file mode 100644 index 0000000..cbc25f8 --- /dev/null +++ b/src/test/helm/deployment_test.yaml @@ -0,0 +1,42 @@ +# +# 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. +# + +suite: test Vorgangfilter general values +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: testIsDeployment + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.containers[0].image + value: docker.ozg-sh.de/vorgang-manager:latest diff --git a/src/test/helm/deployment_test_ozgcloud_base_values_test.yaml b/src/test/helm/deployment_test_ozgcloud_base_values_test.yaml new file mode 100644 index 0000000..e10757b --- /dev/null +++ b/src/test/helm/deployment_test_ozgcloud_base_values_test.yaml @@ -0,0 +1,45 @@ +# +# 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. +# + +suite: test ozgcloud base values +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml + +tests: + - it: should fail on missing environment + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: ozgcloud.environment muss angegeben sein + - it: should not fail on missing environment + template: deployment.yaml + set: + ozgcloud: + environment: dev + asserts: + - notFailedTemplate: {} + diff --git a/src/test/helm/deployment_usermanager_url_test.yaml b/src/test/helm/deployment_usermanager_url_test.yaml new file mode 100644 index 0000000..6bef212 --- /dev/null +++ b/src/test/helm/deployment_usermanager_url_test.yaml @@ -0,0 +1,43 @@ +# +# 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. +# + +suite: test environments +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check if user-manager url is correct + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_user-manager_url + value: http://user-manager.sh-helm-test:8080/migration/user diff --git a/src/test/helm/deployment_zufimanager_address_test.yaml b/src/test/helm/deployment_zufimanager_address_test.yaml new file mode 100644 index 0000000..e42adaf --- /dev/null +++ b/src/test/helm/deployment_zufimanager_address_test.yaml @@ -0,0 +1,43 @@ +# +# 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. +# + +suite: test environments +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check if zufi-manager address is correct + templates: + - templates/deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_zufi-manager_address + value: dns://zufi.zufi-manager:9090 diff --git a/src/test/helm/elasticsearch_cr_test.yaml b/src/test/helm/elasticsearch_cr_test.yaml new file mode 100644 index 0000000..b1ddbc2 --- /dev/null +++ b/src/test/helm/elasticsearch_cr_test.yaml @@ -0,0 +1,76 @@ +# +# 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. +# + +suite: Elasticsearch cr +release: + name: vorgang-manager + namespace: by-helm-test +templates: + - templates/elasticsearch_cr.yaml +tests: + - it: should contain apiVersion + set: + elasticsearch: + enabled: true + asserts: + - isAPIVersion: + of: operator.ozgcloud.de/v1 + - it: should contain kind + set: + elasticsearch: + enabled: true + asserts: + - isKind: + of: OzgCloudElasticsearch + - it: should have metadata name + set: + elasticsearch: + enabled: true + asserts: + - equal: + path: metadata.name + value: vorgang-manager-elasticsearch-cr + - it: should have metadata namespace + set: + app: + namespace: test + elasticsearch: + enabled: true + asserts: + - equal: + path: metadata.namespace + value: by-helm-test + - it: should create cr if enabled + set: + elasticsearch: + enabled: true + asserts: + - hasDocuments: + count: 1 + documentIndex: 1 + - it: should NOT create cr if not enabled + asserts: + - hasDocuments: + count: 0 + documentIndex: 0 \ No newline at end of file diff --git a/src/test/helm/elasticsearch_deployment_test.yaml b/src/test/helm/elasticsearch_deployment_test.yaml new file mode 100644 index 0000000..9f7cbfd --- /dev/null +++ b/src/test/helm/elasticsearch_deployment_test.yaml @@ -0,0 +1,186 @@ +# +# 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. +# + +suite: elasticsearch tests +templates: + - templates/deployment.yaml +set: + ozgcloud: + environment: dev +tests: + - it: check if elastic credentials are disabled by default + template: deployment.yaml + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_address + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: address + optional: false + - notContains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_username + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: username + optional: false + - notContains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_password + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: password + optional: false + - notContains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_index + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: index + optional: false + + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: es-root-ca + mountPath: "/bindings/ca-certificates/es-root-ca.pem" + subPath: ca.crt + readOnly: true + + - notContains: + path: spec.template.spec.volumes + content: + name: es-root-ca + secret: + secretName: elasticsearch-root-ca + + + + + + - it: smoke test if elasticsearch is disabled when set to false + template: deployment.yaml + set: + ozgcloud.environment: test + database.password: hase + elasticsearch.enabled: false + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_address + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: address + optional: false + + - it: check enabled elastic credentials + template: deployment.yaml + set: + elasticsearch.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_address + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: address + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_username + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: username + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_password + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: password + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: ozgcloud_elasticsearch_index + valueFrom: + secretKeyRef: + name: elasticsearch-credentials + key: index + optional: false + - contains: + path: spec.template.spec.containers[0].env + content: + name: spring_ssl_bundle_pem_es-root-ca_truststore_certificate + value: /bindings/ca-certificates/es-root-ca.pem + + + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: bindings + mountPath: "/bindings/ca-certificates/type" + subPath: type + readOnly: true + + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: es-root-ca + mountPath: "/bindings/ca-certificates/es-root-ca.pem" + subPath: ca.crt + readOnly: true + + + - contains: + path: spec.template.spec.volumes + content: + name: bindings + configMap: + name: bindings-type + + - contains: + path: spec.template.spec.volumes + content: + name: es-root-ca + secret: + secretName: elasticsearch-certificate + optional: false diff --git a/src/test/helm/image_pull_secret_test.yaml b/src/test/helm/image_pull_secret_test.yaml new file mode 100644 index 0000000..a3024aa --- /dev/null +++ b/src/test/helm/image_pull_secret_test.yaml @@ -0,0 +1,59 @@ +# +# 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. +# + +suite: test image pull secret +templates: + - templates/image-pull-secret.yaml +release: + name: vorgang-manager + namespace: helm-test +tests: + - it: should match basic data + set: + imageCredentials: + registry: docker.ozg-sh.de + username: test + password: test1234 + email: webmaster@ozg-sh.de + asserts: + - hasDocuments: + count: 1 + - containsDocument: + kind: Secret + apiVersion: v1 + - equal: + path: metadata.name + value: vorgang-manager-image-pull-secret + - equal: + path: metadata.namespace + value: helm-test + - isNotNullOrEmpty: + path: data[".dockerconfigjson"] + + - it: should not create image pull secret + set: + imagePullSecret: "image-pull-secret" + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/network_policy_test.yaml b/src/test/helm/network_policy_test.yaml new file mode 100644 index 0000000..35a3bb4 --- /dev/null +++ b/src/test/helm/network_policy_test.yaml @@ -0,0 +1,306 @@ +# +# 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. +# + +suite: network policy test +release: + namespace: by-helm-test +templates: + - templates/network_policy.yaml +tests: + - it: should match apiVersion + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - isAPIVersion: + of: networking.k8s.io/v1 + + - it: should match kind + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - isKind: + of: NetworkPolicy + + - it: validate metadata + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - equal: + path: metadata + value: + name: network-policy-vorgang-manager + namespace: by-helm-test + + - it: should set policy target matchLabel + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - equal: + path: spec.podSelector + value: + matchLabels: + component: vorgang-manager + + + - it: should add policyType Egress + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.policyTypes + content: Egress + + - it: should add policyType Ingress + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.policyTypes + content: Ingress + + - it: should add ingress rule for eingangsmanager and alfa + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.ingress + content: + ports: + - port: 9090 + from: + - podSelector: + matchLabels: + component: alfa + - podSelector: + matchLabels: + ozg-component: eingangsadapter + + + - it: should add egress rule to elasticsearch + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: elastic-system + podSelector: + matchLabels: + elasticsearch.k8s.elastic.co/cluster-name : ozg-search-cluster + ports: + - port: 9200 + protocol: TCP + + - it: should add egress rule to mongodb + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: ozgcloud-mongodb + ports: + - port: 27017 + protocol: TCP + + - it: should add egress rule to user-manager + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: user-manager + ports: + - port: 9000 + protocol: TCP + + - it: should add egress rule to dns service + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: test-dns-namespace + ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - port: 5353 + protocol: UDP + - port: 5353 + protocol: TCP + + - it: should add egress rule to nachrichten-bayernid-proxy if bayernid is enabled + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + ozgcloud: + bayernid: + enabled: true + proxy: + namespace: bayernidProxyNamespace + asserts: + - contains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: bayernid-proxy + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: bayernidProxyNamespace + ports: + - port: 9090 + protocol: TCP + + - it: should not add egress rule to bayernid-proxy if bayernid is disabled + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + ozgcloud: + bayernid: + enabled: false + asserts: + - notContains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: bayernid-proxy + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: bayernidProxyNamespace + ports: + - port: 9090 + protocol: TCP + + - it: should throw error if bayernid-proxy is enabled but bayernid namespace is not set + set: + networkPolicy: + dnsServerNamespace: test-dns-namespace + ozgcloud: + bayernid: + enabled: true + asserts: + - failedTemplate: + errorMessage: ozgcloud.bayernid.proxy.namespace must be set if bayernid is enabled + + - it: add ingress rule by values + set: + networkPolicy: + ssoPublicIp: 51.89.117.53/32 + dnsServerNamespace: test-namespace-dns + additionalIngressConfig: + - from: + - podSelector: + matchLabels: + component: client2 + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + component: client2 + + - it: add egress rules by values + set: + networkPolicy: + additionalEgressConfig: + - to: + - ipBlock: + cidr: 1.2.3.4/32 + - to: + - podSelector: + matchLabels: + component: ozg-testservice + ports: + - port: 12345 + protocol: TCP + + dnsServerNamespace: test-dns-namespace + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 1.2.3.4/32 + - contains: + path: spec.egress + content: + to: + - podSelector: + matchLabels: + component: ozg-testservice + ports: + - port: 12345 + protocol: TCP + + - it: test network policy disabled + set: + networkPolicy: + disabled: true + dnsServerNamespace: test-dns-namespace + asserts: + - hasDocuments: + count: 0 + + - it: test network policy unset should be disabled + set: + networkPolicy: + disabled: false + dnsServerNamespace: test-dns-namespace + asserts: + - hasDocuments: + count: 1 \ No newline at end of file diff --git a/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_binding_test.yaml b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_binding_test.yaml new file mode 100644 index 0000000..5b75614 --- /dev/null +++ b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_binding_test.yaml @@ -0,0 +1,97 @@ +# +# 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. +# + +suite: test ozg_operator_secrets_read_role_binding +release: + name: release-name + namespace: by-helm-test +templates: + - templates/ozgcloud_elasticsearch_operator_secrets_read_role_binding.yaml +tests: + - it: should contain header data + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - isAPIVersion: + of: rbac.authorization.k8s.io/v1 + - isKind: + of: RoleBinding + + - it: should have metadata + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: metadata.name + value: ozgcloud-elasticsearch-operator-secrets-read-role-binding + - equal: + path: metadata.namespace + value: by-helm-test + + - it: should have subjects values + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: subjects + value: + - kind: ServiceAccount + name: ozgcloud-elasticsearch-operator-serviceaccount + namespace: test-operator-namespace + + - it: should have roleRef values + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: roleRef.kind + value: Role + - equal: + path: roleRef.name + value: ozgcloud-elasticsearch-operator-secrets-read-role + - equal: + path: roleRef.apiGroup + value: rbac.authorization.k8s.io + + - it: should not create RoleBinding if elasticsearch is disabled + asserts: + - hasDocuments: + count: 0 + + - it: should not create RoleBinding if ozgcloud operator is not enabled + set: + elasticsearch: + disableOzgCloudOperator: true + enabled: true + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_test.yaml b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_test.yaml new file mode 100644 index 0000000..d21b7ad --- /dev/null +++ b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_read_role_test.yaml @@ -0,0 +1,86 @@ +# +# 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. +# + +suite: test ozg_operator_secrets_read_role +release: + name: release-name + namespace: by-helm-test +templates: + - templates/ozgcloud_elasticsearch_operator_secrets_read_role.yaml +tests: + - it: should contain header data + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - isAPIVersion: + of: rbac.authorization.k8s.io/v1 + - isKind: + of: Role + - it: should have metadata + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: metadata.name + value: ozgcloud-elasticsearch-operator-secrets-read-role + - equal: + path: metadata.namespace + value: by-helm-test + - it: should have rules + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: rules + value: + - apiGroups: + - "" + resourceNames: + - elasticsearch-credentials + - elasticsearch-certificate + resources: + - secrets + verbs: + - get + - list + + - it: should not create Role if elasticsearch is not enabled + asserts: + - hasDocuments: + count: 0 + + - it: should not create Role if ozgcloud operator is not enabled + set: + elasticsearch: + disableOzgCloudOperator: true + enabled: true + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_binding_test.yaml b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_binding_test.yaml new file mode 100644 index 0000000..8815c58 --- /dev/null +++ b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_binding_test.yaml @@ -0,0 +1,104 @@ +# +# 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. +# + +suite: ozgcloud_elasticsearch_operator_secrets_write_role_binding test +release: + name: test-release-name + namespace: by-helm-test +templates: + - templates/ozgcloud_elasticsearch_operator_secrets_write_role_binding.yaml +tests: + - it: should contain header data + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - isAPIVersion: + of: rbac.authorization.k8s.io/v1 + - isKind: + of: RoleBinding + - it: should have metadata + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: metadata.name + value: ozgcloud-elasticsearch-operator-secrets-write-role-binding-vorgang-manager + - equal: + path: metadata.namespace + value: by-helm-test + - it: should have subjects values + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - contains: + path: subjects + content: + kind: ServiceAccount + name: ozgcloud-elasticsearch-operator-serviceaccount + namespace: test-operator-namespace + - it: should have roleRef values + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: roleRef.kind + value: Role + - equal: + path: roleRef.name + value: ozgcloud-elasticsearch-operator-secrets-write-role-vorgang-manager + - equal: + path: roleRef.apiGroup + value: rbac.authorization.k8s.io + - it: should not create RoleBinding if no elasticsearch users available + asserts: + - hasDocuments: + count: 0 + - it: should have subjects values + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - contains: + path: subjects + content: + kind: ServiceAccount + name: ozgcloud-elasticsearch-operator-serviceaccount + namespace: test-operator-namespace + - it: should not create RoleBinding if ozgcloud operator is not enabled + set: + elasticsearch: + disableOzgCloudOperator: true + enabled: true + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_test.yaml b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_test.yaml new file mode 100644 index 0000000..b0848c4 --- /dev/null +++ b/src/test/helm/ozgcloud_elasticsearch_operator_secrets_write_role_test.yaml @@ -0,0 +1,81 @@ +# +# 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. +# + +suite: ozgcloud_elasticsearch_operator_secrets_write_role test +release: + name: test-release-name + namespace: by-helm-test +templates: + - templates/ozgcloud_elasticsearch_operator_secrets_write_role.yaml +tests: + - it: should contain header data + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - isAPIVersion: + of: rbac.authorization.k8s.io/v1 + - isKind: + of: Role + - it: should have metadata + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - equal: + path: metadata.name + value: ozgcloud-elasticsearch-operator-secrets-write-role-vorgang-manager + - equal: + path: metadata.namespace + value: by-helm-test + - it: should have rules + set: + elasticsearch: + operatorNamespace: test-operator-namespace + enabled: true + asserts: + - contains: + path: rules + content: + apiGroups: + - "" + resources: + - secrets + verbs: + - create + - it: should not create Role if elasticsearch is not enabled + asserts: + - hasDocuments: + count: 0 + + - it: should not create Role if ozgcloud operator is not enabled + set: + elasticsearch: + disableOzgCloudOperator: true + enabled: true + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/rabbitmq_exchange_test.yaml b/src/test/helm/rabbitmq_exchange_test.yaml new file mode 100644 index 0000000..e830117 --- /dev/null +++ b/src/test/helm/rabbitmq_exchange_test.yaml @@ -0,0 +1,59 @@ +# +# 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. +# + +suite: test rabbitmq exchange +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/rabbitmq_exchange.yaml +tests: + - it: test if name like namespace + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: Exchange + - equal: + path: metadata.name + value: sh-helm-test + - it: test if spec name like namespace + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: Exchange + - equal: + path: spec.name + value: sh-helm-test-exchange + - it: should not create rabbitmq exchange + set: + rabbitmq.enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should not create rabbitmq exchange by default + asserts: + - hasDocuments: + count: 0 diff --git a/src/test/helm/rabbitmq_permissions_test.yaml b/src/test/helm/rabbitmq_permissions_test.yaml new file mode 100644 index 0000000..cd0223d --- /dev/null +++ b/src/test/helm/rabbitmq_permissions_test.yaml @@ -0,0 +1,72 @@ +# +# 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. +# + +suite: test rabbitmq permissions +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/rabbitmq_permissions.yaml +tests: + - it: test specs user like namespace + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: Permission + - equal: + path: spec.user + value: sh-helm-test + - it: test specs write permissions + set: + rabbitmq.enabled: true + rabbitmq.cluster.name: rabbit-test + rabbitmq.cluster.namespace: rabbit-test-ns + asserts: + - isKind: + of: Permission + - equal: + path: spec.permissions.write + value: "sh-helm-test-.*" + - it: test specs read permissions + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: Permission + - equal: + path: spec.permissions.read + value: "sh-helm-test-.*" + - it: should not create rabbitmq permission + set: + rabbitmq.enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should not create rabbitmq permission by default + set: + ozgcloud.environment: test + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/rabbitmq_queue_test.yaml b/src/test/helm/rabbitmq_queue_test.yaml new file mode 100644 index 0000000..33bc41e --- /dev/null +++ b/src/test/helm/rabbitmq_queue_test.yaml @@ -0,0 +1,50 @@ +# +# 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. +# + +suite: test rabbitmq queue +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/rabbitmq_queue.yaml +tests: + - it: test if name like namespace + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: Queue + - equal: + path: metadata.name + value: sh-helm-test + - it: should not create rabbitmq queue + set: + rabbitmq.enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should not create rabbitmq queue by default + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/rabbitmq_user_test.yaml b/src/test/helm/rabbitmq_user_test.yaml new file mode 100644 index 0000000..3e9f145 --- /dev/null +++ b/src/test/helm/rabbitmq_user_test.yaml @@ -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. +# + +suite: test rabbitmq user +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/rabbitmq_user.yaml +tests: + - it: test if name like namespace + set: + rabbitmq.enabled: true + asserts: + - isKind: + of: User + - equal: + path: metadata.name + value: sh-helm-test + - it: should not create rabbitmq user + set: + rabbitmq.enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should not create rabbitmq user by default + set: + ozgcloud.environment: test + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/service_account_test.yaml b/src/test/helm/service_account_test.yaml new file mode 100644 index 0000000..d3b2cc0 --- /dev/null +++ b/src/test/helm/service_account_test.yaml @@ -0,0 +1,62 @@ +# +# 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. +# + +suite: test service account +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/service_account.yaml +tests: + - it: should create service account with default name + set: + serviceAccount: + create: true + asserts: + - isKind: + of: ServiceAccount + - equal: + path: metadata.name + value: vorgang-manager-service-account + - equal: + path: metadata.namespace + value: sh-helm-test + - it: should create service account with name + set: + serviceAccount: + create: true + name: helm-service-account + asserts: + - isKind: + of: ServiceAccount + - equal: + path: metadata.name + value: helm-service-account + - equal: + path: metadata.namespace + value: sh-helm-test + - it: should not create service account + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/src/test/helm/service_monitor_test.yaml b/src/test/helm/service_monitor_test.yaml new file mode 100644 index 0000000..e09fc87 --- /dev/null +++ b/src/test/helm/service_monitor_test.yaml @@ -0,0 +1,65 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/service_monitor.yaml +tests: + - it: should have the label component with value vorgang-manager-service-monitor attached + asserts: + - isKind: + of: ServiceMonitor + - equal: + path: metadata.labels["component"] + value: vorgang-manager-service-monitor + - it: should be able to enable the endpoint + asserts: + - isKind: + of: ServiceMonitor + - contains: + path: spec.endpoints + content: + port: metrics + path: /actuator/prometheus + - it: namespace selector should contain the namespace + asserts: + - contains: + path: spec.namespaceSelector.matchNames + content: sh-helm-test + - it: selector should contain the component label with the value vorgang-manager-service + asserts: + - equal: + path: spec.selector.matchLabels["component"] + value: vorgang-manager-service + - it: selector should contain helm recommended labels name and namespace + asserts: + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/name"] + value: vorgang-manager + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/namespace"] + value: sh-helm-test diff --git a/src/test/helm/service_test.yaml b/src/test/helm/service_test.yaml new file mode 100644 index 0000000..c4ec4e8 --- /dev/null +++ b/src/test/helm/service_test.yaml @@ -0,0 +1,77 @@ +# +# 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. +# + +suite: test deployment +release: + name: vorgang-manager + namespace: sh-helm-test +templates: + - templates/service.yaml +tests: + - it: should have the label component with value vorgang-manager-service attached + asserts: + - isKind: + of: Service + - equal: + path: metadata.labels.component + value: vorgang-manager-service + - it: should be of type ClusterIP + asserts: + - equal: + path: spec.type + value: ClusterIP + - it: ports should contain the grpc port + asserts: + - contains: + path: spec.ports + content: + name: grpc-9090 + port: 9090 + protocol: TCP + count: 1 + any: true + - it: ports should contain the metrics port + asserts: + - contains: + path: spec.ports + content: + name: metrics + port: 8081 + protocol: TCP + count: 1 + any: true + - it: selector should contain the component label with the value vorgang-manager + asserts: + - equal: + path: spec.selector.component + value: vorgang-manager + - it: selector should contain helm recommended labels name and namespace + asserts: + - equal: + path: spec.selector["app.kubernetes.io/name"] + value: vorgang-manager + - equal: + path: spec.selector["app.kubernetes.io/namespace"] + value: sh-helm-test + \ No newline at end of file diff --git a/vorgang-manager-base/pom.xml b/vorgang-manager-base/pom.xml new file mode 100644 index 0000000..5f21670 --- /dev/null +++ b/vorgang-manager-base/pom.xml @@ -0,0 +1,86 @@ +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> + <relativePath /> + </parent> + + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-base</artifactId> + <version>2.4.0</version> + + <name>OZG-Cloud Vorgang Manager Base</name> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-core</artifactId> + </dependency> + + <dependency> + <groupId>net.devh</groupId> + <artifactId>grpc-server-spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + + <!-- TEST --> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/LogRunner.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/LogRunner.java new file mode 100644 index 0000000..230a2b0 --- /dev/null +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/LogRunner.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.vorgang; + +import java.nio.charset.Charset; + +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Component +class LogRunner implements ApplicationListener<ContextRefreshedEvent> { + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + LOG.info("Standard Charset: " + Charset.defaultCharset()); + + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerApplication.java similarity index 59% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerApplication.java index aaf2af2..9909628 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/PlutoServerApplication.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto; +package de.ozgcloud.vorgang; import java.util.TimeZone; @@ -30,32 +30,45 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.context.annotation.Primary; +import org.springframework.context.event.ApplicationEventMulticaster; +import org.springframework.context.event.SimpleApplicationEventMulticaster; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.AuthenticationTrustResolverImpl; +import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor; -import io.mongock.runner.springboot.EnableMongock; - -@SpringBootApplication(scanBasePackages = "de.itvsh.*") -@EnableAsync +@SpringBootApplication(scanBasePackages = { "de.ozgcloud" }) +@EnableAsync(proxyTargetClass = true) @EnableScheduling @EnableAspectJAutoProxy(proxyTargetClass = true) -@EnableMongock -@ConfigurationPropertiesScan("de.itvsh.ozg.pluto.common.*") -@EnableMongoRepositories(basePackages = { "de.itvsh.ozg.pluto.vorgang", "de.itvsh.ozg.pluto.attached_item", "de.itvsh.ozg.pluto.command" }) -@EnableElasticsearchRepositories(basePackages = "de.itvsh.ozg.pluto.common.search") -public class PlutoServerApplication { +@ConfigurationPropertiesScan("de.ozgcloud.vorgang.*") +public class VorgangManagerServerApplication { public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - SpringApplication.run(PlutoServerApplication.class, args); + SpringApplication.run(VorgangManagerServerApplication.class, args); } @Bean AuthenticationTrustResolver trustResolver() { return new AuthenticationTrustResolverImpl(); } + + @Bean + @Primary + DelegatingSecurityContextAsyncTaskExecutor delegatingTaskExecutor(AsyncTaskExecutor applicationTaskExecutor) { + return new DelegatingSecurityContextAsyncTaskExecutor(applicationTaskExecutor); + } + + + @Bean(name = "applicationEventMulticaster") + ApplicationEventMulticaster simpleApplicationEventMulticaster(AsyncTaskExecutor delegatingTaskExecutor) { + var eventMulticaster = new SimpleApplicationEventMulticaster(); + + eventMulticaster.setTaskExecutor(delegatingTaskExecutor); + return eventMulticaster; + } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CallContext.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContext.java similarity index 86% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CallContext.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContext.java index 629dc7b..a3a6c45 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CallContext.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContext.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +package de.ozgcloud.vorgang.callcontext; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextAuthenticationToken.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextAuthenticationToken.java similarity index 94% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextAuthenticationToken.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextAuthenticationToken.java index 434c9df..ffba372 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextAuthenticationToken.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextAuthenticationToken.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; import java.util.Collection; import java.util.stream.Collectors; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptor.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptor.java similarity index 80% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptor.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptor.java index 2cc8ae9..0a60629 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptor.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,21 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Optional; import java.util.UUID; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; import org.apache.logging.log4j.CloseableThreadContext; import org.springframework.security.core.context.SecurityContextHolder; import io.grpc.ForwardingServerCallListener; import io.grpc.Metadata; -import io.grpc.Metadata.Key; import io.grpc.ServerCall; import io.grpc.ServerCall.Listener; import io.grpc.ServerCallHandler; @@ -136,26 +132,5 @@ class CallContextHandleInterceptor implements ServerInterceptor { void clearSecurityContext() { SecurityContextHolder.clearContext(); } - } - - // TODO move to a grpcUtil class in common - static Optional<String> getFromHeaders(String key, Metadata headers) { - return Optional.ofNullable(headers.get(createKeyOf(key))).map(val -> new String(val, StandardCharsets.UTF_8)); - } - - // TODO move to a grpcUtil class in common - static Collection<String> getCollection(String key, Metadata headers) { - return Optional.ofNullable(headers.getAll(createKeyOf(key))) - .map(vals -> StreamSupport.stream(vals.spliterator(), false)) - .orElseGet(Stream::empty) - .map(bytes -> new String(bytes, StandardCharsets.UTF_8)) - .toList(); - } - - // TODO move to a grpcUtil class in common - static Key<byte[]> createKeyOf(String key) { - return Key.of(key, Metadata.BINARY_BYTE_MARSHALLER); - } - } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUser.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextUser.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUser.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextUser.java index 0c973fc..5be7d61 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUser.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CallContextUser.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; import java.io.Serializable; import java.util.Collection; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserService.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CurrentUserService.java similarity index 96% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserService.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CurrentUserService.java index a2bf6a8..8b5e269 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserService.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/CurrentUserService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; import java.util.Optional; import java.util.stream.Collectors; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/User.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/User.java similarity index 83% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/User.java rename to vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/User.java index 6806e0e..9d73561 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/User.java +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/User.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.callcontext; -import javax.validation.constraints.NotNull; - -import de.itvsh.ozg.pluto.common.callcontext.CallContextUser; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -33,7 +31,7 @@ import lombok.ToString; /** * - * @deprecated Use {@link CallContextUser} instead + * @deprecated Use {@link de.ozgcloud.vorgang.callcontext.CallContextUser} instead * */ @Deprecated(since = "0.24.0", forRemoval = true) diff --git a/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptor.java b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptor.java new file mode 100644 index 0000000..77b60f2 --- /dev/null +++ b/vorgang-manager-base/src/main/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptor.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.callcontext; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; + +import java.util.UUID; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +public class VorgangManagerClientCallContextAttachingInterceptor implements ClientInterceptor { + + static final String KEY_REQUEST_ID = "REQUEST_ID-bin"; + static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin"; + + public static final String VORGANG_MANAGER_CLIENT_NAME = "OzgCloud_VorgangManager"; + + // <A> = Request, <B> = Response + @Override + public <A, B> ClientCall<A, B> interceptCall(MethodDescriptor<A, B> method, CallOptions callOptions, Channel next) { + return new CallContextAttachingClientCall<>(next.newCall(method, callOptions)); + } + + final class CallContextAttachingClientCall<A, B> extends SimpleForwardingClientCall<A, B> { + + protected CallContextAttachingClientCall(ClientCall<A, B> delegate) { + super(delegate); + } + + @Override + public void start(Listener<B> responseListener, Metadata headers) { + headers.merge(buildCallContextMetadata()); + super.start(responseListener, headers); + } + + private Metadata buildCallContextMetadata() { + var metadata = new Metadata(); + + metadata.put(createKeyOf(KEY_REQUEST_ID), UUID.randomUUID().toString().getBytes()); + metadata.put(createKeyOf(KEY_CLIENT_NAME), VORGANG_MANAGER_CLIENT_NAME.getBytes()); + + return metadata; + } + } +} diff --git a/vorgang-manager-base/src/main/resources/.empty b/vorgang-manager-base/src/main/resources/.empty new file mode 100644 index 0000000..e69de29 diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptorTest.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptorTest.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptorTest.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptorTest.java index 0e83ee1..9b46d59 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextHandleInterceptorTest.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextHandleInterceptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; -import static de.itvsh.ozg.pluto.common.callcontext.CallContextHandleInterceptor.*; +import static de.ozgcloud.common.grpc.GrpcUtil.*; +import static de.ozgcloud.vorgang.callcontext.CallContextHandleInterceptor.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -36,8 +37,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.security.core.context.SecurityContextHolder; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CallContextHandleInterceptor.LogContextSettingListener; +import de.ozgcloud.vorgang.callcontext.CallContextHandleInterceptor.LogContextSettingListener; import io.grpc.Metadata; import io.grpc.ServerCall; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextTestFactory.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextTestFactory.java similarity index 66% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextTestFactory.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextTestFactory.java index 37aa23d..ab2588d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextTestFactory.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,18 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; -import static de.itvsh.ozg.pluto.command.UserTestFactory.*; -import static de.itvsh.ozg.pluto.common.callcontext.CallContextHandleInterceptor.*; +import static de.ozgcloud.vorgang.callcontext.CallContextHandleInterceptor.*; +import static de.ozgcloud.vorgang.callcontext.UserTestFactory.*; import java.util.Map; import java.util.Set; import java.util.UUID; -import de.itvsh.ozg.pluto.command.CallContext; -import de.itvsh.ozg.pluto.command.User; -import de.itvsh.ozg.pluto.command.UserTestFactory; +import de.ozgcloud.common.grpc.GrpcUtil; import io.grpc.Metadata; public class CallContextTestFactory { @@ -65,12 +63,12 @@ public class CallContextTestFactory { public static Metadata createMetadata() { var result = new Metadata(); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_USER_ID), ID.getBytes()); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_USER_NAME), NAME.getBytes()); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_CLIENT_NAME), CLIENT.getBytes()); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_ACCESS_LIMITED_ORGAID), ORGANISATORISCHE_EINHEITEN_ID.getBytes()); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_REQUEST_ID), REQUEST_ID.getBytes()); - result.put(CallContextHandleInterceptor.createKeyOf(KEY_ACCESS_LIMITED), DO_ORGA_ID_ACCESS_CHECK.toString().getBytes()); + result.put(GrpcUtil.HEADER_KEY_USER_ID, ID.getBytes()); + result.put(GrpcUtil.createKeyOf(KEY_USER_NAME), NAME.getBytes()); + result.put(GrpcUtil.createKeyOf(KEY_CLIENT_NAME), CLIENT.getBytes()); + result.put(GrpcUtil.createKeyOf(KEY_ACCESS_LIMITED_ORGAID), ORGANISATORISCHE_EINHEITEN_ID.getBytes()); + result.put(GrpcUtil.createKeyOf(KEY_REQUEST_ID), REQUEST_ID.getBytes()); + result.put(GrpcUtil.createKeyOf(KEY_ACCESS_LIMITED), DO_ORGA_ID_ACCESS_CHECK.toString().getBytes()); return result; } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUserTestFactory.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextUserTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUserTestFactory.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextUserTestFactory.java index 7ddefbe..cb365ff 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CallContextUserTestFactory.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CallContextUserTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; import java.util.Optional; -import de.itvsh.ozg.pluto.command.UserTestFactory; - public class CallContextUserTestFactory { + public static final String ID = UserTestFactory.ID; + public static CallContextUser create() { return createBuilder().build(); } @@ -36,7 +36,7 @@ public class CallContextUserTestFactory { public static CallContextUser.CallContextUserBuilder createBuilder() { return CallContextUser.builder() .clientName(CallContextTestFactory.CLIENT) - .userId(Optional.of(UserTestFactory.ID)) + .userId(Optional.of(ID)) .userName(Optional.of(UserTestFactory.NAME)) .organisatorischeEinheitenId(UserTestFactory.ORGANISATORISCHE_EINHEITEN_ID) .organisationEinheitenIdCheckNecessary(CallContextTestFactory.DO_ORGA_ID_ACCESS_CHECK); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceITCase.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceITCase.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceITCase.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceITCase.java index d11241e..9bf0607 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceITCase.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; + +import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -31,9 +33,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.context.support.WithAnonymousUser; import org.springframework.security.test.context.support.WithMockUser; -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.kop.common.test.ITCase; +import de.ozgcloud.common.test.ITCase; @ITCase class CurrentUserServiceITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceTest.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceTest.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceTest.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceTest.java index 07a4908..627f30b 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/CurrentUserServiceTest.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/CurrentUserServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/TestCallContextAttachingInterceptor.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/TestCallContextAttachingInterceptor.java similarity index 75% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/TestCallContextAttachingInterceptor.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/TestCallContextAttachingInterceptor.java index 6eac9cf..6adc3ce 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/callcontext/TestCallContextAttachingInterceptor.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/TestCallContextAttachingInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.callcontext; +package de.ozgcloud.vorgang.callcontext; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.common.grpc.GrpcUtil; import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.ClientCall; @@ -37,7 +37,7 @@ import lombok.Setter; public class TestCallContextAttachingInterceptor implements ClientInterceptor { private final String clientName = CallContextTestFactory.CLIENT; - private final String organisationEinheitId = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID; + private final String organisationEinheitId = UserTestFactory.ORGANISATORISCHE_EINHEITEN_ID; private final Boolean organisationEinheitIdCheckNecessary = Boolean.TRUE; @Override @@ -54,11 +54,9 @@ public class TestCallContextAttachingInterceptor implements ClientInterceptor { @Override public void start(Listener<RespT> responseListener, Metadata headers) { var metadata = new Metadata(); - metadata.put(CallContextHandleInterceptor.createKeyOf(CallContextHandleInterceptor.KEY_CLIENT_NAME), - clientName.getBytes()); - metadata.put(CallContextHandleInterceptor.createKeyOf(CallContextHandleInterceptor.KEY_ACCESS_LIMITED_ORGAID), - organisationEinheitId.getBytes()); - metadata.put(CallContextHandleInterceptor.createKeyOf(CallContextHandleInterceptor.KEY_ACCESS_LIMITED), + metadata.put(GrpcUtil.createKeyOf(CallContextHandleInterceptor.KEY_CLIENT_NAME), clientName.getBytes()); + metadata.put(GrpcUtil.createKeyOf(CallContextHandleInterceptor.KEY_ACCESS_LIMITED_ORGAID), organisationEinheitId.getBytes()); + metadata.put(GrpcUtil.createKeyOf(CallContextHandleInterceptor.KEY_ACCESS_LIMITED), organisationEinheitIdCheckNecessary.toString().getBytes()); headers.merge(metadata); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/UserTestFactory.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/UserTestFactory.java similarity index 86% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/UserTestFactory.java rename to vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/UserTestFactory.java index 2862afe..4bc4c34 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/UserTestFactory.java +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/UserTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.callcontext; import java.util.UUID; @@ -29,7 +29,7 @@ public class UserTestFactory { public static final String ID = UUID.randomUUID().toString(); public static final String NAME = "Udo Jürgens"; - public static final String ORGANISATORISCHE_EINHEITEN_ID = UUID.randomUUID().toString(); + public static final String ORGANISATORISCHE_EINHEITEN_ID = "08150815"; public static User create() { return createBuilder().build(); diff --git a/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptorTest.java b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptorTest.java new file mode 100644 index 0000000..9357815 --- /dev/null +++ b/vorgang-manager-base/src/test/java/de/ozgcloud/vorgang/callcontext/VorgangManagerClientCallContextAttachingInterceptorTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.callcontext; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; +import static de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +class VorgangManagerClientCallContextAttachingInterceptorTest { + + @InjectMocks + private VorgangManagerClientCallContextAttachingInterceptor interceptor; + + @Nested + class TestInterceptCall<A, B> { + + @Mock + private MethodDescriptor<A, B> method; + @Mock + private CallOptions callOptions; + @Mock + private Channel next; + @Mock + private ClientCall<Object, Object> nextCall; + + @Mock + private ClientCall.Listener<B> listener; + @Mock + private Metadata headers; + @Captor + private ArgumentCaptor<Metadata> metadataCaptor; + + @BeforeEach + void initMocks() { + when(next.newCall(any(), any())).thenReturn(nextCall); + } + + @Test + void shouldAddClientName() { + var addedMetadata = interceptCall(); + + assertThat(addedMetadata.get(createKeyOf(KEY_CLIENT_NAME))).isEqualTo(VORGANG_MANAGER_CLIENT_NAME.getBytes()); + } + + @Test + void shouldAddRequestId() { + var addedMetadata = interceptCall(); + + assertThat(addedMetadata.get(createKeyOf(KEY_REQUEST_ID))).isNotNull(); + } + + private Metadata interceptCall() { + var call = interceptor.interceptCall(method, callOptions, next); + + call.start(listener, headers); + + verify(headers).merge(metadataCaptor.capture()); + return metadataCaptor.getValue(); + } + } + +} diff --git a/vorgang-manager-base/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/vorgang-manager-base/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 0000000..79b126e --- /dev/null +++ b/vorgang-manager-base/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1 @@ +org.mockito.junit.jupiter.MockitoExtension \ No newline at end of file diff --git a/vorgang-manager-base/src/test/resources/junit-platform.properties b/vorgang-manager-base/src/test/resources/junit-platform.properties new file mode 100644 index 0000000..1cebb76 --- /dev/null +++ b/vorgang-manager-base/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled = true \ No newline at end of file diff --git a/vorgang-manager-base/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/vorgang-manager-base/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/vorgang-manager-base/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/vorgang-manager-command/lombok.config b/vorgang-manager-command/lombok.config new file mode 100644 index 0000000..81661f0 --- /dev/null +++ b/vorgang-manager-command/lombok.config @@ -0,0 +1,30 @@ +# +# 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. +# + +lombok.log.fieldName=LOG +lombok.log.slf4j.flagUsage = ERROR +lombok.log.log4j.flagUsage = ERROR +lombok.data.flagUsage = ERROR +lombok.nonNull.exceptionType = IllegalArgumentException +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/vorgang-manager-command/pom.xml b/vorgang-manager-command/pom.xml new file mode 100644 index 0000000..da45403 --- /dev/null +++ b/vorgang-manager-command/pom.xml @@ -0,0 +1,79 @@ +<?xml version="1.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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-dependencies</artifactId> + <version>3.0.1</version> + <relativePath/> + </parent> + + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>2.4.0</version> + <name>OZG-Cloud Command Manager</name> + + <properties> + <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-lib</artifactId> + </dependency> + + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>${maven-jar-plugin.version}</version> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/Command.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java similarity index 90% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/Command.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java index a0fd95a..07acbea 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/Command.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; import java.time.ZonedDateTime; import java.util.Map; @@ -33,7 +33,8 @@ public interface Command { public String getId(); public String getVorgangId(); public String getRelationId(); - public long getRelationVersion(); + + public Long getRelationVersion(); public String getOrder(); @@ -48,4 +49,6 @@ public interface Command { public Map<String, String> getBody(); public String getErrorMessage(); + + String getCreatedResource(); } diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandCreatedEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandCreatedEvent.java similarity index 92% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandCreatedEvent.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandCreatedEvent.java index 7ab71eb..ab7acc7 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandCreatedEvent.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandCreatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; import org.springframework.context.ApplicationEvent; diff --git a/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandExecutedEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandExecutedEvent.java new file mode 100644 index 0000000..b862438 --- /dev/null +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandExecutedEvent.java @@ -0,0 +1,73 @@ +/* + * 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.command; + +import org.springframework.context.ApplicationEvent; + +import lombok.Getter; + +@Getter +public class CommandExecutedEvent extends ApplicationEvent { + + private static final long serialVersionUID = 1L; + + private final Command command; + + private String createdResource; + + @Deprecated + public CommandExecutedEvent(String commandId) { + super(commandId); + + command = null; + } + + @Deprecated + public CommandExecutedEvent(String commandId, String createdResource) { + super(commandId); + command = null; + this.createdResource = createdResource; + } + + public CommandExecutedEvent(Command command) { + super(command.getId()); + + this.command = command; + } + + public CommandExecutedEvent(Command command, String createdResource) { + super(command.getId()); + this.command = command; + this.createdResource = createdResource; + } + + @Override + public String getSource() { + return (String) super.getSource(); + } + + public Command getCommand() { + return command; + } +} \ No newline at end of file diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandFailedEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandFailedEvent.java similarity index 93% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandFailedEvent.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandFailedEvent.java index fd89420..dfaa574 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandFailedEvent.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; import org.springframework.context.ApplicationEvent; diff --git a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachServerProcessException.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokeFailedEvent.java similarity index 74% rename from mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachServerProcessException.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokeFailedEvent.java index f3acfe2..a86875c 100644 --- a/mail-service/src/main/java/de/itvsh/ozg/mail/postfach/OsiPostfachServerProcessException.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokeFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.command; -class OsiPostfachServerProcessException extends OsiPostfachException {// NOSONAR +public class CommandRevokeFailedEvent extends CommandFailedEvent { private static final long serialVersionUID = 1L; - public OsiPostfachServerProcessException() { - super("Osi-Postfach server returned false", OsiPostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE); + public CommandRevokeFailedEvent(String commandId, String errorMessage) { + super(commandId, errorMessage); } -} \ No newline at end of file + +} diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandExecutedEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokedEvent.java similarity index 77% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandExecutedEvent.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokedEvent.java index 9a4a5c2..2613a6a 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandExecutedEvent.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandRevokedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,20 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; import org.springframework.context.ApplicationEvent; -public class CommandExecutedEvent extends ApplicationEvent { +public class CommandRevokedEvent extends ApplicationEvent { private static final long serialVersionUID = 1L; - protected CommandExecutedEvent(String commandId) { - super(commandId); + public CommandRevokedEvent(Command source) { + super(source); } @Override - public String getSource() { - return (String) super.getSource(); + public Command getSource() { + return (Command) super.getSource(); } -} \ No newline at end of file +} diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandStatus.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandStatus.java similarity index 90% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandStatus.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandStatus.java index 0a91a36..51fcb85 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/CommandStatus.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/CommandStatus.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; public enum CommandStatus { PENDING, FINISHED, ERROR, REVOKE_PENDING, REVOKED; diff --git a/vorgang-manager-command/src/main/java/de/ozgcloud/command/RevokeCommandEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/RevokeCommandEvent.java new file mode 100644 index 0000000..9da9e74 --- /dev/null +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/RevokeCommandEvent.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.command; + +import org.springframework.context.ApplicationEvent; + +public class RevokeCommandEvent extends ApplicationEvent { + + private static final long serialVersionUID = 1L; + + public RevokeCommandEvent(Command source) { + super(source); + } + + @Override + public Command getSource() { + return (Command) super.getSource(); + } +} diff --git a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/VorgangCreatedEvent.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/VorgangCreatedEvent.java similarity index 89% rename from pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/VorgangCreatedEvent.java rename to vorgang-manager-command/src/main/java/de/ozgcloud/command/VorgangCreatedEvent.java index 44c3995..8a7d34d 100644 --- a/pluto-interface/src/main/java/de/itvsh/ozg/pluto/command/VorgangCreatedEvent.java +++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/VorgangCreatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.command; import org.springframework.context.ApplicationEvent; public class VorgangCreatedEvent extends ApplicationEvent { + private static final long serialVersionUID = 1L; + public VorgangCreatedEvent(String vorgangId) { super(vorgangId); } diff --git a/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandCreatedEventTestFactory.java b/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandCreatedEventTestFactory.java new file mode 100644 index 0000000..8331a11 --- /dev/null +++ b/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandCreatedEventTestFactory.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.command; + +public class CommandCreatedEventTestFactory { + + public static CommandCreatedEvent create() { + return new CommandCreatedEvent(CommandTestFactory.create()); + } + + public static CommandCreatedEvent withCommand(Command command) { + return new CommandCreatedEvent(command); + } + +} diff --git a/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandTestFactory.java b/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandTestFactory.java new file mode 100644 index 0000000..e24b3f9 --- /dev/null +++ b/vorgang-manager-command/src/test/java/de/ozgcloud/command/CommandTestFactory.java @@ -0,0 +1,49 @@ +/* + * 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.command; + +import java.util.Map; +import java.util.UUID; + +public class CommandTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + public static final String VORGANG_ID = UUID.randomUUID().toString(); + public static final String ORDER = "DO_TEST"; + + public static final String CREATED_BY = UUID.randomUUID().toString(); + + public static Command create() { + return createBuilder().build(); + } + + public static TestCommand.TestCommandBuilder createBuilder() { + return TestCommand.builder() + .id(ID) + .vorgangId(VORGANG_ID) + .body(Map.of()) + .bodyObject(Map.of()) + .createdBy(CREATED_BY); + } +} diff --git a/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java b/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java new file mode 100644 index 0000000..cd47046 --- /dev/null +++ b/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java @@ -0,0 +1,56 @@ +/* + * 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.command; + +import java.time.ZonedDateTime; +import java.util.Map; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class TestCommand implements Command { + + private String id; + private String vorgangId; + private String relationId; + private Long relationVersion; + + private String order; + + private ZonedDateTime createdAt; + private ZonedDateTime finishedAt; + private String createdBy; + private String createdByName; + + private CommandStatus status; + + private Map<String, Object> bodyObject; + private Map<String, String> body; + + private String errorMessage; + + private String createdResource; +} diff --git a/vorgang-manager-interface/pom.xml b/vorgang-manager-interface/pom.xml new file mode 100644 index 0000000..fec773f --- /dev/null +++ b/vorgang-manager-interface/pom.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-dependencies</artifactId> + <version>3.0.1</version> + <relativePath/> + </parent> + + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> + <version>2.4.0</version> + + <name>OZG-Cloud Vorgang Manager gRPC Interface</name> + <description>Interface (gRPC) for Vorgang Manager Server</description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + + <java.version>17</java.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + + <find-and-replace-maven-plugin.version>1.1.0</find-and-replace-maven-plugin.version> + <ozgcloud.license.version>1.6.0</ozgcloud.license.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-dependencies</artifactId> + <version>${ozgcloud-common.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <!-- GRPC --> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-stub</artifactId> + </dependency> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-protobuf</artifactId> + </dependency> + <dependency> + <groupId>jakarta.annotation</groupId> + <artifactId>jakarta.annotation-api</artifactId> + </dependency> + </dependencies> + + <build> + <sourceDirectory>src/main/protobuf</sourceDirectory> + + <extensions> + <extension> + <groupId>kr.motd.maven</groupId> + <artifactId>os-maven-plugin</artifactId> + </extension> + </extensions> + + <plugins> + <plugin> + <groupId>com.github.os72</groupId> + <artifactId>protoc-jar-maven-plugin</artifactId> + <version>${protoc-jar-plugin.version}</version> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <outputTargets> + <outputTarget> + <type>java</type> + </outputTarget> + <outputTarget> + <type>grpc-java</type> + <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.58.0</pluginArtifact> + </outputTarget> + </outputTargets> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>io.github.floverfelt</groupId> + <artifactId>find-and-replace-maven-plugin</artifactId> + <version>${find-and-replace-maven-plugin.version}</version> + <executions> + <execution> + <id>exec</id> + <phase>process-sources</phase> + <goals> + <goal>find-and-replace</goal> + </goals> + <configuration> + <replacementType>file-contents</replacementType> + <baseDir>target/generated-sources/</baseDir> + <findRegex>javax</findRegex> + <replaceValue>jakarta</replaceValue> + <recursive>true</recursive> + <fileMask>.java</fileMask> + </configuration> + </execution> + </executions> + </plugin> + <!-- TODO move to common --> + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <mapping> + <proto>SLASHSTAR_STYLE</proto> + <config>SCRIPT_STYLE</config> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/*.yaml</exclude> + <exclude>**/*.yml</exclude> + <exclude>README.md</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>3.2.1</version> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <distributionManagement> + <repository> + <id>ozg-nexus</id> + <name>ozg-releases</name> + <url>https://nexus.ozg-sh.de/repository/ozg-releases/</url> + </repository> + <snapshotRepository> + <id>ozg-snapshots-nexus</id> + <name>ozg-snapshots</name> + <url>https://nexus.ozg-sh.de/repository/ozg-snapshots/</url> + </snapshotRepository> + </distributionManagement> +</project> diff --git a/vorgang-manager-interface/src/main/protobuf/bescheid.model.proto b/vorgang-manager-interface/src/main/protobuf/bescheid.model.proto new file mode 100644 index 0000000..b038dfe --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/bescheid.model.proto @@ -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. + */ + syntax = "proto3"; + + package de.ozgcloud.bescheid; + + option java_multiple_files = true; + option java_package = "de.ozgcloud.bescheid"; + option java_outer_classname = "BescheidModelProto"; + +message GrpcGetBescheidDraftRequest { + string vorgangId = 1; +} + +message GrpcGetBescheidDraftResponse { + GrpcBescheid bescheid = 1; +} + +message GrpcBescheid { + string beschiedenAm = 1; + bool bewilligt = 2; + string bescheidDocument = 3; + repeated string attachments = 4; + string sendBy = 5; + string nachrichtText = 6; + string nachrichtSubject = 7; +} \ No newline at end of file diff --git a/vorgang-manager-interface/src/main/protobuf/bescheid.proto b/vorgang-manager-interface/src/main/protobuf/bescheid.proto new file mode 100644 index 0000000..9e6bb91 --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/bescheid.proto @@ -0,0 +1,37 @@ +/* + * 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.bescheid; + + import "bescheid.model.proto"; + + option java_multiple_files = true; + option java_package = "de.ozgcloud.bescheid"; + option java_outer_classname = "BescheidProto"; + + service BescheidService { + rpc getBescheidDraft(GrpcGetBescheidDraftRequest) returns (GrpcGetBescheidDraftResponse) { + } + } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/binaryfile.proto b/vorgang-manager-interface/src/main/protobuf/binaryfile.proto similarity index 81% rename from pluto-interface/src/main/protobuf/binaryfile.proto rename to vorgang-manager-interface/src/main/protobuf/binaryfile.proto index 651bb18..c4233ee 100644 --- a/pluto-interface/src/main/protobuf/binaryfile.proto +++ b/vorgang-manager-interface/src/main/protobuf/binaryfile.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,13 +23,13 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.binaryFile; +package de.ozgcloud.vorgang.grpc.binaryFile; import "callcontext.proto"; import "filemodel.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.binaryFile"; +option java_package = "de.ozgcloud.vorgang.grpc.binaryFile"; option java_outer_classname = "BinaryFileProto"; service BinaryFileService { @@ -41,7 +41,6 @@ service BinaryFileService { } rpc FindBinaryFilesMetaData(GrpcBinaryFilesRequest) returns (GrpcFindFilesResponse) { - } rpc GetAttachments(GrpcGetAttachmentsRequest) returns (GrpcGetAttachmentsResponse) { @@ -52,16 +51,16 @@ service BinaryFileService { } message GrpcBinaryFilesRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; repeated string fileId = 2; } message GrpcFindFilesResponse { - repeated de.itvsh.ozg.pluto.grpc.file.GrpcOzgFile file = 1; + repeated de.ozgcloud.vorgang.grpc.file.GrpcOzgFile file = 1; } message GrpcBinaryFileDataRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string fileId = 2; } @@ -73,7 +72,7 @@ message GrpcUploadBinaryFileRequest { } message GrpcUploadBinaryFileMetaData { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; string field = 3; string fileName = 4; @@ -86,7 +85,7 @@ message GrpcUploadBinaryFileResponse { } message GrpcGetBinaryFileDataRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string fileId = 2; } @@ -95,7 +94,7 @@ message GrpcGetBinaryFileDataResponse { } message GrpcGetAttachmentsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string eingangId = 2; } message GrpcGetAttachmentsResponse { @@ -103,7 +102,7 @@ message GrpcGetAttachmentsResponse { } message GrpcGetRepresentationsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string eingangId = 2; } message GrpcGetRepresentationsResponse { diff --git a/pluto-interface/src/main/protobuf/callcontext.proto b/vorgang-manager-interface/src/main/protobuf/callcontext.proto similarity index 87% rename from pluto-interface/src/main/protobuf/callcontext.proto rename to vorgang-manager-interface/src/main/protobuf/callcontext.proto index 5181350..234931d 100644 --- a/pluto-interface/src/main/protobuf/callcontext.proto +++ b/vorgang-manager-interface/src/main/protobuf/callcontext.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.command; +package de.ozgcloud.vorgang.grpc.command; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.command"; +option java_package = "de.ozgcloud.vorgang.grpc.command"; option java_outer_classname = "SharedCommandProto"; message GrpcCallContext { diff --git a/pluto-interface/src/main/protobuf/clientattribute.model.proto b/vorgang-manager-interface/src/main/protobuf/clientattribute.model.proto similarity index 88% rename from pluto-interface/src/main/protobuf/clientattribute.model.proto rename to vorgang-manager-interface/src/main/protobuf/clientattribute.model.proto index 53cd27a..89f6087 100644 --- a/pluto-interface/src/main/protobuf/clientattribute.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/clientattribute.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.clientAttribute; +package de.ozgcloud.vorgang.grpc.clientAttribute; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.clientAttribute"; +option java_package = "de.ozgcloud.vorgang.grpc.clientAttribute"; message GrpcClientAttribute { string clientName = 1; diff --git a/pluto-interface/src/main/protobuf/clientattribute.proto b/vorgang-manager-interface/src/main/protobuf/clientattribute.proto similarity index 90% rename from pluto-interface/src/main/protobuf/clientattribute.proto rename to vorgang-manager-interface/src/main/protobuf/clientattribute.proto index c9189f6..d717d83 100644 --- a/pluto-interface/src/main/protobuf/clientattribute.proto +++ b/vorgang-manager-interface/src/main/protobuf/clientattribute.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.clientAttribute; +package de.ozgcloud.vorgang.grpc.clientAttribute; import "clientattribute.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.clientAttribute"; +option java_package = "de.ozgcloud.vorgang.grpc.clientAttribute"; service ClientAttributeService { rpc Set (GrpcSetClientAttributeRequest) returns (GrpcAcknowledgeResponse) { diff --git a/pluto-interface/src/main/protobuf/command.model.proto b/vorgang-manager-interface/src/main/protobuf/command.model.proto similarity index 79% rename from pluto-interface/src/main/protobuf/command.model.proto rename to vorgang-manager-interface/src/main/protobuf/command.model.proto index 570ae43..4bbd54b 100644 --- a/pluto-interface/src/main/protobuf/command.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/command.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,13 +23,13 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.command; +package de.ozgcloud.vorgang.grpc.command; import "callcontext.proto"; import "common.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.command"; +option java_package = "de.ozgcloud.vorgang.grpc.command"; option java_outer_classname = "CommandModelProto"; @@ -66,14 +66,14 @@ enum GrpcOrder { } message GrpcCreateCommandRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext callContext = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext callContext = 1; string vorgangId = 2; GrpcOrder order = 3; string relationId = 4; int64 relationVersion = 5; GrpcRedirectRequest redirectRequest = 12; repeated GrpcCommandBodyField body = 15; - de.itvsh.ozg.pluto.common.GrpcObject bodyObj = 17; + de.ozgcloud.vorgang.common.GrpcObject bodyObj = 17; string orderString = 21; } @@ -91,15 +91,20 @@ message GrpcCommandResponse { } message GrpcRevokeCommandRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string id = 2; } message GrpcGetCommandRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string id = 2; } +message GrpcSetCommandExecutedRequest { + string commandId = 1; + string createdResource = 2; +} + message GrpcCommand { string id = 1; string vorgangId = 2; @@ -112,13 +117,14 @@ message GrpcCommand { string relationId = 14; GrpcOrder order = 15 [deprecated=true]; GrpcCommandBody body = 16; - de.itvsh.ozg.pluto.common.GrpcObject bodyObj = 17; + de.ozgcloud.vorgang.common.GrpcObject bodyObj = 17; GrpcRedirectRequest redirectRequest = 20; string orderString = 21; + string createdResource = 22; } message GrpcExistsPendingCommandsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; } @@ -127,19 +133,19 @@ message GrpcExistsPendingCommandsResponse { } message GrpcRedirectRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string email = 2; string password = 3; } message GrpcGetPendingCommandsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; } message GrpcFindCommandsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; repeated string status = 3; GrpcOrder order = 4; @@ -160,4 +166,8 @@ message GrpcCommandBody { message GrpcCommandBodyField { string name = 1; string value = 2; +} + +message GrpcEmpty { + } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/command.proto b/vorgang-manager-interface/src/main/protobuf/command.proto similarity index 86% rename from pluto-interface/src/main/protobuf/command.proto rename to vorgang-manager-interface/src/main/protobuf/command.proto index 341e807..019ee5b 100644 --- a/pluto-interface/src/main/protobuf/command.proto +++ b/vorgang-manager-interface/src/main/protobuf/command.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.command; +package de.ozgcloud.vorgang.grpc.command; import "command.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.command"; +option java_package = "de.ozgcloud.vorgang.grpc.command"; option java_outer_classname = "CommandProto"; service CommandService { @@ -50,4 +50,8 @@ service CommandService { rpc FindCommands(GrpcFindCommandsRequest) returns (GrpcCommandsResponse) { } + + rpc SetCommandExecuted(GrpcSetCommandExecutedRequest) returns (GrpcEmpty) { + + } } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/common.model.proto b/vorgang-manager-interface/src/main/protobuf/common.model.proto similarity index 76% rename from pluto-interface/src/main/protobuf/common.model.proto rename to vorgang-manager-interface/src/main/protobuf/common.model.proto index e1db8f9..e4b876f 100644 --- a/pluto-interface/src/main/protobuf/common.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/common.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.common; +package de.ozgcloud.vorgang.common; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.common"; +option java_package = "de.ozgcloud.vorgang.common"; option java_outer_classname = "CommonModelProto"; message GrpcObject { @@ -43,4 +43,17 @@ message GrpcSubObject { string name = 1; repeated GrpcProperty property = 2; repeated GrpcSubObject subObject = 3; +} + +enum GrpcQueryOperator { + GREATER_THEN = 0; // > + GREATER_THEN_OR_EQUAL_TO = 1; // >= + LESS_THEN = 2; // < + LESS_THEN_OR_EQUAL_TO = 3; // <= + EQUAL = 4; // = + UNEQUAL = 5; // <> + IS_NULL = 6; + IS_EMPTY = 7; + EXISTS = 8; + NOT_EXIST = 9; } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/email.model.proto b/vorgang-manager-interface/src/main/protobuf/email.model.proto similarity index 88% rename from pluto-interface/src/main/protobuf/email.model.proto rename to vorgang-manager-interface/src/main/protobuf/email.model.proto index 5e57894..53a0075 100644 --- a/pluto-interface/src/main/protobuf/email.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/email.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.mail.email"; +option java_package = "de.ozgcloud.nachrichten.email"; option java_outer_classname = "EmailModelProto"; message GrpcRecipient { diff --git a/pluto-interface/src/main/protobuf/email.proto b/vorgang-manager-interface/src/main/protobuf/email.proto similarity index 87% rename from pluto-interface/src/main/protobuf/email.proto rename to vorgang-manager-interface/src/main/protobuf/email.proto index 59bec8e..64fd405 100644 --- a/pluto-interface/src/main/protobuf/email.proto +++ b/vorgang-manager-interface/src/main/protobuf/email.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.mail.email; +package de.ozgcloud.nachrichten.email; import "email.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.mail.email"; +option java_package = "de.ozgcloud.nachrichten.email"; option java_outer_classname = "EmailProto"; diff --git a/pluto-interface/src/main/protobuf/file.proto b/vorgang-manager-interface/src/main/protobuf/file.proto similarity index 88% rename from pluto-interface/src/main/protobuf/file.proto rename to vorgang-manager-interface/src/main/protobuf/file.proto index 25f826d..a3061b2 100644 --- a/pluto-interface/src/main/protobuf/file.proto +++ b/vorgang-manager-interface/src/main/protobuf/file.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.file; +package de.ozgcloud.vorgang.grpc.file; import "filemodel.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.grpc.file"; +option java_package = "de.ozgcloud.vorgang.grpc.file"; option java_outer_classname = "FileProto"; option deprecated = true; diff --git a/pluto-interface/src/main/protobuf/filemodel.proto b/vorgang-manager-interface/src/main/protobuf/filemodel.proto similarity index 86% rename from pluto-interface/src/main/protobuf/filemodel.proto rename to vorgang-manager-interface/src/main/protobuf/filemodel.proto index f8785dc..49cbc59 100644 --- a/pluto-interface/src/main/protobuf/filemodel.proto +++ b/vorgang-manager-interface/src/main/protobuf/filemodel.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,7 +23,7 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.grpc.file; +package de.ozgcloud.vorgang.grpc.file; import "callcontext.proto"; @@ -32,7 +32,7 @@ option java_outer_classname = "FileModelProto"; option deprecated = true; message GrpcGetAttachmentsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string eingangId = 2; } message GrpcGetAttachmentsResponse { @@ -40,7 +40,7 @@ message GrpcGetAttachmentsResponse { } message GrpcGetRepresentationsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string eingangId = 2; } message GrpcGetRepresentationsResponse { diff --git a/pluto-interface/src/main/protobuf/forwarding.model.proto b/vorgang-manager-interface/src/main/protobuf/forwarding.model.proto similarity index 89% rename from pluto-interface/src/main/protobuf/forwarding.model.proto rename to vorgang-manager-interface/src/main/protobuf/forwarding.model.proto index 7683959..2e98173 100644 --- a/pluto-interface/src/main/protobuf/forwarding.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/forwarding.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.forwarding; +package de.ozgcloud.vorgang.forwarding; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.forwarding"; +option java_package = "de.ozgcloud.vorgang.forwarding"; option java_outer_classname = "ForwardingModelProto"; enum GrpcForwardingStatus { diff --git a/pluto-interface/src/main/protobuf/forwarding.proto b/vorgang-manager-interface/src/main/protobuf/forwarding.proto similarity index 85% rename from pluto-interface/src/main/protobuf/forwarding.proto rename to vorgang-manager-interface/src/main/protobuf/forwarding.proto index 41ab1aa..840119d 100644 --- a/pluto-interface/src/main/protobuf/forwarding.proto +++ b/vorgang-manager-interface/src/main/protobuf/forwarding.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,13 +23,13 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.forwarding; +package de.ozgcloud.vorgang.forwarding; import "callcontext.proto"; import "forwarding.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.forwarding"; +option java_package = "de.ozgcloud.vorgang.forwarding"; option java_outer_classname = "ForwardingProto"; @@ -39,7 +39,7 @@ service ForwardingService { } message GrpcFindForwardingsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; } diff --git a/pluto-interface/src/main/protobuf/postfach.model.proto b/vorgang-manager-interface/src/main/protobuf/postfach.model.proto similarity index 59% rename from pluto-interface/src/main/protobuf/postfach.model.proto rename to vorgang-manager-interface/src/main/protobuf/postfach.model.proto index 79023e7..20b7b67 100644 --- a/pluto-interface/src/main/protobuf/postfach.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/postfach.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,33 +23,44 @@ */ syntax = "proto3"; -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import "callcontext.proto"; +import "vorgang.model.proto"; +import "common.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.mail.postfach"; +option java_package = "de.ozgcloud.nachrichten.postfach"; option java_outer_classname = "PostfachMailModelProto"; message GrpcSendPostfachMailRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string commandId = 2; GrpcPostfachMail mail = 5; } +message GrpcSaveNachrichtDraftRequest { + string vorgangId = 1; + GrpcPostfachNachricht nachricht = 2; +} + +message GrpcSaveNachrichtDraftResponse { +} + message GrpcSendPostfachMailResponse { } message GrpcFindPostfachMailRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string nachrichtId = 2; } + message GrpcFindPostfachMailResponse { GrpcPostfachMail nachricht = 1; } message GrpcFindPostfachMailsRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string vorgangId = 2; } @@ -63,10 +74,21 @@ enum GrpcDirection { OUT = 2; } +message GrpcPostfachNachricht { + string id = 1; + string createdAt = 2; + de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress postfachAddress = 3; + string subject = 4; + string mailBody = 5; + string replyOption = 6; + repeated string attachment = 7; +} + message GrpcPostfachMail { string id = 1; string vorgangId = 2; - string postfachId = 3; + string postfachId = 3 [deprecated = true]; + GrpcPostfachAddress postfachAddress = 14; string createdAt = 4; string createdBy = 5; string sentAt = 6; @@ -77,10 +99,18 @@ message GrpcPostfachMail { string mailBody = 11; string replyOption = 12; repeated string attachment = 13; + GrpcPostfachAddress address = 15; +} + +message GrpcPostfachAddress { + string version = 1; + de.ozgcloud.vorgang.common.GrpcObject identifier = 2; + int32 type = 3; + string serviceKontoType = 4; } message GrpcResendPostfachMailRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; string commandId = 2; string postfachMailId = 3; } @@ -89,9 +119,22 @@ message GrpcResendPostfachMailResponse { } message GrpcIsPostfachConfiguredRequest { - de.itvsh.ozg.pluto.grpc.command.GrpcCallContext context = 1; + de.ozgcloud.vorgang.grpc.command.GrpcCallContext context = 1; } message GrpcIsPostfachConfiguredResponse { bool isConfigured = 1; +} + +message GrpcGetPostfachConfigRequest { +} + +message GrpcGetPostfachConfigResponse { + bool configured = 1; + repeated GrpcPostfach postfach = 2; +} + +message GrpcPostfach { + string type = 1; + bool replyAllowed = 2; } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/postfach.proto b/vorgang-manager-interface/src/main/protobuf/postfach.proto similarity index 78% rename from pluto-interface/src/main/protobuf/postfach.proto rename to vorgang-manager-interface/src/main/protobuf/postfach.proto index d724555..702bc34 100644 --- a/pluto-interface/src/main/protobuf/postfach.proto +++ b/vorgang-manager-interface/src/main/protobuf/postfach.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,15 +23,18 @@ */ syntax = "proto3"; -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import "postfach.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.mail.postfach"; +option java_package = "de.ozgcloud.nachrichten.postfach"; option java_outer_classname = "MailProto"; service PostfachService { + rpc SaveNachrichtDraft(GrpcSaveNachrichtDraftRequest) returns (GrpcSaveNachrichtDraftResponse) { + } + rpc SendPostfachMail(GrpcSendPostfachMailRequest) returns (GrpcSendPostfachMailResponse) { } @@ -44,6 +47,10 @@ service PostfachService { rpc ResendPostfachMail(GrpcResendPostfachMailRequest) returns (GrpcResendPostfachMailResponse) { } - rpc IsPostfachConfigured(GrpcIsPostfachConfiguredRequest) returns (GrpcIsPostfachConfiguredResponse){ + rpc IsPostfachConfigured(GrpcIsPostfachConfiguredRequest) returns (GrpcIsPostfachConfiguredResponse) { + } + + rpc GetPostfachConfig(GrpcGetPostfachConfigRequest) returns (GrpcGetPostfachConfigResponse) { + } } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/route-forwarding.model.proto b/vorgang-manager-interface/src/main/protobuf/route-forwarding.model.proto similarity index 82% rename from pluto-interface/src/main/protobuf/route-forwarding.model.proto rename to vorgang-manager-interface/src/main/protobuf/route-forwarding.model.proto index a50887c..82b4d5c 100644 --- a/pluto-interface/src/main/protobuf/route-forwarding.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/route-forwarding.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,18 +23,18 @@ */ syntax = "proto3"; -package de.itvsh.kop.eingangsadapter.forwarder; +package de.ozgcloud.eingang.forwarder; -import "vorgangmodel.proto"; +import "vorgang.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.kop.eingangsadapter.forwarding"; +option java_package = "de.ozgcloud.eingang.forwarding"; option java_outer_classname = "RouteForwardingModelProto"; message GrpcRouteForwardingRequest { GrpcRouteCriteria routeCriteria = 1; - de.itvsh.ozg.pluto.vorgang.GrpcEingang eingang = 5; + de.ozgcloud.vorgang.vorgang.GrpcEingang eingang = 5; } message GrpcRouteForwardingResponse { diff --git a/pluto-interface/src/main/protobuf/route-forwarding.proto b/vorgang-manager-interface/src/main/protobuf/route-forwarding.proto similarity index 87% rename from pluto-interface/src/main/protobuf/route-forwarding.proto rename to vorgang-manager-interface/src/main/protobuf/route-forwarding.proto index 10c6656..607c1a1 100644 --- a/pluto-interface/src/main/protobuf/route-forwarding.proto +++ b/vorgang-manager-interface/src/main/protobuf/route-forwarding.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.kop.eingangsadapter.forwarder; +package de.ozgcloud.eingang.forwarder; import "route-forwarding.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.kop.eingangsadapter.forwarder"; +option java_package = "de.ozgcloud.eingang.forwarder"; option java_outer_classname = "RouteForwardingProto"; service RouteForwardingService { diff --git a/vorgang-manager-interface/src/main/protobuf/statistic.model.proto b/vorgang-manager-interface/src/main/protobuf/statistic.model.proto new file mode 100644 index 0000000..88d4542 --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/statistic.model.proto @@ -0,0 +1,92 @@ +/* + * 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.vorgang.statistic; + +import "common.model.proto"; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.vorgang.statistic"; +option java_outer_classname = "StatisticModelProto"; + +message GrpcVorgangCountRequest { + repeated string countByPath = 1; +} + +message GrpcByStatusResult { + int32 neu = 1; + int32 angenommen = 2; + int32 verworfen = 3; + int32 in_bearbeitung = 4; + int32 beschieden = 5; + int32 abgeschlossen = 6; + int32 weitergeleitet = 7; + +} + +message GrpcPathCountResult { + string name = 1; + int32 value = 2; +} + +message GrpcVorgangCountResponse { + GrpcByStatusResult byStatus = 1; + repeated GrpcPathCountResult pathCountResult = 2; +} + +message GrpcVorgangStatisticRequest { + repeated GrpcVorgangStatisticQuery query = 1; +} + +message GrpcVorgangStatisticQuery { + string resultName = 1; + GroupMethod groupMethod = 2; + string path = 3; + de.ozgcloud.vorgang.common.GrpcQueryOperator operator = 4; + oneof operand { + int32 operandIntValue = 5; + bool operandBoolValue = 6; + string operandStringValue = 7; + } + + enum GroupMethod { + COUNT = 0; + EXISTS = 1; + } + +} + +message GrpcVorgangStatisticResponse { + repeated GrpcVorgangStatisticResult result = 1; +} + +message GrpcVorgangStatisticResult { + string name = 1; + oneof result { + int32 resultIntValue = 2; + bool resultBoolValue = 3; + string resultStringValue = 4; + } +} \ No newline at end of file diff --git a/vorgang-manager-interface/src/main/protobuf/statistic.proto b/vorgang-manager-interface/src/main/protobuf/statistic.proto new file mode 100644 index 0000000..6e2929e --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/statistic.proto @@ -0,0 +1,38 @@ +/* + * 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.vorgang.statistic; + +import "statistic.model.proto"; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.vorgang.statistic"; +option java_outer_classname = "StatisticProto"; + +service StatisticService { + rpc CountVorgang(GrpcVorgangCountRequest) returns (GrpcVorgangCountResponse); + + rpc GetVorgangStatistic(GrpcVorgangStatisticRequest) returns (GrpcVorgangStatisticResponse); +} \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/system.model.proto b/vorgang-manager-interface/src/main/protobuf/system.model.proto similarity index 88% rename from pluto-interface/src/main/protobuf/system.model.proto rename to vorgang-manager-interface/src/main/protobuf/system.model.proto index 8d5d05f..61a7751 100644 --- a/pluto-interface/src/main/protobuf/system.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/system.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,10 +23,10 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.system; +package de.ozgcloud.vorgang.system; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.system"; +option java_package = "de.ozgcloud.vorgang.system"; option java_outer_classname = "SystemStatusModelProto"; message GrpcGetSystemStatusRequest {} diff --git a/pluto-interface/src/main/protobuf/system.proto b/vorgang-manager-interface/src/main/protobuf/system.proto similarity index 88% rename from pluto-interface/src/main/protobuf/system.proto rename to vorgang-manager-interface/src/main/protobuf/system.proto index c7e853a..6613130 100644 --- a/pluto-interface/src/main/protobuf/system.proto +++ b/vorgang-manager-interface/src/main/protobuf/system.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.system; +package de.ozgcloud.vorgang.system; import "system.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.system"; +option java_package = "de.ozgcloud.vorgang.system"; option java_outer_classname = "SystemStatusProto"; service SystemStatusService { diff --git a/vorgang-manager-interface/src/main/protobuf/vorgang.model.proto b/vorgang-manager-interface/src/main/protobuf/vorgang.model.proto new file mode 100644 index 0000000..8740ca7 --- /dev/null +++ b/vorgang-manager-interface/src/main/protobuf/vorgang.model.proto @@ -0,0 +1,197 @@ +/* + * 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.vorgang.vorgang; + +import "clientattribute.model.proto"; +import "common.model.proto"; + +option java_multiple_files = true; +option java_package = "de.ozgcloud.vorgang.vorgang"; +option java_outer_classname = "VorgangModelProto"; + +message GrpcVorgangHeader { + string id = 1; + int64 version = 2; + string status = 3; + string name = 4; + string createdAt = 5; + string aktenzeichen = 6; + string assignedTo = 7; + string nummer = 8; + repeated de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute clientAttributes = 9; + string formEngineName = 15; +} + +message GrpcVorgangWithEingang { + string id = 1; + int64 version = 2; + string status = 3; + string name = 4; + string createdAt = 5; + string aktenzeichen = 6; + string assignedTo = 7; + string nummer = 8; + repeated de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute clientAttributes = 9; + + GrpcEingang eingang = 10; + string formEngineName = 15; + GrpcVorgangHead header = 16; +} + +message GrpcVorgangHead { + GrpcServiceKonto serviceKonto = 1; +} + +message GrpcEingang { + string id = 1; + + GrpcEingangHeader header = 2; + GrpcAntragsteller antragsteller = 3; + GrpcZustaendigeStelle zustaendigeStelle = 4; + + GrpcFormData formData = 10; + + int32 numberOfAttachments = 11; + int32 numberOfRepresentations = 12; + + repeated GrpcIncomingFileGroup attachments = 20; + repeated GrpcIncomingFile representations = 21; +} + +message GrpcIncomingFileGroup { + string name = 1; + repeated GrpcIncomingFile files = 2; +} + +message GrpcIncomingFile { + string id = 1; + string vendorId = 2; + string name = 3; + string contentType = 4; + int64 size = 5; + bytes content = 6; +} + +message GrpcEingangHeader { + string requestId = 1; + string createdAt = 2; + string formId = 3; + string formName = 4; + string sender = 5; + string customer = 6 [deprecated = true]; + string customerId = 7 [deprecated = true]; + string client = 8 [deprecated = true]; + string clientId = 9 [deprecated = true]; + string formEngineName = 10; + GrpcServiceKonto serviceKonto = 11; + string vorgangNummer = 12; +} + +message GrpcServiceKonto { + string type = 1; + repeated GrpcPostfachAddress postfachAddresses = 2; +} + +message GrpcPostfachAddress { + string version = 1; + de.ozgcloud.vorgang.common.GrpcObject identifier = 2; + int32 type = 3; +} + +message GrpcAntragsteller { + string anrede = 1; + string nachname = 2; + string vorname = 3; + string geburtsdatum = 4; + string geburtsort = 5; + string geburtsname = 6; + string email = 7; + string telefon = 8; + string strasse = 9; + string hausnummer = 10; + string plz = 11; + string ort = 12; + string postfachId = 13 [deprecated = true]; + + GrpcFormData otherData = 30; +} + +message GrpcFormData { + repeated GrpcFormField field = 1; + repeated GrpcSubForm form = 2; +} + +message GrpcFormField { + string name = 1; + string value = 2; + string label = 3; +} + +message GrpcSubForm { + string title = 1; + repeated GrpcFormField field = 2; + repeated GrpcSubForm subForm = 3; + string label = 4; + GrpcControlData controlData = 5; +} + +message GrpcControlData { + bool metadata = 1; +} + +message GrpcZustaendigeStelle { + string organisationseinheitenId = 1; + string email = 2; + string bezeichnung = 3; + string gemeindeSchluessel = 4; + string amtlicherRegionalSchluessel = 5; + string hausanschriftStrasse = 6; + string hausanschriftPlz = 7; + string hausanschriftOrt = 8; + string telefon = 9; +} + +message GrpcQuery { + GrpcLogicalOperator logicalOperator = 1; + repeated GrpcVorgangQueryExpression expressions = 2; + GrpcQuery nestedQuery = 3; +} + +enum GrpcLogicalOperator { + AND = 0; + OR = 1; +} + +message GrpcVorgangQueryExpression { + string path = 1; + de.ozgcloud.vorgang.common.GrpcQueryOperator operator = 2; + oneof operand { + int32 operandIntValue = 3; + bool operandBoolValue = 4; + string operandStringValue = 5; + } +} + diff --git a/pluto-interface/src/main/protobuf/vorgang.proto b/vorgang-manager-interface/src/main/protobuf/vorgang.proto similarity index 86% rename from pluto-interface/src/main/protobuf/vorgang.proto rename to vorgang-manager-interface/src/main/protobuf/vorgang.proto index 5fecca8..e5770ca 100644 --- a/pluto-interface/src/main/protobuf/vorgang.proto +++ b/vorgang-manager-interface/src/main/protobuf/vorgang.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,19 +23,16 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import "vorgangmodel.proto"; +import "vorgang.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.vorgang"; +option java_package = "de.ozgcloud.vorgang.vorgang"; option java_outer_classname = "VorgangProto"; service VorgangService { - rpc CreateVorgang(GrpcCreateVorgangRequest) returns (GrpcCreateVorgangResponse) { - } - rpc FindVorgang(GrpcFindVorgangRequest) returns (GrpcFindVorgangResponse) { } @@ -61,13 +58,18 @@ message GrpcCreateVorgangResponse { message GrpcFindVorgangRequest { int32 offset = 1; int32 limit = 2; - string searchBy = 3; + oneof request { + string searchBy = 3; + GrpcQuery query = 6; + } GrpcFilterBy filterBy = 4; GrpcOrderBy orderBy = 5; enum GrpcOrderBy { PRIORITY = 0; EA_PRIORITY = 1; + CREATED_AT_DESC = 2; + NEXT_WIEDERVORLAGE_FRIST = 3; } } @@ -86,6 +88,8 @@ message GrpcFilterBy { repeated string organisationseinheitId = 2; repeated string status = 3; string assignedTo = 4; + bool filterByAssignedTo = 5; + bool hasNextWiedervorlageFrist = 6 [deprecated = true]; } message GrpcFindVorgangWithEingangResponse { diff --git a/pluto-interface/src/main/protobuf/vorgangattacheditem.model.proto b/vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.model.proto similarity index 83% rename from pluto-interface/src/main/protobuf/vorgangattacheditem.model.proto rename to vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.model.proto index 359174f..f87b4bd 100644 --- a/pluto-interface/src/main/protobuf/vorgangattacheditem.model.proto +++ b/vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.model.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.vorgangAttachedItem; +package de.ozgcloud.vorgang.vorgangAttachedItem; import "common.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.vorgangAttachedItem"; +option java_package = "de.ozgcloud.vorgang.vorgangAttachedItem"; option java_outer_classname = "VorgangAttachedItemModelProto"; message GrpcVorgangAttachedItem { @@ -37,5 +37,5 @@ message GrpcVorgangAttachedItem { string client = 3; string vorgangId = 4; string itemName = 5; - de.itvsh.ozg.pluto.common.GrpcObject item = 6; + de.ozgcloud.vorgang.common.GrpcObject item = 6; } \ No newline at end of file diff --git a/pluto-interface/src/main/protobuf/vorgangattacheditem.proto b/vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.proto similarity index 90% rename from pluto-interface/src/main/protobuf/vorgangattacheditem.proto rename to vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.proto index 3385e18..55354ab 100644 --- a/pluto-interface/src/main/protobuf/vorgangattacheditem.proto +++ b/vorgang-manager-interface/src/main/protobuf/vorgangattacheditem.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -23,12 +23,12 @@ */ syntax = "proto3"; -package de.itvsh.ozg.pluto.vorgangAttachedItem; +package de.ozgcloud.vorgang.vorgangAttachedItem; import "vorgangattacheditem.model.proto"; option java_multiple_files = true; -option java_package = "de.itvsh.ozg.pluto.vorgangAttachedItem"; +option java_package = "de.ozgcloud.vorgang.vorgangAttachedItem"; option java_outer_classname = "VorgangAttachedItemProto"; service VorgangAttachedItemService { diff --git a/pluto-server/.mvn/wrapper/MavenWrapperDownloader.java b/vorgang-manager-server/.mvn/wrapper/MavenWrapperDownloader.java similarity index 100% rename from pluto-server/.mvn/wrapper/MavenWrapperDownloader.java rename to vorgang-manager-server/.mvn/wrapper/MavenWrapperDownloader.java diff --git a/pluto-server/.mvn/wrapper/maven-wrapper.jar b/vorgang-manager-server/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from pluto-server/.mvn/wrapper/maven-wrapper.jar rename to vorgang-manager-server/.mvn/wrapper/maven-wrapper.jar diff --git a/pluto-server/.mvn/wrapper/maven-wrapper.properties b/vorgang-manager-server/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from pluto-server/.mvn/wrapper/maven-wrapper.properties rename to vorgang-manager-server/.mvn/wrapper/maven-wrapper.properties diff --git a/vorgang-manager-server/lombok.config b/vorgang-manager-server/lombok.config new file mode 100644 index 0000000..81661f0 --- /dev/null +++ b/vorgang-manager-server/lombok.config @@ -0,0 +1,30 @@ +# +# 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. +# + +lombok.log.fieldName=LOG +lombok.log.slf4j.flagUsage = ERROR +lombok.log.log4j.flagUsage = ERROR +lombok.data.flagUsage = ERROR +lombok.nonNull.exceptionType = IllegalArgumentException +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/pluto-server/mvnw b/vorgang-manager-server/mvnw similarity index 100% rename from pluto-server/mvnw rename to vorgang-manager-server/mvnw diff --git a/pluto-server/mvnw.cmd b/vorgang-manager-server/mvnw.cmd similarity index 100% rename from pluto-server/mvnw.cmd rename to vorgang-manager-server/mvnw.cmd diff --git a/pluto-server/pom.xml b/vorgang-manager-server/pom.xml similarity index 56% rename from pluto-server/pom.xml rename to vorgang-manager-server/pom.xml index 55ddeba..c11f838 100644 --- a/pluto-server/pom.xml +++ b/vorgang-manager-server/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,72 +24,131 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-parent</artifactId> - <version>1.2.1</version> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-parent</artifactId> + <version>3.0.1</version> <relativePath /> </parent> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-server</artifactId> - <version>1.0.0</version> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-server</artifactId> + <version>2.4.0</version> - <name>Pluto Server</name> - <description>Server Implementierung des VorgangManagers (Pluto)</description> + <name>OZG-Cloud Vorgang Manager Server</name> + <description>Server Implementierung des VorgangManagers</description> <properties> <java.version>17</java.version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <spring-boot.build-image.imageName>docker.ozg-sh.de/pluto:build-latest</spring-boot.build-image.imageName> + <spring-boot.build-image.imageName>docker.ozg-sh.de/vorgang-manager:build-latest</spring-boot.build-image.imageName> - <zip.version>2.11.1</zip.version> - <jsoup.version>1.15.3</jsoup.version> + <ozgcloud.license.version>1.6.0</ozgcloud.license.version> + <zufi-manager-interface.version>1.0.0-SNAPSHOT</zufi-manager-interface.version> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <mongock.version>5.1.4</mongock.version> + <user-manager-interface.version>2.1.0</user-manager-interface.version> + <bescheid-manager.version>1.8.0</bescheid-manager.version> + <processor-manager.version>0.3.0</processor-manager.version> + <ozgcloud-starter.version>0.5.0</ozgcloud-starter.version> + <zip.version>2.11.1</zip.version> + <jsoup.version>1.15.3</jsoup.version> + <mongock.version>5.3.4</mongock.version> <testcontainer.version>1.17.3</testcontainer.version> + <maven-deploy-plugin.version>3.0.0</maven-deploy-plugin.version> + <find-and-replace-maven-plugin.version>1.1.0</find-and-replace-maven-plugin.version> + <docker-java.version>3.3.3</docker-java.version> + </properties> <dependencies> <!-- own Project --> <dependency> - <groupId>de.itvsh.ozg.mail</groupId> - <artifactId>mail-service</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-base</artifactId> <version>${project.version}</version> </dependency> + <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-interface</artifactId> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>nachrichten-manager</artifactId> <version>${project.version}</version> </dependency> + <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-utils</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>de.itvsh.kop.notification</groupId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.command</groupId> + <artifactId>command-manager</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.notification</groupId> <artifactId>notification-manager</artifactId> <version>${project.version}</version> <scope>runtime</scope> </dependency> + <dependency> + <groupId>de.ozgcloud.bescheid</groupId> + <artifactId>bescheid-manager</artifactId> + <version>${bescheid-manager.version}</version> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>de.ozgcloud.zufi</groupId> + <artifactId>zufi-manager-interface</artifactId> + <version>${zufi-manager-interface.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.processor</groupId> + <artifactId>processor-manager</artifactId> + <version>${processor-manager.version}</version> + </dependency> + + <dependency> + <groupId>de.ozgcloud.user</groupId> + <artifactId>user-manager-interface</artifactId> + <version>${user-manager-interface.version}</version> + <!-- TODO Nur proto sources verwenden um quarkus Abhaenigkeiten zu + vermeiden. Ebenso im notification-manager --> + <exclusions> + <exclusion> + <groupId>io.grpc</groupId> + <artifactId>grpc-core</artifactId> + </exclusion> + <exclusion> + <groupId>org.jboss.slf4j</groupId> + <artifactId>slf4j-jboss-logmanager</artifactId> + </exclusion> + </exclusions> + </dependency> + <!-- Spring --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> - <dependency> - <groupId>net.devh</groupId> - <artifactId>grpc-server-spring-boot-starter</artifactId> - </dependency> <!--only required for NachrichtenManager --> <dependency> @@ -106,23 +165,10 @@ <artifactId>spring-webmvc</artifactId> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-actuator</artifactId> - </dependency> <dependency> <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> - </dependency> - - <dependency> - <groupId>org.springframework.security</groupId> - <artifactId>spring-security-core</artifactId> + <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> @@ -201,20 +247,33 @@ <!-- Test --> <dependency> - <groupId>de.itvsh.ozg.mail</groupId> - <artifactId>mail-service</artifactId> + <groupId>de.ozgcloud.nachrichten</groupId> + <artifactId>nachrichten-manager</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-base</artifactId> <version>${project.version}</version> <type>test-jar</type> <scope>test</scope> </dependency> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-utils</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> <version>${project.version}</version> <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>de.ozgcloud.api-lib</groupId> + <artifactId>ozg-cloud-spring-boot-starter</artifactId> + <version>${ozgcloud-starter.version}</version> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> @@ -226,11 +285,20 @@ </exclusion> </exclusions> </dependency> + <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springframework.ws</groupId> + <artifactId>spring-ws-test</artifactId> + <scope>test</scope> </dependency> + <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> @@ -245,25 +313,33 @@ <dependency> <groupId>org.testcontainers</groupId> <artifactId>mongodb</artifactId> - <version>${testcontainer.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>elasticsearch</artifactId> - <version>${testcontainer.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.github.docker-java</groupId> + <artifactId>docker-java-api</artifactId> + <version>${docker-java.version}</version> + </dependency> + <dependency> + <groupId>org.awaitility</groupId> + <artifactId>awaitility</artifactId> <scope>test</scope> </dependency> <!-- mongock --> <dependency> <groupId>io.mongock</groupId> - <artifactId>mongock-springboot</artifactId> + <artifactId>mongock-springboot-v3</artifactId> <version>${mongock.version}</version> </dependency> <dependency> <groupId>io.mongock</groupId> - <artifactId>mongodb-springdata-v3-driver</artifactId> + <artifactId>mongodb-springdata-v4-driver</artifactId> <version>${mongock.version}</version> </dependency> </dependencies> @@ -274,6 +350,21 @@ <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <mainClass>de.ozgcloud.vorgang.VorgangManagerServerApplication</mainClass> + <image> + <!-- cann be removed when common-lib > 2.3.2--> + <builder>paketobuildpacks/builder-jammy-base</builder> + <env> + <BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS> + <BPE_APPEND_JAVA_TOOL_OPTIONS>-Dfile.encoding=UTF-8</BPE_APPEND_JAVA_TOOL_OPTIONS> + </env> + </image> + <profiles> + <profile>local</profile> + <profile>a12proc</profile> + </profiles> + </configuration> </plugin> <plugin> @@ -299,6 +390,36 @@ <plugin> <groupId>pl.project13.maven</groupId> <artifactId>git-commit-id-plugin</artifactId> + <version>4.9.10</version> + </plugin> + + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <mapping> + <config>SCRIPT_STYLE</config> + <ftlh>FTL</ftlh> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/README</exclude> + <exclude>src/test/resources/**</exclude> + <exclude>src/main/resources/*.yml</exclude> + <exclude>src/main/resources/*.txt</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> </plugin> </plugins> </build> @@ -316,4 +437,4 @@ </snapshotRepository> </distributionManagement> -</project> \ No newline at end of file +</project> diff --git a/vorgang-manager-server/run_local.sh b/vorgang-manager-server/run_local.sh new file mode 100755 index 0000000..66e1805 --- /dev/null +++ b/vorgang-manager-server/run_local.sh @@ -0,0 +1,25 @@ +# +# 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. +# + +./mvnw spring-boot:run -Dspring-boot.run.profiles=local diff --git a/pluto-server/sonar-project.properties b/vorgang-manager-server/sonar-project.properties similarity index 93% rename from pluto-server/sonar-project.properties rename to vorgang-manager-server/sonar-project.properties index 8660b9e..b7f5250 100644 --- a/pluto-server/sonar-project.properties +++ b/vorgang-manager-server/sonar-project.properties @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# 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 diff --git a/vorgang-manager-server/src/db/cleanup_vorgang.mongodb b/vorgang-manager-server/src/db/cleanup_vorgang.mongodb new file mode 100644 index 0000000..273a474 --- /dev/null +++ b/vorgang-manager-server/src/db/cleanup_vorgang.mongodb @@ -0,0 +1,4 @@ +use('sh-schleswigflensburg-test') +//use('sh-kiel-test'); +//db.vorgang.drop(); +db.vorgang.update({"_id": '4d903ada-2895-43cd-82de-85b87aad262e'}, {$set:{ 'name' : 'Lebensberechtigungsschein'}}) \ No newline at end of file diff --git a/vorgang-manager-server/src/license/eupl/header.txt b/vorgang-manager-server/src/license/eupl/header.txt new file mode 100644 index 0000000..6a42e70 --- /dev/null +++ b/vorgang-manager-server/src/license/eupl/header.txt @@ -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. +==== + +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. diff --git a/vorgang-manager-server/src/license/eupl/license.txt b/vorgang-manager-server/src/license/eupl/license.txt new file mode 100644 index 0000000..af26664 --- /dev/null +++ b/vorgang-manager-server/src/license/eupl/license.txt @@ -0,0 +1,125 @@ +==== + 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. +==== + +OPEN-SOURCE-LIZENZ FÜR DIE EUROPÄISCHE UNION v. 1.2 +EUPL © Europäische Union 2007, 2016 +Diese Open-Source-Lizenz für die Europäische Union („EUPL“) gilt für Werke (im Sinne der nachfolgenden Begriffsbestimmung), die unter EUPL-Bedingungen zur Verfügung gestellt werden. Das Werk darf nur in der durch diese Lizenz gestatteten Form genutzt werden (insoweit eine solche Nutzung dem Urheber vorbehalten ist). +Das Werk wird unter den Bedingungen dieser Lizenz zur Verfügung gestellt, wenn der Lizenzgeber (im Sinne der nachfolgenden Begriffsbestimmung) den folgenden Hinweis unmittelbar hinter dem Urheberrechtshinweis dieses Werks anbringt: + Lizenziert unter der EUPL +oder in einer anderen Form zum Ausdruck bringt, dass er es unter der EUPL lizenzieren möchte. + +1.Begriffsbestimmungen +Für diese Lizenz gelten folgende Begriffsbestimmungen: +— „Lizenz“:diese Lizenz. +— „Originalwerk“:das Werk oder die Software, die vom Lizenzgeber unter dieser Lizenz verbreitet oder zugänglich gemacht wird, und zwar als Quellcode und gegebenenfalls auch als ausführbarer Code. +— „Bearbeitungen“:die Werke oder Software, die der Lizenznehmer auf der Grundlage des Originalwerks oder seiner Bearbeitungen schaffen kann. In dieser Lizenz wird nicht festgelegt, wie umfangreich die Änderung oder wie stark die Abhängigkeit vom Originalwerk für eine Einstufung als Bearbeitung sein muss; dies bestimmt sich nach dem Urheberrecht, das in dem unter Artikel 15 aufgeführten Land anwendbar ist. +— „Werk“:das Originalwerk oder seine Bearbeitungen. +— „Quellcode“:diejenige Form des Werkes, die zur Auffassung durch den Menschen bestimmt ist und die am besten geeignet ist, um vom Menschen verstanden und verändert zu werden. +— „Ausführbarer Code“:die — üblicherweise — kompilierte Form des Werks, die von einem Computer als Programm ausgeführt werden soll. +— „Lizenzgeber“:die natürliche oder juristische Person, die das Werk unter der Lizenz verbreitet oder zugänglich macht. +— „Bearbeiter“:jede natürliche oder juristische Person, die das Werk unter der Lizenz verändert oder auf andere Weise zur Schaffung einer Bearbeitung beiträgt. +— „Lizenznehmer“ („Sie“):jede natürliche oder juristische Person, die das Werk unter den Lizenzbedingungen nutzt. +— „Verbreitung“ oder „Zugänglichmachung“:alle Formen von Verkauf, Überlassung, Verleih, Vermietung, Verbreitung, Weitergabe, Übermittlung oder anderweitiger Online- oder Offline-Bereitstellung von Vervielfältigungen des Werks oder Zugänglichmachung seiner wesentlichen Funktionen für dritte natürliche oder juristische Personen. + +2.Umfang der Lizenzrechte +Der Lizenzgeber erteilt Ihnen hiermit für die Gültigkeitsdauer der am Originalwerk bestehenden Urheberrechte eine weltweite, unentgeltliche, nicht ausschließliche, unterlizenzierbare Lizenz, die Sie berechtigt: +— das Werk uneingeschränkt zu nutzen, +— das Werk zu vervielfältigen, +— das Werk zu verändern und Bearbeitungen auf der Grundlage des Werks zu schaffen, +— das Werk öffentlich zugänglich zu machen, was das Recht einschließt, das Werk oder Vervielfältigungsstücke davon öffentlich bereitzustellen oder wahrnehmbar zu machen oder das Werk, soweit möglich, öffentlich aufzuführen, +— das Werk oder Vervielfältigungen davon zu verbreiten, +— das Werk oder Vervielfältigungen davon zu vermieten oder zu verleihen, +— das Werk oder Vervielfältigungen davon weiter zu lizenzieren. +Für die Wahrnehmung dieser Rechte können beliebige, derzeit bekannte oder künftige Medien, Träger und Formate verwendet werden, soweit das geltende Recht dem nicht entgegensteht. Für die Länder, in denen Urheberpersönlichkeitsrechte an dem Werk bestehen, verzichtet der Lizenzgeber im gesetzlich zulässigen Umfang auf seine Urheberpersönlichkeitsrechte, um die Lizenzierung der oben aufgeführten Verwertungsrechte wirksam durchführen zu können. Der Lizenzgeber erteilt dem Lizenznehmer ein nicht ausschließliches, unentgeltliches Nutzungsrecht an seinen Patenten, sofern dies zur Ausübung der durch die Lizenz erteilten Nutzungsrechte am Werk notwendig ist. + +3.Zugänglichmachung des Quellcodes +Der Lizenzgeber kann das Werk entweder als Quellcode oder als ausführbaren Code zur Verfügung stellen. Stellt er es als ausführbaren Code zur Verfügung, so stellt er darüber hinaus eine maschinenlesbare Kopie des Quellcodes für jedes von ihm verbreitete Vervielfältigungsstück des Werks zur Verfügung, oder er verweist in einem Vermerk im Anschluss an den dem Werk beigefügten Urheberrechtshinweis auf einen Speicherort, an dem problemlos und unentgeltlich auf den Quellcode zugegriffen werden kann, solange der Lizenzgeber das Werk verbreitet oder zugänglich macht. + +4.Einschränkungen des Urheberrechts +Es ist nicht Zweck dieser Lizenz, Ausnahmen oder Schranken der ausschließlichen Rechte des Urhebers am Werk, die dem Lizenznehmer zugutekommen, einzuschränken. Auch die Erschöpfung dieser Rechte bleibt von dieser Lizenz unberührt. + +5.Pflichten des Lizenznehmers +Die Einräumung der oben genannten Rechte ist an mehrere Beschränkungen und Pflichten für den Lizenznehmer gebunden: + +Urheberrechtshinweis, Lizenztext, Nennung des Bearbeiters: Der Lizenznehmer muss alle Urheberrechts-, Patent- oder Markenrechtshinweise und alle Hinweise auf die Lizenz und den Haftungsausschluss unverändert lassen. Jedem von ihm verbreiteten oder zugänglich gemachten Vervielfältigungsstück des Werks muss der Lizenznehmer diese Hinweise sowie diese Lizenz beifügen. Der Lizenznehmer muss auf jedem abgeleiteten Werk deutlich darauf hinweisen, dass das Werk geändert wurde, und das Datum der Bearbeitung angeben. + +„Copyleft“-Klausel: Der Lizenznehmer darf Vervielfältigungen des Originalwerks oder Bearbeitungen nur unter den Bedingungen dieser EUPL oder einer neueren Version dieser Lizenz verbreiten oder zugänglich machen, außer wenn das Originalwerk ausdrücklich nur unter dieser Lizenzversion — z. B. mit der Angabe „Nur EUPL V. 1.2“ — verbreitet werden darf. Der Lizenznehmer (der zum Lizenzgeber wird) darf für das Werk oder die Bearbeitung keine zusätzlichen Bedingungen anbieten oder vorschreiben, die die Bedingungen dieser Lizenz verändern oder einschränken. + +Kompatibilitäts-Klausel: Wenn der Lizenznehmer Bearbeitungen, die auf dem Werk und einem anderen Werk, das unter einer kompatiblen Lizenz lizenziert wurde, basieren, oder die Kopien dieser Bearbeitungen verbreitet oder zugänglich macht, kann dies unter den Bedingungen dieser kompatiblen Lizenz erfolgen. Unter „kompatibler Lizenz“ ist eine im Anhang dieser Lizenz angeführte Lizenz zu verstehen. Sollten die Verpflichtungen des Lizenznehmers aus der kompatiblen Lizenz mit denjenigen aus der vorliegenden Lizenz (EUPL) in Konflikt stehen, werden die Verpflichtungen aus der kompatiblen Lizenz Vorrang haben. + +Bereitstellung des Quellcodes: Wenn der Lizenznehmer Vervielfältigungsstücke des Werks verbreitet oder zugänglich macht, muss er eine maschinenlesbare Fassung des Quellcodes mitliefern oder einen Speicherort angeben, über den problemlos und unentgeltlich so lange auf diesen Quellcode zugegriffen werden kann, wie der Lizenznehmer das Werk verbreitet oder zugänglich macht. + +Rechtsschutz: Diese Lizenz erlaubt nicht die Benutzung von Kennzeichen, Marken oder geschützten Namensrechten des Lizenzgebers, soweit dies nicht für die angemessene und übliche Beschreibung der Herkunft des Werks und der inhaltlichen Wiedergabe des Urheberrechtshinweises erforderlich ist. + +6.Urheber und Bearbeiter +Der ursprüngliche Lizenzgeber gewährleistet, dass er das Urheberrecht am Originalwerk innehat oder dieses an ihn lizenziert wurde und dass er befugt ist, diese Lizenz zu erteilen. +Jeder Bearbeiter gewährleistet, dass er das Urheberrecht an den von ihm vorgenommenen Änderungen des Werks besitzt und befugt ist, diese Lizenz zu erteilen. +Jedes Mal, wenn Sie die Lizenz annehmen, erteilen Ihnen der ursprüngliche Lizenzgeber und alle folgenden Bearbeiter eine Befugnis zur Nutzung ihrer Beiträge zum Werk unter den Bedingungen dieser Lizenz. + +7.Gewährleistungsausschluss +Die Arbeit an diesem Werk wird laufend fortgeführt; es wird durch unzählige Bearbeiter ständig verbessert. Das Werk ist nicht vollendet und kann daher Fehler („bugs“) enthalten, die dieser Art der Entwicklung inhärent sind. +Aus den genannten Gründen wird das Werk unter dieser Lizenz „so, wie es ist“ ohne jegliche Gewährleistung zur Verfügung gestellt. Dies gilt unter anderem — aber nicht ausschließlich — für Marktreife, Verwendbarkeit für einen bestimmten Zweck, Mängelfreiheit, Richtigkeit sowie Nichtverletzung von anderen Immaterialgüterrechten als dem Urheberrecht (vgl. dazu Artikel 6 dieser Lizenz). +Dieser Gewährleistungsausschluss ist wesentlicher Bestandteil der Lizenz und Bedingung für die Einräumung von Rechten an dem Werk. + +8.Haftungsausschluss/Haftungsbeschränkung +Außer in Fällen von Vorsatz oder der Verursachung von Personenschäden haftet der Lizenzgeber nicht für direkte oder indirekte, materielle oder immaterielle Schäden irgendwelcher Art, die aus der Lizenz oder der Benutzung des Werks folgen; dies gilt unter anderem, aber nicht ausschließlich, für Firmenwertverluste, Produktionsausfall, Computerausfall oder Computerfehler, Datenverlust oder wirtschaftliche Schäden, und zwar auch dann, wenn der Lizenzgeber auf die Möglichkeit solcher Schäden hingewiesen wurde. Unabhängig davon haftet der Lizenzgeber im Rahmen der gesetzlichen Produkthaftung, soweit die entsprechenden Regelungen auf das Werk anwendbar sind. + +9.Zusatzvereinbarungen +Wenn Sie das Werk verbreiten, können Sie Zusatzvereinbarungen schließen, in denen Verpflichtungen oder Dienstleistungen festgelegt werden, die mit dieser Lizenz vereinbar sind. Sie dürfen Verpflichtungen indessen nur in Ihrem eigenen Namen und auf Ihre eigene Verantwortung eingehen, nicht jedoch im Namen des ursprünglichen Lizenzgebers oder eines anderen Bearbeiters, und nur, wenn Sie sich gegenüber allen Bearbeitern verpflichten, sie zu entschädigen, zu verteidigen und von der Haftung freizustellen, falls aufgrund der von Ihnen eingegangenen Gewährleistungsverpflichtung oder Haftungsübernahme Forderungen gegen sie geltend gemacht werden oder eine Haftungsverpflichtung entsteht. + +10.Annahme der Lizenz +Sie können den Bestimmungen dieser Lizenz zustimmen, indem Sie das Symbol „Lizenz annehmen“ unter dem Fenster mit dem Lizenztext anklicken oder indem Sie Ihre Zustimmung auf vergleichbare Weise in einer nach anwendbarem Recht zulässigen Form geben. Das Anklicken des Symbols gilt als Anzeichen Ihrer eindeutigen und unwiderruflichen Annahme der Lizenz und der darin enthaltenen Klauseln und Bedingungen. In gleicher Weise gilt als Zeichen der eindeutigen und unwiderruflichen Zustimmung die Ausübung eines Rechtes, das in Artikel 2 dieser Lizenz angeführt ist, wie das Erstellen einer Bearbeitung oder die Verbreitung oder Zugänglichmachung des Werks oder dessen Vervielfältigungen. + +11.Informationspflichten +Wenn Sie das Werk verbreiten oder zugänglich machen (beispielsweise, indem Sie es zum Herunterladen von einer Website anbieten), müssen Sie über den Vertriebskanal oder das benutzte Verbreitungsmedium der Öffentlichkeit zumindest jene Informationen bereitstellen, die nach dem anwendbaren Recht bezüglich der Lizenzgeber, der Lizenz und ihrer Zugänglichkeit, des Abschlusses des Lizenzvertrags sowie darüber, wie die Lizenz durch den Lizenznehmer gespeichert und vervielfältigt werden kann, erforderlich sind. + +12.Beendigung der Lizenz +Die Lizenz und die damit eingeräumten Rechte erlöschen automatisch, wenn der Lizenznehmer gegen die Lizenzbedingungen verstößt. Ein solches Erlöschen der Lizenz führt nicht zum Erlöschen der Lizenzen von Personen, denen das Werk vom Lizenznehmer unter dieser Lizenz zur Verfügung gestellt worden ist, solange diese Personen die Lizenzbedingungen erfüllen. +13.Sonstiges +Unbeschadet des Artikels 9 stellt die Lizenz die vollständige Vereinbarung der Parteien über das Werk dar. Sind einzelne Bestimmungen der Lizenz nach geltendem Recht nichtig oder unwirksam, so berührt dies nicht die Wirksamkeit oder Durchsetzbarkeit der Lizenz an sich. Solche Bestimmungen werden vielmehr so ausgelegt oder modifiziert, dass sie wirksam und durchsetzbar sind. Die Europäische Kommission kann weitere Sprachfassungen oder neue Versionen dieser Lizenz oder aktualisierte Fassungen des Anhangs veröffentlichen, soweit dies notwendig und angemessen ist, ohne den Umfang der Lizenzrechte zu verringern. Neue Versionen werden mit einer eindeutigen Versionsnummer veröffentlicht. Alle von der Europäischen Kommission anerkannten Sprachfassungen dieser Lizenz sind gleichwertig. Die Parteien können sich auf die Sprachfassung ihrer Wahl berufen. + +14.Gerichtsstand +Unbeschadet besonderer Vereinbarungen zwischen den Parteien gilt Folgendes: +— Für alle Streitigkeiten über die Auslegung dieser Lizenz zwischen den Organen, Einrichtungen und sonstigen Stellen der Europäischen Union als Lizenzgeber und einem Lizenznehmer ist der Gerichtshof der Europäischen Union gemäß Artikel 272 des Vertrags über die Arbeitsweise der Europäischen Union zuständig; +— Gerichtsstand für Streitigkeiten zwischen anderen Parteien über die Auslegung dieser Lizenz ist allein der Ort, an dem der Lizenzgeber seinen Wohnsitz oder den wirtschaftlichen Mittelpunkt seiner Tätigkeit hat. + +15.Anwendbares Recht +Unbeschadet besonderer Vereinbarungen zwischen den Parteien gilt Folgendes: +— Diese Lizenz unterliegt dem Recht des Mitgliedstaats der Europäischen Union, in dem der Lizenzgeber seinen Sitz, Wohnsitz oder eingetragenen Sitz hat; +— diese Lizenz unterliegt dem belgischen Recht, wenn der Lizenzgeber keinen Sitz, Wohnsitz oder eingetragenen Sitz in einem Mitgliedstaat der Europäischen Union hat. + +Anlage +„Kompatible Lizenzen“ nach Artikel 5 der EUPL sind: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) für andere Werke als Software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) oder Strong Reciprocity (LiLiQ-R+) +Die Europäische Kommission kann diesen Anhang aktualisieren, um neuere Fassungen der obigen Lizenzen aufzunehmen, ohne hierfür eine neue Fassung der EUPL auszuarbeiten, solange diese Lizenzen die in Artikel 2 gewährten Rechte gewährleisten und den erfassten Quellcode vor ausschließlicher Aneignung schützen. +Alle sonstigen Änderungen oder Ergänzungen dieses Anhangs bedürfen der Ausarbeitung einer neuen Version der EUPL. \ No newline at end of file diff --git a/vorgang-manager-server/src/license/licenses.properties b/vorgang-manager-server/src/license/licenses.properties new file mode 100644 index 0000000..9d0f9a0 --- /dev/null +++ b/vorgang-manager-server/src/license/licenses.properties @@ -0,0 +1,25 @@ +# +# 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. +# + +eupl=eupl diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerConfiguration.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerConfiguration.java new file mode 100644 index 0000000..7415dd2 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangManagerServerConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +import io.mongock.runner.springboot.EnableMongock; + +@Configuration +@EnableMongock +@EnableMongoRepositories(basePackages = { "de.ozgcloud.vorgang.vorgang", "de.ozgcloud.vorgang.attached_item", "de.ozgcloud.vorgang.command" }) +@EnableElasticsearchRepositories(basePackages = "de.ozgcloud.vorgang.common.search") +public class VorgangManagerServerConfiguration { + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangProcessorConfiguration.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangProcessorConfiguration.java new file mode 100644 index 0000000..74b4d59 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/VorgangProcessorConfiguration.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.vorgang; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; +import de.ozgcloud.apilib.user.GrpcOzgCloudUserProfileService; +import de.ozgcloud.apilib.user.OzgCloudUserProfileService; +import de.ozgcloud.apilib.user.UserProfileMapper; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangService; +import de.ozgcloud.apilib.vorgang.grpc.GrpcOzgCloudVorgangService; +import de.ozgcloud.apilib.vorgang.grpc.OzgCloudVorgangMapper; +import de.ozgcloud.apilib.vorgang.grpc.OzgCloudVorgangStubMapper; +import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Configuration +class VorgangProcessorConfiguration { + + @GrpcClient("vorgang-manager") + private VorgangServiceBlockingStub vorgangServiceStub; + + @GrpcClient("user-manager") + private UserProfileServiceBlockingStub userProfileServiceGrpc; + + @Bean + OzgCloudVorgangService ozgCloudVorgangService(OzgCloudVorgangMapper mapper, OzgCloudVorgangStubMapper stubMapper, + OzgCloudCallContextProvider contextProvider) { + return new GrpcOzgCloudVorgangService(vorgangServiceStub, mapper, stubMapper, contextProvider); + } + + @Bean + OzgCloudUserProfileService ozgCloudUserProfileService(UserProfileMapper mapper, OzgCloudCallContextProvider contextProvider) { + return new GrpcOzgCloudUserProfileService(userProfileServiceGrpc, mapper, contextProvider); + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapper.java similarity index 89% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapper.java index f87e187..6a21485 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; @@ -30,8 +30,8 @@ import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ReportingPolicy; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItem; @Mapper(uses = GrpcObjectMapper.class, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // unmappedTargetPolicy = ReportingPolicy.WARN, // diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemService.java similarity index 80% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemService.java index 97a0b6f..b7c194e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,19 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.Optional; import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; -import de.itvsh.ozg.pluto.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceImplBase; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceImplBase; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItem.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItem.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItem.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItem.java index b7f791d..85baf2e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItem.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.Map; @@ -30,6 +30,7 @@ import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; +import jakarta.validation.constraints.NotBlank; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -52,15 +53,20 @@ public class VorgangAttachedItem { static final String FIELDNAME_VORGANG_ID = "vorgangId"; static final String FIELDNAME_ITEM_NAME = "itemName"; static final String FIELDNAME_ITEM = "item"; + public static final String FIELDNAME_IS_DELETED = "deleted"; @Id private String id; @Version private long version; + @NotBlank private String client; + @NotBlank private String vorgangId; + @NotBlank private String itemName; + private boolean deleted; private Map<String, Object> item; } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCreatedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCreatedEvent.java similarity index 78% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCreatedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCreatedEvent.java index 3a0953d..81137a5 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCreatedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCreatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandExecutedEvent; public class VorgangAttachedItemCreatedEvent extends CommandExecutedEvent { private static final long serialVersionUID = 1L; - protected VorgangAttachedItemCreatedEvent(String commandId) { - super(commandId); + protected VorgangAttachedItemCreatedEvent(String commandId, String createdResource) { + super(commandId, createdResource); } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepository.java similarity index 83% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepository.java index b0b9228..541469d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.Map; @@ -30,4 +30,8 @@ interface VorgangAttachedItemCustomRepository { void patch(String itemId, long version, Map<String, Object> propertyMap); void forcePatch(String itemId, Map<String, Object> propertyMap); + + void delete(String itemId, long version); + + void updateDeleted(boolean deleted, String itemId, long version); } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepositoryImpl.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImpl.java similarity index 58% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepositoryImpl.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImpl.java index 75024c3..d6f352e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemCustomRepositoryImpl.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; +import static de.ozgcloud.vorgang.common.db.CriteriaUtil.*; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; +import java.util.HashMap; import java.util.Map; -import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; +import jakarta.annotation.PostConstruct; + import org.bson.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; @@ -38,18 +40,36 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; +import de.ozgcloud.vorgang.common.db.CollisionVerifier; + @Repository public class VorgangAttachedItemCustomRepositoryImpl implements VorgangAttachedItemCustomRepository { @Autowired private MongoOperations mongoOperations; + private CollisionVerifier collisionVerifier; + + @PostConstruct + void init() { + collisionVerifier = createCollisionVerifier(); + } + + CollisionVerifier createCollisionVerifier() { + return new CollisionVerifier(this::doVorgangAttachedItemExist); + } + + boolean doVorgangAttachedItemExist(String itemId) { + return mongoOperations.exists(query(isId(itemId)), VorgangAttachedItem.COLLECTION_NAME); + } + @Override public void patch(String itemId, long version, Map<String, Object> propertyMap) { mongoOperations.updateFirst( query(byIdAndVersion(itemId, version)), createUpdateForItemAndVersion(propertyMap), VorgangAttachedItem.class); + } @Override @@ -61,24 +81,46 @@ public class VorgangAttachedItemCustomRepositoryImpl implements VorgangAttachedI } private Query createQueryById(String itemId) { - return query(byId(itemId)); + return query(new Criteria().andOperator(byId(itemId), byNotDeleted())); } private Criteria byIdAndVersion(String itemId, long version) { - return byId(itemId).and(VorgangAttachedItem.FIELDNAME_VERSION).is(version); + return new Criteria().andOperator(byId(itemId), byVersion(version), byNotDeleted()); } private Criteria byId(String itemId) { return where(VorgangAttachedItem.FIELDNAME_ID).is(itemId); } + private Criteria byVersion(long version) { + return where(VorgangAttachedItem.FIELDNAME_VERSION).is(version); + } + + private Criteria byNotDeleted() { + return where(VorgangAttachedItem.FIELDNAME_IS_DELETED).is(false); + } + private Update createUpdateForItemAndVersion(Map<String, Object> propertyMap) { return Update.fromDocument(buildItemPatchDocument(propertyMap)).inc(VorgangAttachedItem.FIELDNAME_VERSION, 1); } private Document buildItemPatchDocument(Map<String, Object> propertiesMap) { - return new Document(propertiesMap.keySet().stream() - .map(fieldName -> Pair.of(String.format("%s.%s", VorgangAttachedItem.FIELDNAME_ITEM, fieldName), propertiesMap.get(fieldName))) - .collect(Collectors.toMap(Pair::getKey, Pair::getValue))); + Map<String, Object> resultMap = new HashMap<>(propertiesMap.size()); + propertiesMap.forEach((k, v) -> resultMap.put("%s.%s".formatted(VorgangAttachedItem.FIELDNAME_ITEM, k), v)); + return new Document(resultMap); + } + + @Override + public void delete(String itemId, long version) { + var deleteResult = mongoOperations.remove(query(whereIdAndVersion(itemId, version)), VorgangAttachedItem.COLLECTION_NAME); + collisionVerifier.verify(deleteResult, itemId); } + + @Override + public void updateDeleted(boolean deleted, String itemId, long version) { + var updateResult = mongoOperations.updateFirst(query(whereIdAndVersion(itemId, version)), + Update.update(VorgangAttachedItem.FIELDNAME_IS_DELETED, deleted), VorgangAttachedItem.COLLECTION_NAME); + collisionVerifier.verify(updateResult, itemId); + } + } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemDeletedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemDeletedEvent.java new file mode 100644 index 0000000..145bcdc --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemDeletedEvent.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.attached_item; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; + +public class VorgangAttachedItemDeletedEvent extends CommandExecutedEvent { + + private static final long serialVersionUID = 1L; + + protected VorgangAttachedItemDeletedEvent(Command command) { + super(command); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListener.java new file mode 100644 index 0000000..cd98cab --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListener.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.attached_item; + +import java.util.Objects; +import java.util.function.Predicate; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import jakarta.validation.ValidationException; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.CommandRevokedEvent; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEvent; +import lombok.extern.log4j.Log4j2; + +@Component +@Log4j2 +class VorgangAttachedItemEventListener { + + private static final String IS_CREATE_ITEM_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.attached_item.VorgangAttachedItemEventListener).IS_CREATE_ITEM_ORDER.test(event.getSource())}"; + private static final String IS_UPDATE_ITEM_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.attached_item.VorgangAttachedItemEventListener).IS_UPDATE_ITEM_ORDER.test(event.getSource())}"; + private static final String IS_PATCH_ITEM_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.attached_item.VorgangAttachedItemEventListener).IS_PATCH_ITEM_ORDER.test(event.getSource())}"; + private static final String IS_DELETE_ITEM_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.attached_item.VorgangAttachedItemEventListener).IS_DELETE_ITEM_ORDER.test(event.getSource())}"; + + public static final Predicate<Command> IS_CREATE_ITEM_ORDER = command -> Order.CREATE_ATTACHED_ITEM.isMeant(command.getOrder()); + public static final Predicate<Command> IS_UPDATE_ITEM_ORDER = command -> Order.UPDATE_ATTACHED_ITEM.isMeant(command.getOrder()); + public static final Predicate<Command> IS_PATCH_ITEM_ORDER = command -> Order.PATCH_ATTACHED_ITEM.isMeant(command.getOrder()); + public static final Predicate<Command> IS_DELETE_ITEM_ORDER = command -> Order.DELETE_ATTACHED_ITEM.isMeant(command.getOrder()); + + @Autowired + private VorgangAttachedItemService service; + @Autowired + private VorgangAttachedItemMapper mapper; + @Autowired + private ApplicationEventPublisher publisher; + + @EventListener(condition = IS_CREATE_ITEM_ORDER_CONDITION) + public void createItem(CommandCreatedEvent event) { + var command = event.getSource(); + validateCreateCommand(command); + + var item = mapper.fill(command.getBodyObject()); + service.create(command.getId(), item.toBuilder().id(null).version(0).build()); + } + + private void validateCreateCommand(Command command) { + if (!StringUtils.equals(command.getRelationId(), command.getVorgangId())) { + throw new ValidationException("Command invalid creation command: vorgangId and relationId must be equals"); + } + + } + + @EventListener(condition = IS_UPDATE_ITEM_ORDER_CONDITION) + public void updateItem(CommandCreatedEvent event) { + var command = event.getSource(); + var itemBuilder = mapper.fill(command.getBodyObject()) + .toBuilder().id(command.getRelationId()); + + if (Objects.nonNull(command.getRelationVersion())) { + itemBuilder.version(command.getRelationVersion()); + service.update(command.getId(), itemBuilder.build()); + } else { + service.forceUpdate(command.getId(), itemBuilder.build()); + } + + } + + @EventListener(condition = IS_PATCH_ITEM_ORDER_CONDITION) + public void patchItem(CommandCreatedEvent event) { + var command = event.getSource(); + var item = mapper.fill(command.getBodyObject()); + + service.patch(command, item.getItem()); + } + + @EventListener(condition = IS_DELETE_ITEM_ORDER_CONDITION) + public void deleteItem(CommandCreatedEvent event) { + var command = event.getSource(); + try { + service.markAsDeleteByIdAndVersion(command.getRelationId(), command.getRelationVersion()); + publisher.publishEvent(new VorgangAttachedItemDeletedEvent(command)); + } catch (RuntimeException e) { + handleException(e, command.getId()); + } + } + + void handleException(Exception e, String commandId) { + LOG.error("Command failed with Exception", e); + publisher.publishEvent(new CommandFailedEvent(commandId, "Command Failed: " + e.getMessage())); + } + + @EventListener + public void onVorgangDeleted(VorgangDeletedEvent event) { + try { + service.deleteByVorgangId(event.getCommand().getVorgangId()); + } catch (RuntimeException e) { + LOG.error("Error on deleting Attached Items.", e); + } + } + + @EventListener(condition = IS_DELETE_ITEM_ORDER_CONDITION) + public void onRevokeDeleteItem(RevokeCommandEvent event) { + var command = event.getSource(); + try { + service.unmarkAsDeleteByIdAndVersion(command.getRelationId(), command.getRelationVersion()); + publisher.publishEvent(new CommandRevokedEvent(command)); + } catch (RuntimeException e) { + LOG.error("Revoke of delete item command failed", e); + publisher.publishEvent(new CommandRevokeFailedEvent(command.getId(), e.getMessage())); + } + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapper.java similarity index 82% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapper.java index 7a83ecc..d23d779 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.Map; import java.util.Optional; +import org.apache.commons.collections.MapUtils; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; @@ -45,11 +46,11 @@ public interface VorgangAttachedItemMapper { return VorgangAttachedItem.builder() .id(extractIdFromItem(propertyMap)) - .client((String) propertyMap.get(PROPERTY_CLIENT)) - .vorgangId((String) propertyMap.get(PROPERTY_VORGANG_ID)) - .itemName((String) propertyMap.get(PROPERTY_ITEM_NAME)) + .client(MapUtils.getString(propertyMap, PROPERTY_CLIENT)) + .vorgangId(MapUtils.getString(propertyMap, PROPERTY_VORGANG_ID)) + .itemName(MapUtils.getString(propertyMap, PROPERTY_ITEM_NAME)) .item((Map<String, Object>) propertyMap.get(PROPERTY_ITEM)) - .version((Long) propertyMap.getOrDefault(PROPERTY_VERSION, 0L)) + .version(MapUtils.getLong(propertyMap, PROPERTY_VERSION, 0L)) .build(); } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepository.java similarity index 64% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepository.java index 3d4af85..f804041 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,19 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; +import java.util.Optional; import java.util.stream.Stream; import org.springframework.data.mongodb.repository.MongoRepository; interface VorgangAttachedItemRepository extends VorgangAttachedItemCustomRepository, MongoRepository<VorgangAttachedItem, String> { - Stream<VorgangAttachedItem> findByVorgangIdAndClientAndItemName(String vorgangId, String client, String itemName); + Optional<VorgangAttachedItem> findByIdAndDeleted(String id, boolean deleted); - Stream<VorgangAttachedItem> findByVorgangIdAndClient(String vorgangId, String client); + Stream<VorgangAttachedItem> findByVorgangIdAndClientAndItemNameAndDeleted(String vorgangId, String client, String itemName, boolean isDeleted); - Stream<VorgangAttachedItem> findByVorgangIdAndItemName(String vorgangId, String itemName); + Stream<VorgangAttachedItem> findByVorgangIdAndClientAndDeleted(String vorgangId, String client, boolean isDeleted); - Stream<VorgangAttachedItem> findByVorgangId(String vorgangId); + Stream<VorgangAttachedItem> findByVorgangIdAndItemNameAndDeleted(String vorgangId, String itemName, boolean isDeleted); + + Stream<VorgangAttachedItem> findByVorgangIdAndDeleted(String vorgangId, boolean deleted); + + void deleteByVorgangId(String vorgangId); } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemService.java similarity index 66% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemService.java index 4961b2b..7146a2e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.Collections; import java.util.HashMap; @@ -29,26 +29,32 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Stream; +import jakarta.validation.Valid; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; import lombok.NonNull; @Service +@Validated public class VorgangAttachedItemService { + static final boolean NOT_DELETED = false; + @Autowired private VorgangAttachedItemRepository repository; @Autowired private ApplicationEventPublisher publisher; - public VorgangAttachedItem create(String commandId, VorgangAttachedItem item) { + public VorgangAttachedItem create(@NonNull String commandId, @Valid VorgangAttachedItem item) { var saved = repository.save(prepareForCreation(item)); - publisher.publishEvent(new VorgangAttachedItemCreatedEvent(commandId)); + publisher.publishEvent(new VorgangAttachedItemCreatedEvent(commandId, saved.getId())); return saved; } @@ -73,19 +79,26 @@ public class VorgangAttachedItemService { publisher.publishEvent(new VorgangAttachedItemUpdatedEvent(commandId)); } + public void forceUpdate(String commandId, VorgangAttachedItem item) { + repository.forcePatch(item.getId(), item.getItem()); + + publisher.publishEvent(new VorgangAttachedItemUpdatedEvent(commandId)); + } + public Optional<VorgangAttachedItem> findById(String itemId) { - return repository.findById(itemId).map(this::addIdToItem); + return repository.findByIdAndDeleted(itemId, NOT_DELETED).map(this::addIdToItem); } public Stream<VorgangAttachedItem> find(String vorgangId, Optional<String> client, Optional<String> itemName) { if (hasVorgangIdOnly(client, itemName)) { - return repository.findByVorgangId(vorgangId).map(this::addIdToItem); + return repository.findByVorgangIdAndDeleted(vorgangId, NOT_DELETED).map(this::addIdToItem); } else if (isEmpty(itemName) && client.isPresent()) { - return repository.findByVorgangIdAndClient(vorgangId, client.get()).map(this::addIdToItem); + return repository.findByVorgangIdAndClientAndDeleted(vorgangId, client.get(), NOT_DELETED).map(this::addIdToItem); } else if (isEmpty(client)) { - return repository.findByVorgangIdAndItemName(vorgangId, itemName.get()).map(this::addIdToItem); + return repository.findByVorgangIdAndItemNameAndDeleted(vorgangId, itemName.get(), NOT_DELETED).map(this::addIdToItem); } else { - return repository.findByVorgangIdAndClientAndItemName(vorgangId, client.get(), itemName.get()).map(this::addIdToItem); + return repository.findByVorgangIdAndClientAndItemNameAndDeleted(vorgangId, client.get(), itemName.get(), NOT_DELETED) + .map(this::addIdToItem); } } @@ -108,7 +121,7 @@ public class VorgangAttachedItemService { } public VorgangAttachedItem getById(String id) { - var attachedItem = repository.findById(id).orElseThrow(() -> new NotFoundException(VorgangAttachedItem.class, id)); + var attachedItem = repository.findByIdAndDeleted(id, NOT_DELETED).orElseThrow(() -> new NotFoundException(VorgangAttachedItem.class, id)); return addIdToItem(attachedItem); } @@ -118,4 +131,17 @@ public class VorgangAttachedItemService { itemMap.put(VorgangAttachedItem.FIELDNAME_ID, attachedItem.getId()); return attachedItem.toBuilder().item(Collections.unmodifiableMap(itemMap)).build(); } + + public void markAsDeleteByIdAndVersion(String itemId, long version) { + repository.updateDeleted(true, itemId, version); + } + + public void unmarkAsDeleteByIdAndVersion(String itemId, long version) { + repository.updateDeleted(false, itemId, version); + } + + public void deleteByVorgangId(String vorgangId) { + repository.deleteByVorgangId(vorgangId); + } + } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemUpdatedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemUpdatedEvent.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemUpdatedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemUpdatedEvent.java index 566a4ec..143aeef 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemUpdatedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemUpdatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandExecutedEvent; public class VorgangAttachedItemUpdatedEvent extends CommandExecutedEvent { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttribute.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttribute.java similarity index 95% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttribute.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttribute.java index 89e07a6..395e5e1 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttribute.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Optional; -import javax.validation.constraints.NotNull; - import org.springframework.data.annotation.AccessType; import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.TypeAlias; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeAlreadyExistsException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeAlreadyExistsException.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeAlreadyExistsException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeAlreadyExistsException.java index 9dcf409..b7cdc3f 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeAlreadyExistsException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeAlreadyExistsException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Map; -import de.itvsh.ozg.pluto.common.errorhandling.FunctionalException; +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; class ClientAttributeAlreadyExistsException extends FunctionalException { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueConstraint.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueConstraint.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueConstraint.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueConstraint.java index e454f02..c25307c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueConstraint.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueConstraint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static java.lang.annotation.RetentionPolicy.*; @@ -30,10 +30,10 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.Payload; @Constraint(validatedBy = ClientAttributeHasValueValidator.class) @Target(ElementType.TYPE) diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificator.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificator.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificator.java index 6be4f8d..041e325 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificator.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; - -import javax.validation.constraints.NotEmpty; +package de.ozgcloud.vorgang.clientattribute; +import jakarta.validation.constraints.NotEmpty; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMap.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMap.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMap.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMap.java index 1f245b9..5a79d44 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMap.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.HashMap; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapper.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapper.java index 565848c..094cbeb 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.List; import java.util.Objects; @@ -34,10 +34,10 @@ import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; import org.mapstruct.ValueMapping; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue.ValueCase; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue.ValueCase; @Mapper public abstract class ClientAttributeMapper { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeNotExistingException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeNotExistingException.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeNotExistingException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeNotExistingException.java index 7d08693..1926898 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeNotExistingException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeNotExistingException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Map; -import de.itvsh.ozg.pluto.common.errorhandling.FunctionalException; +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; class ClientAttributeNotExistingException extends FunctionalException { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermitted.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermitted.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermitted.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermitted.java index f917e03..388c216 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermitted.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermitted.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Objects; import java.util.function.Predicate; @@ -29,8 +29,8 @@ import java.util.function.Predicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute.AccessPermission; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute.AccessPermission; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; @Component public class ClientAttributeReadPermitted implements Predicate<ClientAttribute> { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepository.java similarity index 94% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepository.java index 867a8d4..6b78663 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; @@ -38,10 +38,10 @@ import org.springframework.stereotype.Repository; import com.mongodb.client.result.UpdateResult; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute.AccessPermission; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute.AccessPermission; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.Vorgang; import lombok.NonNull; import lombok.extern.log4j.Log4j2; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeService.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeService.java index 2348180..ea3f81d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; - -import javax.validation.Valid; +package de.ozgcloud.vorgang.clientattribute; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; import lombok.NonNull; @Service diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMap.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMap.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMap.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMap.java index 2adcd7b..7569dcb 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMap.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.HashMap; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeService.java similarity index 80% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeService.java index 68cb264..a0f1f27 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,20 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceImplBase; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAcknowledgeResponse; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceImplBase; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAcknowledgeResponse; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandBodyMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandBodyMapper.java similarity index 73% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandBodyMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandBodyMapper.java index 88ec12d..6987235 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandBodyMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandBodyMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,18 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.mapstruct.Mapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBody; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBodyField; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandBody; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandBodyField; @Mapper public interface CommandBodyMapper { @@ -46,16 +47,16 @@ public interface CommandBodyMapper { default GrpcCommandBody mapToBody(Map<String, String> bodyMap) { var builder = GrpcCommandBody.newBuilder(); - bodyMap.entrySet().stream() - .map(entry -> GrpcCommandBodyField.newBuilder().setName(entry.getKey()).setValue(entry.getValue()).build()) - .forEach(builder::addField); + bodyMap.entrySet().stream().map(this::buildBodyField).forEach(builder::addField); return builder.build(); } default List<GrpcCommandBodyField> mapToBodyFields(Map<String, String> bodyMap) { - return bodyMap.entrySet().stream() - .map(entry -> GrpcCommandBodyField.newBuilder().setName(entry.getKey()).setValue(entry.getValue()).build()) - .collect(Collectors.toList()); + return bodyMap.entrySet().stream().map(this::buildBodyField).toList(); + } + + private GrpcCommandBodyField buildBodyField(Entry<String, String> entry) { + return GrpcCommandBodyField.newBuilder().setName(entry.getKey()).setValue(entry.getValue()).build(); } } \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandDeletionScheduler.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandDeletionScheduler.java new file mode 100644 index 0000000..ec58ea7 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandDeletionScheduler.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import de.ozgcloud.command.Command; + +import lombok.extern.log4j.Log4j2; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; + +@Component +@Profile("!itcase") +@Log4j2 +public class CommandDeletionScheduler { + + static final int CLEANUP_THRESHOLD_MINUTES = 30; + + @Autowired + private CommandService commandService; + + @Scheduled(fixedDelayString = "${ozgcloud.vorgang-manager.command.scheduler.fixedDelay:3600000}", // + initialDelayString = "${ozgcloud.vorgang-manager.command.scheduler.initialDelay:1800000}") + @SchedulerLock(name = "CommandDeletionScheduler") + void deleteCommands() { + try (var deleteVorgangCommands = commandService.findFinishedVorgangLoeschenCommandsOlderThen(getCleanupThreshold())) { + deleteVorgangCommands.map(Command::getVorgangId).distinct() + .forEach(commandService::deleteAllByVorgang); + } catch (RuntimeException e) { + LOG.error("Error deleting commands", e); + } + } + + ZonedDateTime getCleanupThreshold() { + return ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(CLEANUP_THRESHOLD_MINUTES); + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandEventListener.java similarity index 70% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandEventListener.java index 27bf5db..4d62cad 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.CommandRevokedEvent; + @Component public class CommandEventListener { @@ -35,6 +40,11 @@ public class CommandEventListener { @EventListener public void setStatusFinished(CommandExecutedEvent event) { + commandService.setCommandFinished(event.getSource(), event.getCreatedResource()); + } + + @EventListener + public void setStatusFinished(CommandRevokeFailedEvent event) { commandService.setCommandFinished(event.getSource()); } @@ -42,4 +52,9 @@ public class CommandEventListener { public void setStatusError(CommandFailedEvent event) { commandService.setCommandError(event.getSource(), event.getErrorMessage()); } + + @EventListener + public void setCommandRevoked(CommandRevokedEvent event) { + commandService.setCommandRevoked(event.getSource().getId()); + } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandRepository.java similarity index 63% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandRepository.java index 8a4fea8..046aa01 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; @@ -29,7 +29,9 @@ import static org.springframework.data.mongodb.core.query.Query.*; import java.time.ZonedDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; @@ -38,6 +40,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; + @Repository class CommandRepository { @@ -47,6 +52,11 @@ class CommandRepository { private static final String MONGODB_RELATION_VERSION = "relationVersion"; private static final String MONGODB_ERROR_MSG = "errorMessage"; private static final String MONGODB_ORDER = "order"; + private static final String MONGODB_PREVIOUS_STATE = "previousState"; + private static final String MONGODB_CREATED_AT = "createdAt"; + private static final String MONGODB_CREATED_BY = "createdBy"; + private static final String MONGODB_ASSIGNED_TO = "body.assignedTo"; + private static final String MONGODB_CREATED_RESOURCE = "createdResource"; @Autowired private MongoOperations mongoOperations; @@ -56,9 +66,17 @@ class CommandRepository { } void finishCommand(String commandId) { + finishCommand(commandId, new Update()); + } + + void finishCommand(String commandId, String createdResource) { + finishCommand(commandId, new Update().set(MONGODB_CREATED_RESOURCE, createdResource)); + } + + private void finishCommand(String commandId, Update update) { mongoOperations.updateFirst( queryById(commandId), - new Update().set(MONGODB_STATUS, CommandStatus.FINISHED).set(MONGODB_FINISHED_AT, ZonedDateTime.now()), + update.set(MONGODB_STATUS, CommandStatus.FINISHED).set(MONGODB_FINISHED_AT, ZonedDateTime.now()), Command.class); } @@ -92,7 +110,6 @@ class CommandRepository { } Optional<Command> getById(String commandId) { - return Optional.ofNullable(mongoOperations.findById(commandId, Command.class)); } @@ -124,4 +141,41 @@ class CommandRepository { return result; } + + public Stream<Command> findCommands(Order order, CommandStatus status, ZonedDateTime createdBefore) { + return mongoOperations.stream(buildCommandsQuery(order, status, createdBefore), Command.class); + } + + private Query buildCommandsQuery(Order order, CommandStatus status, ZonedDateTime createdBefore) { + var result = query(where(MONGODB_ORDER).is(order.name()).and(MONGODB_STATUS).is(status)); + result.addCriteria(new Criteria(MONGODB_CREATED_AT).lte(createdBefore)); + return result; + } + + public void patch(String commandId, Map<String, Object> previousState) { + mongoOperations.updateFirst( + queryById(commandId), + buildItemPatchUpdate(previousState), + Command.class); + } + + private Update buildItemPatchUpdate(Map<String, Object> valueMap) { + Update update = new Update(); + for (Map.Entry<String, Object> entry : valueMap.entrySet()) { + update.set("%s.%s".formatted(MONGODB_PREVIOUS_STATE, entry.getKey()), entry.getValue()); + } + return update; + } + + public void deleteAllByVorgang(String vorgangId) { + mongoOperations.remove(query(where(PersistedCommand.FIELD_VORGANG_ID).is(vorgangId)), PersistedCommand.COLLECTION_NAME); + } + + public boolean existsCommandWithUserId(String userId) { + return mongoOperations.exists(query(buildCreatedByOrAssignedToCriteria(userId)), PersistedCommand.COLLECTION_NAME); + } + + Criteria buildCreatedByOrAssignedToCriteria(String userId) { + return new Criteria().orOperator(where(MONGODB_CREATED_BY).is(userId), where(MONGODB_ASSIGNED_TO).is(userId)); + } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandResponse.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandResponse.java similarity index 78% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandResponse.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandResponse.java index 0cd6c6f..2db13db 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandResponse.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.util.List; +import de.ozgcloud.command.Command; import lombok.Builder; import lombok.Getter; import lombok.Singular; @@ -33,9 +34,9 @@ import lombok.Singular; @Getter public class CommandResponse { - public static final String MESSAGE_CODE_COMMAND_VORGANG_ID_NOT_FOUND = "de.itvsh.ozg.pluto.vorgang.command.error.invalid-vorgang-id"; - public static final String MESSAGE_CODE_COMMAND_VORGANG_DOCUMENT_VERSION_IS_OUTDATED = "de.itvsh.ozg.pluto.vorgang.command.error.documentversion-outdated"; - public static final String MESSAGE_CODE_COMMAND_VORGANG_INVALID_DOCUMENT_STATUS = "de.itvsh.ozg.pluto.vorgang.command.error.documentstatus-is-invalid"; + public static final String MESSAGE_CODE_COMMAND_VORGANG_ID_NOT_FOUND = "de.ozgcloud.vorgang.vorgang.command.error.invalid-vorgang-id"; + public static final String MESSAGE_CODE_COMMAND_VORGANG_DOCUMENT_VERSION_IS_OUTDATED = "de.ozgcloud.vorgang.vorgang.command.error.documentversion-outdated"; + public static final String MESSAGE_CODE_COMMAND_VORGANG_INVALID_DOCUMENT_STATUS = "de.ozgcloud.vorgang.vorgang.command.error.documentstatus-is-invalid"; public enum ResponseCode { OK, PENDING, ERROR, CONFLICT; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandService.java similarity index 63% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandService.java index e818185..45a86ca 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CommandService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CommandService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,26 +21,38 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.time.ZonedDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Stream; +import org.apache.commons.collections4.MapUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUser; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.CallContextUser; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.User; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; @Service @Validated +@Log4j2 public class CommandService { @Autowired @@ -52,18 +64,13 @@ public class CommandService { private CurrentUserService userService; public Command createCommand(CreateCommandRequest request) { - return createCommand(request, Optional.empty()); - } - - public Command createCommand(CreateCommandRequest request, Optional<Status> currentVorgangStatus) { - var persisted = saveCommand(buildCommand(request, currentVorgangStatus)); + var persisted = saveCommand(buildCommand(request)); publisher.publishEvent(new CommandCreatedEvent(persisted)); return persisted; } - private Command buildCommand(CreateCommandRequest request, Optional<Status> currentVorgangStatus) { + private Command buildCommand(CreateCommandRequest request) { var builder = PersistedCommand.builder() - // TODO id von Datenbank vergeben lassen .id(UUID.randomUUID().toString()) .vorgangId(request.getVorgangId()) .order(request.getOrder()) @@ -75,8 +82,6 @@ public class CommandService { .body(request.getBody()) .bodyObject(request.getBodyObject()); - currentVorgangStatus.ifPresent(builder::previousStatus); - builder = addUserIfExists(builder, Optional.ofNullable(request.getCallContext()).map(CallContext::getUser), userService.findUser()); return builder.build(); } @@ -104,10 +109,18 @@ public class CommandService { return repository.getById(commandId); } + public Stream<Command> findFinishedVorgangLoeschenCommandsOlderThen(@NonNull ZonedDateTime createdAfter) { + return repository.findCommands(Order.VORGANG_LOESCHEN, CommandStatus.FINISHED, createdAfter); + } + public void setCommandFinished(String commandId) { repository.finishCommand(commandId); } + public void setCommandFinished(String commandId, String createdResource) { + repository.finishCommand(commandId, createdResource); + } + public void setCommandError(String id, String errorMessage) { repository.setErrorMessage(id, errorMessage); } @@ -116,8 +129,27 @@ public class CommandService { updateCommandStatus(commandId, CommandStatus.REVOKED); } - public void setCommandRevokePending(String commandId) { + public void setCommandRevokePending(final String commandId) { updateCommandStatus(commandId, CommandStatus.REVOKE_PENDING); + + publishRevokeCommandEvent(commandId); + } + + void publishRevokeCommandEvent(final String commandId) { + var commandOptional = repository.getById(commandId); + commandOptional.ifPresentOrElse(command -> { + if (MapUtils.isEmpty(((PersistedCommand) command).getPreviousState())) { + handleError(commandId, "Command %s can not be revoked because it has no previous state."); + } + publisher.publishEvent(new RevokeCommandEvent(command)); + }, () -> handleError(commandId, "No Command with id %s found.")); + } + + private void handleError(String commandId, String messageTemplate) { + var message = messageTemplate.formatted(commandId); + LOG.error(message); + publisher.publishEvent(new CommandFailedEvent(commandId, message)); + throw new TechnicalException(message); } void updateCommandStatus(String commandId, CommandStatus status) { @@ -136,4 +168,15 @@ public class CommandService { return repository.findCommands(vorgangId, status, order).stream(); } + public void setPreviousState(String commandId, Map<String, Object> previousState) { + repository.patch(commandId, previousState); + } + + public void deleteAllByVorgang(String vorgangId) { + repository.deleteAllByVorgang(vorgangId); + } + + public boolean existsCommandWithUserId(String userId) { + return repository.existsCommandWithUserId(userId); + } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CreateCommandRequest.java similarity index 81% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CreateCommandRequest.java index f9526cc..dacccf5 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/CreateCommandRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; -import de.itvsh.ozg.pluto.vorgang.redirect.RedirectRequest; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.vorgang.redirect.RedirectRequest; import lombok.Builder; import lombok.Getter; import lombok.ToString; @@ -44,14 +45,15 @@ public class CreateCommandRequest { @NotNull private String vorgangId; + @NotNull private String relationId; - @NotNull private Long relationVersion; @NotNull private String order; + // TODO migrate to bodyObject private RedirectRequest redirectRequest; // TODO migrate to bodyObject diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandMapper.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandMapper.java index 3c79f04..38b96bb 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import org.apache.commons.lang3.StringUtils; import org.mapstruct.CollectionMappingStrategy; @@ -30,9 +30,10 @@ import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; @Mapper(uses = { CommandBodyMapper.class, GrpcObjectMapper.class }, // nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandResponseMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandResponseMapper.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandResponseMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandResponseMapper.java index ab62c76..e5e3682 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandResponseMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandResponseMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; @@ -29,8 +29,8 @@ import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; @Mapper(uses = CommandBodyMapper.class, // nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandService.java similarity index 66% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandService.java index cd8ac48..d2294fa 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCommandService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCommandService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,36 +21,44 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; + +import static org.apache.commons.lang3.StringUtils.*; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; - -import de.itvsh.ozg.pluto.command.CommandResponse.ResponseCode; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceImplBase; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcExistsPendingCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcExistsPendingCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcFindCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.grpc.command.GrpcRevokeCommandRequest; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangService; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.command.CommandResponse.ResponseCode; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceImplBase; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcEmpty; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcRevokeCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcSetCommandExecutedRequest; import io.grpc.stub.StreamObserver; +import lombok.extern.log4j.Log4j2; import net.devh.boot.grpc.server.service.GrpcService; +@Log4j2 @GrpcService public class GrpcCommandService extends CommandServiceImplBase { @@ -58,14 +66,16 @@ public class GrpcCommandService extends CommandServiceImplBase { private GrpcCreateCommandRequestMapper createCommandRequestMapper; @Autowired private CommandService commandService; - @Autowired - private VorgangService vorgangService; + @Autowired private GrpcCommandResponseMapper commandResponseMapper; @Autowired private GrpcCommandMapper grpcCommandMapper; + @Autowired private PolicyService policyService; + @Autowired + private ApplicationEventPublisher publisher; @Override public void createCommand(GrpcCreateCommandRequest request, StreamObserver<GrpcCommandResponse> responseObserver) { @@ -73,36 +83,17 @@ public class GrpcCommandService extends CommandServiceImplBase { var mappedRequest = createCommandRequestMapper.fromGrpc(request); - var command = commandService.createCommand(mappedRequest, getActualStatus(mappedRequest)); - - executeOrder(command); + var command = commandService.createCommand(mappedRequest); responseObserver.onNext(mapToGrpcResponse(getCommand(command.getId()))); responseObserver.onCompleted(); } - private Optional<Status> getActualStatus(CreateCommandRequest request) { - if (isStatusChangeOrder(request.getOrder())) { - return Optional.of(getVorgang(request.getRelationId()).getStatus()); - } else { - return Optional.empty(); - } - } - + // TODO check - is this function still in use? boolean isStatusChangeOrder(String order) { return order.startsWith("VORGANG"); } - private Vorgang getVorgang(String vorgangId) { - return vorgangService.getById(vorgangId); - } - - // TODO implement event/listener system to execute (status) order - void executeOrder(Command command) { - StatusOrder.getOrderMethod(command.getOrder()) - .ifPresent(orderMethod -> orderMethod.executeOrder(vorgangService, command)); - } - @Override public void getCommand(GrpcGetCommandRequest request, StreamObserver<GrpcCommand> responseObserver) { policyService.checkPermissionByCommand(request.getId()); @@ -118,22 +109,17 @@ public class GrpcCommandService extends CommandServiceImplBase { policyService.checkPermissionByCommand(request.getId()); String commandId = request.getId(); - commandService.setCommandRevokePending(commandId); - - proceedRevokeCommand(commandId); - - Command updatedCommand = getCommand(commandId); - - responseObserver.onNext(mapToGrpcResponse(updatedCommand)); - responseObserver.onCompleted(); - } - void proceedRevokeCommand(String commandId) { - PersistedCommand command = (PersistedCommand) getCommand(commandId); + try { + commandService.setCommandRevokePending(commandId); - vorgangService.revokeStatusChange(command); + Command updatedCommand = getCommand(commandId); - commandService.setCommandRevoked(commandId); + responseObserver.onNext(mapToGrpcResponse(updatedCommand)); + responseObserver.onCompleted(); + } catch (TechnicalException e) { + responseObserver.onError(e); + } } Command getCommand(String commandId) { @@ -193,4 +179,15 @@ public class GrpcCommandService extends CommandServiceImplBase { private GrpcCommandsResponse buildCommandsResponse(Stream<Command> commands) { return GrpcCommandsResponse.newBuilder().addAllCommand(commands.map(grpcCommandMapper::toGrpc).toList()).build(); } + + @Override + public void setCommandExecuted(GrpcSetCommandExecutedRequest request, StreamObserver<GrpcEmpty> responseObserver) { + commandService.findCommand(request.getCommandId()) + .map(command -> new CommandExecutedEvent(command, trimToNull(request.getCreatedResource()))) + .ifPresentOrElse(publisher::publishEvent, + () -> LOG.warn("Command with ID '%s' not found. Cannot mark as executed.".formatted(request.getCommandId()))); + + responseObserver.onNext(GrpcEmpty.newBuilder().build()); + responseObserver.onCompleted(); + } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapper.java similarity index 82% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapper.java index 2239842..34a361a 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.time.ZonedDateTime; @@ -35,14 +35,16 @@ import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ValueMapping; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.files.FileIdMapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.grpc.command.GrpcUser; -import de.itvsh.ozg.pluto.vorgang.redirect.RedirectRequestMapper; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.User; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.files.FileIdMapper; +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcUser; +import de.ozgcloud.vorgang.vorgang.redirect.RedirectRequestMapper; @Mapper(uses = { RedirectRequestMapper.class, CommandBodyMapper.class, FileIdMapper.class, GrpcObjectMapper.class }, // nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/Order.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/Order.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/Order.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/Order.java index fc04cd3..e6d5a01 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/Order.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/Order.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import org.apache.commons.lang3.StringUtils; @@ -35,9 +35,13 @@ public enum Order { VORGANG_ZURUECKSTELLEN, VORGANG_ABSCHLIESSEN, VORGANG_WIEDEREROEFFNEN, + VORGANG_ZUM_LOESCHEN_MARKIEREN, + VORGANG_LOESCHEN, ASSIGN_USER, + SET_AKTENZEICHEN, + REDIRECT_VORGANG, FORWARD_SUCCESSFULL, FORWARD_FAILED, @@ -55,7 +59,8 @@ public enum Order { CREATE_ATTACHED_ITEM, UPDATE_ATTACHED_ITEM, - PATCH_ATTACHED_ITEM; + PATCH_ATTACHED_ITEM, + DELETE_ATTACHED_ITEM; public boolean isMeant(String orderString) { return StringUtils.equals(name(), orderString); diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistPostfachNachrichtByCommandService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistPostfachNachrichtByCommandService.java new file mode 100644 index 0000000..5795423 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistPostfachNachrichtByCommandService.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URLConnection; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.entity.ContentType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.AttachmentFile; +import de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtService; +import de.ozgcloud.nachrichten.postfach.PostfachAddress; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemMapper; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemService; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.User; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.files.OzgFile; +import de.ozgcloud.vorgang.files.UploadedFilesReference; + +import jakarta.activation.MimetypesFileTypeMap; + +import lombok.extern.log4j.Log4j2; + +/** + * @deprecated Temporally replacement for using GRPC Api by MailService + */ +@Deprecated +@Service +@Log4j2 +class PersistPostfachNachrichtByCommandService implements PersistPostfachNachrichtService { + + static final String CLIENT = "OzgCloud_NachrichtenManager"; + static final String ITEM_NAME = "PostfachMail"; + static final String ATTACHMENT_NAME = "PostfachAttachment"; + + @Autowired + private CommandService service; + @Autowired + private VorgangAttachedItemService attachedItemService; + @Autowired + private FileService fileService; + + @Override + public void persistNachricht(Optional<String> userId, PostfachNachricht nachricht) { + var builder = CreateCommandRequest.builder() + .callContext(buildCallContext(userId)) + .vorgangId(nachricht.getVorgangId()); + + var request = StringUtils.isBlank(nachricht.getId()) ? buildPersistCommand(builder, nachricht) : buildUpdateCommand(builder, nachricht); + + service.createCommand(request); + } + + CreateCommandRequest buildPersistCommand(CreateCommandRequest.CreateCommandRequestBuilder builder, PostfachNachricht nachricht) { + return builder.order(Order.CREATE_ATTACHED_ITEM.name()) + .relationId(nachricht.getVorgangId()) + .bodyObject(buildItem(nachricht)).build(); + } + + CreateCommandRequest buildUpdateCommand(CreateCommandRequest.CreateCommandRequestBuilder builder, PostfachNachricht nachricht) { + return builder.order(Order.UPDATE_ATTACHED_ITEM.name()) + .relationId(nachricht.getId()) + .bodyObject(buildUpdateItem(nachricht)).build(); + } + + private CallContext buildCallContext(Optional<String> userId) { + var builder = CallContext.builder(); + userId.map(id -> User.builder().id(id).build()).ifPresent(builder::user); + + return builder.build(); + } + + private Map<String, Object> buildItem(PostfachNachricht nachricht) { + return Map.of( + VorgangAttachedItemMapper.PROPERTY_CLIENT, CLIENT, + VorgangAttachedItemMapper.PROPERTY_VORGANG_ID, nachricht.getVorgangId(), + VorgangAttachedItemMapper.PROPERTY_ITEM_NAME, ITEM_NAME, + VorgangAttachedItemMapper.PROPERTY_ITEM, buildNachrichtMap(nachricht)); + + } + + private Map<String, Object> buildUpdateItem(PostfachNachricht nachricht) { + return Map.of( + VorgangAttachedItemMapper.PROPERTY_CLIENT, CLIENT, + VorgangAttachedItemMapper.PROPERTY_ITEM, buildNachrichtMap(nachricht)); + + } + + Map<String, Object> buildNachrichtMap(PostfachNachricht nachricht) { + var result = new HashMap<>(Map.of( + PostfachNachricht.FIELD_VORGANG_ID, nachricht.getVorgangId(), + PostfachNachricht.FIELD_CREATED_AT, nachricht.getCreatedAt().format(DateTimeFormatter.ISO_DATE_TIME), + PostfachNachricht.FIELD_DIRECTION, nachricht.getDirection().name(), + PostfachNachricht.FIELD_REPLY_OPTION, nachricht.getReplyOption().name(), + PostfachNachricht.FIELD_SUBJECT, nachricht.getSubject(), + PostfachNachricht.FIELD_MAIL_BODY, nachricht.getMailBody(), + PostfachNachricht.FIELD_ATTACHMENTS, nachricht.getAttachments())); + + putIfNonNull(result, PostfachNachricht.FIELD_POSTFACH_ID, nachricht.getPostfachId()); + putIfNonNull(result, PostfachNachricht.FIELD_MESSAGE_ID, nachricht.getMessageId()); + putIfNonNull(result, PostfachNachricht.FIELD_CREATED_BY, nachricht.getCreatedBy()); + putIfNonNull(result, PostfachNachricht.FIELD_SENT_SUCCESSFUL, nachricht.getSentSuccessful()); + putIfNonNull(result, PostfachNachricht.FIELD_MESSAGE_CODE, nachricht.getMessageCode()); + putDateIfNonNull(result, PostfachNachricht.FIELD_SENT_AT, nachricht.getSentAt()); + + Optional.ofNullable(nachricht.getPostfachAddress()).map(this::buildPostfachAddressMap) + .ifPresent(postfachMaiMap -> result.put(PostfachNachricht.POSTFACH_ADDRESS_FIELD, postfachMaiMap)); + + return Collections.unmodifiableMap(result); + } + + private Map<String, Object> putIfNonNull(Map<String, Object> mapIn, String key, Object value) { + if (Objects.nonNull(value)) { + mapIn.put(key, value); + } + return mapIn; + } + + private Map<String, Object> putDateIfNonNull(Map<String, Object> mapIn, String key, Object value) { + if (Objects.nonNull(value)) { + mapIn.put(key, ((ZonedDateTime) value).format(DateTimeFormatter.ISO_DATE_TIME)); + } + return mapIn; + } + + private Map<String, Object> buildPostfachAddressMap(PostfachAddress postfachAddress) { + var resultMap = new HashMap<String, Object>(); + resultMap.put(PostfachAddress.IDENTIFIER_FIELD, buildPostfachAddressIdentifierMap(postfachAddress)); + resultMap.put(PostfachAddress.VERSION_FIELD, postfachAddress.getVersion()); + resultMap.put(PostfachAddress.TYPE_FIELD, postfachAddress.getType()); + Optional.ofNullable(postfachAddress.getServiceKontoType()).ifPresentOrElse( + serviceKontoType -> resultMap.put(PostfachAddress.SERVICEKONTO_TYPE_FIELD, serviceKontoType), + () -> LOG.warn("ServiceKontoType is null")); + return Collections.unmodifiableMap(resultMap); + } + + private Map<String, Object> buildPostfachAddressIdentifierMap(PostfachAddress postfachAddress) { + var identifier = (StringBasedIdentifier) postfachAddress.getIdentifier(); + return Map.of(PostfachNachricht.FIELD_POSTFACH_ID, identifier.getPostfachId()); + } + + @Override + public Optional<Map<String, Object>> findById(String postfachNachrichtId) { + return attachedItemService.findById(postfachNachrichtId).map(VorgangAttachedItem::getItem); + } + + @Override + public Stream<Map<String, Object>> findByVorgangAsMap(String vorgangId) { + return attachedItemService.find(vorgangId, Optional.of(CLIENT), Optional.of(ITEM_NAME)).map(VorgangAttachedItem::getItem); + } + + @Override + public void patch(String postfachNachrichtId, Map<String, Object> propertyMap) { + attachedItemService.forcePatch(postfachNachrichtId, propertyMap); + } + + @Override + public Map<String, Object> getById(String postfachNachrichtId) { + return attachedItemService.getById(postfachNachrichtId).getItem(); + } + + @Override + public String persistAttachment(String vorgangId, AttachmentFile attachment) { + var contentType = getTypeByFile(attachment); + try (var content = attachment.getContent()) { + var decContent = Base64.getDecoder().decode(content.readAllBytes()); + + return fileService.uploadFileStream( + createUploadedFilesReference(vorgangId), + createOzgFile(attachment.getName(), contentType, decContent.length), + Optional.empty(), + new ByteArrayInputStream(decContent)).get(10, TimeUnit.MINUTES).toString(); + } catch (ExecutionException | TimeoutException e) { + throw new TechnicalException(e.getMessage(), e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new TechnicalException(e.getMessage(), e); + } catch (IOException e) { + throw new TechnicalException("Can not read attached file", e); + } + } + + UploadedFilesReference createUploadedFilesReference(String vorgangId) { + return UploadedFilesReference.builder().vorgangId(vorgangId).client(CLIENT).name(ATTACHMENT_NAME).build(); + } + + OzgFile createOzgFile(String fileName, String contentType, long size) { + return OzgFile.builder().name(fileName).contentType(contentType).size(size).build(); + } + + String getTypeByFile(AttachmentFile attachmentFile) { + var fileNameMap = URLConnection.getFileNameMap(); + + return Optional.ofNullable(fileNameMap.getContentTypeFor(attachmentFile.getName())).orElseGet(() -> getTypeByContent(attachmentFile)); + } + + private String getTypeByContent(AttachmentFile attachmentFile) { + try (var contentStream = attachmentFile.getContent()) { + return Optional.ofNullable(URLConnection.guessContentTypeFromStream(contentStream)) + .orElseGet(() -> getByMimeTypes(attachmentFile.getName())); + } catch (IOException e) { + LOG.warn("IO-Exception while guessing content type", e); + } + return ContentType.APPLICATION_OCTET_STREAM.toString(); + } + + // uses map file: src/main/resources/mime.types + private String getByMimeTypes(String fileName) { + MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap(); + + return fileTypeMap.getContentType(fileName); + } + +} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistedCommand.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistedCommand.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java index 6c284a8..02a6396 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/PersistedCommand.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.time.ZonedDateTime; import java.util.Map; @@ -30,8 +30,9 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.mongodb.core.mapping.Document; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.redirect.RedirectRequest; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.vorgang.vorgang.redirect.RedirectRequest; import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -62,15 +63,19 @@ public class PersistedCommand implements Command { private CommandStatus status; private String relationId; - private long relationVersion; + private Long relationVersion; private String order; - private Status previousStatus; private String errorMessage; private RedirectRequest redirectRequest; private Map<String, String> body; private Map<String, Object> bodyObject; + + @Setter + private Map<String, Object> previousState; + + private String createdResource; } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/CustomConverters.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/CustomConverters.java similarity index 89% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/CustomConverters.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/CustomConverters.java index 3293563..ff27502 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/CustomConverters.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/CustomConverters.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import java.util.Arrays; @@ -33,7 +33,7 @@ import org.springframework.data.mongodb.core.convert.MongoCustomConversions; public class CustomConverters { @Bean - public MongoCustomConversions mongoCustomConversions() { + MongoCustomConversions mongoCustomConversions() { return new MongoCustomConversions( Arrays.asList( diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/FileIdConverter.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/FileIdConverter.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/FileIdConverter.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/FileIdConverter.java index dec0f50..7df3cc4 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/FileIdConverter.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/FileIdConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import java.util.Optional; @@ -30,7 +30,7 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.stereotype.Component; -import de.itvsh.ozg.pluto.files.FileId; +import de.ozgcloud.vorgang.files.FileId; @Component @ReadingConverter diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverter.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverter.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverter.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverter.java index 1ffd071..e7ba089 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverter.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import java.time.ZoneOffset; import java.time.ZonedDateTime; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverter.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverter.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverter.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverter.java index 99dad09..f77492d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverter.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import java.time.ZonedDateTime; import java.util.Date; diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CollisionVerifier.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CollisionVerifier.java new file mode 100644 index 0000000..2da472f --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CollisionVerifier.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.db; + +import java.util.ConcurrentModificationException; + +import com.mongodb.Function; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class CollisionVerifier { + + private final Function<String, Boolean> doEntryWithIdExist; + + public void verify(DeleteResult result, String entryId) { + if (isConcurrentModification(result) && doEntryWithIdExist(entryId)) { + throw new ConcurrentModificationException(); + } + } + + public void verify(UpdateResult result, String entryId) { + if (isConcurrentModification(result) && doEntryWithIdExist(entryId)) { + throw new ConcurrentModificationException(); + } + } + + boolean doEntryWithIdExist(String entryId) { + return doEntryWithIdExist.apply(entryId); + } + + boolean isConcurrentModification(DeleteResult result) { + return result.wasAcknowledged() && result.getDeletedCount() <= 0; + } + + boolean isConcurrentModification(UpdateResult result) { + return result.getModifiedCount() <= 0 && result.getMatchedCount() <= 0; + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtil.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CriteriaUtil.java similarity index 51% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtil.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CriteriaUtil.java index 5320f1c..ee28acb 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtil.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/db/CriteriaUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,70 +21,83 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.common.db; -import static de.itvsh.ozg.pluto.vorgang.Vorgang.*; +import static de.ozgcloud.vorgang.vorgang.Vorgang.*; import java.time.LocalDate; import java.util.Arrays; +import java.util.Collection; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.springframework.data.mongodb.core.query.Criteria; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; -class CriteriaUtil { // NOSONAR +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class CriteriaUtil { private static final String CASE_INSENSITIV = "i"; - static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST = "nextWiedervorlageFrist"; - static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY = String.format("%s.%s.%s", Vorgang.FIELD_CLIENT_ATTRIBUTES, - VorgangHeaderRepositoryImpl.DEFAULT_CLIENT, - CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST); - static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY = CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY + ".value"; - static Criteria isId(String id) { - return new Criteria(Vorgang.MONGODB_FIELDNAME_ID).is(id); + public static final String DEFAULT_CLIENT = "Alfa"; + public static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST = "nextWiedervorlageFrist"; + public static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY = String.format("%s.%s.%s", Vorgang.FIELD_CLIENT_ATTRIBUTES, + DEFAULT_CLIENT, CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST); + public static final String CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY = CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY + ".value"; + + public static Criteria isId(String id) { + return new Criteria(MONGODB_FIELDNAME_ID).is(id); + } + + public static Criteria isNotDeleted() { + return new Criteria(MONGODB_FIELDNAME_STATUS).ne(Vorgang.Status.DELETED); } - static Criteria inOrganisationseinheitenIds(List<String> ids) { - return new Criteria(Vorgang.FIELD_ORGANISATIONSEINHEIT).in(ids); + public static Criteria inOrganisationseinheitenIds(Collection<String> ids) { + return new Criteria(FIELD_ORGANISATIONSEINHEIT).in(ids); } - static Criteria vorgangInCreation() { + public static Criteria vorgangNotInCreation() { return new Criteria(MONGODB_FIELDNAME_IN_CREATION).is(false); } - static Criteria vorgangIsAssignedTo(String assignedTo) { + public static Criteria vorgangIsAssignedTo(String assignedTo) { return new Criteria(MONGODB_FIELDNAME_ASSIGNED_TO).is(assignedTo); } - static Criteria vorgangInStatus(List<Status> status) { + public static Criteria vorgangIsUnassigned() { + return new Criteria(MONGODB_FIELDNAME_ASSIGNED_TO).exists(false); + } + + public static Criteria vorgangInStatus(List<Status> status) { return new Criteria(MONGODB_FIELDNAME_STATUS).in(status); } - static Criteria vorgangRemainingStatus() { + public static Criteria vorgangRemainingStatus() { return new Criteria(MONGODB_FIELDNAME_STATUS).not().in(Status.NEU, Status.ANGENOMMEN, Status.BESCHIEDEN, Status.IN_BEARBEITUNG, Status.WEITERGELEITET); } - static Criteria vorgangStatusBearbeitet() { + public static Criteria vorgangStatusBearbeitet() { return new Criteria(MONGODB_FIELDNAME_STATUS).in(Status.BESCHIEDEN, Status.WEITERGELEITET); } - static Criteria vorgangStatusZuBearbeitendeEA() { + public static Criteria vorgangStatusZuBearbeitendeEA() { return new Criteria(MONGODB_FIELDNAME_STATUS).in(Status.NEU, Status.ANGENOMMEN); } - static Criteria vorgangStatusZuBearbeitende() { + public static Criteria vorgangStatusZuBearbeitende() { return new Criteria(MONGODB_FIELDNAME_STATUS).in(Status.NEU, Status.ANGENOMMEN, Status.IN_BEARBEITUNG); } - static Criteria vorgangStatusInBearbeitung() { + public static Criteria vorgangStatusInBearbeitung() { return new Criteria(MONGODB_FIELDNAME_STATUS).is(Status.IN_BEARBEITUNG); } - static Criteria searchCriteria(String searchString) { + public static Criteria searchCriteria(String searchString) { var searchParts = searchString.trim().split(StringUtils.SPACE); return new Criteria().andOperator(Arrays.stream(searchParts).map(CriteriaUtil::buildSearchPartCriteria).toList()); } @@ -99,11 +112,24 @@ class CriteriaUtil { // NOSONAR new Criteria(FIELD_NUMMER).regex(searchPart, CASE_INSENSITIV)); } - static Criteria nextWiedervorlageFristInThePast() { - return new Criteria(CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY).lte(LocalDate.now().toString()); + public static Criteria nextWiedervorlageFristInThePast() { + return new Criteria(CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).lte(LocalDate.now().toString()); + } + + public static Criteria nextWiedervorlageFristInTheFuture() { + return new Criteria(CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).gt(LocalDate.now().toString()); } - static Criteria withoutNextWiedervorlageFrist() { + public static Criteria withoutNextWiedervorlageFrist() { return Criteria.where(CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).isNull(); } + + public static Criteria nextWiedervorlageFristExists() { + return Criteria.where(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY).exists(true); + } + + public static Criteria whereIdAndVersion(String vorgangId, long version) { + return isId(vorgangId).and(MONGODB_FIELDNAME_VERSION).is(version); + } + } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandler.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandler.java similarity index 95% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandler.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandler.java index 0477ae9..a58a91e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandler.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; import java.util.UUID; import org.springframework.security.access.AccessDeniedException; -import de.itvsh.kop.common.errorhandling.ExceptionUtil; -import de.itvsh.kop.common.errorhandling.TechnicalException; +import de.ozgcloud.common.errorhandling.ExceptionUtil; +import de.ozgcloud.common.errorhandling.TechnicalException; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.grpc.Status; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalException.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalException.java index b1516db..348f49f 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; import java.util.Collections; import java.util.Map; import java.util.UUID; -import de.itvsh.kop.common.errorhandling.ExceptionUtil; -import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; -import de.itvsh.kop.common.errorhandling.IdentifiableException; +import de.ozgcloud.common.errorhandling.ExceptionUtil; +import de.ozgcloud.common.errorhandling.FunctionalErrorCode; +import de.ozgcloud.common.errorhandling.IdentifiableException; import lombok.Getter; public class FunctionalException extends RuntimeException implements IdentifiableException { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/NotFoundException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/NotFoundException.java similarity index 89% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/NotFoundException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/NotFoundException.java index 1f0af7a..ab8ac3c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/NotFoundException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/NotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; import java.util.Map; -import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; +import de.ozgcloud.common.errorhandling.FunctionalErrorCode; import lombok.Getter; @Getter diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/SearchServiceUnavailableException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/SearchServiceUnavailableException.java similarity index 86% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/SearchServiceUnavailableException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/SearchServiceUnavailableException.java index b39c3f8..391f0fe 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/SearchServiceUnavailableException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/errorhandling/SearchServiceUnavailableException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; -import de.itvsh.kop.common.errorhandling.TechnicalException; +import de.ozgcloud.common.errorhandling.TechnicalException; public class SearchServiceUnavailableException extends TechnicalException { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryAspectPointcut.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryAspectPointcut.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryAspectPointcut.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryAspectPointcut.java index 56dee22..7a04f66 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryAspectPointcut.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryAspectPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.logging; +package de.ozgcloud.vorgang.common.logging; import org.aspectj.lang.annotation.Pointcut; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryLoggingAspect.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryLoggingAspect.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryLoggingAspect.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryLoggingAspect.java index 6b5a047..ad369a2 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/logging/RepositoryLoggingAspect.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/logging/RepositoryLoggingAspect.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.logging; +package de.ozgcloud.vorgang.common.logging; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; -import de.itvsh.kop.common.logging.AspectLoggingUtils; +import de.ozgcloud.common.logging.AspectLoggingUtils; @Aspect @Component diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributes.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributes.java new file mode 100644 index 0000000..3faa274 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributes.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.vorgang.common.migration; + +import org.springframework.data.mongodb.core.MongoTemplate; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-16 14:20:00 OZG-4189-OZG-4552", order = "M001", author = "mkuester", runAlways = true) +public class M001_UpdateClientNameInClientAttributes { // NOSONAR + + private static final String VORGANG_COLLECTION = "vorgang"; + + static final String OLD_CLIENT_NAME = "Goofy"; + static final String NEW_CLIENT_NAME = "Alfa"; + + @Execution + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangClientAttributesQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangClientAttributesClientUpdate(OLD_CLIENT_NAME, NEW_CLIENT_NAME), + VORGANG_COLLECTION); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFs.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFs.java new file mode 100644 index 0000000..91b7a75 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFs.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import java.util.List; + +import org.springframework.data.mongodb.core.MongoOperations; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-20 15:20:00 OZG-4189-OZG-4601", order = "M002", author = "mkuester", runAlways = true) +public class M002_UpdateClientNameInGridFs { // NOSONAR + + static final String GRID_FS_FILE_COLLECTION = "fs.files"; + static final String OLD_CLIENT_NAME = "goofy"; + static final String NEW_CLIENT_NAME = "Alfa"; + + @Execution + public void doMigration(MongoOperations db) { + db.getCollection(GRID_FS_FILE_COLLECTION).updateMany( + RenameUtil.createMetadataClientMatchingDocument(OLD_CLIENT_NAME), + List.of( + RenameUtil.createSetFilenameOperation(OLD_CLIENT_NAME, NEW_CLIENT_NAME), + RenameUtil.createSetClientDocument(NEW_CLIENT_NAME))); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollection.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItem.java similarity index 63% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollection.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItem.java index 7add226..5633137 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M008_DropBinaryFilesCollection.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import org.springframework.data.mongodb.core.MongoTemplate; @@ -29,14 +29,20 @@ import io.mongock.api.annotations.ChangeUnit; import io.mongock.api.annotations.Execution; import io.mongock.api.annotations.RollbackExecution; -@ChangeUnit(id = "2022-07-06 13:05:00 OZG-2689", order = "M008", author = "jreese", runAlways = true) -public class M008_DropBinaryFilesCollection {// NOSONAR +@ChangeUnit(id = "2023-11-20 15:20:00 OZG-4189-OZG-4551", order = "M003", author = "mkuester", runAlways = true) +public class M003_UpdateClientNameInVorgangAttachedItem { // NOSONAR - static final String COLLECTION = "binaryFile"; + static final String VORGANG_ATTACHED_ITEM = "vorgangAttachedItem"; + + static final String OLD_CLIENT_NAME = "Goofy"; + static final String NEW_CLIENT_NAME = "Alfa"; @Execution - public void migrationMethod(MongoTemplate template) { - template.dropCollection(COLLECTION); + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangAttachedItemQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangAttachedItemUpdate(NEW_CLIENT_NAME), + VORGANG_ATTACHED_ITEM); } @RollbackExecution diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangs.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem.java similarity index 59% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangs.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem.java index 20f5867..6ce7f56 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/M002_SetInCreationFalseForAllVorgangs.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,32 +21,28 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; import io.mongock.api.annotations.ChangeUnit; import io.mongock.api.annotations.Execution; import io.mongock.api.annotations.RollbackExecution; -@ChangeUnit(id = "2022-04-21 10:31:00 OZG-2093", order = "M002", author = "jreese", runAlways = false) -public class M002_SetInCreationFalseForAllVorgangs { // NOSONAR - private static final String FIELD_NAME = "inCreation"; - private static final String COLLECTION_NAME = "vorgang"; +@ChangeUnit(id = "2023-11-22 11:00:00 OZG-4191-OZG-4573", order = "M004", author = "mkuester", runAlways = true) +public class M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem { // NOSONAR - @Execution - public void migrationMethod(final MongoTemplate template) { - Update update = new Update(); - update.set(FIELD_NAME, Boolean.FALSE); + static final String VORGANG_ATTACHED_ITEM = "vorgangAttachedItem"; - Query query = new Query(Criteria - .where(FIELD_NAME) - .exists(false)); + static final String OLD_CLIENT_NAME = "KopNachrichtenManager"; + static final String NEW_CLIENT_NAME = "OzgCloud_NachrichtenManager"; - template.updateMulti(query, update, COLLECTION_NAME); + @Execution + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangAttachedItemQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangAttachedItemUpdate(NEW_CLIENT_NAME), + VORGANG_ATTACHED_ITEM); } @RollbackExecution diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributes.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributes.java new file mode 100644 index 0000000..f57dbf3 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributes.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.vorgang.common.migration; + +import org.springframework.data.mongodb.core.MongoTemplate; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-22 13:00:00 OZG-4191-OZG-4609", order = "M005", author = "mkuester", runAlways = true) +public class M005_UpdateNachrichtenManagerClientNameInClientAttributes { // NOSONAR + + private static final String VORGANG_COLLECTION = "vorgang"; + + static final String OLD_CLIENT_NAME = "KopNachrichtenManager "; + static final String NEW_CLIENT_NAME = "OzgCloud_NachrichtenManager"; + + @Execution + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangClientAttributesQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangClientAttributesClientUpdate(OLD_CLIENT_NAME, NEW_CLIENT_NAME), + VORGANG_COLLECTION); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItem.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItem.java new file mode 100644 index 0000000..48a9d30 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItem.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.vorgang.common.migration; + +import org.springframework.data.mongodb.core.MongoTemplate; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-29 14:30:00 OZG-4191-OZG-4629", order = "M006", author = "mkuester", runAlways = true) +public class M006_UpdateMailServiceClientNameInVorgangAttachedItem { // NOSONAR + + static final String VORGANG_ATTACHED_ITEM = "vorgangAttachedItem"; + + static final String OLD_CLIENT_NAME = "MailService"; + static final String NEW_CLIENT_NAME = "OzgCloud_NachrichtenManager"; + + @Execution + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangAttachedItemQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangAttachedItemUpdate(NEW_CLIENT_NAME), + VORGANG_ATTACHED_ITEM); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributes.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributes.java new file mode 100644 index 0000000..fd4e603 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributes.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.vorgang.common.migration; + +import org.springframework.data.mongodb.core.MongoTemplate; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-29 14:45:00 OZG-4191-OZG-4629", order = "M007", author = "mkuester", runAlways = true) +public class M007_UpdateMailServiceClientNameInClientAttributes { // NOSONAR + + private static final String VORGANG_COLLECTION = "vorgang"; + + static final String OLD_CLIENT_NAME = "MailService "; + static final String NEW_CLIENT_NAME = "OzgCloud_NachrichtenManager"; + + @Execution + public void doMigration(MongoTemplate template) { + template.updateMulti( + RenameUtil.createFindVorgangClientAttributesQuery(OLD_CLIENT_NAME), + RenameUtil.createVorgangClientAttributesClientUpdate(OLD_CLIENT_NAME, NEW_CLIENT_NAME), + VORGANG_COLLECTION); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFs.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFs.java new file mode 100644 index 0000000..86ecbf8 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFs.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import java.util.List; + +import org.springframework.data.mongodb.core.MongoOperations; + +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; + +@ChangeUnit(id = "2023-11-29 15:30:00 OZG-4191-OZG-4630", order = "M008", author = "mkuester", runAlways = true) +public class M008_UpdateMailServiceClientNameInGridFs { // NOSONAR + + static final String GRID_FS_FILE_COLLECTION = "fs.files"; + static final String OLD_CLIENT_NAME = "MailService"; + static final String NEW_CLIENT_NAME = "OzgCloud_NachrichtenManager"; + + @Execution + public void doMigration(MongoOperations db) { + db.getCollection(GRID_FS_FILE_COLLECTION).updateMany( + RenameUtil.createMetadataClientMatchingDocument(OLD_CLIENT_NAME), + List.of( + RenameUtil.createSetFilenameOperation(OLD_CLIENT_NAME, NEW_CLIENT_NAME), + RenameUtil.createSetClientDocument(NEW_CLIENT_NAME))); + } + + @RollbackExecution + public void rollback() { + // kein rollback implementiert + } +} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MigrationException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MigrationException.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MigrationException.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MigrationException.java index 6147183..7b17fa1 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MigrationException.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MigrationException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; class MigrationException extends RuntimeException { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockFailedEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockFailedEventListener.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockFailedEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockFailedEventListener.java index c976a1b..1495033 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockFailedEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockFailedEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockStartEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockStartEventListener.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockStartEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockStartEventListener.java index 927babb..bcc9ef6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockStartEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockStartEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockSuccessEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockSuccessEventListener.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockSuccessEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockSuccessEventListener.java index f6f38e0..5586fb6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/migration/MongockSuccessEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/MongockSuccessEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/RenameUtil.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/RenameUtil.java new file mode 100644 index 0000000..df12808 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/migration/RenameUtil.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import java.util.Map; + +import org.bson.Document; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; +import org.springframework.data.mongodb.core.query.UpdateDefinition; + +class RenameUtil { + + private final static String SET_OPERATOR = "$set"; + private final static String REPLACE_ONE_OPERATOR = "$replaceOne"; + + static final String CLIENT_KEY = "client"; + + // VorgangAttachedItem + public static Query createFindVorgangAttachedItemQuery(String clientName) { + return Query.query(Criteria.where(CLIENT_KEY).is(clientName)); + } + + public static Update createVorgangAttachedItemUpdate(String newClientName) { + return new Update().set(CLIENT_KEY, newClientName); + } + + // GridFsFiles + static final String FILENAME_KEY = "filename"; + static final String METADATA_KEY = "metadata"; + + public static Document createMetadataClientMatchingDocument(String clientName) { + return new Document(Map.of(METADATA_KEY + "." + CLIENT_KEY, clientName)); + } + + public static Document createSetFilenameOperation(String oldClientName, String newClientName) { + return new Document(Map.of(SET_OPERATOR, + Map.of(FILENAME_KEY, + Map.of(REPLACE_ONE_OPERATOR, + Map.of("input", "$" + FILENAME_KEY, + "find", "/" + oldClientName + "/", + "replacement", "/" + newClientName + "/"))))); + } + + public static Document createSetClientDocument(String newClientName) { + return new Document(Map.of(SET_OPERATOR, Map.of(RenameUtil.METADATA_KEY + "." + CLIENT_KEY, newClientName))); + } + + // Vorgang ClientAttributes + static final String CLIENT_ATTRIBUTES_KEY = "clientAttributes"; + + public static Query createFindVorgangClientAttributesQuery(String clientName) { + return new Query(Criteria.where(CLIENT_ATTRIBUTES_KEY + "." + clientName).exists(true)); + } + + public static UpdateDefinition createVorgangClientAttributesClientUpdate(String oldClientName, String newClientName) { + var update = new Update(); + update.rename(CLIENT_ATTRIBUTES_KEY + "." + oldClientName, CLIENT_ATTRIBUTES_KEY + "." + newClientName); + return update; + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/EqualOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/EqualOperator.java new file mode 100644 index 0000000..51186e2 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/EqualOperator.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.vorgang.common.operator; + +import static java.util.Objects.*; +import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.*; +import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.IfNull.*; + +import org.springframework.data.mongodb.core.aggregation.AggregationExpression; +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class EqualOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).is(operand); + } + + @Override + public AggregationExpression getAggregationExpression() { + return isNull(operand) + ? when(ifNull(fieldPath).then(true)).then(1).otherwise(0) + : Operator.super.getAggregationExpression(); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/ExistsOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/ExistsOperator.java new file mode 100644 index 0000000..cc49ce9 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/ExistsOperator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +public class ExistsOperator implements Operator { + + private String fieldPath; + private boolean negate; + + @Override + public Criteria getCriteria() { + var criteriaBuilder = Criteria.where(fieldPath); + return negate ? criteriaBuilder.exists(false) : criteriaBuilder.exists(true); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessor.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessor.java new file mode 100644 index 0000000..4acac72 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessor.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; + +import de.ozgcloud.vorgang.statistic.InvalidFieldPathException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@Log4j2 +class FieldPathProcessor { + + static final String PATH_ENTITY_VORGANG = "Vorgang"; + static final String PATH_ENTITY_CLIENT_ATTRIBUTE = "ClientAttribute"; + + static final String CRITERIA_PATH_VORGANG = ""; + static final String CRITERIA_PATH_CLIENT_ATTRIBUTE = Vorgang.FIELD_CLIENT_ATTRIBUTES; + + private static final Map<String, String> ENTITY_TO_PATH = Map.of( + PATH_ENTITY_VORGANG, CRITERIA_PATH_VORGANG, + PATH_ENTITY_CLIENT_ATTRIBUTE, CRITERIA_PATH_CLIENT_ATTRIBUTE); + + private static final Map<String, String> ENTITY_TO_PATHSUFFIX = Map.of( + PATH_ENTITY_CLIENT_ATTRIBUTE, "value"); + + private static final String CRITERIA_PATH_TEMPLATE = "%s.%s"; + + public static String processToCriteriaPath(String fieldPath) { + // TODO do path validation earlier + validate(fieldPath); + + if (StringUtils.isBlank(getCriteriaEntity(fieldPath))) { + return getPath(fieldPath); + } + + return CRITERIA_PATH_TEMPLATE.formatted(getCriteriaEntity(fieldPath), getPath(fieldPath)); + } + + private static void validate(String path) { + if (!path.contains(".")) { + throw new InvalidFieldPathException(); + } + } + + static String getCriteriaEntity(@NonNull String path) { + return Optional.ofNullable(ENTITY_TO_PATH.get(getEntity(path))) + .orElseThrow(() -> logAndBuildUnsupportedEntityException(getEntity(path))); + } + + private static RuntimeException logAndBuildUnsupportedEntityException(String entity) { + LOG.error("Given Entity '{}' is unsupported.", entity); + return new UnsupportedEntityException(); + } + + public static String getPath(String path) { + var criteriaPath = StringUtils.substringAfter(path, "."); + + return getPathSuffix(path).map(suffix -> CRITERIA_PATH_TEMPLATE.formatted(criteriaPath, suffix)) + .orElse(criteriaPath); + } + + static Optional<String> getPathSuffix(String path) { + return Optional.ofNullable(ENTITY_TO_PATHSUFFIX.get(getEntity(path))); + } + + private static String getEntity(String path) { + return StringUtils.substringBefore(path, "."); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOperator.java new file mode 100644 index 0000000..d425a71 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOperator.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.vorgang.common.operator; + +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class GreaterThenOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).gt(operand); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOrEqualOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOrEqualOperator.java new file mode 100644 index 0000000..1abedd0 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/GreaterThenOrEqualOperator.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class GreaterThenOrEqualOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).gte(operand); + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOperator.java new file mode 100644 index 0000000..146c700 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOperator.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class LessThenOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).lt(operand); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOrEqualOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOrEqualOperator.java new file mode 100644 index 0000000..ef5dbb5 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/LessThenOrEqualOperator.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class LessThenOrEqualOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).lte(operand); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParser.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParser.java new file mode 100644 index 0000000..9e70688 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParser.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import java.time.LocalDate; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.statistic.VorgangStatisticBadRequestException; + +@Component +public class OperandFunctionParser { + + public String parse(String operand) { + if (operand.equalsIgnoreCase("today()")) { + return LocalDate.now().toString(); + } + throw new VorgangStatisticBadRequestException("Operand function not supported: " + operand); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/Operator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/Operator.java new file mode 100644 index 0000000..0cd9c59 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/Operator.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.*; + +import org.springframework.data.mongodb.core.aggregation.AggregationExpression; +import org.springframework.data.mongodb.core.query.Criteria; + +public interface Operator { + + Criteria getCriteria(); + + default AggregationExpression getAggregationExpression() { + return when(getCriteria()).then(1).otherwise(0); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorBuilder.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorBuilder.java new file mode 100644 index 0000000..a14e353 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorBuilder.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import static java.util.Objects.*; +import static org.apache.commons.lang3.StringUtils.*; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.Collection; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.statistic.VorgangStatisticBadRequestException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class OperatorBuilder { + + private GrpcQueryOperator grpcOperator; + private String fieldPath; + private Object operand; + + public static OperatorBuilder from(GrpcQueryOperator grpcOperator) { + var builder = new OperatorBuilder(); + builder.grpcOperator = grpcOperator; + return builder; + } + + public OperatorBuilder fieldPath(String fieldPath) { + this.fieldPath = FieldPathProcessor.processToCriteriaPath(fieldPath); + return this; + } + + public OperatorBuilder operand(Object operand) { + this.operand = operand; + return this; + } + + public Operator build() { + if (isNull(grpcOperator)) { + throw new NullPointerException("Operator is missing"); + } + operand = getParsedOperand(); + return switch (grpcOperator) { + case EQUAL -> EqualOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case IS_EMPTY -> EqualOperator.builder().fieldPath(fieldPath).operand(StringUtils.EMPTY).build(); + case IS_NULL -> EqualOperator.builder().fieldPath(fieldPath).build(); + case UNEQUAL -> UnequalOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case GREATER_THEN -> GreaterThenOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case GREATER_THEN_OR_EQUAL_TO -> GreaterThenOrEqualOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case LESS_THEN -> LessThenOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case LESS_THEN_OR_EQUAL_TO -> LessThenOrEqualOperator.builder().fieldPath(fieldPath).operand(operand).build(); + case EXISTS -> ExistsOperator.builder().fieldPath(fieldPath).build(); + case NOT_EXIST -> ExistsOperator.builder().fieldPath(fieldPath).negate(true).build(); + case UNRECOGNIZED -> throw new VorgangStatisticBadRequestException("Unrecognized operator"); + }; + } + + @SneakyThrows + Object getParsedOperand() { + return Optional.ofNullable(getFieldClass()).map(this::parseValue).orElse(operand); + } + + Class<?> getFieldClass() { + if (isBlank(fieldPath)) { + return null; + } + var fieldNames = fieldPath.split("\\."); + Class<?> clazz = Vorgang.class; + for (var fieldName : fieldNames) { + try { + clazz = getFieldClass(clazz.getDeclaredField(fieldName)); + } catch (NoSuchFieldException | ClassNotFoundException e) { + LOG.warn("Cannot find field {} from {}", fieldName, fieldPath, e); + return null; + } + } + return clazz; + } + + Class<?> getFieldClass(Field field) throws ClassNotFoundException { + if (Collection.class.isAssignableFrom(field.getType())) { + var actualTypeArgument = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; + return Class.forName(actualTypeArgument.getTypeName()); + } else { + return field.getType(); + } + } + + Object parseValue(Class<?> clazz) { + if (operand instanceof String valueString) { + if (ZonedDateTime.class.equals(clazz)) { + return ZonedDateTime.parse(valueString); + } + if (LocalDate.class.equals(clazz)) { + return LocalDate.parse(valueString); + } + if (LocalDateTime.class.equals(clazz)) { + return LocalDateTime.parse(valueString); + } + } + return operand; + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorFactory.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorFactory.java new file mode 100644 index 0000000..ea7dddf --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/OperatorFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; + +@Component +public class OperatorFactory { + + public OperatorBuilder newUnequalOperatorBuilder() { + return OperatorBuilder.from(GrpcQueryOperator.UNEQUAL); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnequalOperator.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnequalOperator.java new file mode 100644 index 0000000..e351d37 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnequalOperator.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.vorgang.common.operator; + +import static java.util.Objects.*; +import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.*; +import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.IfNull.*; + +import org.springframework.data.mongodb.core.aggregation.AggregationExpression; +import org.springframework.data.mongodb.core.query.Criteria; + +import lombok.Builder; + +@Builder +class UnequalOperator implements Operator { + + private String fieldPath; + private Object operand; + + @Override + public Criteria getCriteria() { + return Criteria.where(fieldPath).ne(operand); + } + + @Override + public AggregationExpression getAggregationExpression() { + return isNull(operand) + ? when(ifNull(fieldPath).then(false)).then(1).otherwise(0) + : Operator.super.getAggregationExpression(); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnsupportedEntityException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnsupportedEntityException.java new file mode 100644 index 0000000..29dec48 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/operator/UnsupportedEntityException.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; + +public class UnsupportedEntityException extends FunctionalException { + + public UnsupportedEntityException() { + super(() -> "entity.unsupported"); + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgang.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgang.java similarity index 78% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgang.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgang.java index f220237..9356de2 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgang.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgang.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.time.ZonedDateTime; @@ -30,12 +30,14 @@ import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.Setting; import lombok.Builder; import lombok.Getter; import lombok.ToString; -@Document(indexName = "#{@environment.getProperty('kop.elasticsearch.index')}") +@Document(indexName = "#{@environment.getProperty('ozgcloud.elasticsearch.index')}") +@Setting(settingPath = "elastic/settings.json") @ToString @Getter @Builder @@ -55,14 +57,19 @@ class IndexedVorgang { @Id private String vorgangId; + @Field(type = FieldType.Keyword, normalizer = "lowercase_normalizer") private String vorgangName; + @Field(type = FieldType.Keyword, normalizer = "lowercase_normalizer") private String vorgangNummer; @Field(type = FieldType.Date, format = DateFormat.date_time, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'") private ZonedDateTime createdAt; + @Field(type = FieldType.Keyword, normalizer = "lowercase_normalizer") private String antragstellerName; + @Field(type = FieldType.Keyword, normalizer = "lowercase_normalizer") private String antragstellerVorname; + @Field(type = FieldType.Keyword, normalizer = "lowercase_normalizer") private String aktenzeichen; private String status; private String organisationseinheitenId; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapper.java similarity index 78% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapper.java index 91fa731..114a372 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.util.Optional; @@ -30,12 +30,11 @@ import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.ozg.pluto.vorgang.Antragsteller; -import de.itvsh.ozg.pluto.vorgang.Eingang; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangHeader; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelle; +import de.ozgcloud.vorgang.vorgang.Antragsteller; +import de.ozgcloud.vorgang.vorgang.Eingang; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangHeader; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelle; @Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) interface IndexedVorgangMapper { @@ -75,15 +74,11 @@ interface IndexedVorgangMapper { return Optional.ofNullable(eingang.getZustaendigeStelle()); } - default VorgangHeader toVorgangHeader(IndexedVorgang vorgang) { - return VorgangHeader.builder() - .aktenzeichen(vorgang.getAktenzeichen()) - .assignedTo(vorgang.getAssignedTo()) - .id(vorgang.getVorgangId()) - .createdAt(vorgang.getCreatedAt()) - .nummer(vorgang.getVorgangNummer()) - .name(vorgang.getVorgangName()) - .status(Status.valueOf(vorgang.getStatus())) - .build(); - } + @Mapping(target = "clientAttributes", ignore = true) + @Mapping(target = "formEngineName", ignore = true) + @Mapping(target = "id", source = "vorgangId") + @Mapping(target = "name", source = "vorgangName") + @Mapping(target = "nummer", source = "vorgangNummer") + @Mapping(target = "version", ignore = true) + VorgangHeader toVorgangHeader(IndexedVorgang vorgang); } diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchConfig.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchConfig.java new file mode 100644 index 0000000..9821a7e --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchConfig.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.search; + +import jakarta.validation.Valid; +import javax.net.ssl.SSLContext; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.client.ClientConfiguration; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration; +import org.springframework.data.elasticsearch.support.HttpHeaders; + +import lombok.SneakyThrows; + +@Configuration +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") +public class SearchConfig extends ElasticsearchConfiguration { + + @Autowired + @Valid + private SearchProperties properties; + + @Autowired + private SslBundles sslBundles; + + @SneakyThrows + @Override + public ClientConfiguration clientConfiguration() { + var configurationBuilder = ClientConfiguration.builder().connectedTo(properties.getAddress()); + if (properties.isUseSsl()) { + configurationBuilder.usingSsl(createSslContext()); + } + return configurationBuilder + .withDefaultHeaders(buildHeaders()) + .withBasicAuth(properties.getUsername(), properties.getPassword()) + .build(); + } + + SSLContext createSslContext() { + return sslBundles.getBundle("es-root-ca").createSslContext(); + } + + HttpHeaders buildHeaders() { + var headers = new HttpHeaders(); + headers.add("Accept", "application/vnd.elasticsearch+json;compatible-with=7"); + headers.add("Content-Type", "application/vnd.elasticsearch+json;compatible-with=7"); + return headers; + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchEventListener.java similarity index 58% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchEventListener.java index 8e0708b..5bc0d38 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,25 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.text.MessageFormat; +import java.util.Collections; +import java.util.HashMap; +import org.apache.commons.collections.MapUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandService; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; -import de.itvsh.ozg.pluto.vorgang.StatusChangedEvent; -import de.itvsh.ozg.pluto.vorgang.VorgangAssignedEvent; -import de.itvsh.ozg.pluto.vorgang.VorgangService; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.status.StatusChangedEvent; +import de.ozgcloud.vorgang.vorgang.SetAktenzeichenCompletedEvent; +import de.ozgcloud.vorgang.vorgang.VorgangAssignedEvent; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEvent; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import lombok.extern.log4j.Log4j2; @Component -@ConditionalOnProperty(prefix = "spring.elasticsearch", name = "uris") +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") +@Log4j2 public class SearchEventListener { + @Autowired private SearchService searchService; @@ -75,4 +83,24 @@ public class SearchEventListener { searchService.updateVorgang(vorgangService.getById(command.getVorgangId())); } + @EventListener + public void onVorgangDeleted(VorgangDeletedEvent event) { + String vorgangId = event.getCommand().getVorgangId(); + try { + searchService.deleteVorgang(vorgangId); + } catch (RuntimeException e) { + LOG.error("Error on deleting Vorgang (" + vorgangId + ") from search index.", e); + } + } + + @EventListener + public void onSetAktenzeichenCompletedEvent(SetAktenzeichenCompletedEvent event) { + var command = event.getCommand(); + var aktenzeichen = MapUtils.getString(command.getBodyObject(), VorgangService.BODY_OBJECT_AKTENZEICHEN); + try { + searchService.setAktenzeichen(command.getVorgangId(), aktenzeichen); + } catch (RuntimeException e) { + LOG.error("Error on setting new aktenzeichen ({}) for Vorgang ({}) in search index.", aktenzeichen, command.getVorgangId(), e); + } + } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializer.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializer.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializer.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializer.java index ed1ee3f..cff29a6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializer.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Profile; @@ -33,12 +33,12 @@ import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; import lombok.extern.log4j.Log4j2; @Component -@ConditionalOnBean(SearchService.class) +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") @Profile("initSearchIndex") @Async @Log4j2 diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchProperties.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchProperties.java similarity index 79% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchProperties.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchProperties.java index b6ba799..b1c18ef 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchProperties.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,25 +21,30 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; - -import javax.validation.constraints.NotEmpty; +package de.ozgcloud.vorgang.common.search; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; +import jakarta.validation.constraints.NotEmpty; import lombok.Getter; import lombok.Setter; @Getter @Setter @Configuration -@ConfigurationProperties(prefix = "kop.elasticsearch") +@ConfigurationProperties(prefix = "ozgcloud.elasticsearch") class SearchProperties { + private boolean initEnabled = false; @NotEmpty private String index; private Resource ca; + private boolean useSsl = true; + + private String address; + private String username; + private String password; } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchRequest.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchRequest.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchRequest.java index 7bf8363..bd98fef 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchRequest.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.util.List; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchService.java similarity index 53% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchService.java index 9bdbc27..646826c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; + +import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -29,53 +31,50 @@ import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; -import de.itvsh.ozg.pluto.common.errorhandling.SearchServiceUnavailableException; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequest; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangHeader; +import de.ozgcloud.vorgang.common.errorhandling.SearchServiceUnavailableException; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangHeader; @Service -@ConditionalOnProperty(prefix = "spring.elasticsearch", name = "uris") +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") public class SearchService { @Autowired - private SearchVorgangRepostitory repostitory; + private SearchVorgangRepository repository; @Autowired - private SearchVorgangCustomRepostitory searchRepostitory; + private SearchVorgangCustomRepository searchRepository; @Autowired private IndexedVorgangMapper mapper; public void addVorgang(Vorgang vorgang) { - repostitory.save(mapper.fromVorgang(vorgang)); + repository.save(mapper.fromVorgang(vorgang)); } public void updateVorgang(Vorgang vorgang) { - repostitory.save(mapper.fromVorgang(vorgang)); + repository.save(mapper.fromVorgang(vorgang)); } public boolean existsById(String vorgangId) { - return repostitory.existsById(vorgangId); + return repository.existsById(vorgangId); } - public Page<VorgangHeader> find(FindVorgangRequest searchRequest) { + public Page<VorgangHeader> find(FindVorgangRequest findVorgangRequest) { try { - return searchRepostitory.searchBy(buildSearchRequest(searchRequest)); + return searchRepository.searchBy(findVorgangRequest); } catch (DataAccessResourceFailureException e) { throw new SearchServiceUnavailableException(e); } } - private SearchRequest buildSearchRequest(FindVorgangRequest request) { - return SearchRequest.builder() - .limit(request.getLimit()) - .offSet(request.getOffset()) - .query(request.getSearchBy()) - .status(request.getFilterBy().getStatus().stream().map(Status::name).toList()) - .filterByOrganisationseinheitIds(request.getFilterBy().isFilterByOrganisationseinheitenId()) - .assignedTo(request.getFilterBy().getAssignedTo()) - .organisationseinheitIds(request.getFilterBy().getOrganisationseinheitIds()).build(); + public void deleteVorgang(String vorgangId) { + repository.deleteById(vorgangId); + } + + public void setAktenzeichen(String vorgangId, String aktenzeichen) { + searchRepository.update(vorgangId, Collections.singletonMap(IndexedVorgang.FIELD_AKTENZEICHEN, aktenzeichen)); } + } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepostitory.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepository.java similarity index 68% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepostitory.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepository.java index 97916f4..8ca9e2f 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangCustomRepostitory.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; + +import java.util.Map; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.domain.Page; -import de.itvsh.ozg.pluto.vorgang.VorgangHeader; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; +import de.ozgcloud.vorgang.vorgang.VorgangHeader; + +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") +interface SearchVorgangCustomRepository { + Page<VorgangHeader> searchBy(FindVorgangRequest request); -@ConditionalOnProperty(prefix = "spring.elasticsearch", name = "uris") -interface SearchVorgangCustomRepostitory { - Page<VorgangHeader> searchBy(SearchRequest request); + void update(String vorangId, Map<String, Object> patch); } diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImpl.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImpl.java new file mode 100644 index 0000000..da3916c --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImpl.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.search; + +import static de.ozgcloud.vorgang.common.search.IndexedVorgang.*; +import static java.util.Objects.*; +import static org.apache.commons.collections4.MapUtils.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.RefreshPolicy; +import org.springframework.data.elasticsearch.core.ScriptType; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.support.PageableExecutionUtils; +import org.springframework.stereotype.Repository; + +import co.elastic.clients.elasticsearch._types.FieldValue; +import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery; +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders; +import de.ozgcloud.vorgang.vorgang.FilterCriteria; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangHeader; + +@Repository +class SearchVorgangCustomRepositoryImpl implements SearchVorgangCustomRepository { + + private static final Pattern SPECIAL_CHARACTERS_PATTERN = Pattern.compile("[+\\-=]|(&&)|(\\|\\|)|[!(){}\\[\\]^\"~*?:\\\\/]"); + + private static final String SCRIPT_REMOVE_FIELD_TEMPLATE = "ctx._source.remove('%s')"; + + private static final String JOIN_AND = " AND "; + private static final String KEYWORD = ".keyword"; + + private static final String STATUS = FIELD_STATUS + KEYWORD; + private static final String ASSIGNED_TO = FIELD_ASSIGNED_TO + KEYWORD; + + private static final float DEFAULT_BOOST = 1f; + private static final float HALF_BOOST = 0.5f; + private static final float DOUBLE_BOOST = 2f; + + private static final List<String> FIELD_LIST = List.of( + FIELD_NAME + "^" + HALF_BOOST, + FIELD_VORGANG_NUMMER + "^" + DOUBLE_BOOST, + FIELD_AKTENZEICHEN + "^" + DOUBLE_BOOST, + FIELD_ANTRAGSTELLER_NAME + "^" + DEFAULT_BOOST, + FIELD_ANTRAGSTELLTER_VORNAME + "^" + DEFAULT_BOOST); + + @Autowired + private ElasticsearchOperations elasticsearchOperations; + + @Autowired + private IndexedVorgangMapper mapper; + + @Override + public Page<VorgangHeader> searchBy(FindVorgangRequest request) { + var pageable = buildPageable(request); + var searchQuery = buildQueryBuilder(request).withPageable(pageable).build(); + + var result = elasticsearchOperations.search(searchQuery, IndexedVorgang.class); + + return PageableExecutionUtils.getPage(mapResult(result), pageable, result::getTotalHits); + } + + PageRequest buildPageable(FindVorgangRequest request) { + return PageRequest.of(request.getOffset() / request.getLimit(), request.getLimit()); + } + + NativeQueryBuilder buildQueryBuilder(FindVorgangRequest request) { + var queryBuilder = new NativeQueryBuilder(); + + queryBuilder.withQuery(buildSearchByQueryBuilder(request)); + queryBuilder.withFilter(buildFilterByQueryBuilder(request.getFilterBy())); + + return queryBuilder; + } + + Query buildSearchByQueryBuilder(FindVorgangRequest request) { + var searchBy = Arrays.stream(request.getSearchBy().strip().split(StringUtils.SPACE)).map(this::adjustSearchTerm) + .collect(Collectors.joining(JOIN_AND)); + return QueryBuilders.queryString(b -> b.query(searchBy).fields(FIELD_LIST)); + } + + String adjustSearchTerm(String searchTerm) { + var resultBuilder = new StringBuilder("(*"); + var lastEnd = 0; + var matcher = SPECIAL_CHARACTERS_PATTERN.matcher(searchTerm); + while (matcher.find()) { + var start = matcher.start(); + var end = matcher.end(); + resultBuilder.append(searchTerm, lastEnd, start).append("\\").append(searchTerm, start, end); + lastEnd = end; + } + if (lastEnd < searchTerm.length()) { + resultBuilder.append(searchTerm, lastEnd, searchTerm.length()); + } + return replaceNotAllowedCharacters(resultBuilder.append("*)").toString()); + } + + String replaceNotAllowedCharacters(String searchTerm) { + return searchTerm.replaceAll("[><]", "?"); + } + + private Query buildFilterByQueryBuilder(FilterCriteria filterCriteria) { + var queryBuilder = QueryBuilders.bool(); + + if (filterCriteria.isFilterByOrganisationseinheitenId()) { + queryBuilder.must(buildTermQuery(FIELD_ORGANISATIONSEINHEITEN_ID, filterCriteria.getOrganisationseinheitIds().stream())); + } + if (filterCriteria.isFilterByAssignedTo()) { + addAssignedToFilter(queryBuilder, filterCriteria); + } + if (CollectionUtils.isNotEmpty(filterCriteria.getStatus())) { + queryBuilder.must(buildStatusQueryBuilder(filterCriteria)); + } + return queryBuilder.build()._toQuery(); + } + + private void addAssignedToFilter(BoolQuery.Builder query, FilterCriteria filterCriteria) { + if (StringUtils.isNotEmpty(filterCriteria.getAssignedTo())) { + query.must(buildTermQuery(ASSIGNED_TO, filterCriteria.getAssignedTo())); + } else { + query.mustNot(QueryBuilders.exists(e -> e.field(ASSIGNED_TO))); + } + } + + private Query buildStatusQueryBuilder(FilterCriteria filterCriteria) { + return buildTermQuery(STATUS, filterCriteria.getStatus().stream().map(Vorgang.Status::name)); + } + + private Query buildTermQuery(String field, String value) { + return QueryBuilders.term(ts -> ts.field(field).value(FieldValue.of(value))); + } + + private Query buildTermQuery(String field, Stream<String> valueStream) { + return QueryBuilders.terms(ts -> ts.field(field).terms(t -> t.value(valueStream.map(FieldValue::of).toList()))); + } + + private List<VorgangHeader> mapResult(SearchHits<IndexedVorgang> searchHits) { + return searchHits.get().map(SearchHit::getContent).map(mapper::toVorgangHeader).toList(); + } + + public void update(String vorgangId, Map<String, Object> patch) { + var fieldsToRemove = getFieldsToRemove(patch); + if (CollectionUtils.isNotEmpty(fieldsToRemove)) { + executeUpdate(buildUpdateQueryWithScript(vorgangId, buildRemoveFieldScript(fieldsToRemove))); + } + var fieldsToUpdate = getFieldsToUpdate(patch); + if (isNotEmpty(fieldsToUpdate)) { + executeUpdate(buildUpdateQueryWithDocument(vorgangId, fieldsToUpdate)); + } + } + + Set<String> getFieldsToRemove(Map<String, Object> patch) { + return patch.entrySet().stream().filter(e -> isNull(e.getValue())).map(Map.Entry::getKey).collect(Collectors.toSet()); + } + + String buildRemoveFieldScript(Collection<String> fields) { + return fields.stream().map(SCRIPT_REMOVE_FIELD_TEMPLATE::formatted).collect(Collectors.joining(";")); + } + + UpdateQuery buildUpdateQueryWithScript(String vorgangId, String script) { + return createUpdateBuilder(vorgangId).withScriptType(ScriptType.INLINE).withScript(script).build(); + } + + Map<String, Object> getFieldsToUpdate(Map<String, Object> patch) { + return patch.entrySet().stream().filter(e -> nonNull(e.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + UpdateQuery buildUpdateQueryWithDocument(String vorgangId, Map<String, Object> fieldMap) { + return createUpdateBuilder(vorgangId).withDocument(Document.from(fieldMap)).build(); + } + + UpdateQuery.Builder createUpdateBuilder(String vorgangId) { + return UpdateQuery.builder(vorgangId).withRefreshPolicy(RefreshPolicy.IMMEDIATE); + } + + void executeUpdate(UpdateQuery updateQuery) { + elasticsearchOperations.update(updateQuery, elasticsearchOperations.indexOps(IndexedVorgang.class).getIndexCoordinates()); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepostitory.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepository.java similarity index 79% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepostitory.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepository.java index 3578944..b7a4f14 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepostitory.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -@ConditionalOnProperty(prefix = "spring.elasticsearch", name = "uris") -interface SearchVorgangRepostitory extends ElasticsearchRepository<IndexedVorgang, String> { +@ConditionalOnProperty(prefix = "ozgcloud.elasticsearch", name = "address") +interface SearchVorgangRepository extends ElasticsearchRepository<IndexedVorgang, String> { } diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyRepository.java new file mode 100644 index 0000000..a6098ce --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyRepository.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.security; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import org.bson.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.aggregation.Aggregation; +import org.springframework.data.mongodb.core.aggregation.AggregationOperation; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.stereotype.Repository; + +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.Vorgang; + +@Repository +class PolicyRepository { + + private static final String VORANG_ID_AS_OBJECT_ID_FIELD = """ + {"$addFields" : {"vorgangObjecId" : {"$toObjectId": "$vorgangId"}}} + """; + private static final String VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD = """ + {"$addFields" : {"vorgangObjecId" : {"$toObjectId": "$metadata.vorgangId"}}} + """; + private static final AggregationOperation ADD_VORGANG_OBJECT_ID_FIELD = context -> org.bson.Document.parse(VORANG_ID_AS_OBJECT_ID_FIELD); + + private static final AggregationOperation ADD_VORGANG_FROM_FILE = context -> org.bson.Document.parse(VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD); + + public static final String FIELD_ORGANISATIONSEINHEIT_ID = "organisationseinheitenId"; + public static final String FIELD_VORGANG = "vorgang"; + public static final String FIELD_VORGANG_ORGANISATIONSEINHEIT = FIELD_VORGANG + "." + Vorgang.FIELD_ORGANISATIONSEINHEIT; + + @Autowired + private MongoTemplate template; + + public boolean existsByCommandId(String commandId, Collection<String> organisationEinheitenIds) { + var document = executeAggregation(buildAggregation(matchId(commandId), ADD_VORGANG_OBJECT_ID_FIELD), Command.class).orElseThrow( + () -> new NotFoundException(Command.class, commandId)); + return evaluateOrganisationseinheitId(document, organisationEinheitenIds); + } + + public boolean existsByFileId(String fileId, Collection<String> organisationEinheitenIds) { + var resultDocument = executeAggregation(buildAggregation(matchId(fileId), ADD_VORGANG_FROM_FILE), "fs.files"); + return resultDocument.map(document -> evaluateOrganisationseinheitId(document, organisationEinheitenIds)).orElse(false); + } + + private AggregationOperation matchId(String id) { + return Aggregation.match(new Criteria(Vorgang.MONGODB_FIELDNAME_ID).is(id)); + } + + public boolean existsByVorgangAttachedItem(String vorgangAttachedItemId, Collection<String> organisationEinheitenIds) { + var result = executeAggregation(buildAggregation(matchVorgangAttachedItemId(vorgangAttachedItemId), ADD_VORGANG_OBJECT_ID_FIELD), + VorgangAttachedItem.class).orElseThrow(() -> new NotFoundException(VorgangAttachedItem.class, vorgangAttachedItemId)); + return evaluateOrganisationseinheitId(result, organisationEinheitenIds); + } + + private AggregationOperation matchVorgangAttachedItemId(String id) { + return Aggregation.match(CriteriaUtil.isId(id).and(VorgangAttachedItem.FIELDNAME_IS_DELETED).is(false)); + } + + private Aggregation buildAggregation(AggregationOperation idAggregation, AggregationOperation operation) { + return Aggregation.newAggregation(Arrays.asList( + idAggregation, + operation, + lookupVorgang(), + Aggregation.project().and(FIELD_VORGANG_ORGANISATIONSEINHEIT).as(FIELD_ORGANISATIONSEINHEIT_ID) + )); + } + + private AggregationOperation lookupVorgang() { + return Aggregation.lookup(Vorgang.COLLECTION_NAME, "vorgangObjecId", "_id", FIELD_VORGANG); + } + + private Optional<Document> executeAggregation(Aggregation aggregation, Class<?> inputType) { + var results = template.aggregate(aggregation, inputType, Document.class).getRawResults(); + return getResult(results); + } + + private Optional<Document> executeAggregation(Aggregation aggregation, String collectionName) { + var results = template.aggregate(aggregation, collectionName, Document.class).getRawResults(); + return getResult(results); + } + + Optional<Document> getResult(Document aggregationResult) { + return aggregationResult.getList("results", Document.class).stream().findFirst(); + } + + boolean evaluateOrganisationseinheitId(Document result, Collection<String> organisationEinheitenIds) { + var nestedList = result.getList(FIELD_ORGANISATIONSEINHEIT_ID, Object.class); + if (nestedList.isEmpty()) { + return false; + } + var organisationseinheitenId = nestedList.get(0); + if (organisationseinheitenId instanceof List<?> orgaIdList) { + return orgaIdList.stream().map(String::valueOf).anyMatch(organisationEinheitenIds::contains); + } + return organisationEinheitenIds.contains(String.valueOf(organisationseinheitenId)); + } + +} \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyService.java similarity index 86% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyService.java index 8b92bea..9e2f59d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/security/PolicyService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/security/PolicyService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.security; +package de.ozgcloud.vorgang.common.security; import java.util.List; import java.util.Set; @@ -33,12 +33,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUser; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.callcontext.CallContextUser; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; @Service public class PolicyService { @@ -81,7 +81,7 @@ public class PolicyService { } public void checkPermissionByVorgangAttachedItem(String vorgangAttachedItemId) { - evaluatePermissions(List.of(hasOrganisationEinheitenIdByVorgangAttachedItem(vorgangAttachedItemId)).stream(), VorgangAttachedItem.class, + evaluatePermissions(Stream.of(hasOrganisationEinheitenIdByVorgangAttachedItem(vorgangAttachedItemId)), VorgangAttachedItem.class, vorgangAttachedItemId); } diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteService.java new file mode 100644 index 0000000..5c47f05 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteService.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.userconfig; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.user.grpc.organisationseinheit.OrganisationsEinheitServiceGrpc.OrganisationsEinheitServiceBlockingStub; +import de.ozgcloud.user.organisationseinheit.GrpcGetSupportedOrganisationsEinheitenRequest; +import de.ozgcloud.user.organisationseinheit.GrpcOrganisationsEinheit; +import de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +public class UserConfigRemoteService { + + @GrpcClient("user-manager") + private OrganisationsEinheitServiceBlockingStub serviceStub; + + public List<String> getSupportedOrganisationsEinheiten() { + return getOrganisationsEinheiten().stream().map(GrpcOrganisationsEinheit::getOrganisationsEinheitId) + .toList(); + } + + List<GrpcOrganisationsEinheit> getOrganisationsEinheiten() { + return getServiceStub() + .getSupportedOrganisationsEinheiten(GrpcGetSupportedOrganisationsEinheitenRequest.newBuilder().build()) + .getOrganisationseinheitenList(); + } + + private OrganisationsEinheitServiceBlockingStub getServiceStub() { + return serviceStub.withInterceptors(new VorgangManagerClientCallContextAttachingInterceptor()); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigService.java new file mode 100644 index 0000000..f4462fe --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/common/userconfig/UserConfigService.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.userconfig; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +public class UserConfigService { + @Autowired + private UserConfigRemoteService userConfigRemoteService; + + public List<String> getSupportedOrganisationsEinheiten() { + return userConfigRemoteService.getSupportedOrganisationsEinheiten(); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/BinaryFileRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/BinaryFileRepository.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/BinaryFileRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/BinaryFileRepository.java index 23151d1..c342573 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/BinaryFileRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/BinaryFileRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; + +import static org.springframework.data.mongodb.core.query.Criteria.*; +import static org.springframework.data.mongodb.core.query.Query.*; import java.io.InputStream; +import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -92,6 +96,7 @@ class BinaryFileRepository { return StreamSupport.stream(fileIds.spliterator(), false) .map(FileId::from) .map(this::getFile) + .filter(Objects::nonNull) .map(this::mapToOzgFile); } @@ -112,4 +117,8 @@ class BinaryFileRepository { .contentType((String) gridFile.getMetadata().getOrDefault(CONTENT_TYPE, StringUtils.EMPTY)) .build(); } + + public void deleteAllByVorgang(String vorgangId) { + gridFsTemplate.delete(query(where("metadata." + VORGANG_ID).is(vorgangId))); + } } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/EingangFilesRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/EingangFilesRepository.java similarity index 96% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/EingangFilesRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/EingangFilesRepository.java index 9d534b3..9240cba 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/EingangFilesRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/EingangFilesRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.util.ArrayList; import java.util.List; @@ -33,7 +33,7 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOperation; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.stereotype.Repository; -import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang; @Repository class EingangFilesRepository { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileId.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileId.java similarity index 89% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileId.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileId.java index 321ee3f..f84ff2b 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileId.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileId.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.util.UUID; -import de.itvsh.kop.common.datatype.StringBasedValue; +import de.ozgcloud.common.datatype.StringBasedValue; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileIdMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileIdMapper.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileIdMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileIdMapper.java index b982e97..a55acfe 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileIdMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileIdMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import org.mapstruct.Mapper; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileService.java similarity index 77% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileService.java index 8b323c9..043060a 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/FileService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/FileService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.io.InputStream; import java.util.Collection; @@ -37,7 +37,7 @@ import org.springframework.stereotype.Service; import com.mongodb.client.gridfs.model.GridFSFile; -import de.itvsh.ozg.mail.postfach.BinaryFileService; +import de.ozgcloud.nachrichten.postfach.BinaryFileService; //TODO make service package protected, as soon PersistPostfachMailByCommandService and FileStreamService is gone @Service @@ -60,8 +60,16 @@ public class FileService implements BinaryFileService { return repository.findRepresentationsByEingangId(eingangId); } - @Async public CompletableFuture<FileId> uploadFileStream(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) { + return uploadFile(ref, file, userId, content); + } + + @Async + public CompletableFuture<FileId> uploadFileStreamAsync(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) { + return uploadFile(ref, file, userId, content); + } + + CompletableFuture<FileId> uploadFile(UploadedFilesReference ref, OzgFile file, Optional<String> userId, InputStream content) { return CompletableFuture.completedFuture(binaryFileRepository.addContentStream(ref, file, userId, content)); } @@ -70,12 +78,12 @@ public class FileService implements BinaryFileService { } @Override - public InputStream getUploadedFileStream(de.itvsh.ozg.mail.postfach.FileId fileId) { + public InputStream getUploadedFileStream(de.ozgcloud.nachrichten.postfach.FileId fileId) { return binaryFileRepository.getFileContent(FileId.from(fileId.toString())); } @Override - public GridFSFile getFile(de.itvsh.ozg.mail.postfach.FileId fileId) { + public GridFSFile getFile(de.ozgcloud.nachrichten.postfach.FileId fileId) { return binaryFileRepository.getFile(FileId.from(fileId.toString())); } @@ -86,4 +94,8 @@ public class FileService implements BinaryFileService { private Iterable<String> mapFileIdToString(Collection<FileId> ids) { return ids.stream().map(fileIdMapper::toString).toList(); } + + public void deleteAllByVorgang(String vorgangId) { + binaryFileRepository.deleteAllByVorgang(vorgangId); + } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcBinaryFileService.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcBinaryFileService.java index a66e8e9..386094e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcBinaryFileService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.io.BufferedInputStream; import java.io.IOException; @@ -35,15 +35,15 @@ import org.springframework.beans.factory.annotation.Autowired; import com.google.protobuf.ByteString; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceImplBase; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcBinaryFilesRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcFindFilesResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.nachrichten.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceImplBase; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcBinaryFilesRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; import io.grpc.stub.CallStreamObserver; import io.grpc.stub.StreamObserver; import lombok.extern.log4j.Log4j2; @@ -54,7 +54,7 @@ import net.devh.boot.grpc.server.service.GrpcService; public class GrpcBinaryFileService extends BinaryFileServiceImplBase { // FIXME use client from security context - static final String CLIENT = "goofy"; // currently single client is hardcoded + static final String CLIENT = "Alfa"; // currently single client is hardcoded @Autowired private FileService service; @@ -110,7 +110,7 @@ public class GrpcBinaryFileService extends BinaryFileServiceImplBase { void sendChunks(CallStreamObserver<GrpcGetBinaryFileDataResponse> callObserver, InputStream fileStream, AtomicBoolean doSendFile) { try { - // TODO remove additional flow control when goofy side has been fixed see + // TODO remove additional flow control when alfa side has been fixed see // OZG-2631 if (doSendFile.get()) { int size = sendNextChunk(callObserver, fileStream); diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcFileService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcFileService.java similarity index 81% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcFileService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcFileService.java index a0c0d48..09bd372 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcFileService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcFileService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,17 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.grpc.file.FileServiceGrpc.FileServiceImplBase; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetAttachmentsRequest; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetAttachmentsResponse; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetRepresentationsRequest; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetRepresentationsResponse; +import de.ozgcloud.vorgang.grpc.file.FileServiceGrpc.FileServiceImplBase; +import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest; +import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsResponse; +import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest; +import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsResponse; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapper.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapper.java index 8f5655c..e7c93bf 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.util.List; @@ -29,7 +29,7 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; -import de.itvsh.ozg.pluto.grpc.file.GrpcOzgFile; +import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile; // TODO rename to GrpcBinaryFileMapper /** diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/OzgFile.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/OzgFile.java similarity index 86% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/OzgFile.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/OzgFile.java index edbd4a2..feb172c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/OzgFile.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/OzgFile.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -30,15 +30,11 @@ import lombok.Getter; import lombok.ToString; // TODO: Rename to BinaryFile -/** - * @deprecated Will be renamed to BinaryFile - * - */ + @Builder(toBuilder = true) @ToString @Getter @AllArgsConstructor(access = AccessLevel.PUBLIC) -@Deprecated(since = "0.25", forRemoval = true) public class OzgFile { private FileId id; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadStreamObserver.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadStreamObserver.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadStreamObserver.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadStreamObserver.java index b758bae..253eafa 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadStreamObserver.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadStreamObserver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.io.IOException; import java.io.PipedInputStream; @@ -33,10 +33,10 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; import io.grpc.stub.StreamObserver; import lombok.AccessLevel; import lombok.Getter; @@ -102,7 +102,7 @@ class UploadStreamObserver implements StreamObserver<GrpcUploadBinaryFileRequest CompletableFuture<FileId> storeMetaData(GrpcUploadBinaryFileRequest fileUploadRequest) { var userId = fileUploadRequest.getMetadata().getContext().getUser().getId(); - return service.uploadFileStream( + return service.uploadFileStreamAsync( buildUploadFilesReferences(fileUploadRequest), buildOzgFile(fileUploadRequest), Optional.of(userId), pipedInput); diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadedFilesReference.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadedFilesReference.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadedFilesReference.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadedFilesReference.java index 9708c03..b123c6f 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/files/UploadedFilesReference.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/files/UploadedFilesReference.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import lombok.Builder; import lombok.Getter; diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryScheduler.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryScheduler.java new file mode 100644 index 0000000..c604a83 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryScheduler.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.common.userconfig.UserConfigService; +import lombok.extern.log4j.Log4j2; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; + +@Profile("!itcase") +@Component +@ConditionalOnProperty(prefix = "ozgcloud.vorgang-manager", name = { "address" }) +@Log4j2 +class RegistryScheduler { + @Autowired + private RegistryService registryService; + + @Autowired + private UserConfigService userConfigService; + + @Scheduled(fixedDelayString = "${ozgcloud.vorgang-manager.registry.scheduler.fixedDelay:5}", // + initialDelayString = "${ozgcloud.vorgang-manager.registry.scheduler.initialDelay:5}", // + timeUnit = TimeUnit.MINUTES) + @SchedulerLock(name = "RegistryScheduler") + void register() { + try { + registryService.registerVorgangManager(userConfigService.getSupportedOrganisationsEinheiten()); + } catch (Exception e) { + LOG.error("Error registering VorgangManager", e); + } + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryService.java new file mode 100644 index 0000000..f5e3618 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/RegistryService.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import java.util.List; +import java.util.Optional; + +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import lombok.extern.log4j.Log4j2; + +@Service +@Log4j2 +class RegistryService { + @Value(value = "${ozgcloud.vorgang-manager.address:#{null}}") + private Optional<String> vorgangManagerAddress; + + @Autowired + private ZufiRemoteService zufiRemoteService; + + public void registerVorgangManager(List<String> supportedOrganisationsEinheiten) { + try { + register(supportedOrganisationsEinheiten); + } catch (Exception e) { + LOG.error("Error registering this VorgangsManager.", e); + } + } + + private void register(List<String> supportedOrganisationsEinheiten) { + if (CollectionUtils.isNotEmpty(supportedOrganisationsEinheiten)) { + registerAddress(supportedOrganisationsEinheiten, vorgangManagerAddress); + } else { + LOG.warn("No OrganistationsEinheitenIds provided. Not registering this VorgangsManager"); + } + } + + void registerAddress(List<String> supportedOrganisationsEinheiten, Optional<String> vorgangManagerAddress) { + vorgangManagerAddress.ifPresentOrElse(address -> { + zufiRemoteService.registerVorgangManager(supportedOrganisationsEinheiten, address); + }, () -> LOG.error("Property ozgcloud.vorgang-manager.address not set. Not registering this VorgangsManager")); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/ZufiRemoteService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/ZufiRemoteService.java new file mode 100644 index 0000000..e6355ab --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/registry/ZufiRemoteService.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor; +import de.ozgcloud.zufi.grpc.registration.GrpcVorgangManagerRegistrationRequest; +import de.ozgcloud.zufi.grpc.registration.VorgangManagerRegistrationServiceGrpc.VorgangManagerRegistrationServiceBlockingStub; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Log4j2 +@Service +class ZufiRemoteService { + @GrpcClient("zufi-manager") + private VorgangManagerRegistrationServiceBlockingStub serviceStub; + + public void registerVorgangManager(@NonNull List<String> organistationsEinheitenIds, String vorgangManagerAddress) { + boolean success = getServiceStub() + .register(buildRequest(organistationsEinheitenIds, vorgangManagerAddress)).getSuccess(); + LOG.info("Register success: " + success); + } + + private VorgangManagerRegistrationServiceBlockingStub getServiceStub() { + return serviceStub.withInterceptors(new VorgangManagerClientCallContextAttachingInterceptor()); + } + + private GrpcVorgangManagerRegistrationRequest buildRequest(List<String> organistationsEinheitenIds, String address) { + return GrpcVorgangManagerRegistrationRequest.newBuilder().addAllOrganisationsEinheitenIds(organistationsEinheitenIds) + .setServiceAddress(address).build(); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/PostfachAddress.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/PostfachAddress.java new file mode 100644 index 0000000..651c6b6 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/PostfachAddress.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.vorgang.servicekonto; + +import java.util.Map; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class PostfachAddress { + + public static final String IDENTIFIER_POSTFACH_ID_FIELD = "postfachId"; + + private String version; + private int type; + private Map<String, Object> identifier; +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKonto.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKonto.java new file mode 100644 index 0000000..eff05ad --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKonto.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.Singular; + +@Getter +@Builder +@Setter +public class ServiceKonto { + + public static final String OSI_IDENTIFIER = "OSI"; + + private String type; + @Singular + private List<PostfachAddress> postfachAddresses; +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapper.java new file mode 100644 index 0000000..c3e12fa --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, + unmappedSourcePolicy = ReportingPolicy.WARN, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, + uses = GrpcObjectMapper.class) +public interface ServiceKontoMapper { + + @Mapping(target = "postfachAddresses", source = "postfachAddressesList") + ServiceKonto fromServiceKonto(GrpcServiceKonto serviceKonto); + + @Mapping(target = "postfachAddressesList", source = "postfachAddresses") + GrpcServiceKonto toServiceKonto(ServiceKonto serviceKonto); +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountByPath.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountByPath.java new file mode 100644 index 0000000..427ca78 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountByPath.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +class CountByPath{ + + private String fieldPath; + private String alias; + + public static CountByPath fromStatisticRequest(VorgangStatisticRequest statisticRequest) { + return CountByPath.builder().fieldPath(statisticRequest.getFieldPath()).alias(statisticRequest.getResultName()).build(); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountResult.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountResult.java new file mode 100644 index 0000000..8cc4f2c --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountResult.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Builder +@Getter +@EqualsAndHashCode +public class CountResult { + static final String KEY_NAME = "name"; + static final String KEY_VALUE = "value"; + + private String name; + private int value; +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountStatisticMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountStatisticMapper.java new file mode 100644 index 0000000..7cd60d9 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/CountStatisticMapper.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.vorgang.Vorgang; + +@Component +class CountStatisticMapper { + + static final Pattern PATH_COUNT_REQUEST_PATTERN = Pattern.compile(".+:.+"); + static final String PATH_COUNT_REQUEST_SEPARATOR = ":"; + + GrpcVorgangCountResponse mapTo(Statistic statistic) { + return GrpcVorgangCountResponse.newBuilder() + .setByStatus(mapToByStatus(statistic)) + .addAllPathCountResult(mapToPathCountResults(statistic)) + .build(); + } + + GrpcByStatusResult mapToByStatus(Statistic statistic) { + var counterByStatus = statistic.getCountByStatus(); + return GrpcByStatusResult.newBuilder() + .setNeu(counterByStatus.get(Vorgang.Status.NEU)) + .setAngenommen(counterByStatus.get(Vorgang.Status.ANGENOMMEN)) + .setVerworfen(counterByStatus.get(Vorgang.Status.VERWORFEN)) + .setInBearbeitung(counterByStatus.get(Vorgang.Status.IN_BEARBEITUNG)) + .setBeschieden(counterByStatus.get(Vorgang.Status.BESCHIEDEN)) + .setAbgeschlossen(counterByStatus.get(Vorgang.Status.ABGESCHLOSSEN)) + .setWeitergeleitet(counterByStatus.get(Vorgang.Status.WEITERGELEITET)) + .build(); + } + + private List<GrpcPathCountResult> mapToPathCountResults(Statistic statistic) { + return statistic.getCountResult().entrySet().stream().map(this::mapToPathCountResult).toList(); + } + + private GrpcPathCountResult mapToPathCountResult(Entry<String, Integer> countPathEntry) { + return GrpcPathCountResult.newBuilder().setName(countPathEntry.getKey()).setValue(countPathEntry.getValue()).build(); + } + + public VorgangCountRequest mapFromVorgangCountRequest(GrpcVorgangCountRequest request) { + return VorgangCountRequest.builder().countByPaths(mapFromCountByPathRequest(request.getCountByPathList())).build(); + } + + List<CountByPath> mapFromCountByPathRequest(List<String> countByPathRequests) { + return countByPathRequests.stream().filter(StringUtils::isNoneBlank).map(this::mapPathCountRequest).toList(); + } + + CountByPath mapPathCountRequest(String pathCountRequest) { + return CountByPath.builder().alias(extractAlias(pathCountRequest)).fieldPath(extractFieldPath(pathCountRequest)).build(); + } + + String extractFieldPath(String pathCountRequest) { + validatePathCountRequest(pathCountRequest); + return pathCountRequest.split(PATH_COUNT_REQUEST_SEPARATOR)[1]; + } + + String extractAlias(String pathCountRequest) { + validatePathCountRequest(pathCountRequest); + return pathCountRequest.split(PATH_COUNT_REQUEST_SEPARATOR)[0]; + } + + void validatePathCountRequest(String pathCountRequest) { + if (!PATH_COUNT_REQUEST_PATTERN.matcher(pathCountRequest).matches()) { + throw new VorgangStatisticBadRequestException( + "Invalid path count request. Expected format 'alias:path.to.field' but was: '%s'".formatted(pathCountRequest)); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/InvalidFieldPathException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/InvalidFieldPathException.java new file mode 100644 index 0000000..0172829 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/InvalidFieldPathException.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; + +public class InvalidFieldPathException extends FunctionalException { + + public InvalidFieldPathException() { + super(() -> "statistic.invalid.path"); + + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/Statistic.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/Statistic.java new file mode 100644 index 0000000..f7958e0 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/Statistic.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import java.util.HashMap; +import java.util.Map; + +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +class Statistic { + + @Singular("addStatusCount") + private Map<Vorgang.Status, Integer> countByStatus; + + @Builder.Default + private Map<String, Integer> countResult = new HashMap<>(); + + @Builder.Default + private Map<String, Boolean> existsResult = new HashMap<>(); + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticFilter.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticFilter.java new file mode 100644 index 0000000..361d860 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticFilter.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.apache.commons.collections4.CollectionUtils.*; + +import java.util.Collection; + +import org.springframework.data.mongodb.core.query.Criteria; + +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import lombok.Builder; +import lombok.Singular; + +@Builder +class StatisticFilter { + + @Builder.Default + private Criteria filterCriteria = new Criteria(); + + @Singular + private Collection<String> organisationsEinheitIds; + + public Criteria getCriteria() { + return CriteriaUtil.vorgangNotInCreation().andOperator(getOrganisationsEinheitIdCriteria(), filterCriteria); + } + + public Criteria getOrganisationsEinheitIdCriteria() { + if (isEmpty(organisationsEinheitIds)) { + return new Criteria(); + } + return CriteriaUtil.inOrganisationseinheitenIds(organisationsEinheitIds); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGroupMethod.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGroupMethod.java new file mode 100644 index 0000000..231ad37 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGroupMethod.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +public enum StatisticGroupMethod { + + COUNT, EXISTS; + + public static StatisticGroupMethod from(GrpcVorgangStatisticQuery.GroupMethod groupMethod) { + return switch (groupMethod) { + case COUNT -> COUNT; + case EXISTS -> EXISTS; + case UNRECOGNIZED -> throw new VorgangStatisticBadRequestException("Unrecognized group method: " + groupMethod); + }; + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGrpcService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGrpcService.java new file mode 100644 index 0000000..e0dddcc --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticGrpcService.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import org.springframework.beans.factory.annotation.Autowired; + +import io.grpc.stub.StreamObserver; +import net.devh.boot.grpc.server.service.GrpcService; + +@GrpcService +public class StatisticGrpcService extends StatisticServiceGrpc.StatisticServiceImplBase { + + @Autowired + private StatisticService statisticService; + @Autowired + private CountStatisticMapper countStatisticMapper; + @Autowired + private StatisticMapper statisticMapper; + + @Override + public void countVorgang(GrpcVorgangCountRequest request, StreamObserver<GrpcVorgangCountResponse> responseObserver) { + var statistic = statisticService.countVorgang(countStatisticMapper.mapFromVorgangCountRequest(request)); + + responseObserver.onNext(countStatisticMapper.mapTo(statistic)); + responseObserver.onCompleted(); + } + + @Override + public void getVorgangStatistic(GrpcVorgangStatisticRequest request, StreamObserver<GrpcVorgangStatisticResponse> responseObserver) { + var statistic = statisticService.collectStatistic(statisticMapper.mapFromVorgangStatisticRequest(request)); + + responseObserver.onNext(statisticMapper.mapToVorgangStatisticResponse(statistic)); + responseObserver.onCompleted(); + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticMapper.java new file mode 100644 index 0000000..c53bdc4 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticMapper.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.common.operator.OperandFunctionParser; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.vorgang.Vorgang; + +@Component +class StatisticMapper { + + @Autowired + private OperandFunctionParser operandFunctionParser; + + public List<VorgangStatisticRequest> mapFromVorgangStatisticRequest(GrpcVorgangStatisticRequest grpcRequest) { + return grpcRequest.getQueryList().stream().map(this::mapFromVorgangStatisticQuery).toList(); + } + + VorgangStatisticRequest mapFromVorgangStatisticQuery(GrpcVorgangStatisticQuery statisticQuery) { + return VorgangStatisticRequest.builder() + .resultName(statisticQuery.getResultName()) + .fieldPath(getFieldPath(statisticQuery)) + .statisticGroupMethod(StatisticGroupMethod.from(statisticQuery.getGroupMethod())) + .operator(buildOperator(statisticQuery)) + .build(); + } + + String getFieldPath(GrpcVorgangStatisticQuery statisticQuery) { + return statisticQuery.getPath().startsWith(Vorgang.FIELD_CLIENT_ATTRIBUTES) + ? statisticQuery.getPath() + ".value" + : statisticQuery.getPath(); + } + + Operator buildOperator(GrpcVorgangStatisticQuery statisticQuery) { + return OperatorBuilder.from(statisticQuery.getOperator()) + .fieldPath(statisticQuery.getPath()) + .operand(getValue(statisticQuery)).build(); + } + + Object getValue(GrpcVorgangStatisticQuery statisticQuery) { + return switch (statisticQuery.getOperandCase()) { + case OPERANDBOOLVALUE -> statisticQuery.getOperandBoolValue(); + case OPERANDINTVALUE -> statisticQuery.getOperandIntValue(); + case OPERANDSTRINGVALUE -> getStringValue(statisticQuery); + case OPERAND_NOT_SET -> null; + }; + } + + String getStringValue(GrpcVorgangStatisticQuery statisticQuery) { + var operandStringValue = statisticQuery.getOperandStringValue(); + if ("null".equalsIgnoreCase(operandStringValue)) { + return null; + } else if (operandStringValue.endsWith(")")) { + return operandFunctionParser.parse(operandStringValue); + } + return operandStringValue; + } + + public GrpcVorgangStatisticResponse mapToVorgangStatisticResponse(Statistic statistic) { + return GrpcVorgangStatisticResponse.newBuilder() + .addAllResult(mapCountByPathStatistic(statistic.getCountResult())) + .addAllResult(mapIsFieldExistsStatistic(statistic.getExistsResult())) + .build(); + } + + List<GrpcVorgangStatisticResult> mapCountByPathStatistic(Map<String, Integer> countByPathStatistic) { + return countByPathStatistic.entrySet().stream().map(entry -> mapToCountResult(entry.getKey(), entry.getValue())).toList(); + } + + GrpcVorgangStatisticResult mapToCountResult(String key, Integer value) { + return GrpcVorgangStatisticResult.newBuilder().setName(key).setResultIntValue(value).build(); + } + + List<GrpcVorgangStatisticResult> mapIsFieldExistsStatistic(Map<String, Boolean> isFieldExistsStatistic) { + return isFieldExistsStatistic.entrySet().stream().map(entry -> mapToIsFieldExistsResult(entry.getKey(), entry.getValue())).toList(); + } + + GrpcVorgangStatisticResult mapToIsFieldExistsResult(String key, Boolean value) { + return GrpcVorgangStatisticResult.newBuilder().setName(key).setResultBoolValue(value).build(); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticRepository.java new file mode 100644 index 0000000..4ce04e6 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticRepository.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.bson.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation; +import org.springframework.data.mongodb.core.aggregation.AggregationExpression; +import org.springframework.data.mongodb.core.aggregation.AggregationOperation; +import org.springframework.data.mongodb.core.aggregation.AggregationResults; +import org.springframework.data.mongodb.core.aggregation.GroupOperation; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.NonNull; + +@Repository +class StatisticRepository { + + @Autowired + private MongoOperations mongoOperations; + + public List<CountResult> countVorgangByStatus(StatisticFilter filter) { + var aggregationOperations = initAggregationOperations(filter); + var groupOperation = group(Vorgang.MONGODB_FIELDNAME_STATUS).count().as(CountResult.KEY_VALUE); + aggregationOperations.add(groupOperation); + var projectOperation = project(CountResult.KEY_VALUE).and(CountResult.KEY_NAME).previousOperation(); + aggregationOperations.add(projectOperation); + + return executeAggregation(CountResult.class, aggregationOperations).getMappedResults(); + } + + public List<CountResult> countVorgangByPath(CountByPath countByPaths, Operator operator, StatisticFilter filter) { + var aggregationOperations = initAggregationOperations(filter); + aggregationOperations.add(buildAddFieldOperation(countByPaths.getAlias(), operator.getAggregationExpression())); + aggregationOperations.add(buildGroupOperation(countByPaths)); + + var countByPathResults = executeAggregation(Document.class, aggregationOperations); + return mapCountByPathResults(countByPathResults.getUniqueMappedResult(), countByPaths.getAlias()); + } + + List<AggregationOperation> initAggregationOperations(StatisticFilter filter) { + var aggregationOperations = new ArrayList<AggregationOperation>(); + aggregationOperations.add(match(filter.getCriteria())); + return aggregationOperations; + } + + AddFieldsOperation buildAddFieldOperation(String alias, AggregationExpression aggregationExpression) { + return addFields().addFieldWithValue(alias, aggregationExpression).build(); + } + + GroupOperation buildGroupOperation(CountByPath countByPaths) { + return group().sum(countByPaths.getAlias()).as(countByPaths.getAlias()); + } + + List<CountResult> mapCountByPathResults(Document countByPathResults, String resultAlias) { + if (Objects.isNull(countByPathResults)) { + return List.of(buildZeroResult(resultAlias)); + } + + return mapCountByPathResults(countByPathResults); + } + + private CountResult buildZeroResult(String resultAlias) { + return CountResult.builder().name(resultAlias).value(0).build(); + } + + private List<CountResult> mapCountByPathResults(@NonNull Document countByPathResults) { + return countByPathResults.entrySet().stream().filter(entry -> !"_id".equals(entry.getKey())).map(this::mapCountResult).toList(); + } + + CountResult mapCountResult(Map.Entry<String, Object> entry) { + return CountResult.builder().name(entry.getKey()).value((Integer) entry.getValue()).build(); + } + + <O> AggregationResults<O> executeAggregation(Class<O> outputType, List<AggregationOperation> aggregationOperations) { + return mongoOperations.aggregate(newAggregation(aggregationOperations), Vorgang.COLLECTION_NAME, outputType); + } + + public boolean isFieldsExists(StatisticFilter filter) { + return mongoOperations.exists(Query.query(filter.getCriteria()), Vorgang.COLLECTION_NAME); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticService.java new file mode 100644 index 0000000..0a06357 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/StatisticService.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.apache.commons.collections4.CollectionUtils.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; + +@Service +class StatisticService { + + @Autowired + private StatisticRepository statisticRepository; + @Autowired + private CurrentUserService currentUserService; + @Autowired + private OperatorFactory operatorFactory; + + public Statistic countVorgang(VorgangCountRequest request) { + return Statistic.builder().countByStatus(countVorgangByStatus()).countResult(countVorgangByPathsOld(request.getCountByPaths())).build(); + } + + Map<String, Integer> countVorgangByPathsOld(List<CountByPath> countByPaths) { + var organisationsEinheitIds = getOrganisationsEinheitIds(); + if (organisationsEinheitIds.isEmpty()) { + return countByPaths.stream().collect(Collectors.toMap(CountByPath::getAlias, counterByPath -> 0)); + } + var statisticFilter = StatisticFilter.builder().organisationsEinheitIds(organisationsEinheitIds.get()).build(); + return countByPaths.stream() + .flatMap( + countByPath -> statisticRepository.countVorgangByPath(countByPath, buildFieldExistsStatisticQuery(countByPath.getFieldPath()), + statisticFilter).stream()) + .collect(Collectors.toMap(CountResult::getName, CountResult::getValue)); + } + + Operator buildFieldExistsStatisticQuery(String fieldPath) { + return operatorFactory.newUnequalOperatorBuilder().fieldPath(fieldPath).operand(null).build(); + } + + Map<Vorgang.Status, Integer> countVorgangByStatus() { + var organisationsEinheitIds = getOrganisationsEinheitIds(); + if (organisationsEinheitIds.isEmpty()) { + return fillMissingStatusCounters(Collections.emptyMap()); + } + var statisticFilter = StatisticFilter.builder().organisationsEinheitIds(organisationsEinheitIds.get()).build(); + List<CountResult> countResults = statisticRepository.countVorgangByStatus(statisticFilter); + return fillMissingStatusCounters(mapCountResults(countResults)); + } + + Map<Vorgang.Status, Integer> mapCountResults(List<CountResult> countResults) { + var countByStatus = new EnumMap<Vorgang.Status, Integer>(Vorgang.Status.class); + countResults.forEach(countResult -> countByStatus.put(Vorgang.Status.valueOf(countResult.getName()), countResult.getValue())); + return countByStatus; + } + + Map<Vorgang.Status, Integer> fillMissingStatusCounters(Map<Vorgang.Status, Integer> countByStatus) { + var resultMap = new EnumMap<Vorgang.Status, Integer>(Vorgang.Status.class); + resultMap.putAll(countByStatus); + Arrays.stream(Vorgang.Status.values()).forEach(status -> resultMap.putIfAbsent(status, 0)); + return resultMap; + } + + public Statistic collectStatistic(Collection<VorgangStatisticRequest> statisticRequests) { + return Statistic.builder() + .countResult(countVorgangByPaths(getCountRequests(statisticRequests))) + .existsResult(collectFieldExistsStatistic(getExistsRequests(statisticRequests))) + .build(); + } + + Set<VorgangStatisticRequest> getCountRequests(Collection<VorgangStatisticRequest> statisticRequests) { + return statisticRequests.stream().filter(request -> request.getStatisticGroupMethod() == StatisticGroupMethod.COUNT) + .collect(Collectors.toSet()); + } + + Set<VorgangStatisticRequest> getExistsRequests(Collection<VorgangStatisticRequest> statisticRequests) { + return statisticRequests.stream().filter(request -> request.getStatisticGroupMethod() == StatisticGroupMethod.EXISTS) + .collect(Collectors.toSet()); + } + + Map<String, Integer> countVorgangByPaths(Collection<VorgangStatisticRequest> statisticRequests) { + return statisticRequests.stream().flatMap(this::countVorgangByPath).collect(Collectors.toMap(CountResult::getName, CountResult::getValue)); + } + + Stream<CountResult> countVorgangByPath(VorgangStatisticRequest statisticRequest) { + var organisationsEinheitIds = getOrganisationsEinheitIds(); + if (organisationsEinheitIds.isEmpty()) { + return Stream.of(CountResult.builder().name(statisticRequest.getResultName()).value(0).build()); + } + var statisticFilter = StatisticFilter.builder().organisationsEinheitIds(organisationsEinheitIds.get()).build(); + return statisticRepository + .countVorgangByPath(CountByPath.fromStatisticRequest(statisticRequest), statisticRequest.getOperator(), statisticFilter).stream(); + } + + Map<String, Boolean> collectFieldExistsStatistic(Collection<VorgangStatisticRequest> fieldExistsRequests) { + return fieldExistsRequests.stream().collect(Collectors.toMap(VorgangStatisticRequest::getResultName, this::isFieldExists)); + } + + boolean isFieldExists(VorgangStatisticRequest fieldExistsRequest) { + var organisationsEinheitIds = getOrganisationsEinheitIds(); + if (organisationsEinheitIds.isEmpty()) { + return false; + } + var filter = StatisticFilter.builder().filterCriteria(fieldExistsRequest.getOperator().getCriteria()) + .organisationsEinheitIds(organisationsEinheitIds.get()).build(); + return statisticRepository.isFieldsExists(filter); + } + + Optional<Collection<String>> getOrganisationsEinheitIds() { + var callContextUser = currentUserService.getUser(); + if (callContextUser.isOrganisationEinheitenIdCheckNecessary()) { + if (isEmpty(callContextUser.getOrganisatorischeEinheitenIds())) { + return Optional.empty(); + } + return Optional.of(callContextUser.getOrganisatorischeEinheitenIds()); + } + return Optional.of(Collections.emptyList()); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangCountRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangCountRequest.java new file mode 100644 index 0000000..1ec38d3 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangCountRequest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Getter +@Builder +class VorgangCountRequest { + + @Singular + private List<CountByPath> countByPaths; +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticBadRequestException.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticBadRequestException.java new file mode 100644 index 0000000..6adb0c2 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticBadRequestException.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; + +public class VorgangStatisticBadRequestException extends FunctionalException { + + public VorgangStatisticBadRequestException(String message) { + super(message, () -> "COUNT_VORGANG.BAD_REQUEST"); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequest.java new file mode 100644 index 0000000..60527e5 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequest.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.common.operator.Operator; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class VorgangStatisticRequest { + + private String resultName; + private String fieldPath; + private StatisticGroupMethod statisticGroupMethod; + private Operator operator; + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/StatusChangedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusChangedEvent.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/StatusChangedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusChangedEvent.java index 5d19f8e..307ec1c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/StatusChangedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusChangedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.status; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; public class StatusChangedEvent extends CommandExecutedEvent { @@ -37,5 +37,4 @@ public class StatusChangedEvent extends CommandExecutedEvent { StatusChangedEvent(String commandId) { super(commandId); } - } diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusEventListener.java new file mode 100644 index 0000000..64a41e9 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusEventListener.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static de.ozgcloud.vorgang.vorgang.Vorgang.*; + +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import lombok.extern.log4j.Log4j2; + +@Component +@Log4j2 +class StatusEventListener { + @Autowired + private StatusService statusService; + @Autowired + private VorgangService vorgangService; + @Autowired + private CommandService commandService; + + @Autowired + private ApplicationEventPublisher publisher; + + private static final String IS_ABSCHLIESSEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_ABSCHLIESSEN_EVENT.test(event.getSource())}"; + private static final String IS_ANNEHMEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_ANNEHMEN_EVENT.test(event.getSource())}"; + private static final String IS_VERWERFEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_VERWERFEN_EVENT.test(event.getSource())}"; + private static final String IS_BEARBEITEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_BEARBEITEN_EVENT.test(event.getSource())}"; + private static final String IS_BESCHEIDEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_BESCHEIDEN_EVENT.test(event.getSource())}"; + private static final String IS_WIEDEREROEFFNEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_WIEDEREROEFFNEN_EVENT.test(event.getSource())}"; + private static final String IS_ZURUECKHOLEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_ZURUECKHOLEN_EVENT.test(event.getSource())}"; + private static final String IS_ZURUECKSTELLEN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_ZURUECKSTELLEN_EVENT.test(event.getSource())}"; + private static final String IS_ZUMLOESCHENMARKIEREN = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_ZUMLOESCHENMARKIEREN_EVENT.test(event.getSource())}"; + private static final String IS_STATUS_CHANGE = "{T(de.ozgcloud.vorgang.status.StatusEventListener).IS_STATUS_CHANGE_EVENT.test(event.getSource())}"; + + public static final Predicate<Command> IS_ABSCHLIESSEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_ABSCHLIESSEN.name()); + public static final Predicate<Command> IS_ANNEHMEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_ANNEHMEN.name()); + public static final Predicate<Command> IS_VERWERFEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_VERWERFEN.name()); + public static final Predicate<Command> IS_BEARBEITEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_BEARBEITEN.name()); + public static final Predicate<Command> IS_BESCHEIDEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_BESCHEIDEN.name()); + public static final Predicate<Command> IS_WIEDEREROEFFNEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_WIEDEREROEFFNEN.name()); + public static final Predicate<Command> IS_ZURUECKHOLEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_ZURUECKHOLEN.name()); + public static final Predicate<Command> IS_ZURUECKSTELLEN_EVENT = command -> command.getOrder().equals(Order.VORGANG_ZURUECKSTELLEN.name()); + public static final Predicate<Command> IS_ZUMLOESCHENMARKIEREN_EVENT = command -> command.getOrder() + .equals(Order.VORGANG_ZUM_LOESCHEN_MARKIEREN.name()); + public static final Predicate<Command> IS_STATUS_CHANGE_EVENT = command -> command.getOrder().startsWith("VORGANG_"); + + @EventListener(condition = IS_ABSCHLIESSEN) + public void abschiessen(CommandCreatedEvent event) { + processEvent(event, statusService::abschliessen); + } + + @EventListener(condition = IS_ANNEHMEN) + public void annehmen(CommandCreatedEvent event) { + processEvent(event, statusService::annehmen); + } + + @EventListener(condition = IS_VERWERFEN) + public void verwerfen(CommandCreatedEvent event) { + processEvent(event, statusService::verwerfen); + } + + @EventListener(condition = IS_BEARBEITEN) + public void bearbeiten(CommandCreatedEvent event) { + processEvent(event, statusService::bearbeiten); + } + + @EventListener(condition = IS_BESCHEIDEN) + public void bescheiden(CommandCreatedEvent event) { + processEvent(event, statusService::bescheiden); + } + + @EventListener(condition = IS_WIEDEREROEFFNEN) + public void wiedereroeffnen(CommandCreatedEvent event) { + processEvent(event, statusService::wiedereroeffnen); + } + + @EventListener(condition = IS_ZURUECKHOLEN) + public void zurueckholen(CommandCreatedEvent event) { + processEvent(event, statusService::setStatusNeu); + } + + @EventListener(condition = IS_ZURUECKSTELLEN) + public void zurueckstellen(CommandCreatedEvent event) { + processEvent(event, statusService::annehmen); + } + + @EventListener(condition = IS_ZUMLOESCHENMARKIEREN) + public void zuLoeschenMarkieren(CommandCreatedEvent event) { + processEvent(event, statusService::zumLoeschenMarkieren); + } + + private void processEvent(CommandCreatedEvent event, Consumer<Command> eventConsumer) { + var command = event.getSource(); + try { + command = setPreviousState(command); + eventConsumer.accept(command); + } catch (NotFoundException e) { + handleError("Error processing event because related vorgang (%s) not found.".formatted(command.getVorgangId()), e, command.getId()); + } catch (Exception e) { + handleError("Unexpected Error on handling Status event.", e, command.getId()); + } + } + + Command setPreviousState(Command command) { + var vorgang = vorgangService.getById(command.getVorgangId()); + commandService.setPreviousState(command.getId(), getPreviousStateMap(vorgang)); + return commandService.findCommand(command.getId()) + .orElseThrow(() -> new NoSuchElementException("No command with Id %s found".formatted(command.getId()))); + } + + Map<String, Object> getPreviousStateMap(Vorgang vorgang) { + return Map.of(MONGODB_FIELDNAME_STATUS, vorgang.getStatus()); + } + + @EventListener(condition = IS_STATUS_CHANGE) + public void statusRevokedEvent(RevokeCommandEvent event) { + var command = event.getSource(); + try { + statusService.revokeStatusChange(command); + } catch (Exception e) { + LOG.error("Unexpected error on command revoke.", e); + publisher.publishEvent(new CommandRevokeFailedEvent(command.getId(), "Unexpected error on command revoke")); + } + } + + private void handleError(String message, Exception e, String commandId) { + LOG.error(message, e); + publisher.publishEvent(new CommandFailedEvent(commandId, message)); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusRepository.java new file mode 100644 index 0000000..40da495 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusRepository.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static de.ozgcloud.vorgang.common.db.CriteriaUtil.*; +import static de.ozgcloud.vorgang.vorgang.Vorgang.*; +import static org.springframework.data.mongodb.core.query.Query.*; + +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Update; +import org.springframework.stereotype.Repository; + +import com.mongodb.client.result.UpdateResult; + +import de.ozgcloud.vorgang.common.db.CollisionVerifier; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import lombok.extern.log4j.Log4j2; + +@Repository +@Log4j2 +class StatusRepository { + + @Autowired + private MongoOperations mongoOperations; + + private CollisionVerifier collisionVerifier; + + @PostConstruct + void init() { + collisionVerifier = createCollisionVerifier(); + } + + CollisionVerifier createCollisionVerifier() { + return new CollisionVerifier(this::doVorgangExist); + } + + boolean doVorgangExist(String vorgangId) { + return mongoOperations.exists(query(isId(vorgangId)), Vorgang.COLLECTION_NAME); + } + + public void updateStatusWithoutVersionCheck(String vorgangId, Status status) { + var update = new Update() + .inc(MONGODB_FIELDNAME_VERSION, 1) + .set(MONGODB_FIELDNAME_STATUS, status); + updateFirst(new Criteria(MONGODB_FIELDNAME_ID).is(vorgangId), update); + } + + public void patch(String vorgangId, long version, Map<String, Object> patch) { + var update = new Update().inc(MONGODB_FIELDNAME_VERSION, 1); + patch.forEach(update::set); + + collisionVerifier.verify(updateFirst(whereIdAndVersion(vorgangId, version), update), vorgangId); + } + + private UpdateResult updateFirst(Criteria queryObj, Update update) { + var result = mongoOperations.updateFirst(query(queryObj), update, Vorgang.class); + LOG.debug("Update result: {}", result); + return result; + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusService.java new file mode 100644 index 0000000..1c5a5a9 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/status/StatusService.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import java.util.ConcurrentModificationException; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.collections4.MapUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokedEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import lombok.extern.log4j.Log4j2; + +@Service +@Log4j2 +public class StatusService { + private static final String CONCURRENT_MODIFICATION_ERROR_CODE = "concurrent_modification"; + + @Autowired + private ApplicationEventPublisher publisher; + + @Autowired + private StatusRepository repository; + + void setStatusNeu(Command command) { + executeStatusChangeCommand(command, Status.NEU); + } + + public void annehmen(Command command) { + executeStatusChangeCommand(command, Status.ANGENOMMEN); + } + + public void verwerfen(Command command) { + executeStatusChangeCommand(command, Status.VERWORFEN); + } + + public void bescheiden(Command command) { + executeStatusChangeCommand(command, Status.BESCHIEDEN); + } + + public void abschliessen(Command command) { + executeStatusChangeCommand(command, Status.ABGESCHLOSSEN); + } + + public void wiedereroeffnen(Command command) { + bearbeiten(command); + } + + public void bearbeiten(Command command) { + executeStatusChangeCommand(command, Status.IN_BEARBEITUNG); + } + + public void zumLoeschenMarkieren(Command command) { + executeStatusChangeCommand(command, Status.ZU_LOESCHEN); + } + + public void executeStatusChangeCommand(Command command, Status status) { + try { + doUpdateStatus(command.getRelationId(), command.getRelationVersion(), status.name()); + publisher.publishEvent(new StatusChangedEvent(command)); + } catch (ConcurrentModificationException e) { + LOG.warn("Concurrent modification on changeing status."); + publisher.publishEvent(new CommandFailedEvent(command.getId(), CONCURRENT_MODIFICATION_ERROR_CODE)); + } + } + + public void setStatusToInBearbeitung(String vorgangId, long version) { + doUpdateStatus(vorgangId, version, Status.IN_BEARBEITUNG.name()); + } + + public void revokeStatusChange(Command command) { + try { + doUpdateStatus(command.getRelationId(), command.getRelationVersion() + 1, + getPreviousStatus(command).orElseThrow(() -> new TechnicalException("Malformed or missing previous state for status revoke."))); + + publisher.publishEvent(new CommandRevokedEvent(command)); + } catch (ConcurrentModificationException e) { + publisher.publishEvent(new CommandFailedEvent(command.getId(), CONCURRENT_MODIFICATION_ERROR_CODE)); + } + } + + Optional<String> getPreviousStatus(Command command) { + return Optional.ofNullable(((PersistedCommand) command).getPreviousState()) + .map(previousState -> MapUtils.getString(previousState, Vorgang.MONGODB_FIELDNAME_STATUS)) + .filter(Objects::nonNull); + } + + void doUpdateStatus(String vorgangId, long version, String statusValue) { + Map<String, Object> patch = Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, statusValue); + + repository.patch(vorgangId, version, patch); + } + + public void setStatusToWeitergeleitet(String vorgangId, String commandId) { + doUpdateStatusWithoutVerisonCheck(vorgangId, Status.WEITERGELEITET, commandId); + } + + public void setStatusToInBearbeitung(String vorgangId, String commandId) { + doUpdateStatusWithoutVerisonCheck(vorgangId, Status.IN_BEARBEITUNG, commandId); + } + + void doUpdateStatusWithoutVerisonCheck(String vorgangId, Status newStatus, String commandId) { + repository.updateStatusWithoutVersionCheck(vorgangId, newStatus); + + publisher.publishEvent(new StatusChangedEvent(commandId)); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/system/SystemStatusGrpcService.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/system/SystemStatusGrpcService.java index 32cdd9f..344db6f 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/system/SystemStatusGrpcService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.system; +package de.ozgcloud.vorgang.system; + +import java.util.Objects; -import de.itvsh.ozg.pluto.common.search.SearchService; -import io.grpc.stub.StreamObserver; -import net.devh.boot.grpc.server.service.GrpcService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.info.BuildProperties; -import java.util.Objects; +import de.ozgcloud.vorgang.common.search.SearchService; +import io.grpc.stub.StreamObserver; +import net.devh.boot.grpc.server.service.GrpcService; @GrpcService public class SystemStatusGrpcService extends SystemStatusServiceGrpc.SystemStatusServiceImplBase { diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/DeleteUserScheduler.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/DeleteUserScheduler.java new file mode 100644 index 0000000..6ac9e70 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/DeleteUserScheduler.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static java.util.function.Predicate.*; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.command.CommandService; +import lombok.extern.log4j.Log4j2; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; + +@Component +@Profile("!itcase") +@Log4j2 +public class DeleteUserScheduler { + + @Autowired + private UserService userService; + @Autowired + private CommandService commandService; + + @Scheduled(cron = "${ozgcloud.user.cleanup.cron:0 0 1 * * *}") + @SchedulerLock(name = "DeleteUserScheduler") + public void deleteUsers() { + try { + LOG.debug("Deleting inactive users."); + userService.findInactiveUserIds().filter(not(commandService::existsCommandWithUserId)).forEach(userService::deleteInactiveUser); + } catch (RuntimeException e) { + LOG.error("Cannot delete inactive users.", e); + } + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserProfileRemoteService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserProfileRemoteService.java new file mode 100644 index 0000000..69fd57a --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserProfileRemoteService.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub; +import de.ozgcloud.user.userprofile.GrpcDeleteInactiveUserRequest; +import de.ozgcloud.user.userprofile.GrpcFindInactiveUserIdsRequest; +import de.ozgcloud.user.userprofile.GrpcFindInactiveUserIdsResponse; +import de.ozgcloud.user.userprofile.GrpcUserProfileId; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class UserProfileRemoteService { + + @GrpcClient("user-manager") + private UserProfileServiceBlockingStub userProfileServiceGrpc; + + public Stream<String> findInactiveUserIds() { + var response = getUserServiceStub().findInactiveUserIds(GrpcFindInactiveUserIdsRequest.newBuilder().build()); + return mapFindInactiveUserIdsResponse(response); + } + + Stream<String> mapFindInactiveUserIdsResponse(GrpcFindInactiveUserIdsResponse response) { + return response.getUserProfileIdsList().stream().map(GrpcUserProfileId::getId); + } + + public void deleteInactiveUser(String userId) { + getUserServiceStub().deleteInactiveUser(buildDeleteInactiveUsersRequest(userId)); + } + + UserProfileServiceBlockingStub getUserServiceStub() { + return userProfileServiceGrpc.withInterceptors(new VorgangManagerCallContextAttachingInterceptor()); + } + + GrpcDeleteInactiveUserRequest buildDeleteInactiveUsersRequest(String userId) { + return GrpcDeleteInactiveUserRequest.newBuilder().setUserId(userId).build(); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserService.java new file mode 100644 index 0000000..e682a06 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/UserService.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +class UserService { + + @Autowired + private UserProfileRemoteService userRemoteService; + + public Stream<String> findInactiveUserIds() { + return userRemoteService.findInactiveUserIds(); + } + + public void deleteInactiveUser(String userId) { + userRemoteService.deleteInactiveUser(userId); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptor.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptor.java new file mode 100644 index 0000000..ad6747c --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptor.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; + +import java.util.UUID; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +public class VorgangManagerCallContextAttachingInterceptor implements ClientInterceptor { + + static final String KEY_USER_ID = "USER_ID-bin"; + static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin"; + static final String KEY_REQUEST_ID = "REQUEST_ID-bin"; + + public static final String VORGANG_MANAGER_CLIENT_NAME = "OzgCloudVorgangManager"; + static final String VORGANG_MANAGER_SENDER_USER_ID = "system-vorgang_manager-delete_user"; + + // <A> = Request, <B> = Response + @Override + public <A, B> ClientCall<A, B> interceptCall(MethodDescriptor<A, B> method, CallOptions callOptions, Channel next) { + return new CallContextAttachingClientCall<>(next.newCall(method, callOptions)); + } + + final class CallContextAttachingClientCall<A, B> extends SimpleForwardingClientCall<A, B> { + + protected CallContextAttachingClientCall(ClientCall<A, B> delegate) { + super(delegate); + } + + @Override + public void start(Listener<B> responseListener, Metadata headers) { + headers.merge(buildCallContextMetadata()); + super.start(responseListener, headers); + } + + private Metadata buildCallContextMetadata() { + var metadata = new Metadata(); + + metadata.put(createKeyOf(KEY_USER_ID), VORGANG_MANAGER_SENDER_USER_ID.getBytes()); + metadata.put(createKeyOf(KEY_CLIENT_NAME), VORGANG_MANAGER_CLIENT_NAME.getBytes()); + metadata.put(createKeyOf(KEY_REQUEST_ID), generateRequestId().getBytes()); + + return metadata; + } + + // TODO requestId in Scheduler erzeugen + private String generateRequestId() { + return UUID.randomUUID().toString(); + } + + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProvider.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProvider.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProvider.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProvider.java index bf302ec..7f94799 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProvider.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; interface AktenzeichenProvider { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderConfiguration.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderConfiguration.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderConfiguration.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderConfiguration.java index c18463e..1de0b92 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderConfiguration.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.lang.reflect.InvocationTargetException; import java.util.Optional; @@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import de.itvsh.kop.common.errorhandling.TechnicalException; +import de.ozgcloud.common.errorhandling.TechnicalException; @Configuration public class AktenzeichenProviderConfiguration { @@ -39,8 +39,8 @@ public class AktenzeichenProviderConfiguration { private static final String MSG_CLASSNOTFOUND_TEMPL = "Class '%s' for AktenzeichenProvider not found"; private static final String MSG_INSTANCE = "Error on getInstance for aktenzeichen provider."; - // TODO configruations-hirachie verwenden - @Value("${aktenzeichen:#{null}}") + // TODO configruations-hierachie verwenden + @Value("${ozgcloud.aktenzeichen:#{null}}") private Optional<String> aktenzeichenCalculator; @Bean diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEA.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEA.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEA.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEA.java index 8b1c87f..cb6f864 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEA.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEA.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import lombok.NoArgsConstructor; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Antragsteller.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Antragsteller.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Antragsteller.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Antragsteller.java index 2b12ab1..9f14fad 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Antragsteller.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Antragsteller.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Map; import lombok.Builder; import lombok.Getter; -import lombok.ToString; -@ToString @Getter @Builder public class Antragsteller { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapper.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapper.java index 29a7436..ef3d3e6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.kop.pluto.common.grpc.GrpcFormDataMapper; +import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper; @Mapper(uses = { GrpcFormDataMapper.class }, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CustomVorgangHeaderRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/CustomVorgangHeaderRepository.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CustomVorgangHeaderRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/CustomVorgangHeaderRepository.java index 048f25c..406571d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/CustomVorgangHeaderRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/CustomVorgangHeaderRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.springframework.data.domain.Page; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProvider.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProvider.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProvider.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProvider.java index f46e735..d757703 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProvider.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import lombok.NoArgsConstructor; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Eingang.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Eingang.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Eingang.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Eingang.java index efce349..20fd2b8 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Eingang.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Eingang.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.List; import java.util.Map; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeader.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeader.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeader.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeader.java index 2cd5275..ace40bf 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeader.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeader.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; +import de.ozgcloud.vorgang.servicekonto.ServiceKonto; import lombok.Builder; import lombok.Getter; import lombok.ToString; @@ -40,6 +41,8 @@ public class EingangHeader { private String formName; private String formEngineName; - private String sender; + private String vorgangNummer; + private String sender; + private ServiceKonto serviceKonto; } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapper.java similarity index 75% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapper.java index 8120b98..30df00c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -29,8 +29,15 @@ import java.time.format.DateTimeFormatter; import org.mapstruct.Mapper; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; -@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +import de.ozgcloud.vorgang.servicekonto.ServiceKontoMapper; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, // + unmappedSourcePolicy = ReportingPolicy.WARN, // + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, // + uses = ServiceKontoMapper.class) interface EingangHeaderMapper { EingangHeader fromGrpc(GrpcEingangHeader grpcEingangHeader); diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangMapper.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangMapper.java index cfa1cf1..35d3de3 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/EingangMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/EingangMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; - -import java.util.Map.Entry; -import java.util.function.Predicate; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; @@ -32,7 +29,7 @@ import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.kop.pluto.common.grpc.GrpcFormDataMapper; +import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper; @Mapper(uses = { AntragstellerMapper.class, EingangHeaderMapper.class, IncomingFileMapper.class, GrpcFormDataMapper.class }, // @@ -41,8 +38,6 @@ import de.itvsh.kop.pluto.common.grpc.GrpcFormDataMapper; collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) interface EingangMapper { - static final Predicate<Entry<String, Object>> IS_FIELD_VALUE = entry -> entry.getValue() instanceof String; - @Mapping(source = "attachmentsList", target = "attachments") @Mapping(source = "representationsList", target = "representations") Eingang fromGrpc(GrpcEingang grpcEingang); diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterByMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterByMapper.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterByMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterByMapper.java index 1378719..856ef02 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterByMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterByMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Collection; @@ -32,8 +32,8 @@ import org.springframework.beans.factory.annotation.Autowired; import com.google.protobuf.ProtocolStringList; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUser; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.CallContextUser; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; @Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) abstract class FilterByMapper { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteria.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteria.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteria.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteria.java index bf31217..c69f555 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteria.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteria.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.List; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; import lombok.Builder; import lombok.Getter; import lombok.Singular; @@ -39,5 +39,7 @@ public class FilterCriteria { private List<String> organisationseinheitIds; @Singular("singleStatus") private List<Status> status; + private boolean filterByAssignedTo; private String assignedTo; + private boolean hasNextWiedervorlageFrist; } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaDefault.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaDefault.java similarity index 90% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaDefault.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaDefault.java index b03edd6..c170de6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaDefault.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; enum FilterCriteriaDefault { SHOW_ALL, diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQuery.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQuery.java new file mode 100644 index 0000000..8404ace --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQuery.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import java.util.List; + +import de.ozgcloud.vorgang.common.operator.Operator; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class FindVorgangQuery { + + public enum LogicalOperator { + AND, OR + } + + private LogicalOperator logicalOperator; + @Singular + private List<Operator> operators; + private FindVorgangQuery nestedQuery; +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapper.java new file mode 100644 index 0000000..7071d26 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapper.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import org.mapstruct.Mapper; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.vorgang.common.operator.OperandFunctionParser; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; + +@Mapper +abstract class FindVorgangQueryMapper { + + @Autowired + private OperandFunctionParser operandFunctionParser; + + public FindVorgangQuery fromQuery(GrpcQuery query) { + var findVorgangQueryBuilder = FindVorgangQuery.builder() + .logicalOperator(fromLogicalOperator(query.getLogicalOperator())); + query.getExpressionsList().stream().map(this::buildOperator).forEach(findVorgangQueryBuilder::operator); + if (hasSubQuery(query)) { + findVorgangQueryBuilder.nestedQuery(fromQuery(query.getNestedQuery())); + } + return findVorgangQueryBuilder.build(); + } + + boolean hasSubQuery(GrpcQuery query) { + return !GrpcQuery.getDefaultInstance().equals(query.getNestedQuery()); + } + + FindVorgangQuery.LogicalOperator fromLogicalOperator(GrpcLogicalOperator operator) { + return FindVorgangQuery.LogicalOperator.valueOf(operator.name()); + } + + Operator buildOperator(GrpcVorgangQueryExpression queryExpression) { + return OperatorBuilder.from(queryExpression.getOperator()) + .fieldPath(queryExpression.getPath()) + .operand(getValue(queryExpression)).build(); + } + + Object getValue(GrpcVorgangQueryExpression queryExpression) { + return switch (queryExpression.getOperandCase()) { + case OPERANDBOOLVALUE -> queryExpression.getOperandBoolValue(); + case OPERANDINTVALUE -> queryExpression.getOperandIntValue(); + case OPERANDSTRINGVALUE -> getStringValue(queryExpression); + case OPERAND_NOT_SET -> null; + }; + } + + String getStringValue(GrpcVorgangQueryExpression queryExpression) { + var operandStringValue = queryExpression.getOperandStringValue(); + if ("null".equalsIgnoreCase(operandStringValue)) { + return null; + } else if (operandStringValue.endsWith(")")) { + return operandFunctionParser.parse(operandStringValue); + } + return operandStringValue; + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequest.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequest.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequest.java index ed3cb51..eef7387 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequest.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import lombok.Builder; import lombok.Getter; @@ -31,11 +31,12 @@ import lombok.Getter; public class FindVorgangRequest { enum OrderCriteria { - PRIORITY, EA_PRIORITY + PRIORITY, EA_PRIORITY, CREATED_AT_DESC, NEXT_WIEDERVORLAGE_FRIST } private FilterCriteria filterBy; private String searchBy; + private FindVorgangQuery findVorgangQuery; @Builder.Default private OrderCriteria orderBy = OrderCriteria.PRIORITY; @Builder.Default diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapper.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapper.java index 7cd3357..43330d7 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,18 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.apache.commons.lang3.StringUtils; import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; import org.mapstruct.ValueMapping; -@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { FilterByMapper.class }) +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { FilterByMapper.class, FindVorgangQueryMapper.class }) interface FindVorgangRequestMapper { @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) + @Mapping(target = "findVorgangQuery", source = "query") FindVorgangRequest fromFindVorgangRequest(GrpcFindVorgangRequest vorgangRequest); default String emptyToNull(String inString) { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangService.java similarity index 79% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangService.java index 5744a6f..fe60cea 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -51,35 +51,20 @@ class GrpcVorgangService extends VorgangServiceGrpc.VorgangServiceImplBase { @Autowired private IncomingFileGroupMapper incomingFileGroupMapper; - /** - * @deprecated Kann nach dem Ausrollen von Version 0.23.0 entfernt werden - * @param eingang - * @return - */ - @Deprecated(since = "0.22.0", forRemoval = true) - @Override - public void createVorgang(GrpcCreateVorgangRequest request, StreamObserver<GrpcCreateVorgangResponse> responseObserver) { - var vorgang = vorgangService.createVorgang(eingangMapper.fromGrpc(request.getEingang())); - - completeRequest(responseObserver, vorgang); - } - @Override public void startCreation(GrpcCreateVorgangRequest request, StreamObserver<GrpcCreateVorgangResponse> responseObserver) { - var vorgang = vorgangService.startCreation(eingangMapper.fromGrpc(request.getEingang())); + GrpcCreateVorgangResponse response = buildCreateVorgangResponse(startVorgangCreation(request.getEingang())); - completeRequest(responseObserver, vorgang); + responseObserver.onNext(response); + responseObserver.onCompleted(); } - private void completeRequest(StreamObserver<GrpcCreateVorgangResponse> responseObserver, Vorgang vorgang) { - responseObserver.onNext(buildCreateVorgangResponse(vorgang)); - responseObserver.onCompleted(); + private Vorgang startVorgangCreation(GrpcEingang eingang) { + return vorgangService.startCreation(eingangMapper.fromGrpc(eingang)); } private GrpcCreateVorgangResponse buildCreateVorgangResponse(Vorgang vorgang) { - return GrpcCreateVorgangResponse.newBuilder() - .setVorgangId(vorgang.getId()) - .setMessage("ok").build(); + return GrpcCreateVorgangResponse.newBuilder().setVorgangId(vorgang.getId()).setMessage("ok").build(); } @Override @@ -108,7 +93,7 @@ class GrpcVorgangService extends VorgangServiceGrpc.VorgangServiceImplBase { private GrpcFindVorgangResponse buildFindVorgangResponse(Page<VorgangHeader> page) { var replyBuilder = page.getContent().stream() .map(vorgangHeaderMapper::toGrpcVorgangHeader)// - .collect(GrpcFindVorgangResponse::newBuilder, (builder, header) -> builder.addVorgang(header), + .collect(GrpcFindVorgangResponse::newBuilder, GrpcFindVorgangResponse.Builder::addVorgang, (builder1, builder2) -> builder1.addAllVorgang(builder2.getVorgangList())); return replyBuilder.setTotal(page.getTotalElements()).build(); diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFile.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFile.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFile.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFile.java index 1336b16..6d10523 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFile.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFile.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import de.itvsh.ozg.pluto.files.FileId; +import de.ozgcloud.vorgang.files.FileId; import lombok.Builder; import lombok.Getter; import lombok.ToString; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroup.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroup.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroup.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroup.java index e5aec0c..5d6da95 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroup.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.List; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapper.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapper.java index 32d8a63..2ecad62 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.Mapper; import org.mapstruct.Mapping; + @Mapper(uses = IncomingFileMapper.class) interface IncomingFileGroupMapper { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapper.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapper.java index 45da1de..e176fa9 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.Mapper; import com.google.protobuf.ByteString; -import de.itvsh.ozg.pluto.files.FileIdMapper; +import de.ozgcloud.vorgang.files.FileIdMapper; @Mapper(uses = FileIdMapper.class) public interface IncomingFileMapper { diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/LabelProcessor.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/LabelProcessor.java new file mode 100644 index 0000000..28e9d52 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/LabelProcessor.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static java.util.stream.Collectors.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.stereotype.Component; + +import lombok.NonNull; + +@Component +class LabelProcessor { + + static final String CONTROL_DATA_KEY = "_kopControlData"; + + static final String LABELS_KEY = "labels"; + static final String META_DATA = "metaData"; + + public static final String VALUE_KEY = "value"; + public static final String LABEL_KEY = "label"; + + private static final Predicate<Entry<String, Object>> IS_NOT_CONTROL_DATA = entry -> !StringUtils.equals(entry.getKey(), CONTROL_DATA_KEY); + + public Eingang moveLabelsToControlData(Eingang eingang) { + var mappedFormData = moveLabelsToControlData(eingang.getFormData()); + return eingang.toBuilder().formData(mappedFormData).build(); + } + + Map<String, Object> moveLabelsToControlData(Map<String, Object> formData) { + Map<String, Object> formDataWithoutLables = formData.entrySet().stream() + .filter(IS_NOT_CONTROL_DATA) + .map(entry -> Pair.of(entry.getKey(), entry.getValue())) + .map(this::removeLabels) + .map(this::doRecursionIfSubForm) + .collect(toMap(Pair::getKey, Pair::getValue, this::merge, LinkedHashMap::new)); + + return replaceControlData(formDataWithoutLables, addLabelsToControlData(formData)); + } + + private Pair<String, Object> removeLabels(Pair<String, Object> formEntry) { + return Pair.of(formEntry.getKey(), getValueWithoutLabel(formEntry.getValue())); + } + + Map<String, Object> addLabelsToControlData(Map<String, Object> formData) { + var controlData = new HashMap<>(getControlData(formData)); + var labels = getLabelsFromFormData(formData); + if (MapUtils.isNotEmpty(labels)) { + controlData.put(LABELS_KEY, labels); + } + + return controlData; + } + + Map<String, Object> replaceControlData(Map<String, Object> formData, Map<String, Object> controlData) { + if (controlData.isEmpty()) { + return formData; + } + + var editableFormData = new LinkedHashMap<String, Object>(formData); + editableFormData.put(CONTROL_DATA_KEY, Collections.unmodifiableMap(controlData)); + + return Collections.unmodifiableMap(editableFormData); + } + + Pair<String, Object> doRecursionIfSubForm(Pair<String, Object> formEntry) { + if (isSubFormValue(formEntry.getValue())) { + return Pair.of(formEntry.getKey(), moveLabelsToControlData(castToSubFormMap(formEntry.getValue()))); + } + return formEntry; + } + + Map<String, String> getLabelsFromFormData(Map<String, Object> formData) { + return formData.entrySet().stream() + .filter(IS_NOT_CONTROL_DATA) + .map(entry -> Pair.of(entry.getKey(), getLabelFromFieldValue(entry.getValue()))) + .filter(optPair -> optPair.getValue().isPresent()) + .collect(toMap(Pair::getKey, pair -> pair.getValue().get())); + } + + Optional<String> getLabelFromFieldValue(Object value) { + if (isMap(value)) { + return Optional.ofNullable((String) castToSubFormMap(value).get(LABEL_KEY)); + } + return Optional.empty(); + } + + Object getValueWithoutLabel(Object value) { + if (isMap(value)) { + return castToSubFormMap(value).getOrDefault(VALUE_KEY, value); + } + return value; + } + + public Eingang addLabels(Eingang eingang) { + var mappedFormData = addLabels(eingang.getFormData()); + return eingang.toBuilder().formData(mappedFormData).build(); + } + + Map<String, Object> addLabels(Map<String, Object> originFormData) { + return originFormData.entrySet().stream().filter(IS_NOT_CONTROL_DATA) + .map(entry -> Pair.of(entry.getKey(), addLabel(entry.getKey(), entry.getValue(), getLabels(originFormData)))) + .collect(toMap(Pair::getKey, Pair::getValue, this::merge, LinkedHashMap::new)); + } + + private Object merge(Object m1, Object m2) { + throw new IllegalStateException("Collision in mapping function."); + } + + @SuppressWarnings("unchecked") + private Map<String, String> getLabels(@NonNull Map<String, Object> formData) { + return (Map<String, String>) getControlData(formData).getOrDefault(LABELS_KEY, Collections.emptyMap()); + } + + private Map<String, Object> getControlData(@NonNull Map<String, Object> formData) { + return castToSubFormMap(formData.getOrDefault(CONTROL_DATA_KEY, Collections.emptyMap())); + } + + Map<String, Object> addLabel(String fieldName, Object fieldValue, Map<String, String> labels) { + if (isFieldValue(fieldValue)) { + return addLabelToFieldValue(fieldName, fieldValue, labels); + } else { + return addLabelsToSubForm(castToSubFormMap(fieldValue), Optional.ofNullable(labels.get(fieldName))); + } + } + + Map<String, Object> addLabelToFieldValue(String fieldName, Object fieldValue, Map<String, String> labels) { + if (labels.containsKey(fieldName)) { + return Map.of( + LABEL_KEY, labels.get(fieldName), + VALUE_KEY, fieldValue); + } else { + return Map.of(VALUE_KEY, fieldValue); + } + } + + Map<String, Object> addLabelsToSubForm(Map<String, Object> subForm, Optional<String> subFormLabel) { + Map<String, Object> subFormMap = new LinkedHashMap<>(); + subFormLabel.ifPresent(label -> subFormMap.put(LABEL_KEY, label)); + + subFormMap.put(VALUE_KEY, addLabels(subForm)); + return Collections.unmodifiableMap(subFormMap); + } + + boolean isFieldValue(Object value) { + if (isNotMap(value)) { + return true; + } + + var valueMap = castToSubFormMap(value); + if (!valueMap.containsKey(LABEL_KEY)) { + return false; + } + + return isNotMap(valueMap.get(VALUE_KEY)); + } + + boolean isSubFormValue(Object value) { + return !isFieldValue(value); + } + + private boolean isMap(Object object) { + return object instanceof Map<?, ?>; + } + + Object getFieldValue(Object fieldValue) { + if (isNotMap(fieldValue) || !castToSubFormMap(fieldValue).containsKey(LABEL_KEY)) { + return fieldValue; + } + + return castToSubFormMap(fieldValue).get(VALUE_KEY); + } + + private boolean isNotMap(Object object) { + return !isMap(object); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> castToSubFormMap(Object value) { + return (Map<String, Object>) value; + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilder.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilder.java new file mode 100644 index 0000000..0f035d2 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilder.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static java.util.Objects.*; + +import java.util.ArrayList; +import java.util.Collection; + +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.stereotype.Component; + +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.vorgang.FindVorgangQuery.LogicalOperator; + +@Component +public class QueryCriteriaBuilder { + + public Criteria from(FindVorgangQuery query) { + var criterias = new ArrayList<Criteria>(); + if (nonNull(query.getNestedQuery())) { + criterias.add(from(query.getNestedQuery())); + } + addFromOperators(criterias, query.getOperators()); + return connect(query.getLogicalOperator(), criterias); + } + + void addFromOperators(Collection<Criteria> criterias, Collection<Operator> operators) { + operators.stream().map(Operator::getCriteria).forEach(criterias::add); + } + + Criteria connect(LogicalOperator logicalOperator, Collection<Criteria> criterias) { + if (criterias.isEmpty()) { + return new Criteria(); + } + if (criterias.size() == 1) { + return criterias.iterator().next(); + } + return switch (logicalOperator) { + case AND -> new Criteria().andOperator(criterias); + case OR -> new Criteria().orOperator(criterias); + }; + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/SetAktenzeichenCompletedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/SetAktenzeichenCompletedEvent.java new file mode 100644 index 0000000..42b04b2 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/SetAktenzeichenCompletedEvent.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; + +public class SetAktenzeichenCompletedEvent extends CommandExecutedEvent { + + public SetAktenzeichenCompletedEvent(Command command) { + super(command); + } +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgagnQueryExpression.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgagnQueryExpression.java new file mode 100644 index 0000000..994b926 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgagnQueryExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +public class VorgagnQueryExpression { +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Vorgang.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java similarity index 70% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Vorgang.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java index 8d12260..0506c51 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/Vorgang.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -31,8 +31,8 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.mongodb.core.mapping.Document; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMap; -import de.itvsh.ozg.pluto.vorgang.redirect.Forwarding; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.vorgang.redirect.Forwarding; import lombok.Builder; import lombok.Getter; import lombok.Singular; @@ -45,25 +45,24 @@ public class Vorgang { public static final String COLLECTION_NAME = "vorgang"; public static final String MONGODB_FIELDNAME_ID = "_id"; - static final String MONGODB_FIELDNAME_VERSION = "version"; - static final String MONGODB_FIELDNAME_STATUS = "status"; + public static final String MONGODB_FIELDNAME_VERSION = "version"; + public static final String MONGODB_FIELDNAME_STATUS = "status"; static final String MONGODB_FIELDNAME_CREATED_AT = "createdAt"; - static final String MONGODB_FIELDNAME_ASSIGNED_TO = "assignedTo"; - static final String MONGODB_FIELDNAME_IN_CREATION = "inCreation"; + public static final String MONGODB_FIELDNAME_ASSIGNED_TO = "assignedTo"; + public static final String MONGODB_FIELDNAME_IN_CREATION = "inCreation"; - static final String FIELD_EINGANGSKENNZ = "eingangs.header.requestId"; - static final String FIELD_AKTENZEICHEN = "aktenzeichen"; - static final String FIELD_ANTRAGSTELLER_VORNAME = "eingangs.antragsteller.vorname"; - static final String FIELD_ANTRAGSTELLER_NACHNAME = "eingangs.antragsteller.nachname"; - static final String FIELD_NAME = "name"; - static final String FIELD_NUMMER = "nummer"; + public static final String FIELD_EINGANGSKENNZ = "eingangs.header.requestId"; + public static final String FIELD_AKTENZEICHEN = "aktenzeichen"; + public static final String FIELD_ANTRAGSTELLER_VORNAME = "eingangs.antragsteller.vorname"; + public static final String FIELD_ANTRAGSTELLER_NACHNAME = "eingangs.antragsteller.nachname"; + public static final String FIELD_NAME = "name"; + public static final String FIELD_NUMMER = "nummer"; public static final String FIELD_ORGANISATIONSEINHEIT = "eingangs.zustaendigeStelle.organisationseinheitenId"; - static final String FIELD_WIEDERVORLAGE = "wiedervorlages"; public static final String FIELD_CLIENT_ATTRIBUTES = "clientAttributes"; public enum Status { - NEU, ANGENOMMEN, VERWORFEN, IN_BEARBEITUNG, BESCHIEDEN, ABGESCHLOSSEN, WEITERGELEITET; + NEU, ANGENOMMEN, VERWORFEN, IN_BEARBEITUNG, BESCHIEDEN, ABGESCHLOSSEN, WEITERGELEITET, ZU_LOESCHEN, DELETED; } @Id @@ -84,6 +83,8 @@ public class Vorgang { private Status status = Status.NEU; private String aktenzeichen; + private VorgangHead header; + @Singular private List<Eingang> eingangs; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAssignedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAssignedEvent.java similarity index 83% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAssignedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAssignedEvent.java index 662454e..c1c4216 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAssignedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAssignedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; import lombok.Getter; @Getter public class VorgangAssignedEvent extends CommandExecutedEvent { - private Command command; + private transient Command command; private static final long serialVersionUID = 1L; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationService.java similarity index 95% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationService.java index a3fc30a..c293f03 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Optional; diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEvent.java new file mode 100644 index 0000000..11ca2d7 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEvent.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; +import lombok.Getter; + +@Getter +public class VorgangDeletedEvent extends CommandExecutedEvent { + + protected VorgangDeletedEvent(Command command) { + super(command); + } + +} diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangEventListener.java new file mode 100644 index 0000000..d826941 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangEventListener.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import java.util.Collections; +import java.util.function.Predicate; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.status.StatusService; +import de.ozgcloud.vorgang.vorgang.redirect.VorgangForwardFailedEvent; +import de.ozgcloud.vorgang.vorgang.redirect.VorgangRedirectedEvent; +import lombok.extern.log4j.Log4j2; + +@Component +@Log4j2 +public class VorgangEventListener { + + private static final String IS_ASSIGN_COMMAND_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.VorgangEventListener).IS_ASSIGN_COMMAND.test(event.getSource())}"; + private static final String IS_LOESCHEN_COMMAND_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.VorgangEventListener).IS_LOESCHEN_COMMAND.test(event.getSource())}"; + private static final String IS_SET_AKTENZEICHEN_COMMAND_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.VorgangEventListener).IS_SET_AKTENZEICHEN_COMMAND.test(event.getSource())}"; + public static final Predicate<Command> IS_ASSIGN_COMMAND = command -> Order.ASSIGN_USER.isMeant(command.getOrder()); + public static final Predicate<Command> IS_LOESCHEN_COMMAND = command -> Order.VORGANG_LOESCHEN.isMeant(command.getOrder()); + public static final Predicate<Command> IS_SET_AKTENZEICHEN_COMMAND = command -> Order.SET_AKTENZEICHEN.isMeant(command.getOrder()); + + @Autowired + private StatusService statusService; + @Autowired + private VorgangService vorgangService; + @Autowired + private VorgangHeaderService vorgangHeaderService; + @Autowired + private FileService fileService; + @Autowired + private CommandService commandService; + + @Autowired + private ApplicationEventPublisher publisher; + + @EventListener + public void updateStatus(VorgangRedirectedEvent event) { + statusService.setStatusToWeitergeleitet(event.getSource().getVorgangId(), event.getSource().getCreatedByCommand()); + } + + @EventListener + public void updateStatus(VorgangForwardFailedEvent event) { + statusService.setStatusToInBearbeitung(event.getVorgangId(), event.getSource()); + } + + @EventListener(condition = IS_ASSIGN_COMMAND_CONDITION) + public void assignToUser(CommandCreatedEvent event) { + vorgangService.assignToUser(event.getSource()); + } + + @EventListener(condition = IS_LOESCHEN_COMMAND_CONDITION) + public void onVorgangLoeschen(CommandCreatedEvent event) { + Command command = event.getSource(); + try { + String vorgangId = command.getVorgangId(); + vorgangService.deleteVorgang(vorgangId); + fileService.deleteAllByVorgang(vorgangId); + + publishEvent(new VorgangDeletedEvent(command)); + } catch (RuntimeException e) { + LOG.error("Unexpected Error on deleting Vorgang.", e); + publisher.publishEvent(new CommandFailedEvent(command.getId(), e.getMessage())); + } + } + + @EventListener(condition = IS_SET_AKTENZEICHEN_COMMAND_CONDITION) + public void onSetAktenzeichen(CommandCreatedEvent event) { + var command = event.getSource(); + try { + updatePreviousState(command); + vorgangService.setAktenzeichen(command); + publisher.publishEvent(new SetAktenzeichenCompletedEvent(command)); + } catch (RuntimeException e) { + LOG.error("Unexpected Error setting Aktenzeichen.", e); + publisher.publishEvent(new CommandFailedEvent(command.getId(), e.getMessage())); + } + } + + void publishEvent(CommandExecutedEvent event) { + LOG.debug("Command {} executed", event.getSource()); + publisher.publishEvent(event); + } + + private void updatePreviousState(Command command) { + commandService.setPreviousState(command.getId(), + Collections.singletonMap(VorgangService.BODY_OBJECT_AKTENZEICHEN, getAktenzeichen(command.getVorgangId()))); + } + + private String getAktenzeichen(String vorgangId) { + return vorgangHeaderService.getById(vorgangId).getAktenzeichen(); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java new file mode 100644 index 0000000..f0d4c2e --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.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.vorgang.vorgang; + +import org.springframework.data.annotation.TypeAlias; + +import de.ozgcloud.vorgang.servicekonto.ServiceKonto; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +@TypeAlias("VorgangHeader") +public class VorgangHead { + + private ServiceKonto serviceKonto; + + private String organisationsEinheitId; +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeader.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeader.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeader.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeader.java index 0420a4b..4dcd971 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeader.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeader.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; import org.springframework.data.mongodb.core.mapping.Document; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMap; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; import lombok.Builder; import lombok.Getter; import lombok.ToString; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderMapper.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderMapper.java index e98b696..e4c435e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -29,7 +29,7 @@ import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeMapper; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeMapper; @Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = ClientAttributeMapper.class) diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepository.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepository.java index 160c5aa..92c37a5 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.springframework.data.mongodb.repository.MongoRepository; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImpl.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImpl.java similarity index 72% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImpl.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImpl.java index e29aec8..2c0c796 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImpl.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static de.itvsh.ozg.pluto.vorgang.Vorgang.*; +import static de.ozgcloud.vorgang.vorgang.Vorgang.*; -import java.time.LocalDate; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -48,17 +47,18 @@ import org.springframework.data.mongodb.core.aggregation.UnionWithOperation; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequest.OrderCriteria; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest.OrderCriteria; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @Log4j2 class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { - static final String DEFAULT_CLIENT = "Goofy"; - @Autowired private MongoTemplate template; + @Autowired + private QueryCriteriaBuilder queryCriteriaBuilder; @Override public Page<VorgangHeader> findAll(FindVorgangRequest request) { @@ -73,15 +73,16 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { } private List<VorgangHeader> executeRequest(FindVorgangRequest request) { - return execAggration(aggregationBuilder(buildPageable(request)) - .withSearchBy(StringUtils.trimToNull(request.getSearchBy())) - .withFilterBy(request.getFilterBy()) - .build(request.getOrderBy())); + var aggregationBuilder = aggregationBuilder(buildPageable(request)) + .withFilterBy(request.getFilterBy()); + Optional.ofNullable(request.getFindVorgangQuery()) + .ifPresentOrElse(aggregationBuilder::withQuery, () -> aggregationBuilder.withSearchBy(StringUtils.trimToNull(request.getSearchBy()))); + return execAggration(aggregationBuilder.build(request.getOrderBy())); } private boolean hasNoPermissionByOrganisationseinheitenId(FilterCriteria filterCriteria) { - return Objects.nonNull(filterCriteria)// - && filterCriteria.getOrganisationseinheitIds().isEmpty()// + return Objects.nonNull(filterCriteria) + && filterCriteria.getOrganisationseinheitIds().isEmpty() && filterCriteria.isFilterByOrganisationseinheitenId(); } @@ -105,8 +106,10 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { var organisationseinheitenIdCriteria = buildOrganisationseinheitenCriteria(filterCriteria); var assignedToCriteria = buildAssignedToCriteria(filterCriteria); var statusCriteria = buildStatusCriteria(filterCriteria); + var hasNextWiedervorlageFrist = buildHasNextWiedervorlageCriteria(filterCriteria); - return CriteriaUtil.vorgangInCreation().andOperator(organisationseinheitenIdCriteria, assignedToCriteria, statusCriteria); + return CriteriaUtil.vorgangNotInCreation().andOperator(organisationseinheitenIdCriteria, assignedToCriteria, statusCriteria, + hasNextWiedervorlageFrist); } private Criteria buildOrganisationseinheitenCriteria(FilterCriteria filterCriteria) { @@ -119,17 +122,32 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { private Criteria buildAssignedToCriteria(FilterCriteria filterCriteria) { return Optional.ofNullable(filterCriteria) + .filter(FilterCriteria::isFilterByAssignedTo) .map(FilterCriteria::getAssignedTo) - .filter(StringUtils::isNotEmpty) - .map(CriteriaUtil::vorgangIsAssignedTo) + .map(this::getAssigendToCriteria) .orElseGet(Criteria::new); } + private Criteria getAssigendToCriteria(String assignedTo) { + if (StringUtils.isNotEmpty(assignedTo)) { + return CriteriaUtil.vorgangIsAssignedTo(assignedTo); + } else { + return CriteriaUtil.vorgangIsUnassigned(); + } + } + private Criteria buildStatusCriteria(FilterCriteria filterCriteria) { return Optional.ofNullable(filterCriteria) .map(FilterCriteria::getStatus) .filter(CollectionUtils::isNotEmpty) .map(CriteriaUtil::vorgangInStatus) + .orElseGet(CriteriaUtil::isNotDeleted); + } + + private Criteria buildHasNextWiedervorlageCriteria(FilterCriteria filterCriteria) { + return Optional.ofNullable(filterCriteria) + .filter(FilterCriteria::isHasNextWiedervorlageFrist) + .map(criteria -> CriteriaUtil.nextWiedervorlageFristExists()) .orElseGet(Criteria::new); } @@ -141,6 +159,7 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { private class AggregationBuilder { private final Pageable pageRequest; private Optional<String> searchBy = Optional.empty(); + private Optional<FindVorgangQuery> findVorgangQuery = Optional.empty(); private Optional<FilterCriteria> filterCriteria = Optional.empty(); AggregationBuilder withSearchBy(String searchBy) { @@ -148,6 +167,11 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { return this; } + AggregationBuilder withQuery(FindVorgangQuery findVorgangQuery) { + this.findVorgangQuery = Optional.ofNullable(findVorgangQuery); + return this; + } + AggregationBuilder withFilterBy(FilterCriteria filterCriteria) { this.filterCriteria = Optional.ofNullable(filterCriteria); return this; @@ -159,6 +183,10 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { return buildSortedByEAPriority(); case PRIORITY: return buildSortedByPriority(); + case CREATED_AT_DESC: + return buildSortedByCreatedAtDesc(); + case NEXT_WIEDERVORLAGE_FRIST: + return buildSortedNextWiedervorlageFrist(); default: LOG.warn("Unkown order by expression '{}'. Using default order.", orderBy); return buildSortedByPriority(); @@ -176,7 +204,6 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { unionWithVorgang().pipeline(buildRemainingStatusPipeline()))); addPageableAggregations(operations); - return Aggregation.newAggregation(operations); } @@ -191,7 +218,24 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { unionWithVorgang().pipeline(buildRemainingStatusPipeline()))); addPageableAggregations(operations); + return Aggregation.newAggregation(operations); + } + + private Aggregation buildSortedByCreatedAtDesc() { + var operations = buildSearchAndFilterAggregation(); + + operations.add(Aggregation.sort(Sort.by(MONGODB_FIELDNAME_CREATED_AT).descending())); + + addPageableAggregations(operations); + return Aggregation.newAggregation(operations); + } + private Aggregation buildSortedNextWiedervorlageFrist() { + var operations = buildSearchAndFilterAggregation(); + + operations.add(Aggregation.sort(Sort.by(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).ascending())); + + addPageableAggregations(operations); return Aggregation.newAggregation(operations); } @@ -201,9 +245,7 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { private List<AggregationOperation> findAndSortExpiredWiedervorlagen() { return List.of( - Aggregation.match(Criteria.where(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY).ne(null) - .andOperator(Criteria.where(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY) - .lte(getLocalTimeAsString()))), + Aggregation.match(CriteriaUtil.nextWiedervorlageFristInThePast()), Aggregation.sort(Sort.by(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).ascending())); } @@ -211,17 +253,12 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { var operations = buildSearchAndFilterAggregation(); operations.addAll(List.of( - Aggregation.match(Criteria.where(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_KEY).ne(null) - .andOperator( - Criteria.where(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).gt(getLocalTimeAsString()))), + Aggregation + .match(CriteriaUtil.nextWiedervorlageFristInTheFuture()), Aggregation.sort(Sort.by(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST_VALUE_KEY).ascending()))); return Aggregation.newAggregation(operations).getPipeline(); } - private String getLocalTimeAsString() { - return LocalDate.now().toString(); - } - private AggregationPipeline buildZuBearbeitendePipeline() { var operations = buildSearchAndFilterAggregation(); operations.addAll(List.of( @@ -256,7 +293,7 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { var operations = buildSearchAndFilterAggregation(); operations.addAll(List.of( - Aggregation.match(Criteria.where(FIELD_WIEDERVORLAGE).exists(false)), + Aggregation.match(CriteriaUtil.withoutNextWiedervorlageFrist()), Aggregation.match(CriteriaUtil.vorgangRemainingStatus()), Aggregation.sort(Sort.by(MONGODB_FIELDNAME_CREATED_AT).descending()))); @@ -268,21 +305,22 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { operations.add(buildInCreationCriteria()); buildMatchOrganisationseinheitenId(filterCriteria).ifPresent(operations::add); - buildMatchSearchBy(searchBy).ifPresent(operations::add); + buildMatchQuery().or(this::buildMatchSearchBy).ifPresent(operations::add); buildMatchStatus(filterCriteria).ifPresent(operations::add); buildMatchAssignedTo(filterCriteria).ifPresent(operations::add); + buildHasNextWiedervorlagenFrist(filterCriteria).ifPresent(operations::add); return operations; } private void addPageableAggregations(List<AggregationOperation> aggregations) { - aggregations.add(Aggregation.project(VorgangHeader.class)); aggregations.add(Aggregation.skip(pageRequest.getOffset())); aggregations.add(Aggregation.limit(pageRequest.getPageSize())); + aggregations.add(Aggregation.project(VorgangHeader.class)); } private AggregationOperation buildInCreationCriteria() { - return Aggregation.match(CriteriaUtil.vorgangInCreation()); + return Aggregation.match(CriteriaUtil.vorgangNotInCreation()); } private Optional<AggregationOperation> buildMatchOrganisationseinheitenId(Optional<FilterCriteria> filterCriteria) { @@ -291,8 +329,12 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { .map(organisationseinheitIds -> Aggregation.match(CriteriaUtil.inOrganisationseinheitenIds(organisationseinheitIds))); } - private Optional<AggregationOperation> buildMatchSearchBy(Optional<String> searchStr) { - return searchStr.map(search -> Aggregation.match(CriteriaUtil.searchCriteria(search))); + private Optional<AggregationOperation> buildMatchQuery() { + return findVorgangQuery.map(queryCriteriaBuilder::from).map(Aggregation::match); + } + + private Optional<AggregationOperation> buildMatchSearchBy() { + return searchBy.map(search -> Aggregation.match(CriteriaUtil.searchCriteria(search))); } private Optional<AggregationOperation> buildMatchStatus(Optional<FilterCriteria> filterCriteria) { @@ -302,9 +344,14 @@ class VorgangHeaderRepositoryImpl implements CustomVorgangHeaderRepository { } private Optional<AggregationOperation> buildMatchAssignedTo(Optional<FilterCriteria> filterCriteria) { - return filterCriteria.map(FilterCriteria::getAssignedTo) - .filter(StringUtils::isNotEmpty) - .map(assignedTo -> Aggregation.match(CriteriaUtil.vorgangIsAssignedTo(assignedTo))); + return filterCriteria.filter(FilterCriteria::isFilterByAssignedTo) + .map(FilterCriteria::getAssignedTo) + .map(assignedTo -> Aggregation.match(getAssigendToCriteria(assignedTo))); + } + + private Optional<AggregationOperation> buildHasNextWiedervorlagenFrist(Optional<FilterCriteria> filterCriteria) { + return filterCriteria.filter(FilterCriteria::isHasNextWiedervorlageFrist) + .map(hasNextWiedervorlageFrist -> Aggregation.match(CriteriaUtil.nextWiedervorlageFristExists())); } } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderService.java similarity index 76% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderService.java index ee4c7c3..42740a9 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import java.util.Objects; +import static java.util.Objects.*; + +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; -import de.itvsh.ozg.pluto.common.search.SearchService; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.common.search.SearchService; @Service class VorgangHeaderService { @@ -45,7 +48,7 @@ class VorgangHeaderService { private SearchService searchService; public Page<VorgangHeader> findAll(FindVorgangRequest request) { - if (Objects.nonNull(searchService) && Objects.nonNull(request.getSearchBy())) { + if (nonNull(searchService) && nonNull(request.getSearchBy())) { return removeUnpermitted(searchService.find(request)); } return removeUnpermitted(repository.findAll(request)); @@ -64,4 +67,12 @@ class VorgangHeaderService { .clientAttributes(vorgangService.removeUnpermitted(vorgangHeader.getClientAttributes())) .build(); } + + public Optional<VorgangHeader> findById(String vorgangId) { + return repository.findById(vorgangId); + } + + public VorgangHeader getById(String vorgangId) { + return findById(vorgangId).orElseThrow(() -> new TechnicalException(vorgangId + " could not be found")); + } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java similarity index 62% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java index 27ce3bd..8fb43e1 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,23 +21,28 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static org.springframework.data.mongodb.core.query.Query.query; +import static de.ozgcloud.vorgang.common.db.CriteriaUtil.*; +import static org.springframework.data.mongodb.core.query.Query.*; import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; +import jakarta.annotation.PostConstruct; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import com.mongodb.client.result.UpdateResult; + +import de.ozgcloud.vorgang.common.db.CollisionVerifier; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; @Repository class VorgangRepository { @@ -45,6 +50,13 @@ class VorgangRepository { @Autowired private MongoOperations mongoOperations; + private CollisionVerifier collisionVerifier; + + @PostConstruct + void init() { + collisionVerifier = new CollisionVerifier(this::exists); + } + public Optional<Vorgang> findById(String vorgangId) { return Optional.ofNullable(findOne(CriteriaUtil.isId(vorgangId))); } @@ -54,31 +66,19 @@ class VorgangRepository { } private Vorgang findOne(Criteria queryObj) { - return mongoOperations.findOne(query(queryObj), Vorgang.class); + return mongoOperations.findOne(query(queryObj.andOperator(CriteriaUtil.isNotDeleted())), Vorgang.class); } public Vorgang save(Vorgang vorgang) { return mongoOperations.save(vorgang); } - public Stream<Vorgang> findAll() { - return mongoOperations.stream(Query.query(Criteria.where(Vorgang.MONGODB_FIELDNAME_IN_CREATION).is(false)), Vorgang.class).stream(); - } - - /** @deprecated use {@link #patch(String, long, Map)} */ - @Deprecated - public void updateStatus(String vorgangId, long version, Status status) { - var update = new Update() - .inc(Vorgang.MONGODB_FIELDNAME_VERSION, 1) - .set(Vorgang.MONGODB_FIELDNAME_STATUS, status); - updateFirst(whereIdAndVersion(vorgangId, version), update); + public void saveStub(VorgangStub vorgangStub) { + mongoOperations.save(vorgangStub); } - public void updateStatusWithoutVersionCheck(String vorgangId, Status status) { - var update = new Update() - .inc(Vorgang.MONGODB_FIELDNAME_VERSION, 1) - .set(Vorgang.MONGODB_FIELDNAME_STATUS, status); - updateFirst(CriteriaUtil.isId(vorgangId), update); + public Stream<Vorgang> findAll() { + return mongoOperations.stream(query(CriteriaUtil.vorgangNotInCreation().andOperator(CriteriaUtil.isNotDeleted())), Vorgang.class); } public void patch(String vorgangId, long version, Map<String, Object> patch) { @@ -88,17 +88,28 @@ class VorgangRepository { updateFirst(whereIdAndVersion(vorgangId, version), update); } - private void updateFirst(Criteria queryObj, Update update) { - mongoOperations.updateFirst(query(queryObj), update, Vorgang.class); + public void setAktenzeichen(String vorgangId, long version, String akteneinsicht) { + var updateResult = updateFirst(whereIdAndVersion(vorgangId, version), new Update().set(Vorgang.FIELD_AKTENZEICHEN, akteneinsicht)); + collisionVerifier.verify(updateResult, vorgangId); + } + + private UpdateResult updateFirst(Criteria queryObj, Update update) { + return mongoOperations.updateFirst(query(queryObj), update, Vorgang.class); } private Criteria whereIdAndVersion(String vorgangId, long version) { return CriteriaUtil.isId(vorgangId).and(Vorgang.MONGODB_FIELDNAME_VERSION).is(version); } + public boolean exists(String vorgangId) { + return mongoOperations.exists(query(isId(vorgangId)), Vorgang.class); + } + public boolean exists(String vorgangId, Collection<String> organisationEinheitenIds) { return mongoOperations.exists( - query(CriteriaUtil.isId(vorgangId).and(Vorgang.FIELD_ORGANISATIONSEINHEIT).in(organisationEinheitenIds)), + query(isId(vorgangId) + .andOperator(inOrganisationseinheitenIds(organisationEinheitenIds) + .andOperator(isNotDeleted()))), Vorgang.class); } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java similarity index 55% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java index ea9471b..6bc4085 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Collection; import java.util.List; @@ -30,25 +30,29 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Stream; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeMap; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeReadPermitted; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMap; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.PersistedCommand; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.redirect.Forwarding; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeMap; +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 lombok.NonNull; @Service public class VorgangService { + private static final String BODY_ASSIGNED_TO_FIELD = "assignedTo"; + public static final String BODY_OBJECT_AKTENZEICHEN = "aktenzeichen"; + @Autowired private VorgangAuthorizationService vorgangAuthenticationService; @Autowired @@ -62,37 +66,53 @@ public class VorgangService { @Autowired private ClientAttributeReadPermitted readIsPermitted; - /** - * @deprecated Kann nach dem Ausrollen von Version 0.23.0 entfernt werden - * @param eingang - * @return - */ - @Deprecated - public Vorgang createVorgang(Eingang eingang) { - var vorgang = repository.save(buildVorgang(eingang, false)); - - publishVorgangeCreatedEvent(vorgang); + @Autowired + private LabelProcessor kopControlDataMapper; - return vorgang; - } + @Autowired + private VorgangStubMapper stubMapper; public Vorgang startCreation(Eingang eingang) { - return repository.save(buildVorgang(eingang, true)); + var mappedEingang = kopControlDataMapper.moveLabelsToControlData(eingang); + + return repository.save(buildVorgang(mappedEingang, true)); } private Vorgang buildVorgang(Eingang eingang, boolean inCreation) { return Vorgang.builder() .name(eingang.getHeader().getFormName()) .aktenzeichen(aktenzeichenProvider.provideAktenzeichen(eingang)) - .nummer(eingang.getHeader().getRequestId()) + .nummer(getVorgangNummer(eingang.getHeader())) .formEngineName(eingang.getHeader().getFormEngineName()) .inCreation(inCreation) + .header(buildVorgangHead(eingang)) .eingang(eingang) .build(); } + String getVorgangNummer(@NonNull EingangHeader header) { + return Optional.ofNullable(header.getVorgangNummer()) + .orElseGet(header::getRequestId); + } + + private Optional<ServiceKonto> getServiceKonto(Eingang eingang) { + return Optional.ofNullable(eingang.getHeader().getServiceKonto()); + } + + private VorgangHead buildVorgangHead(Eingang eingang) { + var vorgangHeadBuilder = VorgangHead.builder(); + + getServiceKonto(eingang).ifPresent(vorgangHeadBuilder::serviceKonto); + + return vorgangHeadBuilder.build(); + } + public void finishCreation(String vorgangId, List<IncomingFileGroup> attachments, List<IncomingFile> representations) { - var vorgang = addAttachmentsAndRepresentations(getById(vorgangId), attachments, representations).inCreation(false).build(); + // TODO nicht den ganzen Vorgang laden und überschreiben sondern nur die + // notwendigen Felder anpassen (patch) + var loaded = repository.findById(vorgangId) + .orElseThrow(() -> new IllegalStateException("Cannot load vorgang for finishing creation -" + vorgangId)); + var vorgang = addAttachmentsAndRepresentations(loaded, attachments, representations).inCreation(false).build(); var savedVorgang = repository.save(vorgang); @@ -113,74 +133,6 @@ public class VorgangService { publisher.publishEvent(new VorgangCreatedEvent(vorgang.getId())); } - public Vorgang setStatusNeu(Command command) { - return executeStatusChangeCommand(command, Status.NEU); - } - - public Vorgang annehmen(Command command) { - return executeStatusChangeCommand(command, Status.ANGENOMMEN); - } - - public Vorgang verwerfen(Command command) { - return executeStatusChangeCommand(command, Status.VERWORFEN); - } - - public Vorgang bescheiden(Command command) { - return executeStatusChangeCommand(command, Status.BESCHIEDEN); - } - - public Vorgang abschliessen(Command command) { - return executeStatusChangeCommand(command, Status.ABGESCHLOSSEN); - } - - public Vorgang wiedereroeffnen(Command command) { - return bearbeiten(command); - } - - public Vorgang bearbeiten(Command command) { - return executeStatusChangeCommand(command, Status.IN_BEARBEITUNG); - } - - Vorgang executeStatusChangeCommand(Command command, Status status) { - var vorgang = doUpdateStatus(command.getRelationId(), command.getRelationVersion(), status); - - publisher.publishEvent(new StatusChangedEvent(command.getId())); - - return vorgang; - } - - public Vorgang setStatusToWeitergeleitet(Forwarding forwarding) { - return doUpdateStatusWithoutVerisonCheck(forwarding.getVorgangId(), Status.WEITERGELEITET, forwarding.getCreatedByCommand()); - } - - public Vorgang setStatusToInBearbeitung(String commandId, String vorgangId) { - return doUpdateStatusWithoutVerisonCheck(vorgangId, Status.IN_BEARBEITUNG, commandId); - } - - Vorgang doUpdateStatusWithoutVerisonCheck(String vorgangId, Status newStatus, String commandId) { - repository.updateStatusWithoutVersionCheck(vorgangId, newStatus); - - publisher.publishEvent(new StatusChangedEvent(commandId)); - - return getById(vorgangId); - } - - public Vorgang revokeStatusChange(PersistedCommand command) { - return doUpdateStatus(command.getRelationId(), command.getRelationVersion() + 1, command.getPreviousStatus()); - } - - public void setStatusToInBearbeitung(String vorgangId, long version) { - doUpdateStatus(vorgangId, version, Status.IN_BEARBEITUNG); - } - - Vorgang doUpdateStatus(String vorgangId, long version, Status status) { - Map<String, Object> patch = Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, status); - - repository.patch(vorgangId, version, patch); - - return getById(vorgangId); - } - public Vorgang getById(String vorgangId, FilterCriteria filterCriteria) { var vorgang = getById(vorgangId); @@ -196,7 +148,14 @@ public class VorgangService { } public Vorgang getById(String vorgangId) { - return removeUnpermittedClientAttributes(repository.findById(vorgangId).orElseThrow(() -> new NotFoundException(Vorgang.class, vorgangId))); + var loaded = removeUnpermittedClientAttributes(loadById(vorgangId)); + + return addLabels(loaded); + } + + public void setAktenzeichen(Command command) { + var aktenzeichen = StringUtils.trimToNull(MapUtils.getString(command.getBodyObject(), BODY_OBJECT_AKTENZEICHEN)); + repository.setAktenzeichen(command.getVorgangId(), command.getRelationVersion(), aktenzeichen); } Vorgang removeUnpermittedClientAttributes(Vorgang vorgang) { @@ -206,7 +165,8 @@ public class VorgangService { ClientAttributesMap removeUnpermitted(ClientAttributesMap attributes) { var result = new ClientAttributesMap(); - Optional.ofNullable(attributes).ifPresent(attri -> attri.entrySet().stream().map(this::removeUnpermitted) + Optional.ofNullable(attributes).ifPresent(attri -> attri.entrySet().stream() + .map(this::removeUnpermitted) .filter(pair -> !pair.getValue().isEmpty()) .forEach(pair -> result.put(pair.getKey(), pair.getValue()))); @@ -215,14 +175,15 @@ public class VorgangService { private Pair<String, ClientAttributeMap> removeUnpermitted(Entry<String, ClientAttributeMap> entry) { var resultAttributeMap = new ClientAttributeMap(); - entry.getValue().entrySet().stream().filter(e -> readIsPermitted.test(e.getValue())) + entry.getValue().entrySet().stream() + .filter(e -> readIsPermitted.test(e.getValue())) .forEach(e -> resultAttributeMap.put(e.getKey(), e.getValue())); return Pair.of(entry.getKey(), resultAttributeMap); } public void assignToUser(Command command) { - Map<String, Object> patch = Map.of(Vorgang.MONGODB_FIELDNAME_ASSIGNED_TO, command.getBody().get("assignedTo")); + var patch = Map.<String, Object>of(Vorgang.MONGODB_FIELDNAME_ASSIGNED_TO, command.getBody().get(BODY_ASSIGNED_TO_FIELD)); repository.patch(command.getRelationId(), command.getRelationVersion(), patch); @@ -236,4 +197,21 @@ public class VorgangService { public boolean exists(String vorgangId, Collection<String> organisationEinheitenIds) { return repository.exists(vorgangId, organisationEinheitenIds); } + + Vorgang addLabels(Vorgang vorgang) { + var mappedEingaenge = vorgang.getEingangs().stream().map(kopControlDataMapper::addLabels).toList(); + + return vorgang.toBuilder().clearEingangs().eingangs(mappedEingaenge).build(); + } + + public void deleteVorgang(String vorgangId) { + // TODO check version + var stub = stubMapper.fromVorgang(loadById(vorgangId)); + + repository.saveStub(stub); + } + + Vorgang loadById(String vorgangId) { + return repository.findById(vorgangId).orElseThrow(() -> new NotFoundException(Vorgang.class, vorgangId)); + } } \ 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 new file mode 100644 index 0000000..11b7490 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStub.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import java.time.ZonedDateTime; + +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.mongodb.core.mapping.Document; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +@Document(collection = Vorgang.COLLECTION_NAME) +@TypeAlias("VorgangStub") +class VorgangStub { + + @Id + private String id; + @Builder.Default + private Vorgang.Status status = Vorgang.Status.DELETED; + + private String name; + private ZonedDateTime createdAt; + @Builder.Default + private ZonedDateTime deletedAt = ZonedDateTime.now(); + + private VorgangHeadStub header; + + private EingangStub eingangs; + +} + +@Builder +@Getter +class VorgangHeadStub { + private String organisationsEinheitId; +} + +@Builder +@Getter +class EingangStub { + private ZustaendigeStelleStub zustaendigeStelle; +} + +@Builder +@Getter +class ZustaendigeStelleStub { + private String organisationseinheitenId; +} 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 new file mode 100644 index 0000000..2cff577 --- /dev/null +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapper.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +interface VorgangStubMapper { + + @Mapping(target = "deletedAt", ignore = true) + @Mapping(target = "status", constant = "DELETED") + @Mapping(target = "header", expression = "java(extractStubHeader(vorgang))") + @Mapping(target = "eingangs", expression = "java(extractStubEingang(vorgang))") + VorgangStub fromVorgang(Vorgang vorgang); + + default VorgangHeadStub extractStubHeader(Vorgang vorgang) { + var builder = VorgangHeadStub.builder(); + getOrganisationsEinheitenId(vorgang).ifPresent(builder::organisationsEinheitId); + return builder.build(); + } + + default EingangStub extractStubEingang(Vorgang vorgang) { + var builder = EingangStub.builder(); + getOrganisationsEinheitenId(vorgang) + .map(orgaId -> ZustaendigeStelleStub.builder().organisationseinheitenId(orgaId).build()) + .ifPresent(builder::zustaendigeStelle); + return builder.build(); + + } + + default Optional<String> getOrganisationsEinheitenId(Vorgang vorgang) { + try { + return Optional.ofNullable(vorgang.getEingangs().get(0).getZustaendigeStelle().getOrganisationseinheitenId()); + } catch (NullPointerException | IndexOutOfBoundsException e) { + return Optional.empty(); + } + } + +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapper.java similarity index 80% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapper.java index 55470c6..4766257 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.List; @@ -32,11 +32,12 @@ import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeMapper; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeMapper; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoMapper; -@Mapper(uses = { EingangMapper.class, ClientAttributeMapper.class }, // - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, // + uses = { EingangMapper.class, ClientAttributeMapper.class, ServiceKontoMapper.class }) public abstract class VorgangWithEingangMapper { @Autowired @@ -59,5 +60,4 @@ public abstract class VorgangWithEingangMapper { } return eingaenge.get(0); } - } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelle.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelle.java similarity index 78% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelle.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelle.java index e639dd1..159d0b6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelle.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelle.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import lombok.Builder; import lombok.Getter; @@ -35,4 +35,10 @@ public class ZustaendigeStelle { private String organisationseinheitenId; private String bezeichnung; private String email; + private String gemeindeSchluessel; + private String amtlicherRegionalSchluessel; + private String hausanschriftStrasse; + private String hausanschriftPlz; + private String hausanschriftOrt; + private String telefon; } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapper.java similarity index 93% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapper.java index 61111fc..6441899 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import org.mapstruct.Mapper; import org.mapstruct.NullValueCheckStrategy; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/Forwarding.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/Forwarding.java similarity index 94% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/Forwarding.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/Forwarding.java index 1794eff..85600ce 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/Forwarding.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/Forwarding.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import java.time.ZoneOffset; import java.time.ZonedDateTime; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListener.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListener.java similarity index 60% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListener.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListener.java index f5aa9c5..8c65352 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListener.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,28 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; +import java.util.ConcurrentModificationException; import java.util.function.Predicate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; -import de.itvsh.ozg.mail.email.MailSendErrorEvent; -import de.itvsh.ozg.mail.email.MailSendRequest; -import de.itvsh.ozg.mail.email.MailSentEvent; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; -import de.itvsh.ozg.pluto.command.Order; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.nachrichten.email.MailSendErrorEvent; +import de.ozgcloud.nachrichten.email.MailSendRequest; +import de.ozgcloud.nachrichten.email.MailSentEvent; +import de.ozgcloud.vorgang.command.Order; +import lombok.extern.log4j.Log4j2; @Component +@Log4j2 public class ForwardingEventListener { - private static final String IS_REDIRECT_EVENT_CONDITION = "{T(de.itvsh.ozg.pluto.vorgang.redirect.ForwardingEventListener).IS_REDIRECT_MAIL_REQ.test(event.getSource())}"; - private static final String IS_SUCCESSFULL_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.vorgang.redirect.ForwardingEventListener).IS_SUCCESSFULL_ORDER.test(event.getSource())}"; - private static final String IS_FAILED_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.vorgang.redirect.ForwardingEventListener).IS_FAILED_ORDER.test(event.getSource())}"; - private static final String IS_FORWARD_ORDER_CONDITION = "{T(de.itvsh.ozg.pluto.vorgang.redirect.ForwardingEventListener).IS_FORWARD_ORDER.test(event.getSource())}"; + private static final String IS_REDIRECT_EVENT_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.redirect.ForwardingEventListener).IS_REDIRECT_MAIL_REQ.test(event.getSource())}"; + private static final String IS_SUCCESSFULL_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.redirect.ForwardingEventListener).IS_SUCCESSFULL_ORDER.test(event.getSource())}"; + private static final String IS_FAILED_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.redirect.ForwardingEventListener).IS_FAILED_ORDER.test(event.getSource())}"; + private static final String IS_FORWARD_ORDER_CONDITION = "{T(de.ozgcloud.vorgang.vorgang.redirect.ForwardingEventListener).IS_FORWARD_ORDER.test(event.getSource())}"; public static final Predicate<MailSendRequest> IS_REDIRECT_MAIL_REQ = req -> req.getRequestReference() instanceof Forwarding; public static final Predicate<Command> IS_SUCCESSFULL_ORDER = command -> Order.FORWARD_SUCCESSFULL.isMeant(command.getOrder()); @@ -52,9 +57,12 @@ public class ForwardingEventListener { @Autowired private ForwardingService service; + @Autowired + private ApplicationEventPublisher publisher; + @EventListener(condition = IS_FORWARD_ORDER_CONDITION) public void onForwardOrder(CommandCreatedEvent event) { - service.forwardByCommand(event.getSource()); + handleException(() -> service.forwardByCommand(event.getSource()), event.getSource().getId()); } @EventListener(condition = IS_REDIRECT_EVENT_CONDITION) @@ -73,11 +81,27 @@ public class ForwardingEventListener { @EventListener(condition = IS_SUCCESSFULL_ORDER_CONDITION) public void markAsSuccessfull(CommandCreatedEvent event) { - service.markAsSuccessfull(event.getSource()); + handleException(() -> service.markAsSuccessfull(event.getSource()), event.getSource().getId()); } @EventListener(condition = IS_FAILED_ORDER_CONDITION) public void markAsFailed(CommandCreatedEvent event) { service.markAsFailed(event.getSource()); } + + private void handleException(Runnable runnable, String commandId) { + try { + runnable.run(); + } catch (ConcurrentModificationException e) { + LOG.warn("Concurrent modification in executing Forwarding."); + publishFailedEvent(commandId, "Concurrent modification in executing Forwarding."); + } catch (RuntimeException e) { + LOG.error("Command failed with Exception", e); + publishFailedEvent(commandId, "Command Failed on Error"); + } + } + + private void publishFailedEvent(String commandId, String message) { + publisher.publishEvent(new CommandFailedEvent(commandId, message)); + } } \ No newline at end of file diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcService.java similarity index 83% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcService.java index 91de06e..0601c55 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.ozg.pluto.forwarding.ForwardingServiceGrpc.ForwardingServiceImplBase; -import de.itvsh.ozg.pluto.forwarding.GrpcFindForwardingsRequest; -import de.itvsh.ozg.pluto.forwarding.GrpcForwardingsResponse; +import de.ozgcloud.vorgang.forwarding.ForwardingServiceGrpc.ForwardingServiceImplBase; +import de.ozgcloud.vorgang.forwarding.GrpcFindForwardingsRequest; +import de.ozgcloud.vorgang.forwarding.GrpcForwardingsResponse; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingMapper.java similarity index 88% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingMapper.java index 1b0033d..5764a4c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import org.mapstruct.Mapper; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import de.itvsh.ozg.pluto.forwarding.GrpcForwarding; +import de.ozgcloud.vorgang.forwarding.GrpcForwarding; @Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, // nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepository.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepository.java similarity index 95% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepository.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepository.java index 1eca4f0..54b9a9d 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepository.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; @@ -39,7 +39,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; -import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang; @Repository class ForwardingRepository { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingService.java similarity index 86% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingService.java index 1e73824..bafd560 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import java.io.IOException; import java.io.StringWriter; @@ -32,9 +32,6 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Stream; -import javax.mail.util.ByteArrayDataSource; - -import de.itvsh.ozg.mail.email.MailRecipient; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -44,20 +41,25 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.util.MimeTypeUtils; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.mail.email.MailSendRequest; -import de.itvsh.ozg.mail.email.MailSendRequest.MailAttachment; -import de.itvsh.ozg.mail.email.MailService; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.PersistedCommand; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.redirect.Forwarding.Status; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.email.MailRecipient; +import de.ozgcloud.nachrichten.email.MailSendRequest; +import de.ozgcloud.nachrichten.email.MailSendRequest.MailAttachment; +import de.ozgcloud.nachrichten.email.MailService; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.status.StatusService; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.redirect.Forwarding.Status; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; +import jakarta.mail.util.ByteArrayDataSource; +import lombok.extern.log4j.Log4j2; @Service +@Log4j2 public class ForwardingService { static final String MAIL_TEMPLATE = "/mail/redirect.txt.ftlh"; @@ -99,26 +101,37 @@ public class ForwardingService { @Autowired private VorgangService vorgangService; + // TODO abhängigkeit entfernen + @Autowired + private StatusService statusService; + @Autowired private ApplicationEventPublisher publisher; - @Value("${pluto.redirect.mail-from}") + @Value("${ozgcloud.redirect.mail-from}") private String mailFrom; - @Value("${pluto.forwarding.reply-to:#{null}}") + @Value("${ozgcloud.forwarding.reply-to:#{null}}") private Optional<String> replyTo; - @Value("${kop.production}") + @Value("${ozgcloud.production}") private boolean production; public Vorgang forwardByCommand(Command command) { - // TODO verify vorgang version _befor_ doing forward var vorgang = vorgangService.getById(command.getRelationId()); - redirectVorgang(vorgang, command); - - vorgangService.setStatusToInBearbeitung(command.getRelationId(), command.getRelationVersion()); + if (vorgang.getVersion() == command.getRelationVersion()) { + doRedirect(command, vorgang); + } else { + LOG.warn("concurrend modification on forwarding Vorgang"); + markAsFailed(command); + } return vorgang; } + void doRedirect(Command command, Vorgang vorgang) { + statusService.setStatusToInBearbeitung(command.getRelationId(), command.getRelationVersion()); + redirectVorgang(vorgang, command); + } + void redirectVorgang(Vorgang vorgang, Command command) { var forwarding = saveForwarding(command); @@ -189,7 +202,7 @@ public class ForwardingService { private void setForwardingSent(Forwarding forwarding) { repository.patch(forwarding.getId(), - Map.of(Forwarding.FIELD_STATUS, Forwarding.Status.SENT, Forwarding.FIELD_SENT_AT, ZonedDateTime.now(ZoneOffset.UTC))); + Map.of(Forwarding.FIELD_STATUS, Status.SENT, Forwarding.FIELD_SENT_AT, ZonedDateTime.now(ZoneOffset.UTC))); } public void sendRedirectConfirmationMail(Forwarding forwarding) { @@ -227,7 +240,7 @@ public class ForwardingService { } private void setForwardingSendError(Forwarding forwarding, String errorMessage) { - repository.patch(forwarding.getId(), Map.of(Forwarding.FIELD_STATUS, Forwarding.Status.SEND_ERROR, Forwarding.FIELD_ERROR_MSG, errorMessage)); + repository.patch(forwarding.getId(), Map.of(Forwarding.FIELD_STATUS, Status.SEND_ERROR, Forwarding.FIELD_ERROR_MSG, errorMessage)); } MailSendRequest.MailSendRequestBuilder createRedirectMailRequestBuilder() { @@ -302,13 +315,13 @@ public class ForwardingService { } public void markAsSuccessfull(Command command) { - repository.patch(command.getRelationId(), Map.of(Forwarding.FIELD_STATUS, Forwarding.Status.SUCCESSFULL)); + repository.patch(command.getRelationId(), Map.of(Forwarding.FIELD_STATUS, Status.SUCCESSFULL)); publisher.publishEvent(new VorgangForwardSuccessfullEvent(command)); } public void markAsFailed(Command command) { - repository.patch(command.getRelationId(), Map.of(Forwarding.FIELD_STATUS, Forwarding.Status.FAILED)); + repository.patch(command.getRelationId(), Map.of(Forwarding.FIELD_STATUS, Status.FAILED)); publisher.publishEvent(new VorgangForwardFailedEvent(command)); } diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequest.java similarity index 92% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequest.java index 78ba579..bb6c38c 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import lombok.AccessLevel; import lombok.AllArgsConstructor; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestMapper.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestMapper.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestMapper.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestMapper.java index e791933..19b702e 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestMapper.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import org.mapstruct.Mapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcRedirectRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcRedirectRequest; @Mapper public interface RedirectRequestMapper { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEvent.java similarity index 85% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEvent.java index 26491e2..31681fa 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; import lombok.Getter; public class VorgangForwardFailedEvent extends CommandExecutedEvent { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardSuccessfullEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardSuccessfullEvent.java similarity index 84% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardSuccessfullEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardSuccessfullEvent.java index a51dcc0..3734840 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardSuccessfullEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardSuccessfullEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandExecutedEvent; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; public class VorgangForwardSuccessfullEvent extends CommandExecutedEvent { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectFailedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectFailedEvent.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectFailedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectFailedEvent.java index 2cfeff7..e705276 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectFailedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; -import de.itvsh.ozg.pluto.command.CommandFailedEvent; +import de.ozgcloud.command.CommandFailedEvent; public class VorgangRedirectFailedEvent extends CommandFailedEvent { diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEvent.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEvent.java similarity index 91% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEvent.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEvent.java index c307ddf..32c0ab6 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEvent.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import org.springframework.context.ApplicationEvent; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderService.java similarity index 87% rename from pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderService.java rename to vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderService.java index 5d022ee..296a883 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderService.java +++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -32,12 +32,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.MimeTypeUtils; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.pluto.files.FileService; -import de.itvsh.ozg.pluto.vorgang.Eingang; -import de.itvsh.ozg.pluto.vorgang.IncomingFile; -import de.itvsh.ozg.pluto.vorgang.IncomingFileGroup; -import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.vorgang.Eingang; +import de.ozgcloud.vorgang.vorgang.IncomingFile; +import de.ozgcloud.vorgang.vorgang.IncomingFileGroup; +import de.ozgcloud.vorgang.vorgang.Vorgang; import net.lingala.zip4j.io.outputstream.ZipOutputStream; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.AesKeyStrength; @@ -101,7 +101,7 @@ class ZipBuilderService { } private String folderByContentType(String contentType) { - return StringUtils.equals(contentType, MimeTypeUtils.APPLICATION_XML_VALUE) ? FOLDER_NAME_XML : "/"; + return StringUtils.equals(contentType, MimeTypeUtils.APPLICATION_XML_VALUE) ? FOLDER_NAME_XML : ""; } private void addAttachments() { @@ -113,7 +113,7 @@ class ZipBuilderService { } void addFile(String folder, IncomingFile file) { - var fileName = String.format(FILE_NAME_TEMPLATE, folder, file.getName()); + var fileName = StringUtils.isEmpty(folder) ? file.getName() : String.format(FILE_NAME_TEMPLATE, folder, file.getName()); try { zipOut.putNextEntry(buildZipParameter(fileName)); diff --git a/pluto-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/vorgang-manager-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 65% rename from pluto-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to vorgang-manager-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 8eff43e..b56b784 100644 --- a/pluto-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/vorgang-manager-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,37 +1,37 @@ {"properties": [ { - "name": "pluto.redirect.mail-from", + "name": "ozgcloud.redirect.mail-from", "type": "java.lang.String", "description": "Mail address for forwarding" }, { - "name": "pluto.production", + "name": "ozgcloud.production", "type": "java.lang.String", "description": "Enables/Disables the production mode. (default: false)" }, { - "name": "pluto.forwarding.lninfo.url", + "name": "ozgcloud.forwarding.lninfo.url", "type": "java.lang.String", "description": "Source of landesnetzinfo given as url(http://) or filepath(classpath:)" }, { - "name": "pluto.forwarding.reply-to", + "name": "ozgcloud.forwarding.reply-to", "type": "java.lang.String", "description": "Mail replyTo address for forwarding" }, { - "name": "kop.production", + "name": "ozgcloud.osi.postfach.scheduler.enabled", "type": "java.lang.String", - "description": "Enable production mode" + "description": "Enable or disable polling of osi postfach for new messages" }, { - "name": "kop.osi.postfach.scheduler.enabled", + "name": "ozgcloud.user-manager.url", "type": "java.lang.String", - "description": "Enable or disable polling of osi postfach for new messages" + "description": "Url of the user manager migration endpoint" }, { - "name": "kop.usermanager.url", + "name": "ozgcloud.notification.mail-from", "type": "java.lang.String", - "description": "Url of the user manager migration endpoint" + "description": "The sender email address used in notification emails" } ]} \ No newline at end of file diff --git a/pluto-server/src/main/resources/META-INF/mime.types b/vorgang-manager-server/src/main/resources/META-INF/mime.types similarity index 100% rename from pluto-server/src/main/resources/META-INF/mime.types rename to vorgang-manager-server/src/main/resources/META-INF/mime.types diff --git a/vorgang-manager-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/vorgang-manager-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..08abec6 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,20 @@ +net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration +net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration +net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcHealthServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration +net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration diff --git a/vorgang-manager-server/src/main/resources/application-a12proc.yml b/vorgang-manager-server/src/main/resources/application-a12proc.yml new file mode 100644 index 0000000..ad31c61 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-a12proc.yml @@ -0,0 +1,23 @@ +ozgcloud: + processors: + - address: https://a12-client-a12presales-ozg-poc.mgm-demo.com/api/v1/ozg/process-request + name: mgm-demo + forms: + - formId: mob_dtickerst/mob_dtickerst + formEngineName: AFM + +--- + +spring: + config: + activate: + on-profile: + - nf + +ozgcloud: + processors: + - address: http://a12-data-services:8080/api/v1/ozg/process-request + name: ticketCheck + forms: + - formId: mob_dtickerst/mob_dtickerst + formEngineName: AFM \ No newline at end of file diff --git a/vorgang-manager-server/src/main/resources/application-bayern.yml b/vorgang-manager-server/src/main/resources/application-bayern.yml new file mode 100644 index 0000000..5a5b1a1 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-bayern.yml @@ -0,0 +1,29 @@ +spring: + config: + activate: + on-profile: + - dev +ozgcloud: + antragsraum: + url: dev.antragsraum.de + +--- +spring: + config: + activate: + on-profile: + - test +ozgcloud: + antragsraum: + url: test.antragsraum.de + +--- +spring: + config: + activate: + on-profile: + - prod +ozgcloud: + antragsraum: + url: www.antragsraum.de + diff --git a/vorgang-manager-server/src/main/resources/application-dev.yml b/vorgang-manager-server/src/main/resources/application-dev.yml new file mode 100644 index 0000000..1deba0a --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-dev.yml @@ -0,0 +1,9 @@ + +ozgcloud: + redirect: + mail-from: dev-environment@ozg-cloud.de + notification: + mail-from: dev-environment@ozg-cloud.de + user: + cleanup: + cron: 0 */10 * * * * diff --git a/vorgang-manager-server/src/main/resources/application-e2e.yml b/vorgang-manager-server/src/main/resources/application-e2e.yml new file mode 100644 index 0000000..78afbf9 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-e2e.yml @@ -0,0 +1,14 @@ +mongock: + enabled: false + +ozgcloud: + osi: + postfach: + scheduler: + enabled: false + proxyapi: + url: mockedForE2E + key: mockedForE2E + realm: mockedForE2E + elasticsearch: + index: e2e-test-index \ No newline at end of file diff --git a/vorgang-manager-server/src/main/resources/application-local.yml b/vorgang-manager-server/src/main/resources/application-local.yml new file mode 100644 index 0000000..4b2b1a5 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-local.yml @@ -0,0 +1,124 @@ +logging: + level: + root: WARN, + '[de.ozgcloud]': DEBUG + '[org.elasticsearch.client]': WARN + '[io.grpc]': WARN + config: classpath:log4j2-local.xml + +server: + port: 8085 + +management: + server.port: 8083 + health: + elasticsearch: + enabled: false + endpoint: + health: + show-details: always + +grpc: + client: + user-manager: + address: static://127.0.0.1:9000 + negotiationType: PLAINTEXT + zufi-manager: + address: static://127.0.0.1:9190 + negotiationType: PLAINTEXT + +spring: + data: + mongodb: + database: vorgang-manager-local + mail: + username: ea@ozg-sh.de + password: + host: mail.bruns.com.de + port: 587 + properties: + '[mail.smtp.starttls.enable]': true + +ozgcloud: + aktenzeichen: de.ozgcloud.vorgang.vorgang.AktenzeichenProviderEA + notification: + mail-from: ea@ozg-sh.de + redirect: + mail-from: ea@ozg-sh.de + user-manager: + url: http://localhost:9092/migration/user + bescheid: + smart-documents: + url: https://demo-de.smartdocuments.com/wsxmldeposit/deposit/unattended + basicAuth: + username: + password: + templateGroup: Kiel + template: Halteverbot +# proxy: +# host: http://localhost +# port: 8080 +# username: theo +# password: + user: + cleanup: + cron: 0 */5 * * * * + elasticsearch: + initEnabled: true + index: test-index + + +mongock: + transactionEnabled: false + +--- + +spring: + config: + activate: + on-profile: + - with-elastic +ozgcloud: + elasticsearch: + address: localhost:9200 + username: elastic + password: + useSsl: false + +--- + +spring: + config: + activate: + on-profile: osi + +ozgcloud: + osi: + postfach: + scheduler: + enabled: false + fixedDelay: 10000 + proxyapi: + url: https://postfach.serviceportal-stage.schleswig-holstein.de/ApiProxy/V1/Message + key: db03d369-438a-4c1a-bcb8-9de951f5ef41 + realm: urn:osp:names:realm:stage:sh + +--- + +spring: + config: + activate: + on-profile: bayern-id +ozgcloud: + osi: + bayernid: + enabled: true + absender: + name: Test Name + mandant: Fürth + dienst: Stadtverwaltung +grpc: + client: + bayern-id: + address: static://127.0.0.1:9099 + negotiationType: PLAINTEXT diff --git a/pluto-server/src/main/resources/application-oc.yml b/vorgang-manager-server/src/main/resources/application-oc.yml similarity index 100% rename from pluto-server/src/main/resources/application-oc.yml rename to vorgang-manager-server/src/main/resources/application-oc.yml diff --git a/vorgang-manager-server/src/main/resources/application-prod.yml b/vorgang-manager-server/src/main/resources/application-prod.yml new file mode 100644 index 0000000..3b582a1 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-prod.yml @@ -0,0 +1,3 @@ + +ozgcloud: + production: true \ No newline at end of file diff --git a/pluto-server/src/main/resources/application-stage.yml b/vorgang-manager-server/src/main/resources/application-stage.yml similarity index 55% rename from pluto-server/src/main/resources/application-stage.yml rename to vorgang-manager-server/src/main/resources/application-stage.yml index 73d4bd4..daeb1b5 100644 --- a/pluto-server/src/main/resources/application-stage.yml +++ b/vorgang-manager-server/src/main/resources/application-stage.yml @@ -1,3 +1,4 @@ spring: mail: + host: 10.61.127.74 port: 25 diff --git a/vorgang-manager-server/src/main/resources/application-test.yml b/vorgang-manager-server/src/main/resources/application-test.yml new file mode 100644 index 0000000..ea66e7a --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-test.yml @@ -0,0 +1,7 @@ + + +ozgcloud: + redirect: + mail-from: test-environment@ozg-cloud.de + notification: + mail-from: test-environment@ozg-cloud.de \ No newline at end of file diff --git a/vorgang-manager-server/src/main/resources/application-withdevdb.yml b/vorgang-manager-server/src/main/resources/application-withdevdb.yml new file mode 100644 index 0000000..6004167 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/application-withdevdb.yml @@ -0,0 +1,5 @@ +spring: + data: + mongodb: + database: vorgang-manager-database + uri: mongodb://vorgang-manager-user:XnHhfznNWg65NNd@192.168.101.199:30225/admin?ssl=false \ No newline at end of file diff --git a/pluto-server/src/main/resources/application.yml b/vorgang-manager-server/src/main/resources/application.yml similarity index 53% rename from pluto-server/src/main/resources/application.yml rename to vorgang-manager-server/src/main/resources/application.yml index 3864230..a00f11e 100644 --- a/pluto-server/src/main/resources/application.yml +++ b/vorgang-manager-server/src/main/resources/application.yml @@ -1,38 +1,41 @@ logging: level: ROOT: WARN - '[de.itvsh]': INFO + '[de.ozgcloud]': INFO mongock: runner-type: initializingbean migration-scan-package: - - de.itvsh.ozg.pluto.common.migration + - de.ozgcloud.vorgang.common.migration enabled: true transactionEnabled: false spring: application: - name: Pluto + name: OzgCloud_VorgangManager data: mongodb: authentication-database: admin freemarker: cache: true - grpc: client: pluto: address: self:self negotiationType: PLAINTEXT + vorgang-manager: + address: self:self + negotiationType: PLAINTEXT user-manager: - address: static://127.0.0.1:9000 - negotiationType: PLAINTEXT + negotiationType: TLS email: address: self:self - negotiationType: PLAINTEXT -pluto: - redirect: - mail-from: EA-Poststelle@itvsh.de + negotiationType: PLAINTEXT + nachrichten-manager: + address: self:self + negotiationType: PLAINTEXT + info-manager: + negotiationType: TLS management: server: @@ -57,11 +60,25 @@ management: exposure: include: health,prometheus -kop: +ozgcloud: production: false osi: postfach: scheduler: enabled: true + redirect: + mail-from: EA-Poststelle@itvsh.de notification: - mail-from: hilfe@kop.support + mail-from: hilfe@ozgcloud.support +# vorgang-manager: +# address: self:self +# negotiation-type: plaintext +# file-manager: +# address: ${ozgcloud.vorgang-manager.address} +# negotiation-type: plaintext + command-manager: + address: self:self + negotiation-type: plaintext + user-manager: + address: ${grpc.client.user-manager.address:false} + negotiation-type: ${grpc.client.user-manager.negotiationType} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/resources/banner.txt b/vorgang-manager-server/src/main/resources/banner.txt new file mode 100644 index 0000000..8f04f0a --- /dev/null +++ b/vorgang-manager-server/src/main/resources/banner.txt @@ -0,0 +1,7 @@ + __ ______ _____ _____ _ _ _____ __ __ _ _ _____ ______ _____ + \ \ / / __ \| __ \ / ____| /\ | \ | |/ ____| | \/ | /\ | \ | | /\ / ____| ____| __ \ + \ \ / / | | | |__) | | __ / \ | \| | | __ ______| \ / | / \ | \| | / \ | | __| |__ | |__) | + \ \/ /| | | | _ /| | |_ | / /\ \ | . ` | | |_ |______| |\/| | / /\ \ | . ` | / /\ \| | |_ | __| | _ / + \ / | |__| | | \ \| |__| |/ ____ \| |\ | |__| | | | | |/ ____ \| |\ |/ ____ \ |__| | |____| | \ \ + \/ \____/|_| \_\\_____/_/ \_\_| \_|\_____| |_| |_/_/ \_\_| \_/_/ \_\_____|______|_| \_\ +${spring-boot.version} ${application.version} \ No newline at end of file diff --git a/vorgang-manager-server/src/main/resources/elastic/settings.json b/vorgang-manager-server/src/main/resources/elastic/settings.json new file mode 100644 index 0000000..0fdf5ea --- /dev/null +++ b/vorgang-manager-server/src/main/resources/elastic/settings.json @@ -0,0 +1,10 @@ +{ + "analysis": { + "normalizer": { + "lowercase_normalizer": { + "type": "custom", + "filter": [ "lowercase" ] + } + } + } +} \ No newline at end of file diff --git a/pluto-server/src/main/resources/images/logo-ea-sh.png b/vorgang-manager-server/src/main/resources/images/logo-ea-sh.png similarity index 100% rename from pluto-server/src/main/resources/images/logo-ea-sh.png rename to vorgang-manager-server/src/main/resources/images/logo-ea-sh.png diff --git a/pluto-server/src/main/resources/images/logo-itvsh.png b/vorgang-manager-server/src/main/resources/images/logo-itvsh.png similarity index 100% rename from pluto-server/src/main/resources/images/logo-itvsh.png rename to vorgang-manager-server/src/main/resources/images/logo-itvsh.png diff --git a/vorgang-manager-server/src/main/resources/log4j2-local.xml b/vorgang-manager-server/src/main/resources/log4j2-local.xml new file mode 100644 index 0000000..c2dccf3 --- /dev/null +++ b/vorgang-manager-server/src/main/resources/log4j2-local.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<configuration> + <Appenders> + <Console name="CONSOLE" target="SYSTEM_OUT"> + <PatternLayout pattern="[%-5level] %c{1.} %msg%n"/> + </Console> + </Appenders> + + <Loggers> + <Root level="WARN"> + <appender-ref ref="CONSOLE" /> + </Root> + </Loggers> +</configuration> \ No newline at end of file diff --git a/pluto-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh b/vorgang-manager-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh similarity index 97% rename from pluto-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh rename to vorgang-manager-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh index ad1f80e..0199a03 100644 --- a/pluto-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh +++ b/vorgang-manager-server/src/main/resources/templates/mail/redirect.confirmation.txt.ftlh @@ -1,6 +1,6 @@ <#-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 diff --git a/pluto-server/src/main/resources/templates/mail/redirect.txt.ftlh b/vorgang-manager-server/src/main/resources/templates/mail/redirect.txt.ftlh similarity index 97% rename from pluto-server/src/main/resources/templates/mail/redirect.txt.ftlh rename to vorgang-manager-server/src/main/resources/templates/mail/redirect.txt.ftlh index 5ddfc93..36e6735 100644 --- a/pluto-server/src/main/resources/templates/mail/redirect.txt.ftlh +++ b/vorgang-manager-server/src/main/resources/templates/mail/redirect.txt.ftlh @@ -1,6 +1,6 @@ <#-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 diff --git a/pluto-server/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeITCase.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeITCase.java index 840a741..1051820 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/mail/attributes/ClientAttributeITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/attributes/ClientAttributeITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.attributes; +package de.ozgcloud.nachrichten.attributes; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -38,11 +38,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.mail.common.grpc.NachrichtenCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.PlutoServerApplication; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.nachrichten.common.grpc.NachrichtenCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.grpc.ServerCall; @@ -52,7 +52,7 @@ import io.grpc.ServerInterceptor; import lombok.Getter; import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor; -@SpringBootTest(classes = { PlutoServerApplication.class }, properties = { +@SpringBootTest(classes = { VorgangManagerServerApplication.class }, properties = { "grpc.server.inProcessName=test", "grpc.server.port=-1", "grpc.client.pluto.address=in-process:test" @@ -66,12 +66,12 @@ class ClientAttributeITCase { @Autowired private ServerTestCallContextHandleInterceptor serverTestInterceptor; - // Um die Abhängigkeit zum Pluto-Code zu entfernen, kann man eine Server Dummy + // Um die Abhängigkeit zum VorgangManager-Code zu entfernen, kann man eine Server Dummy // Implementierung machen // siehe // https://yidongnan.github.io/grpc-spring-boot-starter/en/client/testing.html#running-a-dummy-server @MockBean - private de.itvsh.ozg.pluto.clientattribute.ClientAttributeService serverService; + private de.ozgcloud.vorgang.clientattribute.ClientAttributeService serverService; @Captor private ArgumentCaptor<ClientAttribute> attributeCaptor; @@ -101,7 +101,7 @@ class ClientAttributeITCase { } private ClientAttribute createHasPostfachNachrichtAttribute() { - return de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.createBuilder() + return de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.createBuilder() .clientName(NachrichtenCallContextAttachingInterceptor.NACHRICHTEN_MANAGER_CLIENT_NAME) .attributeName(ClientAttributeService.ATTRIBUTE_NAME_HAS_POSTFACH_NACHRICHT) .boolValue(Optional.of(true)).intValue(Optional.empty()) diff --git a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerITCase.java similarity index 67% rename from pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerITCase.java index 5b34c1b..87eac4f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachEventListenerITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,27 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.Optional; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.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 de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.PlutoServerApplication; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangService; @ITCase -@SpringBootTest(classes = { PlutoServerApplication.class }) +@SpringBootTest(classes = { VorgangManagerServerApplication.class }) class PostfachEventListenerITCase { @Autowired @@ -53,6 +59,12 @@ class PostfachEventListenerITCase { @SpyBean private PostfachEventListener listener; + @MockBean + private VorgangService vorgangService; + + @MockBean + private CommandService commandService; + @Nested class TestSendPostfachNachricht { @@ -61,6 +73,11 @@ class PostfachEventListenerITCase { when(command.getOrder()).thenReturn("SEND_POSTFACH_NACHRICHT"); } + @BeforeEach + void initServices() { + when(commandService.findCommand(any())).thenReturn(Optional.of(CommandTestFactory.create())); + } + @Test void shouldCallService() { doNothing().when(listener).sendPostfachNachricht(any()); @@ -68,7 +85,7 @@ class PostfachEventListenerITCase { publisher.publishEvent(event); - verify(listener).sendPostfachNachricht(any()); + verify(listener, timeout(500)).sendPostfachNachricht(any()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMailITCase.java similarity index 68% rename from pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMailITCase.java index 03d90f9..9dcdc08 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/PostfachMailITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachMailITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,8 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach; +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; @@ -30,7 +32,9 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.Collection; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -41,6 +45,7 @@ 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.data.mongodb.core.MongoOperations; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; @@ -49,21 +54,29 @@ import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.mail.attributes.ClientAttributeService; -import de.itvsh.ozg.pluto.PlutoServerApplication; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.files.FileId; -import de.itvsh.ozg.pluto.files.FileService; -import de.itvsh.ozg.pluto.files.OzgFile; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.nachrichten.attributes.ClientAttributeService; +import de.ozgcloud.nachrichten.postfach.osi.MessageAttachmentTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageJsonReplyTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.OsiPostfachProperties; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.files.FileId; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.files.OzgFile; import io.grpc.stub.StreamObserver; -@SpringBootTest(classes = { PlutoServerApplication.class, OsiPostfachProperties.class }) -@DataITCase +@SpringBootTest(classes = { VorgangManagerServerApplication.class, OsiPostfachProperties.class }, properties = { + "ozgcloud.osi.postfach.proxyapi.url=http://localhost/ApiProxy/V1/Message", + "ozgcloud.osi.postfach.proxyapi.key=1234", + "ozgcloud.osi.postfach.proxyapi.realm=test-realm", + "ozgcloud.osi.postfach.notification.mail-from=test@local.host" +}) @WithMockUser +@DataITCase class PostfachMailITCase { private static final String TEST_OSI_POSTFACH_URI = "http://localhost/ApiProxy/V1/Message"; @@ -88,6 +101,9 @@ class PostfachMailITCase { @MockBean private ClientAttributeService clientAttributeService; + @SpyBean + private CommandService commandService; + @BeforeEach void prepareDatabase() { mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); @@ -126,9 +142,9 @@ class PostfachMailITCase { mockServerSendSuccess(); callGrpcEndpoint(); - var mails = callGrpcListEndpoint(); + var mails = await().atMost(5, TimeUnit.SECONDS) + .until(PostfachMailITCase.this::callGrpcListEndpoint, PostfachMailITCase.this::hasAtLeastOneElement); - assertThat(mails).hasSize(1); assertThat(mails.get(0).getCreatedAt()).isNotNull(); assertThat(mails.get(0).getDirection()).isEqualTo(GrpcDirection.OUT); assertThat(mails.get(0).getSentAt()).isNotNull(); @@ -140,17 +156,27 @@ class PostfachMailITCase { @Nested class TestSendingFailed { + @BeforeEach + void init() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + } + @Test void shouldMarkFailed() { mockServerSendFailed(); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + assertThat(callGrpcListEndpoint()).isEmpty(); + }); callGrpcEndpoint(); - var mails = callGrpcListEndpoint(); - assertThat(mails).hasSize(1); - assertThat(mails.get(0).getSentAt()).isNotNull(); - assertThat(ZonedDateTime.parse(mails.get(0).getSentAt())).isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); - assertThat(mails.get(0).getSentSuccessful()).isFalse(); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + assertThat(callGrpcListEndpoint()).hasSize(1).first().satisfies(mail -> { + assertThat(mail.getSentAt()).isNotNull(); + assertThat(ZonedDateTime.parse(mail.getSentAt())).isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); + assertThat(mail.getSentSuccessful()).isFalse(); + }); + }); } @Test @@ -159,13 +185,13 @@ class PostfachMailITCase { mockServerSendSuccess(); callGrpcEndpoint(); - var mails = callGrpcListEndpoint(); + var mails = await().atMost(5, TimeUnit.SECONDS) + .until(PostfachMailITCase.this::callGrpcListEndpoint, PostfachMailITCase.this::hasAtLeastOneElement); var mailId = mails.get(0).getId(); callResendGrpcEndpoint(mailId); - - mails = callGrpcListEndpoint(); - assertThat(mails.get(0).getSentSuccessful()).isTrue(); + await().atMost(5, TimeUnit.SECONDS).untilAsserted( + () -> assertThat(callGrpcListEndpoint()).hasSize(1).first().extracting(GrpcPostfachMail::getSentSuccessful).isEqualTo(true)); } @Test @@ -174,14 +200,15 @@ class PostfachMailITCase { mockServerSendFailed(); callGrpcEndpoint(); - var mails = callGrpcListEndpoint(); + var mails = await().atMost(5, TimeUnit.SECONDS) + .until(PostfachMailITCase.this::callGrpcListEndpoint, PostfachMailITCase.this::hasAtLeastOneElement); var mailId = mails.get(0).getId(); callResendGrpcEndpoint(mailId); mails = callGrpcListEndpoint(); assertThat(mails.get(0).getSentSuccessful()).isFalse(); - assertThat(mails.get(0).getMessageCode()).isEqualTo(OsiPostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE.getMessageCode()); + assertThat(mails.get(0).getMessageCode()).isEqualTo(PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE.getMessageCode()); } } @@ -202,7 +229,7 @@ class PostfachMailITCase { } private GrpcSendPostfachMailRequest buildSendPostfachMailRequestWithoutAttachments() { - var grpcPostfachMail = GrpcPostfachMailTestFactory.createBuilder().clearAttachment().clearCreatedAt().clearDirection().build(); + var grpcPostfachMail = GrpcPostfachMailTestFactory.createBuilder().clearId().clearAttachment().clearCreatedAt().clearDirection().build(); return GrpcSendPostfachMailRequestTestFactory.createBuilder().setMail(grpcPostfachMail).build(); } @@ -234,9 +261,9 @@ class PostfachMailITCase { @Test void shouldListNachrichten() { - mockServerReceiveReply(OsiPostfachServiceTest.buildReplyJson()); + mockServerReceiveReply(MessageJsonReplyTestFactory.buildReplyJson()); - service.fetchAndPersistReplies(); + fetchAndPersistReplies(); var mails = callGrpcListEndpoint(); assertThat(mails).hasSize(1); @@ -248,9 +275,9 @@ class PostfachMailITCase { @Test void shouldContainAttachment() { - mockServerReceiveReply(OsiPostfachServiceTest.buildReplyJson()); + mockServerReceiveReply(MessageJsonReplyTestFactory.buildReplyJson()); - service.fetchAndPersistReplies(); + fetchAndPersistReplies(); var mails = callGrpcListEndpoint(); assertThat(mails).hasSize(1); @@ -260,17 +287,22 @@ class PostfachMailITCase { @Test void shouldHaveContentTypeDOCX() { var attachment = MessageAttachmentTestFactory.createBuilder().fileName("wort-datei.docx").build(); + mockServerReceiveReply(MessageJsonReplyTestFactory.buildReplyJson(MessageTestFactory.create(), attachment)); - mockServerReceiveReply(OsiPostfachServiceTest.buildReplyJson(MessageTestFactory.create(), - attachment)); + fetchAndPersistReplies(); - service.fetchAndPersistReplies(); var mails = callGrpcListEndpoint(); - + assertThat(mails).hasSize(1); var binaryFile = fileService.findFilesMetaData(List.of(FileId.from(mails.get(0).getAttachmentList().get(0)))).findFirst() .orElse(OzgFile.builder().build()); assertThat(binaryFile.getContentType()).isEqualTo("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); } + + private void fetchAndPersistReplies() { + service.fetchAndPersistReplies(); + + verify(commandService, timeout(5000)).setCommandFinished(any(), any()); + } } } @@ -283,4 +315,7 @@ class PostfachMailITCase { return responseCaptor.getValue().getMailsList(); } + private boolean hasAtLeastOneElement(Collection<GrpcPostfachMail> mails) { + return !mails.isEmpty(); + } } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachServiceConfigurationITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachServiceConfigurationITCase.java new file mode 100644 index 0000000..9b2dcfe --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachServiceConfigurationITCase.java @@ -0,0 +1,85 @@ +/* + * 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.nachrichten.postfach.bayernid; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; + +class BayernIdPostfachServiceConfigurationITCase { + + @Nested + @SpringBootTest(classes = { VorgangManagerServerApplication.class }) + @ITCase + class BayernIdPostfachServiceNotConfiguredITCase { + + @Autowired(required = false) + private BayernIdPostfachRemoteService bayernIdPostfachRemoteService; + + @Test + void contextLoads() { + assertThat(bayernIdPostfachRemoteService).isNull(); + } + } + + @Nested + @SpringBootTest(classes = { VorgangManagerServerApplication.class }, properties = { + "ozgcloud.bayernid.enabled=false", + }) + @ITCase + class BayernIdPostfachServiceDisabledITCase { + + @Autowired(required = false) + private BayernIdPostfachRemoteService bayernIdPostfachRemoteService; + + @Test + void contextLoads() { + assertThat(bayernIdPostfachRemoteService).isNull(); + } + } + + @Nested + @SpringBootTest(classes = { VorgangManagerServerApplication.class }, properties = { + "ozgcloud.bayernid.enabled=true", + "ozgcloud.bayernid.absender.name=Test Name", + "ozgcloud.bayernid.absender.mandant=Fürth", + "ozgcloud.bayernid.absender.dienst=Stadtverwaltung", + }) + @ITCase + class BayernIdPostfachServiceConfiguredITCase { + + @Autowired + private BayernIdPostfachRemoteService bayernIdPostfachRemoteService; + + @Test + void contextLoads() { // NOSONAR empty test just starting spring-boot + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachApiTestCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachApiTestCase.java similarity index 63% rename from pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachApiTestCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachApiTestCase.java index 74011a5..9359d93 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachApiTestCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachApiTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -33,25 +33,29 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.PlutoServerApplication; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; @Disabled("Echter Test für OSI Postfach mit echtem Zugriff. Unbedingt defaultmäßig deaktivieren!!") -@SpringBootTest(properties = { - "kop.osi.postfach.proxyapi.url=https://postfach.serviceportal-stage.schleswig-holstein.de/ApiProxy/V1/Message", - "kop.osi.postfach.proxyapi.key=db03d369-438a-4c1a-bcb8-9de951f5ef41", - "kop.osi.postfach.proxyapi.realm=urn:osp:names:realm:stage:sh", - "kop.osi.postfach.scheduler.enabled=false" -}, classes = { PlutoServerApplication.class, OsiPostfachProperties.class }) +@SpringBootTest( + classes = { VorgangManagerServerApplication.class, OsiPostfachProperties.class }, + properties = { + "ozgcloud.osi.postfach.proxyapi.url=https://postfach.serviceportal-stage.schleswig-holstein.de/ApiProxy/V1/Message", + "ozgcloud.osi.postfach.proxyapi.key=db03d369-438a-4c1a-bcb8-9de951f5ef41", + "ozgcloud.osi.postfach.proxyapi.realm=urn:osp:names:realm:stage:sh", + "ozgcloud.osi.postfach.scheduler.enabled=false" + }) @ITCase class OsiPostfachApiTestCase { @Autowired - private OsiPostfachService service; + private OsiPostfachRemoteService service; @Test void testGetAllMessages() { - Stream<Message> messages = service.getAllMessages(); + Stream<PostfachNachricht> messages = service.getAllMessages(); assertThat(messages).hasSizeGreaterThan(0); } @@ -60,11 +64,11 @@ class OsiPostfachApiTestCase { @Disabled("Echter Test für OSI Postfach mit echtem Zugriff. Unbedingt defaultmäßig deaktivieren!!") void testSendMessage() { - Message message = MessageTestFactory.createBuilder() // + PostfachNachricht nachricht = PostfachNachrichtTestFactory.createBuilder() .postfachId("2f5c78f8-4891-456f-269b-08d937ab9a72").vorgangId("98877665544").build(); assertDoesNotThrow(() -> { - service.sendMessage(message); + service.sendMessage(nachricht); }); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java similarity index 63% rename from pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java index f1e56bf..3903e94 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/mail/postfach/OsiPostfachServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.mail.postfach; +package de.ozgcloud.nachrichten.postfach.osi; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; import static org.springframework.test.web.client.response.MockRestResponseCreators.*; @@ -32,16 +33,25 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; 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.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.PlutoServerApplication; - -@SpringBootTest(classes = { PlutoServerApplication.class, OsiPostfachProperties.class }) +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.nachrichten.postfach.FileId; +import de.ozgcloud.nachrichten.postfach.PostfachException; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; + +@SpringBootTest(classes = { VorgangManagerServerApplication.class, OsiPostfachProperties.class }, properties = { + "ozgcloud.osi.postfach.proxyapi.url=http://localhost/ApiProxy/V1/Message", + "ozgcloud.osi.postfach.proxyapi.key=1234", + "ozgcloud.osi.postfach.proxyapi.realm=test-realm", + "ozgcloud.osi.postfach.scheduler.enabled=false" +}) @ITCase -class OsiPostfachServiceITCase { +class OsiPostfachRemoteServiceITCase { // properties, configured in application-itcase.yml static final String URL = "http://localhost/ApiProxy/V1/Message"; @@ -49,22 +59,28 @@ class OsiPostfachServiceITCase { static final String API_REALM = "test-realm"; @Autowired - private OsiPostfachService service; + private OsiPostfachRemoteService service; + @Autowired private RestTemplate restTemplate; + @MockBean + private MessageAttachmentService messageAttachmentService; + private MockRestServiceServer mockServer; @BeforeEach void initMockServer() { mockServer = MockRestServiceServer.createServer(restTemplate); + when(messageAttachmentService.getMessageAttachment(FileId.from(PostfachNachrichtTestFactory.ATTACHMENT_FILE_ID))) + .thenReturn(MessageAttachmentTestFactory.create()); } @Test void shouldCallWithApiKeyHeader() { mockServer.expect(header(PostfachConfiguration.HEADER_API_KEY, API_KEY)).andRespond(withSuccess()); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(PostfachNachrichtTestFactory.create()); mockServer.verify(); } @@ -73,7 +89,7 @@ class OsiPostfachServiceITCase { void shouldCallWithRealmHeader() { mockServer.expect(header(PostfachConfiguration.HEADER_API_REALM, API_REALM)).andRespond(withSuccess()); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(PostfachNachrichtTestFactory.create()); mockServer.verify(); } @@ -82,7 +98,18 @@ class OsiPostfachServiceITCase { void shouldRequestBaseUrl() { mockServer.expect(requestTo(URL)).andRespond(withSuccess()); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(PostfachNachrichtTestFactory.create()); + + mockServer.verify(); + } + + @Test + void shouldSendHtmlBody() { + mockServer.expect(jsonPath("$.isHtml").value(true)) + .andExpect(jsonPath("$.body").value(MessageTestFactory.MAIL_BODY)) + .andRespond(withSuccess()); + + service.sendMessage(PostfachNachrichtTestFactory.create()); mockServer.verify(); } @@ -95,7 +122,7 @@ class OsiPostfachServiceITCase { mockServer.expect(header(PostfachConfiguration.HEADER_API_REALM, API_REALM)) .andRespond(withSuccess(String.valueOf(true), MediaType.APPLICATION_JSON)); - service.sendMessage(MessageTestFactory.create()); + service.sendMessage(PostfachNachrichtTestFactory.create()); mockServer.verify(); } @@ -105,7 +132,7 @@ class OsiPostfachServiceITCase { mockServer.expect(header(PostfachConfiguration.HEADER_API_REALM, API_REALM)) .andRespond(withSuccess(String.valueOf(false), MediaType.APPLICATION_JSON)); - assertThrows(OsiPostfachException.class, () -> service.sendMessage(MessageTestFactory.create()));// NOSONAR + assertThrows(PostfachException.class, () -> service.sendMessage(PostfachNachrichtTestFactory.create()));// NOSONAR mockServer.verify(); } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/processor/ProcessorITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/processor/ProcessorITCase.java new file mode 100644 index 0000000..e1ad5eb --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/processor/ProcessorITCase.java @@ -0,0 +1,129 @@ +/* + * 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.processor; + +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.util.Map; +import java.util.Optional; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.ActiveProfiles; + +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.notification.postfach.PostfachService; +import de.ozgcloud.processor.processor.ProcessorService; +import de.ozgcloud.processor.vorgang.Vorgang; +import de.ozgcloud.processor.vorgang.VorgangId; +import de.ozgcloud.processor.vorgang.VorgangService; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CreateCommandRequest; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@SpringBootTest(properties = { + "ozgcloud.processors.0.name=test", + "ozgcloud.processors.0.address=http://localhost:8090/testprocessor", + "ozgcloud.processors.0.forms.0.formEngineName=testFormEngine", + "ozgcloud.processors.0.forms.0.formId=testForm", + "grpc.server.port=9091", + "ozgcloud.command-manager.address=static://127.0.0.1:9091" +}, classes = { VorgangManagerServerApplication.class }) +@ActiveProfiles({ "local", "itcase" }) +class ProcessorITCase { + + @Autowired + private ApplicationEventPublisher publisher; + + @MockBean + private VorgangService processorVorgangService; + + @MockBean + private PostfachService postfachService; + @MockBean + private de.ozgcloud.notification.vorgang.VorgangService notificationService; + + @MockBean + private CommandService commandService; + @MockBean + private ProcessorService processorService; + + @Captor + private ArgumentCaptor<CreateCommandRequest> requestCaptor; + + @BeforeEach + void init() { + when(processorVorgangService.getVorgang(any())).thenReturn(buildVorgang()); + + when(notificationService.getVorgang(any())).thenReturn(de.ozgcloud.notification.vorgang.Vorgang.builder().build()); + + when(processorService.processVorgang(any())).thenThrow(RuntimeException.class); + } + + @BeforeEach + void setupCommandService() { + var commandBuilder = PersistedCommand.builder().id("42").status(CommandStatus.PENDING).createdAt(ZonedDateTime.now()); + + when(commandService.createCommand(any())).thenReturn(commandBuilder.build()); + when(commandService.findCommand("42")) + .thenReturn(Optional.of(commandBuilder.status(CommandStatus.FINISHED).finishedAt(ZonedDateTime.now()).build())); + } + + @Test + void triggerProcessorOnNewVorgang() { + publisher.publishEvent(new VorgangCreatedEvent(VorgangTestFactory.ID)); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + verify(processorVorgangService).getVorgang(any()); + verify(commandService).createCommand(requestCaptor.capture()); + }); + + var request = requestCaptor.getValue(); + @SuppressWarnings("unchecked") + Map<String, Object> item = (Map<String, Object>) request.getBodyObject().get("item"); + assertThat(item).containsEntry("text", "Es ist eine Fehler bei der Verarbeitung des Vorganges aufgetreten"); + } + + private Vorgang buildVorgang() { + return Vorgang.builder() + .id(VorgangId.from(VorgangTestFactory.ID)) + .formEngineName("testFormEngine") + .formId("testForm") + .build(); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/DbInitializer.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/DbInitializer.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/DbInitializer.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/DbInitializer.java index 63df9e2..90a000d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/DbInitializer.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/DbInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto; +package de.ozgcloud.vorgang; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/TestConfiguration.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/TestConfiguration.java similarity index 88% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/TestConfiguration.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/TestConfiguration.java index 986bb23..8e89a11 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/TestConfiguration.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/TestConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto; +package de.ozgcloud.vorgang; import static org.mockito.Mockito.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.mail.javamail.JavaMailSender; @Configuration diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/PlutoServerApplicationTests.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/VorgangManagerServerApplicationTests.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/PlutoServerApplicationTests.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/VorgangManagerServerApplicationTests.java index 04165a6..4dfae4b 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/PlutoServerApplicationTests.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/VorgangManagerServerApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto; +package de.ozgcloud.vorgang; import org.junit.jupiter.api.Test; -import de.itvsh.kop.common.test.ITCase; +import de.ozgcloud.common.test.ITCase; @ITCase -class PlutoServerApplicationTests { +class VorgangManagerServerApplicationTests { @Test void contextLoads() { // NOSONAR empty test just starting spring-boot diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java index 106e64b..a425c70 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcFindVorgangAttachedItemRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; class GrpcFindVorgangAttachedItemRequestTestFactory { static GrpcFindVorgangAttachedItemRequest create() { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapperTest.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapperTest.java index 349658d..2d03898 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import static org.assertj.core.api.Assertions.*; @@ -31,9 +31,9 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Spy; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItem; class GrpcVorgangAttachedItemMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java similarity index 86% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java index 734d98f..5e8883b 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; class GrpcVorgangAttachedItemRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java similarity index 86% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java index 81a3a6e..7415bc1 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemResponseTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; class GrpcVorgangAttachedItemResponseTestFactory { static GrpcVorgangAttachedItemResponse create() { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemServiceTest.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemServiceTest.java index 6ca7dcd..62f7cdc 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -37,12 +37,12 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; import io.grpc.stub.StreamObserver; class GrpcVorgangAttachedItemServiceTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemTestFactory.java index 42edf9b..d8fb946 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/GrpcVorgangAttachedItemTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/GrpcVorgangAttachedItemTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import de.itvsh.ozg.pluto.common.GrpcObject; -import de.itvsh.ozg.pluto.common.GrpcProperty; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItem; public class GrpcVorgangAttachedItemTestFactory { public static final String PROPERTY_NAME = "propertyName"; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImplTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImplTest.java new file mode 100644 index 0000000..4ec17fa --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemCustomRepositoryImplTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.attached_item; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +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 org.springframework.data.mongodb.core.MongoOperations; + +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; + +import de.ozgcloud.vorgang.common.db.CollisionVerifier; + +class VorgangAttachedItemCustomRepositoryImplTest { + + @Spy + @InjectMocks + private VorgangAttachedItemCustomRepositoryImpl repository; + + @Mock + private MongoOperations mongoOperations; + @Mock + private CollisionVerifier collisionVerifier; + + @Nested + class TestDelete { + + @Test + void shouldCallCollisionVerifier() { + var deleteResult = mock(DeleteResult.class); + when(mongoOperations.remove(any(), anyString())).thenReturn(deleteResult); + + repository.delete(VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + + verify(collisionVerifier).verify(deleteResult, VorgangAttachedItemTestFactory.ID); + } + } + + @Nested + class TestMarkAsDeleted { + + @Test + void shouldCallCollisionVerifier() { + var updateResult = mock(UpdateResult.class); + when(mongoOperations.updateFirst(any(), any(), anyString())).thenReturn(updateResult); + + repository.updateDeleted(true, VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + + verify(collisionVerifier).verify(updateResult, VorgangAttachedItemTestFactory.ID); + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerITCase.java similarity index 55% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerITCase.java index 680f8bb..2c17022 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; +import static org.awaitility.Awaitility.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Map; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -35,11 +37,15 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.ApplicationEventPublisher; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.command.CommandCreatedEventTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.Order; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEventTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @ITCase class VorgangAttachedItemEventListenerITCase { @@ -51,6 +57,10 @@ class VorgangAttachedItemEventListenerITCase { private VorgangAttachedItemEventListener listener; @MockBean private VorgangAttachedItemService service; + @MockBean + private VorgangService vorgangService; + @MockBean + private CommandService commandService; @Nested class TestOnCreateItemCommand { @@ -62,7 +72,7 @@ class VorgangAttachedItemEventListenerITCase { publisher.publishEvent(event); - verify(listener).createItem(any()); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(listener).createItem(any())); } } @@ -76,7 +86,7 @@ class VorgangAttachedItemEventListenerITCase { publisher.publishEvent(event); - verify(listener).updateItem(any()); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(listener).updateItem(any())); } } @@ -92,8 +102,49 @@ class VorgangAttachedItemEventListenerITCase { publisher.publishEvent(event); - verify(listener).patchItem(any()); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(listener).patchItem(any())); + } + } + + @Nested + class TestOnDeleteItemCommand { + + @Test + void shouldCallListener() { + var command = CommandTestFactory.createBuilder().order(Order.DELETE_ATTACHED_ITEM.name()).build(); + var event = CommandCreatedEventTestFactory.create(command); + + publisher.publishEvent(event); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(listener).deleteItem(any())); } } + @Nested + class TestDeleteOnVorgangDeleted { + + @Test + void shouldCallListener() { + publisher.publishEvent(VorgangDeletedEventTestFactory.create()); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(listener).onVorgangDeleted(any())); + } + } + + @Nested + class TestOnRevokeDeleteItem { + + @Test + void shouldCallUnmarkAsDeleted() { + var command = CommandTestFactory.createBuilder().order(Order.DELETE_ATTACHED_ITEM.name()).build(); + var event = new RevokeCommandEvent(command); + + publisher.publishEvent(event); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted( + () -> verify(service).unmarkAsDeleteByIdAndVersion(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION)); + } + + } + } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerTest.java similarity index 67% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerTest.java index 2daaf6b..d35c2a3 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemEventListenerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemEventListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -30,7 +30,7 @@ import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.Map; -import javax.validation.ValidationException; +import jakarta.validation.ValidationException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -41,19 +41,26 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.springframework.context.ApplicationEventPublisher; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEventTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEventTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class VorgangAttachedItemEventListenerTest { + @Spy @InjectMocks private VorgangAttachedItemEventListener listener; @Mock private VorgangAttachedItemService service; + @Mock + private ApplicationEventPublisher publisher; @Spy private VorgangAttachedItemMapper mapper = Mappers.getMapper(VorgangAttachedItemMapper.class); @@ -187,4 +194,75 @@ class VorgangAttachedItemEventListenerTest { } } + @Nested + @DisplayName("Delete item") + class TestDeleteItem { + + private Command command = CommandTestFactory.createBuilder().relationId(VorgangAttachedItemTestFactory.ID) + .relationVersion(VorgangAttachedItemTestFactory.VERSION).build(); + + @Nested + @DisplayName("by itemId and version") + class TestDeleteByIdAndVersion { + + @Test + void shouldCallService() { + listener.deleteItem(CommandCreatedEventTestFactory.create(command)); + + verify(service).markAsDeleteByIdAndVersion(VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + } + + @Test + void shouldPublishCommandExecutedEvent() { + listener.deleteItem(CommandCreatedEventTestFactory.create(command)); + + verify(publisher).publishEvent(any(VorgangAttachedItemDeletedEvent.class)); + } + + @Test + void shouldCallHandleException() { + doThrow(new RuntimeException()).when(service).markAsDeleteByIdAndVersion(anyString(), anyLong()); + + listener.deleteItem(CommandCreatedEventTestFactory.create(command)); + + verify(listener).handleException(any(), eq(CommandTestFactory.ID)); + } + } + + @Nested + @DisplayName("by vorgangId") + class TestDeleteByVorgangId { + + @Test + void shouldCallService() { + listener.onVorgangDeleted(VorgangDeletedEventTestFactory.create()); + + verify(service).deleteByVorgangId(VorgangTestFactory.ID); + } + } + } + + @Nested + class TestRevokeCommand { + + @Nested + class TestDeleteItem { + + @Test + void shouldCallService() { + listener.onRevokeDeleteItem(new RevokeCommandEvent(CommandTestFactory.createBuilder().build())); + + verify(service).unmarkAsDeleteByIdAndVersion(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION); + } + + @Test + void shouldCallHandleException() { + doThrow(new RuntimeException()).when(service).unmarkAsDeleteByIdAndVersion(anyString(), anyLong()); + + listener.onRevokeDeleteItem(new RevokeCommandEvent(CommandTestFactory.createBuilder().build())); + + verify(publisher).publishEvent(any(CommandRevokeFailedEvent.class)); + } + } + } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemITCase.java similarity index 74% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemITCase.java index f15c945..fa3ee8e 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.Optional; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -43,20 +45,20 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.access.AccessDeniedException; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEvent; -import de.itvsh.ozg.pluto.command.CommandCreatedEventTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.Order; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; import io.grpc.stub.StreamObserver; @DataITCase @@ -64,6 +66,7 @@ class VorgangAttachedItemITCase { @Autowired private GrpcVorgangAttachedItemService service; + @MockBean private CurrentUserService currentUserService; @Autowired @@ -87,13 +90,15 @@ class VorgangAttachedItemITCase { @Test void shouldPersistInDatabase() { publisher.publishEvent(event); - - var loaded = mongoOperations.findAll(VorgangAttachedItem.class); - - assertThat(loaded).hasSize(1); - assertThat(loaded.get(0)).usingRecursiveComparison().ignoringFields("id", "version").isEqualTo(VorgangAttachedItemTestFactory.create()); - assertThat(loaded.get(0).getId()).isNotNull(); - assertThat(loaded.get(0).getVersion()).isEqualTo(1L); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var loadedItems = mongoOperations.findAll(VorgangAttachedItem.class); + + assertThat(loadedItems).hasSize(1).first().satisfies(item -> { + assertThat(item).usingRecursiveComparison().ignoringFields("id", "version").isEqualTo(VorgangAttachedItemTestFactory.create()); + assertThat(item.getId()).isNotNull(); + assertThat(item.getVersion()).isEqualTo(1L); + }); + }); } } @@ -114,9 +119,9 @@ class VorgangAttachedItemITCase { @BeforeEach void step2createEvent() { - var itemMap = new HashMap<String, Object>(persistedItem.getItem()); + var itemMap = new HashMap<>(persistedItem.getItem()); - var bodyObjectMap = new HashMap<String, Object>(VorgangAttachedItemTestFactory.asMap()); + var bodyObjectMap = new HashMap<>(VorgangAttachedItemTestFactory.asMap()); bodyObjectMap.put(VorgangAttachedItem.FIELDNAME_ITEM, itemMap); command = CommandTestFactory.createBuilder() .order(Order.UPDATE_ATTACHED_ITEM.name()) @@ -131,11 +136,14 @@ class VorgangAttachedItemITCase { void shouldIncrementVersion() { publisher.publishEvent(event); - var loaded = mongoOperations.findAll(VorgangAttachedItem.class); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var loaded = mongoOperations.findAll(VorgangAttachedItem.class); - assertThat(loaded).hasSize(1); - assertThat(loaded.get(0)).usingRecursiveComparison().ignoringFields("id", "version").isEqualTo(VorgangAttachedItemTestFactory.create()); - assertThat(loaded.get(0).getVersion()).isEqualTo(2L); + assertThat(loaded).hasSize(1).first().satisfies(item -> { + assertThat(item).usingRecursiveComparison().ignoringFields("id", "version").isEqualTo(VorgangAttachedItemTestFactory.create()); + assertThat(item.getVersion()).isEqualTo(2L); + }); + }); } } @@ -173,11 +181,13 @@ class VorgangAttachedItemITCase { assertDoesNotThrow(() -> doFind()); } + // TODO remove this Test. Implement PoicyServiceITCase to test permission check + // and verify service call in Unit Test @Test void shouldThrowAccessDeniedException() { var user = CallContextUserTestFactory.createBuilder() .organisationEinheitenIdCheckNecessary(true) - .organisatorischeEinheitenId("doesNotMatch") + .clearOrganisatorischeEinheitenIds().organisatorischeEinheitenId("doesNotMatch") .build(); when(currentUserService.findUser()).thenReturn(Optional.of(user)); @@ -233,7 +243,7 @@ class VorgangAttachedItemITCase { @Test void shouldThrowAccessDeniedException() { var user = CallContextUserTestFactory.createBuilder() - .organisatorischeEinheitenId("doesNotMatch") + .clearOrganisatorischeEinheitenIds().organisatorischeEinheitenId("doesNotMatch") .build(); when(currentUserService.findUser()).thenReturn(Optional.of(user)); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapperTest.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapperTest.java index 6a6a39b..faec91f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import static org.assertj.core.api.Assertions.*; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepositoryITCase.java new file mode 100644 index 0000000..cc9fbe4 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemRepositoryITCase.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.attached_item; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@DataITCase +class VorgangAttachedItemRepositoryITCase { + + @Autowired + private VorgangAttachedItemRepository repository; + @Autowired + private MongoOperations mongoOperations; + + private VorgangAttachedItem persistedItem; + + @BeforeEach + void prepareDatabase() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + } + + @DisplayName("Find by") + @Nested + class TestFindBy { + + @BeforeEach + void init() { + persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + } + + @Nested + class VorgangIdAndClientAndItemName { + + @Test + void shouldReturnResult() { + var loadedItems = repository.findByVorgangIdAndClientAndItemNameAndDeleted(VorgangTestFactory.ID, + VorgangAttachedItemTestFactory.CLIENT, + VorgangAttachedItemTestFactory.ITEM_NAME, VorgangAttachedItemService.NOT_DELETED); + + assertThat(loadedItems).hasSize(1); + } + + @Test + void shouldReturnEmptyResult() { + var loadedItems = repository.findByVorgangIdAndClientAndItemNameAndDeleted(VorgangTestFactory.ID, + VorgangAttachedItemTestFactory.CLIENT, + VorgangAttachedItemTestFactory.ITEM_NAME, VorgangAttachedItemTestFactory.DELETED); + + assertThat(loadedItems).isEmpty(); + } + } + + @Nested + class VorgangIdAndClient { + + @Test + void shouldReturnResult() { + var loadedItems = repository.findByVorgangIdAndClientAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.CLIENT, + VorgangAttachedItemService.NOT_DELETED); + + assertThat(loadedItems).hasSize(1); + } + + @Test + void shouldReturnEmptyResult() { + var loadedItems = repository.findByVorgangIdAndClientAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.CLIENT, + VorgangAttachedItemTestFactory.DELETED); + + assertThat(loadedItems).isEmpty(); + } + } + + @Nested + class VorgangIdAndItemName { + + @Test + void shouldReturnResult() { + var loadedItems = repository.findByVorgangIdAndItemNameAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.ITEM_NAME, + VorgangAttachedItemService.NOT_DELETED); + + assertThat(loadedItems).hasSize(1); + } + + @Test + void shouldReturnEmptyResult() { + var loadedItems = repository.findByVorgangIdAndItemNameAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.ITEM_NAME, + VorgangAttachedItemTestFactory.DELETED); + + assertThat(loadedItems).isEmpty(); + } + } + + @Nested + class VorgangId { + + @Test + void shouldReturnResult() { + var loadedItems = repository.findByVorgangIdAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemService.NOT_DELETED); + + assertThat(loadedItems).hasSize(1); + } + + @Test + void shouldReturnEmptyResult() { + var loadedItems = repository.findByVorgangIdAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemTestFactory.DELETED); + + assertThat(loadedItems).isEmpty(); + } + } + } + + @Nested + class TestPatch { + + @BeforeEach + void prepareDatabase() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + + persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + } + + @Test + void shouldUpdateFieldValue() { + repository.patch(persistedItem.getId(), persistedItem.getVersion(), buildPatchMap()); + + var loaded = findVorgangAttachedItem(); + assertThat(loaded).isNotNull(); + assertThat(loaded.getItem()).containsOnly( + entry("dontTouch", 600), + entry(VorgangAttachedItemTestFactory.ITEM_FIELD_NAME, VorgangAttachedItemTestFactory.ITEM_FIELD_STRING_VALUE)); + } + + @Test + void shouldUpdateWithNullValue() { + Map<String, Object> sourceMap = Collections.singletonMap(VorgangAttachedItemTestFactory.ITEM_FIELD_NAME, null); + + repository.patch(persistedItem.getId(), persistedItem.getVersion(), sourceMap); + + var loaded = findVorgangAttachedItem(); + assertThat(loaded.getItem()).containsOnly(entry(VorgangAttachedItemTestFactory.ITEM_FIELD_NAME, null)); + } + + @Test + void shouldIncreaseVersion() { + repository.patch(persistedItem.getId(), persistedItem.getVersion(), buildPatchMap()); + + var loaded = findVorgangAttachedItem(); + assertThat(loaded).isNotNull(); + assertThat(loaded.getVersion()).isEqualTo(persistedItem.getVersion() + 1); + } + + @Test + void shouldNotUpdateOnWrongVersion() { + repository.patch(persistedItem.getId(), 42, buildPatchMap()); + + var loaded = findVorgangAttachedItem(); + + assertThat(loaded).usingRecursiveComparison().isEqualTo(persistedItem); + } + + @Test + void shouldNotPatchDeletedItem() { + var deletedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).deleted(true).build()); + + repository.patch(deletedItem.getId(), deletedItem.getVersion(), buildPatchMap()); + + var loaded = mongoOperations.findById(deletedItem.getId(), VorgangAttachedItem.class); + assertThat(loaded).usingRecursiveComparison().isEqualTo(deletedItem); + } + + private Map<String, Object> buildPatchMap() { + return Map.of("dontTouch", 600); + } + } + + @Nested + class TestForceUpdate { + + @Test + void shouldNotPatchDeletedItem() { + var deletedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).deleted(true).build()); + + repository.forcePatch(deletedItem.getId(), buildPatchMap()); + + var loaded = mongoOperations.findById(deletedItem.getId(), VorgangAttachedItem.class); + assertThat(loaded).usingRecursiveComparison().isEqualTo(deletedItem); + } + + private Map<String, Object> buildPatchMap() { + return Map.of("dontTouch", 600); + } + } + + @Nested + class TestDelete { + + @BeforeEach + void setup() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + } + + @Test + void shouldDeleteByVorgangId() { + repository.deleteByVorgangId(VorgangTestFactory.ID); + + assertThat(mongoOperations.findAll(VorgangAttachedItem.class)).isEmpty(); + } + + @Test + void shouldDeleteByIdAndVersion() { + repository.delete(persistedItem.getId(), persistedItem.getVersion()); + + assertThat(repository.findById(persistedItem.getId())).isEmpty(); + } + + @Test + void shouldThrowExceptionWhenVersionMismatch() { + var expectedId = persistedItem.getId(); + var expectedVersion = persistedItem.getVersion(); + mongoOperations.save(persistedItem); + + assertThrows(ConcurrentModificationException.class, () -> repository.delete(expectedId, expectedVersion)); + } + } + + @Nested + class TestMarkAsDeleted { + + private static final boolean IS_DELETED = true; + + @BeforeEach + void setup() { + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder().id(null).version(0).build()); + } + + @Test + void shouldMarkAsDeleted() { + repository.updateDeleted(IS_DELETED, persistedItem.getId(), persistedItem.getVersion()); + + var loaded = findVorgangAttachedItem(); + assertThat(loaded.isDeleted()).isTrue(); + } + + @Test + void shouldThrowExceptionWhenVersionMismatch() { + var expectedId = persistedItem.getId(); + var expectedVersion = persistedItem.getVersion(); + mongoOperations.save(persistedItem); + + assertThrows(ConcurrentModificationException.class, () -> repository.delete(expectedId, expectedVersion)); + } + } + + private VorgangAttachedItem findVorgangAttachedItem() { + return mongoOperations.findById(persistedItem.getId(), VorgangAttachedItem.class); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceITCase.java new file mode 100644 index 0000000..e8b6b7d --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceITCase.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.attached_item; + +import static org.assertj.core.api.Assertions.*; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import jakarta.validation.ConstraintViolationException; + +@ITCase +class VorgangAttachedItemServiceITCase { + + @Autowired + private VorgangAttachedItemService service; + + @MockBean + private VorgangAttachedItemRepository repository; + @MockBean + private ApplicationEventPublisher eventPublisher; + + @Nested + class TestCreate { + @Test + void shouldDenyMissingClientName() { + var item = VorgangAttachedItemTestFactory.createBuilder().client(StringUtils.EMPTY).build(); + + assertThatThrownBy(() -> service.create(CommandTestFactory.ID, item)) + .isInstanceOf(ConstraintViolationException.class); + } + + @Test + void shouldDenyMissingVorgangId() { + var item = VorgangAttachedItemTestFactory.createBuilder().vorgangId(StringUtils.EMPTY).build(); + + assertThatThrownBy(() -> service.create(CommandTestFactory.ID, item)) + .isInstanceOf(ConstraintViolationException.class); + } + + @Test + void shouldDenyMissingItemName() { + var item = VorgangAttachedItemTestFactory.createBuilder().itemName(StringUtils.EMPTY).build(); + + assertThatThrownBy(() -> service.create(CommandTestFactory.ID, item)) + .isInstanceOf(ConstraintViolationException.class); + } + } + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceTest.java similarity index 55% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceTest.java index 73c9773..126d872 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; -import static de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory.*; +import static de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -38,17 +38,19 @@ 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 org.springframework.context.ApplicationEventPublisher; -import de.itvsh.ozg.mail.postfach.PostfachMailTestFactory; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class VorgangAttachedItemServiceTest { @InjectMocks + @Spy private VorgangAttachedItemService service; @Mock private VorgangAttachedItemRepository repository; @@ -60,6 +62,8 @@ class VorgangAttachedItemServiceTest { @Test void shouldCallRepository() { + when(repository.save(any())).thenReturn(VorgangAttachedItemTestFactory.create()); + service.create(CommandTestFactory.ID, VorgangAttachedItemTestFactory.create()); verify(repository).save(any()); @@ -67,6 +71,8 @@ class VorgangAttachedItemServiceTest { @Test void shouldPublishEvent() { + when(repository.save(any())).thenReturn(VorgangAttachedItemTestFactory.create()); + service.create(CommandTestFactory.ID, VorgangAttachedItemTestFactory.create()); verify(publisher).publishEvent(any(VorgangAttachedItemCreatedEvent.class)); @@ -94,6 +100,13 @@ class VorgangAttachedItemServiceTest { assertThat(prepared.getItem()).doesNotContainKey(VorgangAttachedItem.FIELDNAME_ID); } + + @Test + void shouldSetIsDeletedToFalse() { + var prepared = service.prepareForCreation(VorgangAttachedItemTestFactory.create()); + + assertThat(prepared.isDeleted()).isFalse(); + } } } @@ -116,46 +129,66 @@ class VorgangAttachedItemServiceTest { } } + @Nested + class TestForceUpdateItem { + + @Test + void shouldCallRepository() { + service.forceUpdate(CommandTestFactory.ID, VorgangAttachedItemTestFactory.create()); + + verify(repository).forcePatch(eq(VorgangAttachedItemTestFactory.ID), any()); + } + + @Test + void shouldPublishEvent() { + service.forceUpdate(CommandTestFactory.ID, VorgangAttachedItemTestFactory.create()); + + verify(publisher).publishEvent(any(VorgangAttachedItemUpdatedEvent.class)); + } + } + @Nested class TestFindBy { @Test - void shouldCallFindById() { - service.findById(PostfachMailTestFactory.ID); + void shouldCallFindByIdAndDeleted() { + service.findById(PostfachNachrichtTestFactory.ID); - verify(repository).findById(PostfachMailTestFactory.ID); + verify(repository).findByIdAndDeleted(PostfachNachrichtTestFactory.ID, VorgangAttachedItemService.NOT_DELETED); } } @Nested class TestFind { + @Test - void shouldCallFindByClientAndItemNameAndVorgangId() { + void shouldCallFindByClientAndItemNameAndVorgangIdAndDeleted() { service.find(VorgangTestFactory.ID, Optional.of(CLIENT), Optional.of(ITEM_NAME)); - verify(repository).findByVorgangIdAndClientAndItemName(VorgangTestFactory.ID, CLIENT, ITEM_NAME); + verify(repository).findByVorgangIdAndClientAndItemNameAndDeleted(VorgangTestFactory.ID, CLIENT, ITEM_NAME, + VorgangAttachedItemService.NOT_DELETED); } @Test - void shouldCallFindByClientAndVorgangId() { + void shouldCallFindByClientAndVorgangIdAndDeleted() { service.find(VorgangTestFactory.ID, Optional.of(CLIENT), Optional.empty()); - verify(repository).findByVorgangIdAndClient(VorgangTestFactory.ID, CLIENT); + verify(repository).findByVorgangIdAndClientAndDeleted(VorgangTestFactory.ID, CLIENT, VorgangAttachedItemService.NOT_DELETED); } @Test - void shouldCallFindByItemNameAndVorgangId() { + void shouldCallFindByItemNameAndVorgangIdAndDeleted() { service.find(VorgangTestFactory.ID, Optional.empty(), Optional.of(ITEM_NAME)); - verify(repository).findByVorgangIdAndItemName(VorgangTestFactory.ID, ITEM_NAME); + verify(repository).findByVorgangIdAndItemNameAndDeleted(VorgangTestFactory.ID, ITEM_NAME, VorgangAttachedItemService.NOT_DELETED); } @Test - void shouldCallFindByVorgangId() { + void shouldCallFindByVorgangIdAndDeleted() { service.find(VorgangTestFactory.ID, Optional.empty(), Optional.empty()); - verify(repository).findByVorgangId(VorgangTestFactory.ID); + verify(repository).findByVorgangIdAndDeleted(VorgangTestFactory.ID, VorgangAttachedItemService.NOT_DELETED); } } @@ -175,8 +208,10 @@ class VorgangAttachedItemServiceTest { } private Command buildCommand(Map<String, Object> bodyMap) { - return CommandTestFactory.createBuilder().relationId(VorgangAttachedItemTestFactory.ID) - .relationVersion(VorgangAttachedItemTestFactory.VERSION).bodyObject(bodyMap).build(); + return CommandTestFactory.createBuilder() + .relationId(VorgangAttachedItemTestFactory.ID) + .relationVersion(VorgangAttachedItemTestFactory.VERSION) + .bodyObject(bodyMap).build(); } } @@ -195,11 +230,12 @@ class VorgangAttachedItemServiceTest { } @Nested + class TestGetById { @Test void shouldReturnAttachedItem() { var item = VorgangAttachedItemTestFactory.create(); - when(repository.findById(any())).thenReturn(Optional.of(item)); + when(repository.findByIdAndDeleted(any(), anyBoolean())).thenReturn(Optional.of(item)); var attachedItem = service.getById(VorgangAttachedItemTestFactory.ID); @@ -209,10 +245,20 @@ class VorgangAttachedItemServiceTest { @DisplayName("should throw an exception if no attachedItem was found") @Test void shouldThrowException() { - when(repository.findById(any())).thenReturn(Optional.empty()); + when(repository.findByIdAndDeleted(any(), anyBoolean())).thenReturn(Optional.empty()); assertThrows(NotFoundException.class, () -> service.getById(VorgangAttachedItemTestFactory.ID)); } + + @Test + void shouldCallFindByIdAndDeleted() { + var item = VorgangAttachedItemTestFactory.create(); + when(repository.findByIdAndDeleted(any(), anyBoolean())).thenReturn(Optional.of(item)); + + service.getById(VorgangAttachedItemTestFactory.ID); + + verify(repository).findByIdAndDeleted(VorgangAttachedItemTestFactory.ID, VorgangAttachedItemService.NOT_DELETED); + } } @Test @@ -223,4 +269,42 @@ class VorgangAttachedItemServiceTest { assertThat(enrichedItem.getItem()).containsEntry(VorgangAttachedItem.FIELDNAME_ID, id); } + + @Nested + @DisplayName("Set deleted by ID and version") + class TestMarkDeletedByIdAndVersion { + + @Test + @DisplayName("should call updateDeletedByIdAndVersion to mark item as deleted") + void shouldCallUpdateIsDeletedMethod() { + var deletedFlag = true; + + service.markAsDeleteByIdAndVersion(VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + + verify(repository).updateDeleted(deletedFlag, VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + } + + @Test + @DisplayName("should call updateDeletedByIdAndVersion to mark item as not deleted") + void shouldCallUpdateIsDeletedMethod1() { + var deletedFlag = false; + + service.unmarkAsDeleteByIdAndVersion(VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + + verify(repository).updateDeleted(deletedFlag, VorgangAttachedItemTestFactory.ID, VorgangAttachedItemTestFactory.VERSION); + } + } + + @Nested + @DisplayName("Delete item by vorgangId") + class TestDelete { + + @Test + void shouldCallDeleteMethod() { + service.deleteByVorgangId(VorgangAttachedItemTestFactory.ID); + + verify(repository).deleteByVorgangId(VorgangAttachedItemTestFactory.ID); + } + + } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemTestFactory.java index be7f4a5..ead2acb 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/attached_item/VorgangAttachedItemTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/attached_item/VorgangAttachedItemTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,21 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.attached_item; +package de.ozgcloud.vorgang.attached_item; import java.util.List; import java.util.Map; import java.util.UUID; -import de.itvsh.kop.common.binaryfile.FileId; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.common.binaryfile.FileId; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class VorgangAttachedItemTestFactory { + public static final boolean DELETED = true; + public static final String ID = UUID.randomUUID().toString(); public static final long VERSION = 1L; - public static final String CLIENT = "Goofy"; + public static final String CLIENT = LoremIpsum.getInstance().getFirstName() + "Client"; public static final String ITEM_NAME = "test"; public static final String ITEM_FIELD_NAME = "number"; @@ -67,6 +71,7 @@ public class VorgangAttachedItemTestFactory { .version(VERSION) .client(CLIENT) .itemName(ITEM_NAME) + .deleted(false) .item(STRING_MAP); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueValidatorTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueValidatorTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueValidatorTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueValidatorTest.java index 9fb1e9b..8e14b3f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeHasValueValidatorTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeHasValueValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,21 +21,21 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import static de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.*; +import static de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.*; import static org.assertj.core.api.Assertions.*; import java.util.Optional; -import javax.validation.ConstraintValidatorContext; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import jakarta.validation.ConstraintValidatorContext; + class ClientAttributeHasValueValidatorTest { @InjectMocks diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeITCase.java similarity index 86% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeITCase.java index e99a518..3daae63 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.assertj.core.api.Assertions.*; @@ -34,14 +34,14 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.annotation.DirtiesContext; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.common.callcontext.TestCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; -import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangRequestTestFactory; -import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangRequest; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.TestCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangRequestTestFactory; +import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import net.devh.boot.grpc.client.inject.GrpcClient; @SpringBootTest(properties = { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificatorTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificatorTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificatorTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificatorTestFactory.java index 0486379..78b0095 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeIdentificatorTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeIdentificatorTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class ClientAttributeIdentificatorTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapperTest.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapperTest.java index 1982cf8..615daf8 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import static de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.*; +import static de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.*; import static org.assertj.core.api.Assertions.*; import java.util.Optional; @@ -34,9 +34,9 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; class ClientAttributeMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermittedTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermittedTest.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermittedTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermittedTest.java index 24c2a82..84280fc 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeReadPermittedTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeReadPermittedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -35,9 +35,9 @@ import org.junit.jupiter.params.provider.EnumSource.Mode; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute.AccessPermission; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute.AccessPermission; class ClientAttributeReadPermittedTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepositoryITCase.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepositoryITCase.java index 6dfb9bc..463bd31 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import static de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.*; +import static de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.*; import static org.assertj.core.api.Assertions.*; import java.util.Map; @@ -40,12 +40,12 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute.AccessPermission; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute.AccessPermission; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @DataITCase class ClientAttributeRepositoryITCase { @@ -75,9 +75,9 @@ class ClientAttributeRepositoryITCase { void withIntValue() { repository.set(vorgang.getId(), ClientAttributeTestFactory.create()); - Map<String, ClientAttribute> goofyAttributes = loadTestClientAttributes(); + Map<String, ClientAttribute> attributes = loadTestClientAttributes(); - assertThat(goofyAttributes.get(ATTRIBUTE_NAME)) + assertThat(attributes.get(ATTRIBUTE_NAME)) .usingRecursiveComparison().ignoringFields(ClientAttribute.FIELD_CLIENTNAME, ClientAttribute.FIELD_ATTRIBUTENAME) .isEqualTo(ClientAttributeTestFactory.create()); } @@ -89,8 +89,8 @@ class ClientAttributeRepositoryITCase { repository.set(vorgang.getId(), attribute); - Map<String, ClientAttribute> goofyAttributes = loadTestClientAttributes(); - assertThat(goofyAttributes.get(ATTRIBUTE_NAME)) + Map<String, ClientAttribute> attributes = loadTestClientAttributes(); + assertThat(attributes.get(ATTRIBUTE_NAME)) .usingRecursiveComparison().ignoringFields(ClientAttribute.FIELD_CLIENTNAME, ClientAttribute.FIELD_ATTRIBUTENAME) .isEqualTo(attribute); } @@ -102,8 +102,8 @@ class ClientAttributeRepositoryITCase { repository.set(vorgang.getId(), attribute); - Map<String, ClientAttribute> goofyAttributes = loadTestClientAttributes(); - assertThat(goofyAttributes.get(ATTRIBUTE_NAME)) + Map<String, ClientAttribute> attributes = loadTestClientAttributes(); + assertThat(attributes.get(ATTRIBUTE_NAME)) .usingRecursiveComparison().ignoringFields(ClientAttribute.FIELD_CLIENTNAME, ClientAttribute.FIELD_ATTRIBUTENAME) .isEqualTo(attribute); } @@ -115,8 +115,8 @@ class ClientAttributeRepositoryITCase { repository.set(vorgang.getId(), attribute); - Map<String, ClientAttribute> goofyAttributes = loadTestClientAttributes(); - assertThat(goofyAttributes.get(ATTRIBUTE_NAME)) + Map<String, ClientAttribute> attributes = loadTestClientAttributes(); + assertThat(attributes.get(ATTRIBUTE_NAME)) .usingRecursiveComparison().ignoringFields(ClientAttribute.FIELD_CLIENTNAME, ClientAttribute.FIELD_ATTRIBUTENAME) .isEqualTo(attribute); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceITCase.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceITCase.java index ed315ad..f3650bd 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,21 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.assertj.core.api.Assertions.*; import java.util.Optional; -import javax.validation.ConstraintViolationException; - import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import jakarta.validation.ConstraintViolationException; @ITCase class ClientAttributeServiceITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceTest.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceTest.java index a0b5810..8c1aa5c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class ClientAttributeServiceTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeTestFactory.java index bfc237f..d3075e9 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributeTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributeTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import java.util.Optional; import com.thedeanda.lorem.LoremIpsum; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute.AccessPermission; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute.AccessPermission; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class ClientAttributeTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMapTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMapTestFactory.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMapTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMapTestFactory.java index fe99faa..4711148 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/ClientAttributesMapTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/ClientAttributesMapTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; public class ClientAttributesMapTestFactory { public static final ClientAttributesMap create() { - return createWithAttribute(ClientAttributeTestFactory.createBuilder().build()); + return createWithAttribute(ClientAttributeTestFactory.create()); } public static final ClientAttributesMap createWithAttribute(ClientAttribute clientAttribute) { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceITCase.java similarity index 88% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceITCase.java index 9942dfa..d24c63c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,8 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -37,14 +38,11 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.ozg.pluto.common.callcontext.TestCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; +import de.ozgcloud.vorgang.callcontext.TestCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; -@Disabled @SpringBootTest(properties = { "grpc.server.inProcessName=test", "grpc.server.port=-1", diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceTest.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceTest.java index 53804a8..da4865f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -38,14 +38,14 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAcknowledgeResponse; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAcknowledgeResponse; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; class GrpcClientAttributeServiceTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeTestFactory.java similarity index 76% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeTestFactory.java index 10e098b..845fb08 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcClientAttributeTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcClientAttributeTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import static de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.*; +import static de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.*; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcAccessPermission; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttribute; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; public class GrpcClientAttributeTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java similarity index 81% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java index 422defb..b1ebcd9 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcDeleteClientAttributeRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class GrpcDeleteClientAttributeRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcSetClientAttributeRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcSetClientAttributeRequestTestFactory.java similarity index 76% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcSetClientAttributeRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcSetClientAttributeRequestTestFactory.java index 6538937..356699c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcSetClientAttributeRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcSetClientAttributeRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import static de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory.*; +import static de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory.*; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttributeValue; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcSetClientAttributeRequest.Builder; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcClientAttributeValue; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcSetClientAttributeRequest.Builder; public class GrpcSetClientAttributeRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java index e7d455e..b89efc3 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/clientattribute/GrpcUpdateClientAttributeRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.clientattribute; +package de.ozgcloud.vorgang.clientattribute; -import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; +import de.ozgcloud.vorgang.grpc.clientAttribute.GrpcUpdateClientAttributeRequest; public class GrpcUpdateClientAttributeRequestTestFactory { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/AttachmentFileTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/AttachmentFileTestFactory.java new file mode 100644 index 0000000..37d5e6a --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/AttachmentFileTestFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.function.Supplier; + +import org.apache.commons.io.IOUtils; + +import de.ozgcloud.nachrichten.postfach.AttachmentFile; +import de.ozgcloud.nachrichten.postfach.AttachmentFile.AttachmentFileBuilder; + +public class AttachmentFileTestFactory { + + public static final String ATTACHMENT_NAME = "test.txt"; + public static final String CONTENT_TYPE = "text/plain"; + + public static final String BASE64_CONTENT = "dGVzdA=="; + public static final String CONTENT = "test"; + public static final long SIZE = 4L; + public static final Supplier<InputStream> CONTENT_SUPPLIER = () -> IOUtils.toInputStream(CONTENT, Charset.defaultCharset()); + public static final Supplier<InputStream> BASE64_CONTENT_SUPPLIER = () -> IOUtils.toInputStream(BASE64_CONTENT, Charset.defaultCharset()); + + public static AttachmentFile create() { + return createBuilder().build(); + } + + public static AttachmentFileBuilder createBuilder() { + return AttachmentFile.builder() + .name(ATTACHMENT_NAME) + .contentType(CONTENT_TYPE) + .content(CONTENT_SUPPLIER); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandCreatedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandCreatedEventTestFactory.java similarity index 78% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandCreatedEventTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandCreatedEventTestFactory.java index ab11c35..6daf777 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandCreatedEventTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandCreatedEventTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; public class CommandCreatedEventTestFactory { + public static CommandCreatedEvent create() { + return create(CommandTestFactory.create()); + } + public static CommandCreatedEvent create(Command command) { return new CommandCreatedEvent(command); } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandDeletionSchedulerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandDeletionSchedulerTest.java new file mode 100644 index 0000000..b39dcb3 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandDeletionSchedulerTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +class CommandDeletionSchedulerTest { + + @InjectMocks + @Spy + private CommandDeletionScheduler scheduler; + @Mock + private CommandService commandService; + + private ZonedDateTime cleanupThreshold = ZonedDateTime.now().minusMinutes(CommandDeletionScheduler.CLEANUP_THRESHOLD_MINUTES); + + @Test + void shouldCallGetCleanupThreshold() { + scheduler.deleteCommands(); + + verify(scheduler).getCleanupThreshold(); + } + + @Test + void shouldFindFinishedCommands() { + doReturn(cleanupThreshold).when(scheduler).getCleanupThreshold(); + + scheduler.deleteCommands(); + + verify(commandService).findFinishedVorgangLoeschenCommandsOlderThen(cleanupThreshold); + } + + @Test + void shouldCallCommandService() { + Stream<Command> commands = Stream.of(CommandTestFactory.create(), CommandTestFactory.create()); + when(commandService.findFinishedVorgangLoeschenCommandsOlderThen(any())).thenReturn(commands); + + scheduler.deleteCommands(); + + verify(commandService).deleteAllByVorgang(VorgangTestFactory.ID); + } + + @Test + void shouldCatchExceptionWhenFindMethodCalled() { + doThrow(new RuntimeException()).when(commandService).findFinishedVorgangLoeschenCommandsOlderThen(any()); + + scheduler.deleteCommands(); + + verify(commandService, never()).deleteAllByVorgang(any()); + } + + @Test + void shouldCatchExceptionWhenDeleteMethodCalled() { + when(commandService.findFinishedVorgangLoeschenCommandsOlderThen(any())).thenReturn(Stream.of(CommandTestFactory.create())); + doThrow(new RuntimeException()).when(commandService).deleteAllByVorgang(any()); + + assertThatNoException().isThrownBy(scheduler::deleteCommands); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandEventListenerTest.java new file mode 100644 index 0000000..23d1885 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandEventListenerTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.CommandRevokedEvent; + +class CommandEventListenerTest { + + @InjectMocks // NOSONAR + private CommandEventListener listener; + + @Mock + private CommandService commandService; + + @Nested + class TestCommandExecutedEventListener { + + @Test + void shouldSetStatusFinished() { + listener.setStatusFinished( + CommandExecutedEventTestFactory.createFor(CommandTestFactory.create(), CommandTestFactory.CREATED_RESOURCE)); + + verify(commandService).setCommandFinished(CommandTestFactory.ID, CommandTestFactory.CREATED_RESOURCE); + } + + } + + @Nested + class TestCommandRevokeFailedEventListener { + + @Test + void shouldSetStatusFinished() { + listener.setStatusFinished(new CommandRevokeFailedEvent(CommandTestFactory.ID, "test Error")); + + verify(commandService).setCommandFinished(CommandTestFactory.ID); + } + } + + @Nested + class TestCommandFailedEventListener { + private static final String ERROR_MESSAGE = "test Error"; + + @Test + void shouldSetStatusError() { + listener.setStatusError(new CommandFailedEvent(CommandTestFactory.ID, ERROR_MESSAGE)); + + verify(commandService).setCommandError(CommandTestFactory.ID, ERROR_MESSAGE); + } + } + + @Nested + class TestCommandRevokedEventListener { + @Test + void shouldSetStatusRevoked() { + listener.setCommandRevoked(new CommandRevokedEvent(CommandTestFactory.create())); + + verify(commandService).setCommandRevoked(CommandTestFactory.ID); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandExecutedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandExecutedEventTestFactory.java new file mode 100644 index 0000000..de5a85f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandExecutedEventTestFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; + +public class CommandExecutedEventTestFactory { + + public static CommandExecutedEvent createFor(Command command, String createdResource) { + return new CommandExecutedEvent(command, createdResource); + } + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandITCase.java similarity index 67% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandITCase.java index f4e694c..e55a4e0 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; 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.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -37,23 +42,22 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBodyField; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse.GrpcResponseCode; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.grpc.command.GrpcRevokeCommandRequest; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandBodyField; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcRevokeCommandRequest; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; /** @@ -67,7 +71,6 @@ import io.grpc.stub.StreamObserver; * einige wenige Testfälle in eine E2E-ITCase (CommandITCase) ziehen, dabei aber * reaktionen von Umsystemen (NAchrichtenMAnager, NotificationManager) * berúcksichtigen / ausschalten - * */ @WithMockUser @@ -114,44 +117,56 @@ class CommandITCase { var response = responseCaptor.getValue(); - assertThat(response.getResponseCode()).isEqualTo(GrpcResponseCode.OK); + assertThat(response.getResponseCode()).isEqualTo(GrpcCommandResponse.GrpcResponseCode.OK); assertThat(response.getCommand()).isNotNull(); + } - var command = response.getCommand(); + @Test + void shouldCreateCommand() { + callServiceCreateCommand(); + var response = responseCaptor.getValue(); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var command = commandService.findCommand(response.getCommand().getId()); + + assertThat(command).isPresent().get().satisfies(cmd -> { + assertThat(cmd.getId()).isNotNull(); + assertThat(cmd.getCreatedAt()).isNotNull(); + assertThat(cmd.getStatus()).isEqualTo(CommandStatus.FINISHED); + assertThat(cmd.getRelationId()).isEqualTo(persistedVorgang.getId()); + }); + }); - assertThat(command.getId()).isNotNull(); - assertThat(command.getCreatedAt()).isNotNull(); - // assertThat(command.getCreatedBy()).isEqualTo(UserTestFactory.ID); - assertThat(command.getStatus()).isEqualTo(CommandStatus.FINISHED.name()); - assertThat(command.getRelationId()).isEqualTo(persistedVorgang.getId()); - assertThat(command.getOrder()).isEqualTo(GrpcOrder.VORGANG_ANNEHMEN); } @Test void validateUpdatedVorgang() { callServiceCreateCommand(); - var vorgang = mongoOperations.findById(persistedVorgang.getId(), Vorgang.class); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var vorgang = mongoOperations.findById(persistedVorgang.getId(), Vorgang.class); + + assertThat(vorgang).isNotNull(); + assertThat(vorgang.getVersion()).isEqualTo(VorgangTestFactory.VERSION + 1); + }); - assertThat(vorgang).isNotNull(); - assertThat(vorgang.getVersion()).isEqualTo(VorgangTestFactory.VERSION + 1); } @Test void validateCreatedCommand() { callServiceCreateCommand(); - var commands = mongoOperations.findAll(Command.class); - - assertThat(commands).hasSize(1); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var commands = mongoOperations.findAll(Command.class); - var command = commands.get(0); - assertThat(command.getId()).hasSize(36); - assertThat(command.getCreatedAt()).isNotNull(); - // assertThat(command.getCreatedBy()).isNotNull(); - assertThat(command.getStatus()).isEqualTo(CommandStatus.FINISHED); - assertThat(command.getRelationId()).isEqualTo(persistedVorgang.getId()); - assertThat(command.getRelationVersion()).isEqualTo(VorgangTestFactory.VERSION); + assertThat(commands).hasSize(1).first().satisfies(command -> { + assertThat(command.getId()).hasSize(36); + assertThat(command.getCreatedAt()).isNotNull(); + assertThat(command.getStatus()).isEqualTo(CommandStatus.FINISHED); + assertThat(command.getRelationId()).isEqualTo(persistedVorgang.getId()); + assertThat(command.getRelationVersion()).isEqualTo(VorgangTestFactory.VERSION); + }); + }); } @DisplayName("with Order SEND_POSTFACH_MAIL") @@ -295,31 +310,39 @@ class CommandITCase { mongoOperations.save(VorgangTestFactory.createBuilder().status(Status.ANGENOMMEN).build()); mongoOperations.save(CommandTestFactory.createBuilder() - .relationId(VorgangTestFactory.ID).relationVersion(VorgangTestFactory.VERSION - 1).build()); + .relationId(VorgangTestFactory.ID).relationVersion(VorgangTestFactory.VERSION - 1) + .previousState(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Status.NEU)).build()); } @Test void shouldSetRevokeStatus() { callServiceRevokeCommand(); - var response = responseCaptor.getValue(); - assertThat(response.getCommand().getStatus()).isEqualTo(CommandStatus.REVOKED.toString()); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var command = findCommand(responseCaptor.getValue().getCommand().getId()); + + assertThat(command).isNotNull().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + }); } @Test void shouldUpdateVorgang() { callServiceRevokeCommand(); - var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); - assertThat(vorgang).isNotNull().extracting(Vorgang::getStatus).isEqualTo(Status.NEU); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); + assertThat(vorgang).isNotNull().extracting(Vorgang::getStatus).isEqualTo(Status.NEU); + }); } @Test void shouldUpdateCommand() { callServiceRevokeCommand(); - var command = findCommand(); - assertThat(command).isNotNull().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var command = findCommand(); + assertThat(command).isNotNull().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + }); } @Test @@ -331,7 +354,11 @@ class CommandITCase { } private Command findCommand() { - return mongoOperations.findById(CommandTestFactory.ID, Command.class); + return findCommand(CommandTestFactory.ID); + } + + private Command findCommand(String id) { + return mongoOperations.findById(id, Command.class); } } @@ -343,15 +370,20 @@ class CommandITCase { mongoOperations.save(VorgangTestFactory.createBuilder().status(Status.VERWORFEN).build()); mongoOperations.save(CommandTestFactory.createBuilder().relationId(VorgangTestFactory.ID) - .relationVersion(VorgangTestFactory.VERSION - 1).order(Order.VORGANG_VERWERFEN.toString()).build()); + .relationVersion(VorgangTestFactory.VERSION - 1).order(Order.VORGANG_VERWERFEN.toString()) + .previousState(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Status.IN_BEARBEITUNG)) + .build()); } @Test void shouldSetRevokeStatus() { callServiceRevokeCommand(); - var response = responseCaptor.getValue(); - assertThat(response.getCommand().getStatus()).isEqualTo(CommandStatus.REVOKED.toString()); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var command = commandService.findCommand(responseCaptor.getValue().getCommand().getId()); + + assertThat(command).isPresent().get().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + }); } @Test @@ -359,15 +391,17 @@ class CommandITCase { callServiceRevokeCommand(); var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); - assertThat(vorgang).isNotNull().extracting(Vorgang::getStatus).isEqualTo(Status.NEU); + assertThat(vorgang).isNotNull().extracting(Vorgang::getStatus).isEqualTo(Status.IN_BEARBEITUNG); } @Test void shouldUpdateCommand() { callServiceRevokeCommand(); - var command = mongoOperations.findById(CommandTestFactory.ID, Command.class); - assertThat(command).isNotNull().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var command = mongoOperations.findById(CommandTestFactory.ID, Command.class); + assertThat(command).isNotNull().extracting(Command::getStatus).isEqualTo(CommandStatus.REVOKED); + }); } } @@ -385,6 +419,11 @@ class CommandITCase { assertThat(command.getStatus()).isEqualTo(CommandStatus.REVOKED); assertThat(command.getRelationId()).isEqualTo(VorgangTestFactory.ID); assertThat(command.getRelationVersion()).isEqualTo(VorgangTestFactory.VERSION); + + assertThat(command).isInstanceOf(PersistedCommand.class) + .extracting("previousState") + .asInstanceOf(InstanceOfAssertFactories.map(String.class, Object.class)) + .containsKey(Vorgang.MONGODB_FIELDNAME_STATUS).isEqualTo(Status.NEU); } private void callServiceRevokeCommand() { @@ -394,44 +433,4 @@ class CommandITCase { } } - @Nested - class TestCreateAttachedItem { - - private CreateCommandRequest request; - - @BeforeEach - void prepareDatabase() { - mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); - mongoOperations.dropCollection(Command.COLLECTION_NAME); - mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); - - var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()); - - request = CreateCommandRequestTestFactory.createBuilder() - .vorgangId(vorgang.getId()).relationId(vorgang.getId()) - .order(Order.CREATE_ATTACHED_ITEM.toString()).bodyObject(VorgangAttachedItemTestFactory.asMap()).build(); - } - - @Test - void shouldPersistCommand() { - // TODO use grpc-service - commandService.createCommand(request); - - var commands = mongoOperations.findAll(Command.class); - assertThat(commands).hasSize(1); - assertThat(commands.get(0).getBodyObject()).isNotNull(); - assertThat(commands.get(0).getBodyObject()).containsEntry("itemName", - VorgangAttachedItemTestFactory.ITEM_NAME); - } - - @Test - void shouldExecuteCommand() { - // TODO use grpc-service - commandService.createCommand(request); - - var commands = mongoOperations.findAll(Command.class); - assertThat(commands).hasSize(1); - assertThat(commands.get(0).getStatus()).isEqualTo(CommandStatus.FINISHED); - } - } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRepositoryITCase.java new file mode 100644 index 0000000..99293b0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRepositoryITCase.java @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.mongodb.core.query.Query.*; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Criteria; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@DataITCase +class CommandRepositoryITCase { + + @Autowired + private CommandRepository repository; + @Autowired + private MongoOperations mongoOperations; + + @BeforeEach + void clearDB() { + mongoOperations.dropCollection(Command.class); + } + + @Nested + class TestSave { + + @Test + void shouldSave() { + repository.save(CommandTestFactory.create()); + + verifyCommandExists(CommandTestFactory.ID); + } + + @Test + void shouldGenerateIdOnSave() { + Command command = repository.save(CommandTestFactory.createBuilder().id(null).build()); + + verifyCommandExists(command.getId()); + } + + private void verifyCommandExists(String id) { + Command command = mongoOperations.findById(id, Command.class); + + assertThat(command).isNotNull(); + assertThat(command.getId()).isEqualTo(id); + } + } + + @Nested + class TestFinishCommand { + + @Test + void shouldUpdateStatusToFinished() { + var command = mongoOperations.save(CommandTestFactory.create()); + + repository.finishCommand(command.getId()); + + var result = repository.getById(command.getId()).get(); + assertThat(result.getStatus()).isEqualTo(CommandStatus.FINISHED); + } + + @Test + void shouldSetFinishedAt() { + var command = mongoOperations.save(CommandTestFactory.createBuilder().createdAt(null).build()); + + repository.finishCommand(command.getId()); + + var result = repository.getById(command.getId()).get(); + assertThat(result.getFinishedAt()).isNotNull(); + } + + @Test + void shouldUpdateStatusToFinishedWithCreatedResource() { + var command = mongoOperations.save(CommandTestFactory.create()); + + repository.finishCommand(command.getId(), CommandTestFactory.CREATED_RESOURCE); + + var result = repository.getById(command.getId()).get(); + assertThat(result.getStatus()).isEqualTo(CommandStatus.FINISHED); + } + + @Test + void shouldSetFinishedAtWithCreatedResource() { + var command = mongoOperations.save(CommandTestFactory.createBuilder().createdAt(null).build()); + + repository.finishCommand(command.getId(), CommandTestFactory.CREATED_RESOURCE); + + var result = repository.getById(command.getId()).get(); + assertThat(result.getFinishedAt()).isNotNull(); + } + + @Test + void shouldSetCreatedResource() { + var command = CommandTestFactory.createBuilder().id(null).build(); + var savedCommand = repository.save(command); + assertThat(savedCommand.getCreatedResource()).isNull(); + + repository.finishCommand(savedCommand.getId(), CommandTestFactory.CREATED_RESOURCE); + + var result = repository.getById(savedCommand.getId()).get(); + assertThat(result.getCreatedResource()).isEqualTo(CommandTestFactory.CREATED_RESOURCE); + } + + @Test + void shouldNotOverrideCreatedResource() { + var command = CommandTestFactory.createBuilder().id(null).createdResource(CommandTestFactory.CREATED_RESOURCE).build(); + var savedCommand = repository.save(command); + + repository.finishCommand(savedCommand.getId(), CommandTestFactory.CREATED_RESOURCE); + + var result = repository.getById(savedCommand.getId()).get(); + assertThat(result.getCreatedResource()).isEqualTo(CommandTestFactory.CREATED_RESOURCE); + } + } + + @Nested + class TestGetById { + + private final String ADDITIONAL_COMMAND_ID = UUID.randomUUID().toString(); + + @BeforeEach + void persistAdditionalCommandToVorgang() { + mongoOperations.save(CommandTestFactory.create()); + } + + @Test + void shouldFindCommand() { + verifyCommandExists(CommandTestFactory.ID); + } + + @Test + void shouldFindAdditionalCommand() { + mongoOperations.save(CommandTestFactory.createBuilder().id(ADDITIONAL_COMMAND_ID).build()); + + verifyCommandExists(ADDITIONAL_COMMAND_ID); + } + + private void verifyCommandExists(String id) { + Optional<Command> command = repository.getById(id); + + assertThat(command).isPresent(); + assertThat(command.get().getId()).isEqualTo(id); + } + } + + @Nested + class TestUpdateCommandStatus { + + @BeforeEach + void persistVorgangWithCommand() { + repository.save(CommandTestFactory.create()); + } + + @ParameterizedTest + @EnumSource(CommandStatus.class) + void shouldUpdateCommandStatus(CommandStatus status) { + repository.updateCommandStatus(CommandTestFactory.ID, status); + + Optional<Command> command = repository.getById(CommandTestFactory.ID); + + assertThat(command).isPresent(); + assertThat(command.get().getStatus()).isEqualTo(status); + } + } + + @Nested + class TestUpdateCommandStatusAndVersion { + + @BeforeEach + void persistVorgangWithCommand() { + repository.save(CommandTestFactory.create()); + } + + @ParameterizedTest + @EnumSource(CommandStatus.class) + void shouldUpdateCommandStatus(CommandStatus status) { + repository.updateCommandStatusAndVersion(CommandTestFactory.ID, status, 78L); + + Optional<Command> command = repository.getById(CommandTestFactory.ID); + + assertThat(command).isPresent(); + assertThat(command.get().getRelationVersion()).isEqualTo(78L); + assertThat(command.get().getStatus()).isEqualTo(status); + } + } + + @Nested + class TestGetPendingCommands { + + @BeforeEach + void persistCommand() { + repository.save(CommandTestFactory.create()); + repository.save(CommandTestFactory.createBuilder().id(null).vorgangId(VorgangTestFactory.ID).status(CommandStatus.FINISHED).build()); + } + + @Test + void shouldReturnPendingCommand() { + var result = repository.getPendingCommands(VorgangTestFactory.ID); + + assertThat(result).hasSize(1); + assertThat(result.get(0).getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); + assertThat(result.get(0).getStatus()).isEqualTo(CommandStatus.PENDING); + } + } + + @Nested + class TestFindCommands { + + @Test + void shouldReturnCommandByVorgang() { + repository.save(CommandTestFactory.create()); + + var commands = repository.findCommands(VorgangTestFactory.ID, Collections.emptyList(), Optional.empty()); + + assertThat(commands).hasSize(1); + } + + @Nested + @DisplayName("by order, status and createdBy") + class TestByOrderStatusTime { + + @BeforeEach + void setup() { + repository.save(createCommandBuilder().build()); + repository.save(createCommandBuilder().status(CommandStatus.FINISHED).build()); + repository.save(createCommandBuilder().status(CommandStatus.FINISHED).order(Order.VORGANG_LOESCHEN.name()).build()); + } + + private PersistedCommand.PersistedCommandBuilder createCommandBuilder() { + return CommandTestFactory.createBuilder().id(null).createdAt(getNow()); + } + + private ZonedDateTime getNow() { + return ZonedDateTime.now(ZoneOffset.UTC).withNano(0); + } + + @Test + // TODO schreibe ein Testcase für Order, Status und Zeit + void shouldFindCommand() { + var command = repository.save(createCommandBuilder() + .status(CommandStatus.FINISHED) + .order(Order.VORGANG_LOESCHEN.name()) + .createdAt(getNow().minusMinutes(2)).build()); + + var commands = repository.findCommands(Order.VORGANG_LOESCHEN, CommandStatus.FINISHED, getNow().minusSeconds(1)); + + assertThat(commands).hasSize(1).first().usingRecursiveComparison().isEqualTo(command); + + } + } + + } + + @DisplayName("Test adding and updating previous state data") + @Nested + class TestHandlingPreviousState { + private static final String PREVIOUS_STATE_STATUS_VALUE = "NEU"; + private static final String PREVIOUS_STATE_STATUS_FIELD_KEY = Vorgang.MONGODB_FIELDNAME_STATUS; + + private Command command = CommandTestFactory.create(); + + @BeforeEach + void init() { + command = mongoOperations.save(command); + } + + @Test + void shouldSavePreviousStateValue() { + repository.patch(command.getId(), Map.of(PREVIOUS_STATE_STATUS_FIELD_KEY, PREVIOUS_STATE_STATUS_VALUE)); + + var persitedCommand = repository.getById(command.getId()); + + assertThat(persitedCommand).isPresent().get() + .extracting(command -> ((PersistedCommand) command).getPreviousState(), as(InstanceOfAssertFactories.MAP)) + .containsEntry(PREVIOUS_STATE_STATUS_FIELD_KEY, + PREVIOUS_STATE_STATUS_VALUE); + } + } + + @Nested + class TestDeleteAllByVorgang { + @Test + void shouldDeleteCommand() { + mongoOperations.save(CommandTestFactory.create()); + + repository.deleteAllByVorgang(VorgangTestFactory.ID); + + assertThat(mongoOperations.count(query(new Criteria()), Command.COLLECTION_NAME)).isZero(); + } + + @Test + void shouldNotDeleteOther() { + mongoOperations.save(CommandTestFactory.create()); + + repository.deleteAllByVorgang("other"); + + assertThat(mongoOperations.count(query(new Criteria()), Command.COLLECTION_NAME)).isOne(); + } + } + + @Nested + class TestExistsCommandWithUserId { + + @BeforeEach + void setup() { + mongoOperations.save(CommandTestFactory.create()); + } + + @Test + void shouldFindInCreatedBy() { + var isExists = repository.existsCommandWithUserId(CommandTestFactory.CREATED_BY); + + assertThat(isExists).isTrue(); + } + + @Test + void shouldFindInAssignedTo() { + var userId = "userId"; + var command = CommandTestFactory.createBuilder().createdBy(null).body(Map.of("assignedTo", userId)).build(); + mongoOperations.save(command); + + var isExists = repository.existsCommandWithUserId(userId); + + assertThat(isExists).isTrue(); + } + + @Test + void shouldReturnFalse() { + var esExists = repository.existsCommandWithUserId("userId"); + + assertThat(esExists).isFalse(); + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseMapperTest.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseMapperTest.java index db3d6da..15509a7 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.assertThat; @@ -29,9 +29,9 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse.GrpcResponseCode; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse.GrpcResponseCode; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; class CommandResponseMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseTestFactory.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseTestFactory.java index ca4e021..40fa14a 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandResponseTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandResponseTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.util.List; -import de.itvsh.ozg.pluto.command.CommandResponse.ResponseCode; +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.command.CommandResponse.ResponseCode; public class CommandResponseTestFactory { static final ResponseCode RESPONSE_CODE = ResponseCode.PENDING; - static final String MESSAGE_CODE = "de.itvsh.ozg.pluto.vorgang.command.error.invalid-document-version"; + static final String MESSAGE_CODE = "de.ozgcloud.vorgang.vorgang.command.error.invalid-document-version"; static final String MESSAGE_PARAM1 = "MessageParam1"; static final String MESSAGE_PARAM2 = "MessageParam2"; static final Command COMMAND = CommandTestFactory.create(); diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRevokedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRevokedEventTestFactory.java new file mode 100644 index 0000000..9b2b1a5 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandRevokedEventTestFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandRevokedEvent; + +public class CommandRevokedEventTestFactory { + public static CommandRevokedEvent create(Command command) { + return new CommandRevokedEvent(command); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceITCase.java similarity index 76% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceITCase.java index c6ae12a..6916ba9 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import java.util.Optional; import java.util.UUID; @@ -32,29 +33,63 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @DataITCase +@WithMockUser class CommandServiceITCase { - @Autowired + @SpyBean private CommandService commandService; @Autowired private MongoOperations mongoOperations; + @MockBean + private CurrentUserService currentUserService; + @Nested class TestVorgangCommandPersist { + @BeforeEach + void initCurrentUserService() { + when(currentUserService.findUser()).thenReturn(Optional.of(CallContextUserTestFactory.create())); + when(currentUserService.getUser()).thenReturn(CallContextUserTestFactory.create()); + } + @BeforeEach void persistVorgang() { mongoOperations.save(VorgangTestFactory.create()); } + @Test + void persistCommand() { + Command persistedCommand = commandService.saveCommand( + CommandTestFactory.createBuilder() + .relationId(CommandTestFactory.RELATION_ID) + .relationVersion(CommandTestFactory.RELATION_VERSION).build()); + + Optional<Command> commandOpt = commandService.findCommand(persistedCommand.getId()); + assertThat(commandOpt).isPresent(); + + Command command = commandOpt.get(); + assertThat(command.getId()).hasSize(36); + assertThat(command.getCreatedAt()).isNotNull(); + assertThat(command.getStatus()).isEqualTo(CommandStatus.PENDING); + assertThat(command.getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); + } + @Test void persistCommandHappyPath() { CreateCommandRequest request = CreateCommandRequestTestFactory @@ -63,7 +98,8 @@ class CommandServiceITCase { .relationVersion(CommandTestFactory.RELATION_VERSION) .build(); - Command persistedCommand = commandService.createCommand(request, Optional.of(VorgangTestFactory.STATUS)); + Command persistedCommand = commandService.createCommand(request); + verify(commandService, timeout(500)).setCommandFinished(eq(persistedCommand.getId()), any()); Optional<Command> commandOpt = commandService.findCommand(persistedCommand.getId()); assertThat(commandOpt).isPresent(); @@ -72,7 +108,7 @@ class CommandServiceITCase { assertThat(command.getId()).hasSize(36); assertThat(command.getCreatedAt()).isNotNull(); assertThat(command.getCreatedBy()).isEqualTo(request.getCallContext().getUser().getId()); - assertThat(command.getStatus()).isEqualTo(CommandStatus.PENDING); + assertThat(command.getStatus()).isEqualTo(CommandStatus.FINISHED); assertThat(command.getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceTest.java similarity index 62% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceTest.java index 74c21e8..4f40c42 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -42,11 +43,15 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class CommandServiceTest { @@ -71,14 +76,14 @@ class CommandServiceTest { @Test void shouldCallOperationRepository() { - service.createCommand(request, Optional.of(VorgangTestFactory.STATUS)); + service.createCommand(request); verify(repository).save(any()); } @Test void shouldReturnCommand() { - var command = (PersistedCommand) service.createCommand(request, Optional.of(Status.ANGENOMMEN)); + var command = (PersistedCommand) service.createCommand(request); assertThat(command.getOrder()).isEqualTo(Order.VORGANG_ANNEHMEN.name()); assertThat(command.getId()).isNotNull(); @@ -87,14 +92,13 @@ class CommandServiceTest { assertThat(command.getCreatedBy()).isEqualTo(UserTestFactory.ID); assertThat(command.getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); assertThat(command.getRelationVersion()).isEqualTo(CreateCommandRequestTestFactory.RELATION_VERSION); - assertThat(command.getPreviousStatus()).isEqualTo(Status.ANGENOMMEN); } @Test void shouldHandleMissingCallContext() { var request = CreateCommandRequestTestFactory.createBuilder().callContext(null).build(); - var command = service.createCommand(request, Optional.of(Status.ANGENOMMEN)); + var command = service.createCommand(request); assertThat(command).isNotNull(); } @@ -106,7 +110,7 @@ class CommandServiceTest { void fromCallContext() { when(currentUserService.findUser()).thenReturn(Optional.empty()); - var command = service.createCommand(request, Optional.of(Status.ANGENOMMEN)); + var command = service.createCommand(request); assertThat(command.getCreatedBy()).isEqualTo(UserTestFactory.ID); } @@ -116,7 +120,7 @@ class CommandServiceTest { var request = CreateCommandRequestTestFactory.createBuilder().callContext(null).build(); when(currentUserService.findUser()).thenReturn(Optional.of(CallContextUserTestFactory.create())); - var command = service.createCommand(request, Optional.of(Status.ANGENOMMEN)); + var command = service.createCommand(request); assertThat(command.getCreatedBy()).isEqualTo(UserTestFactory.ID); } @@ -126,7 +130,7 @@ class CommandServiceTest { when(currentUserService.findUser()) .thenReturn(Optional.of(CallContextUserTestFactory.createBuilder().userId(Optional.of("other")).build())); - var command = service.createCommand(request, Optional.of(Status.ANGENOMMEN)); + var command = service.createCommand(request); assertThat(command.getCreatedBy()).isEqualTo("other"); } @@ -138,7 +142,7 @@ class CommandServiceTest { var request = CreateCommandRequestTestFactory.createBuilder().callContext(CallContextTestFactory.createBuilder().user(null).build()) .build(); - service.createCommand(request, Optional.empty()); + service.createCommand(request); verify(repository).save(commandCaptor.capture()); assertThat(commandCaptor.getValue().getCreatedBy()).isNull(); @@ -176,6 +180,19 @@ class CommandServiceTest { } } + @Nested + class TestFindCommands { + + @Test + void shouldCallRepository() { + var createdAfter = ZonedDateTime.now(); + + service.findFinishedVorgangLoeschenCommandsOlderThen(createdAfter); + + verify(repository).findCommands(Order.VORGANG_LOESCHEN, CommandStatus.FINISHED, createdAfter); + } + } + @Nested class TestSetCommandFinished { @@ -185,6 +202,20 @@ class CommandServiceTest { verify(repository).updateCommandStatusAndVersion(CommandTestFactory.ID, CommandStatus.FINISHED, 17L); } + + @Test + void shouldCallRepositoryFinishCommand() { + service.setCommandFinished(CommandTestFactory.ID); + + verify(repository).finishCommand(CommandTestFactory.ID); + } + + @Test + void shouldCallRepositoryFinishCommandWithCreatedResource() { + service.setCommandFinished(CommandTestFactory.ID, CommandTestFactory.CREATED_RESOURCE); + + verify(repository).finishCommand(CommandTestFactory.ID, CommandTestFactory.CREATED_RESOURCE); + } } @Nested @@ -199,18 +230,64 @@ class CommandServiceTest { } @Nested - class TestRevokeCommand { + class TestRevokeCommandPending { final String commandId = CommandTestFactory.ID; + @Test + void shouldThrowException() { + assertThatExceptionOfType(TechnicalException.class).isThrownBy(() -> service.setCommandRevokePending(commandId)); + } + @Test void shouldUpdateCommandStatus() { + when(repository.getById(commandId)).thenReturn(Optional.of(CommandTestFactory.create())); + + service.setCommandRevokePending(commandId); + + verify(repository).updateCommandStatus(anyString(), any(CommandStatus.class)); + } + + @Test + void shouldCallPublishRevokeCommandEvent() { + when(repository.getById(commandId)).thenReturn(Optional.of(CommandTestFactory.create())); + service.setCommandRevokePending(commandId); - verify(service).updateCommandStatus(commandId, CommandStatus.REVOKE_PENDING); + verify(service).publishRevokeCommandEvent(any(String.class)); } } + @Nested + class TestFiringRevokeCommand { + + final String commandId = CommandTestFactory.ID; + + @Test + void shoudlFireEvent() { + when(repository.getById(commandId)).thenReturn(Optional.of(CommandTestFactory.create())); + + service.publishRevokeCommandEvent(commandId); + + verify(publisher).publishEvent(any(RevokeCommandEvent.class)); + } + + @Test + void shoudlThrowTechnicalExceptionBecauseCommandNotFound() { + when(repository.getById(commandId)).thenReturn(Optional.empty()); + + assertThatExceptionOfType(TechnicalException.class).isThrownBy(() -> service.publishRevokeCommandEvent(commandId)); + } + + @Test + void shoudlThrowTechnicalExceptionBecauseNoPreviousState() { + when(repository.getById(commandId)).thenReturn(Optional.of(CommandTestFactory.createBuilder().previousState(null).build())); + + assertThatExceptionOfType(TechnicalException.class).isThrownBy(() -> service.publishRevokeCommandEvent(commandId)); + } + + } + @Nested class TestExistsPendingCommands { @@ -251,4 +328,39 @@ class CommandServiceTest { assertThat(result).isEqualTo(pendingCommands); } } + + @Nested + class TestCommandSetPreviousState { + + final String commandId = CommandTestFactory.ID; + + @Test + void shouldSetPreviousState() { + service.setPreviousState(commandId, CommandTestFactory.PREVIOUS_STATE); + + verify(repository).patch(anyString(), any()); + } + } + + @Nested + class TestDeleteAllByVorgang { + @Test + void shouldCallRepository() { + service.deleteAllByVorgang(VorgangTestFactory.ID); + + verify(repository).deleteAllByVorgang(VorgangTestFactory.ID); + } + } + + @Nested + class TestFilterUserIdsWithoutCommands { + + @Test + void shouldCallRepository() { + service.existsCommandWithUserId(UserTestFactory.ID); + + verify(repository).existsCommandWithUserId(UserTestFactory.ID); + } + + } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java similarity index 79% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java index 3fde549..881cb3f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.time.ZonedDateTime; +import java.util.Map; import java.util.UUID; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class CommandTestFactory { @@ -43,7 +45,8 @@ public class CommandTestFactory { public static final long RELATION_VERSION = VorgangTestFactory.VERSION; public static final Order ORDER = Order.VORGANG_ANNEHMEN; - public static final Status PREV_STATUS = Status.NEU; + public static final Map<String, Object> PREVIOUS_STATE = Map.of("test", "value"); + public static final String CREATED_RESOURCE = "createdResource"; public static PersistedCommand create() { return createBuilder().build(); @@ -59,7 +62,7 @@ public class CommandTestFactory { .status(STATUS) .relationId(RELATION_ID) .relationVersion(RELATION_VERSION) - .previousStatus(PREV_STATUS) + .previousState(PREVIOUS_STATE) .order(ORDER.name()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CreateCommandRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CreateCommandRequestTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CreateCommandRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CreateCommandRequestTestFactory.java index ef097e9..021e5cd 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CreateCommandRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CreateCommandRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class CreateCommandRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCallContextTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCallContextTestFactory.java similarity index 78% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCallContextTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCallContextTestFactory.java index f35988f..7b474c2 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCallContextTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCallContextTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcUser; +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.vorgang.grpc.command.GrpcUser; public class GrpcCallContextTestFactory { private static final GrpcUser USER = GrpcUserTestFactory.create(); - public static final String CLIENT = "testGoofyClient"; + public static final String CLIENT = LoremIpsum.getInstance().getFirstName() + "Client"; public static GrpcCallContext create() { return createBuilder().build(); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandMapperTest.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandMapperTest.java index 1ace4f8..5346247 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; @@ -29,8 +29,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; class GrpcCommandMapperTest { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceITCase.java new file mode 100644 index 0000000..1692eb4 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceITCase.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.command; + +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; +import static org.mockito.Mockito.*; + +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +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.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeReadPermitted; +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@SpringBootTest(properties = { + "grpc.server.inProcessName=test", + "grpc.client.inProcess.address=in-process:test" +}) +@DirtiesContext +@DataITCase +@WithMockUser +class GrpcCommandServiceITCase { + + @GrpcClient("inProcess") + private CommandServiceBlockingStub serviceBlockingStub; + + @Autowired + private MongoOperations mongoOperations; + + @MockBean + private ClientAttributeReadPermitted readIsPermitted; + + private GrpcObjectMapper grpcObjectMapper = Mappers.getMapper(GrpcObjectMapper.class); + + @Nested + class TestCreateCommand { + + private GrpcCreateCommandRequest request; + + @BeforeEach + void prepareDatabase() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + mongoOperations.dropCollection(Command.COLLECTION_NAME); + mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + + var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()); + + request = GrpcCreateCommandRequestTestFactory.createBuilder() + .setVorgangId(vorgang.getId()).setRelationId(vorgang.getId()) + .setOrder(GrpcOrder.CREATE_ATTACHED_ITEM) + .setBodyObj(grpcObjectMapper.fromMap(VorgangAttachedItemTestFactory.asMap())).build(); + + when(readIsPermitted.test(any())).thenReturn(true); + } + + @Test + void shouldPersistCommand() { + serviceBlockingStub.createCommand(request); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var commands = mongoOperations.findAll(Command.class); + + assertThat(commands).hasSize(1).first().satisfies(command -> { + assertThat(command.getBodyObject()).isNotNull(); + assertThat(command.getBodyObject()).containsEntry("itemName", VorgangAttachedItemTestFactory.ITEM_NAME); + }); + }); + } + + @Test + void shouldExecuteCommand() { + serviceBlockingStub.createCommand(request); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var commands = mongoOperations.findAll(Command.class); + + assertThat(commands).hasSize(1).first().extracting(Command::getStatus).isEqualTo(CommandStatus.FINISHED); + }); + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceTest.java similarity index 79% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceTest.java index 7a0b2da..e73d1ec 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCommandServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCommandServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -44,23 +44,29 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; - -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcExistsPendingCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcExistsPendingCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcFindCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcGetPendingCommandsResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.grpc.command.GrpcRevokeCommandRequest; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcEmpty; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcGetPendingCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcRevokeCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcSetCommandExecutedRequest; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; +import lombok.SneakyThrows; class GrpcCommandServiceTest { @@ -68,17 +74,19 @@ class GrpcCommandServiceTest { @InjectMocks private GrpcCommandService service; @Mock - private VorgangService vorgangService; - @Mock private GrpcCreateCommandRequestMapper createCommandRequestMapper; @Mock private CommandService commandService; + @Mock private GrpcCommandResponseMapper commandResponseMapper; @Mock private GrpcCommandMapper commandMapper; + @Mock private PolicyService policyService; + @Mock + private ApplicationEventPublisher eventPublisher; @Nested class TestCreateCommand { @@ -95,12 +103,9 @@ class GrpcCommandServiceTest { @BeforeEach void mockMapper() { when(createCommandRequestMapper.fromGrpc(any(GrpcCreateCommandRequest.class))).thenReturn(createComandRequest); - when(vorgangService.getById(any())).thenReturn(VorgangTestFactory.create()); - when(commandService.createCommand(any(CreateCommandRequest.class), any())).thenReturn(persistedCommand); + when(commandService.createCommand(any(CreateCommandRequest.class))).thenReturn(persistedCommand); when(commandService.findCommand(anyString())).thenReturn(Optional.of(CommandTestFactory.create())); when(commandResponseMapper.toGrpc(any(CommandResponse.class))).thenReturn(response); - - doNothing().when(service).executeOrder(any()); } @Test @@ -117,18 +122,11 @@ class GrpcCommandServiceTest { verify(createCommandRequestMapper).fromGrpc(request); } - @Test - void shouldCallVorgangService() throws Exception { - callCreateCommand(); - - verify(vorgangService).getById(CommandTestFactory.RELATION_ID); - } - @Test void shouldCallCommandService() throws Exception { callCreateCommand(); - verify(commandService).createCommand(createComandRequest, Optional.of(VorgangTestFactory.STATUS)); + verify(commandService).createCommand(createComandRequest); } @Test @@ -161,7 +159,8 @@ class GrpcCommandServiceTest { @ParameterizedTest @EnumSource(mode = Mode.EXCLUDE, names = { "VORGANG_ANNEHMEN", "VORGANG_VERWERFEN", "VORGANG_ZURUECKHOLEN", "VORGANG_BEARBEITEN", - "VORGANG_BESCHEIDEN", "VORGANG_ZURUECKSTELLEN", "VORGANG_ABSCHLIESSEN", "VORGANG_WIEDEREROEFFNEN" }) + "VORGANG_BESCHEIDEN", "VORGANG_ZURUECKSTELLEN", "VORGANG_ABSCHLIESSEN", "VORGANG_WIEDEREROEFFNEN", "VORGANG_ZUM_LOESCHEN_MARKIEREN", + "VORGANG_LOESCHEN" }) void shouldReturnFalse(Order order) { var result = service.isStatusChangeOrder(order.name()); @@ -257,20 +256,6 @@ class GrpcCommandServiceTest { verify(commandResponseMapper).toGrpc(any()); } - @Test - void shouldCallServiceSetCommandRevoked() throws Exception { - callRevokeCommand(); - - verify(commandService).setCommandRevoked(any()); - } - - @Test - void shouldCallProceed() throws Exception { - callRevokeCommand(); - - verify(service).proceedRevokeCommand(CommandTestFactory.ID); - } - @Nested class TestProceedRevokeCommand { @@ -282,25 +267,12 @@ class GrpcCommandServiceTest { } @Test + @SneakyThrows void shouldLoadCommand() { - service.proceedRevokeCommand(CommandTestFactory.ID); + callRevokeCommand(); verify(service).getCommand(CommandTestFactory.ID); } - - @Test - void shouldRevokeCommand() { - service.proceedRevokeCommand(CommandTestFactory.ID); - - verify(vorgangService).revokeStatusChange(command); - } - - @Test - void shouldSetCommandRevoked() { - service.proceedRevokeCommand(CommandTestFactory.ID); - - verify(commandService).setCommandRevoked(CommandTestFactory.ID); - } } private void callRevokeCommand() throws Exception { @@ -428,4 +400,59 @@ class GrpcCommandServiceTest { service.findCommands(request, responseObserver); } } + + @Nested + class TestSetCommandExecuted { + + @Mock + private StreamObserver<GrpcEmpty> responseObserver; + + @BeforeEach + void init() { + when(commandService.findCommand(any())).thenReturn(Optional.of(CommandTestFactory.create())); + } + + @Test + void shouldLoadCommand() { + service.setCommandExecuted(buildRequest(), responseObserver); + + verify(commandService).findCommand(CommandTestFactory.ID); + } + + @Test + void shouldPublishEvent() { + service.setCommandExecuted(buildRequest(), responseObserver); + + verify(eventPublisher).publishEvent(any(CommandExecutedEvent.class)); + } + + @Test + void shouldHandleMissingCommand() { + when(commandService.findCommand(any())).thenReturn(Optional.empty()); + + service.setCommandExecuted(buildRequest(), responseObserver); + + verifyNoInteractions(eventPublisher); + } + + @Test + void shouldCallOnNext() { + service.setCommandExecuted(buildRequest(), responseObserver); + + verify(responseObserver).onNext(GrpcEmpty.newBuilder().build()); + } + + @Test + void shouldCallOnCompleted() { + service.setCommandExecuted(buildRequest(), responseObserver); + + verify(responseObserver).onCompleted(); + } + + private GrpcSetCommandExecutedRequest buildRequest() { + return GrpcSetCommandExecutedRequest.newBuilder() + .setCommandId(CommandTestFactory.ID) + .build(); + } + } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapperTest.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapperTest.java index d6ab033..edfa651 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; @@ -32,9 +32,11 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.files.FileIdMapper; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.User; +import de.ozgcloud.vorgang.files.FileIdMapper; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; class GrpcCreateCommandRequestMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestTestFactory.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestTestFactory.java index 9b328d2..08e25dd 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcCreateCommandRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcCreateCommandRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class GrpcCreateCommandRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcUserTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcUserTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcUserTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcUserTestFactory.java index 3aec033..ae7c36d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/GrpcUserTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/GrpcUserTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import java.util.List; -import de.itvsh.ozg.pluto.grpc.command.GrpcUser; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcUser; public class GrpcUserTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceITCase.java similarity index 80% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceITCase.java index 5b8e1ba..066ad75 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; @@ -36,19 +36,21 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.mail.postfach.PostfachMailTestFactory; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @WithMockUser @DataITCase class PersistPostfachMailByCommandServiceITCase { @Autowired - private PersistPostfachMailByCommandService service; + private PersistPostfachNachrichtByCommandService service; @Autowired private MongoOperations mongoOperations; @@ -72,7 +74,8 @@ class PersistPostfachMailByCommandServiceITCase { @Test void shouldCreateCommand() { - service.persistMail(Optional.of(UserTestFactory.ID), PostfachMailTestFactory.createBuilder().vorgangId(persistedVorgang.getId()).build()); + service.persistNachricht(Optional.of(UserTestFactory.ID), + PostfachNachrichtTestFactory.createBuilder().vorgangId(persistedVorgang.getId()).build()); var commands = mongoOperations.findAll(Command.class); assertThat(commands).hasSize(1); @@ -90,8 +93,8 @@ class PersistPostfachMailByCommandServiceITCase { mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); persistedItem = mongoOperations.save(VorgangAttachedItemTestFactory.createBuilder() .id(null).version(0).vorgangId(persistedVorgang.getId()) - .client(PersistPostfachMailByCommandService.CLIENT) - .itemName(PersistPostfachMailByCommandService.ITEM_NAME).build()); + .client(PersistPostfachNachrichtByCommandService.CLIENT) + .itemName(PersistPostfachNachrichtByCommandService.ITEM_NAME).build()); } @DisplayName("find by vorgang") diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceTest.java similarity index 64% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceTest.java index df36dee..d13b312 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/PersistPostfachMailByCommandServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/PersistPostfachMailByCommandServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.command; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Optional; @@ -45,22 +44,23 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.mail.postfach.MessageAttachmentTestFactory; -import de.itvsh.ozg.mail.postfach.MessageTestFactory; -import de.itvsh.ozg.mail.postfach.PostfachMailTestFactory; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemMapper; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemService; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.files.FileId; -import de.itvsh.ozg.pluto.files.FileService; -import de.itvsh.ozg.pluto.files.OzgFile; -import de.itvsh.ozg.pluto.files.UploadedFilesReference; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageAttachmentTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemMapper; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemService; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.files.FileId; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.files.OzgFile; +import de.ozgcloud.vorgang.files.UploadedFilesReference; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class PersistPostfachMailByCommandServiceTest { @InjectMocks - private PersistPostfachMailByCommandService service; + private PersistPostfachNachrichtByCommandService service; @Mock private CommandService commandService; @Mock @@ -68,6 +68,7 @@ class PersistPostfachMailByCommandServiceTest { @Mock private FileService fileService; + @DisplayName("Persist mail") @Nested class TestPersistMail { @@ -93,7 +94,7 @@ class PersistPostfachMailByCommandServiceTest { var request = callService(); assertThat(request.getRelationId()).isEqualTo(MessageTestFactory.VORGANG_ID); - assertThat(request.getRelationVersion()).isEqualTo(-1); + assertThat(request.getRelationVersion()).isNull(); } @Test @@ -117,34 +118,35 @@ class PersistPostfachMailByCommandServiceTest { assertThat(request.getBodyObject()) .containsEntry(VorgangAttachedItemMapper.PROPERTY_VORGANG_ID, MessageTestFactory.VORGANG_ID) - .containsEntry(VorgangAttachedItemMapper.PROPERTY_CLIENT, "MailService") + .containsEntry(VorgangAttachedItemMapper.PROPERTY_CLIENT, "OzgCloud_NachrichtenManager") .containsEntry(VorgangAttachedItemMapper.PROPERTY_ITEM_NAME, "PostfachMail") .containsKey(VorgangAttachedItemMapper.PROPERTY_ITEM); } @Test void shouldNotAddUser() { - service.persistMail(Optional.empty(), PostfachMailTestFactory.create()); + service.persistNachricht(Optional.empty(), PostfachNachrichtTestFactory.create()); verify(commandService).createCommand(requestCaptor.capture()); assertThat(requestCaptor.getValue().getCallContext().getUser()).isNull(); } private CreateCommandRequest callService() { - service.persistMail(Optional.of(UserTestFactory.ID), PostfachMailTestFactory.create()); + service.persistNachricht(Optional.of(UserTestFactory.ID), PostfachNachrichtTestFactory.createBuilder().id(null).build()); verify(commandService).createCommand(requestCaptor.capture()); return requestCaptor.getValue(); } + @DisplayName("build mail map") @Nested class TestBuildMailMap { @Test void shouldContainAllFieldsIgnoringId() { - var map = service.buildMailMap(PostfachMailTestFactory.createBuilder().id(null).build()); + var map = service.buildNachrichtMap(PostfachNachrichtTestFactory.createBuilder().id(null).build()); - var mapWithoutId = PostfachMailTestFactory.asMap(); + var mapWithoutId = PostfachNachrichtTestFactory.asMap(); mapWithoutId.remove("id"); assertThat(map).containsAllEntriesOf(mapWithoutId); @@ -152,12 +154,26 @@ class PersistPostfachMailByCommandServiceTest { @Test void shouldIgnoreEmptyMessageId() { - assertDoesNotThrow(() -> service.buildMailMap(PostfachMailTestFactory.createBuilder().messageId(null).build())); + assertDoesNotThrow(() -> service.buildNachrichtMap(PostfachNachrichtTestFactory.createBuilder().messageId(null).build())); } @Test void shouldIgnoreEmptyCreatedBy() { - assertDoesNotThrow(() -> service.buildMailMap(PostfachMailTestFactory.createBuilder().createdBy(null).build())); + assertDoesNotThrow(() -> service.buildNachrichtMap(PostfachNachrichtTestFactory.createBuilder().createdBy(null).build())); + } + + @Test + void shouldHandleNullAsPostfachId() { + var postfachMail = PostfachNachrichtTestFactory.createBuilder().postfachId(null).build(); + + assertDoesNotThrow(() -> service.buildNachrichtMap(postfachMail)); + } + + @Test + void shouldProceedWithEmptyPostfachAddress() { + var postfachMail = PostfachNachrichtTestFactory.createBuilder().postfachAddress(null).build(); + + assertDoesNotThrow(() -> service.buildNachrichtMap(postfachMail)); } } } @@ -168,21 +184,21 @@ class PersistPostfachMailByCommandServiceTest { @BeforeEach void init() { when(attachedItemService.findById(anyString())) - .thenReturn(Optional.of(VorgangAttachedItemTestFactory.createBuilder().item(PostfachMailTestFactory.asMap()).build())); + .thenReturn(Optional.of(VorgangAttachedItemTestFactory.createBuilder().item(PostfachNachrichtTestFactory.asMap()).build())); } @Test void shouldCallItemService() { - service.findById(PostfachMailTestFactory.ID); + service.findById(PostfachNachrichtTestFactory.ID); - verify(attachedItemService).findById(PostfachMailTestFactory.ID); + verify(attachedItemService).findById(PostfachNachrichtTestFactory.ID); } @Test void shouldReturnNachrichtAsMap() { - var found = service.findById(PostfachMailTestFactory.ID); + var found = service.findById(PostfachNachrichtTestFactory.ID); - assertThat(found).isPresent().get().usingRecursiveComparison().isEqualTo(PostfachMailTestFactory.asMap()); + assertThat(found).isPresent().get().usingRecursiveComparison().isEqualTo(PostfachNachrichtTestFactory.asMap()); } } @@ -192,22 +208,22 @@ class PersistPostfachMailByCommandServiceTest { @BeforeEach void init() { when(attachedItemService.find(anyString(), any(), any())) - .thenReturn(Stream.of(VorgangAttachedItemTestFactory.createBuilder().item(PostfachMailTestFactory.asMap()).build())); + .thenReturn(Stream.of(VorgangAttachedItemTestFactory.createBuilder().item(PostfachNachrichtTestFactory.asMap()).build())); } @Test void shouldCallItemService() { service.findByVorgangAsMap(VorgangTestFactory.ID); - verify(attachedItemService).find(VorgangTestFactory.ID, Optional.of(PersistPostfachMailByCommandService.CLIENT), - Optional.of(PersistPostfachMailByCommandService.ITEM_NAME)); + verify(attachedItemService).find(VorgangTestFactory.ID, Optional.of(PersistPostfachNachrichtByCommandService.CLIENT), + Optional.of(PersistPostfachNachrichtByCommandService.ITEM_NAME)); } @Test void shouldReturnNachrichtenAsMap() { var found = service.findByVorgangAsMap(VorgangTestFactory.ID); - assertThat(found).first().usingRecursiveComparison().isEqualTo(PostfachMailTestFactory.asMap()); + assertThat(found).first().usingRecursiveComparison().isEqualTo(PostfachNachrichtTestFactory.asMap()); } } @@ -231,21 +247,21 @@ class PersistPostfachMailByCommandServiceTest { @BeforeEach void mockService() { when(attachedItemService.getById(anyString())) - .thenReturn(VorgangAttachedItemTestFactory.createBuilder().item(PostfachMailTestFactory.asMap()).build()); + .thenReturn(VorgangAttachedItemTestFactory.createBuilder().item(PostfachNachrichtTestFactory.asMap()).build()); } @Test void shouldCallService() { - service.getById(PostfachMailTestFactory.ID); + service.getById(PostfachNachrichtTestFactory.ID); - verify(attachedItemService).getById(PostfachMailTestFactory.ID); + verify(attachedItemService).getById(PostfachNachrichtTestFactory.ID); } @Test void shouldReturnItem() { - Map<String, Object> item = service.getById(PostfachMailTestFactory.ID); + Map<String, Object> item = service.getById(PostfachNachrichtTestFactory.ID); - assertThat(item).isEqualTo(PostfachMailTestFactory.asMap()); + assertThat(item).isEqualTo(PostfachNachrichtTestFactory.asMap()); } } @@ -256,8 +272,8 @@ class PersistPostfachMailByCommandServiceTest { UploadedFilesReference ref = service.createUploadedFilesReference(MessageTestFactory.VORGANG_ID); assertThat(ref.getVorgangId()).isEqualTo(MessageTestFactory.VORGANG_ID); - assertThat(ref.getClient()).isEqualTo(PersistPostfachMailByCommandService.CLIENT); - assertThat(ref.getName()).isEqualTo(PersistPostfachMailByCommandService.ATTACHMENT_NAME); + assertThat(ref.getClient()).isEqualTo(PersistPostfachNachrichtByCommandService.CLIENT); + assertThat(ref.getName()).isEqualTo(PersistPostfachNachrichtByCommandService.ATTACHMENT_NAME); } } @@ -265,7 +281,7 @@ class PersistPostfachMailByCommandServiceTest { class TestOzgFileCreation { @Test void shouldCreateOzgFile() { - OzgFile file = service.createOzgFile(MessageAttachmentTestFactory.create(), ContentType.APPLICATION_OCTET_STREAM.toString(), + OzgFile file = service.createOzgFile(MessageAttachmentTestFactory.FILENAME, ContentType.APPLICATION_OCTET_STREAM.toString(), MessageAttachmentTestFactory.SIZE); assertThat(file.getContentType()).isEqualTo(ContentType.APPLICATION_OCTET_STREAM.toString()); @@ -293,14 +309,14 @@ class PersistPostfachMailByCommandServiceTest { void shouldHaveClientName() { var ref = callService(); - assertThat(ref.getClient()).isEqualTo(PersistPostfachMailByCommandService.CLIENT); + assertThat(ref.getClient()).isEqualTo(PersistPostfachNachrichtByCommandService.CLIENT); } @Test void shouldHaveName() { var ref = callService(); - assertThat(ref.getName()).isEqualTo(PersistPostfachMailByCommandService.ATTACHMENT_NAME); + assertThat(ref.getName()).isEqualTo(PersistPostfachNachrichtByCommandService.ATTACHMENT_NAME); } @Test @@ -311,7 +327,7 @@ class PersistPostfachMailByCommandServiceTest { } private UploadedFilesReference callService() { - service.persistAttachment(VorgangTestFactory.ID, MessageAttachmentTestFactory.create()); + service.persistAttachment(VorgangTestFactory.ID, AttachmentFileTestFactory.create()); verify(fileService).uploadFileStream(refCaptor.capture(), any(), any(), any()); @@ -347,7 +363,9 @@ class PersistPostfachMailByCommandServiceTest { } private OzgFile callService() { - service.persistAttachment(VorgangTestFactory.ID, MessageAttachmentTestFactory.create()); + var attachmentFile = AttachmentFileTestFactory.createBuilder().content(AttachmentFileTestFactory.BASE64_CONTENT_SUPPLIER).build(); + + service.persistAttachment(VorgangTestFactory.ID, attachmentFile); verify(fileService).uploadFileStream(any(), ozgFileCaptor.capture(), any(), any()); @@ -356,18 +374,19 @@ class PersistPostfachMailByCommandServiceTest { } @Test - void shouldHaveContent() throws IOException { + void shouldHaveContent() { ArgumentCaptor<InputStream> contentCaptor = ArgumentCaptor.forClass(InputStream.class); + var attachment = AttachmentFileTestFactory.createBuilder().content(AttachmentFileTestFactory.BASE64_CONTENT_SUPPLIER).build(); - service.persistAttachment(VorgangTestFactory.ID, MessageAttachmentTestFactory.create()); + service.persistAttachment(VorgangTestFactory.ID, attachment); verify(fileService).uploadFileStream(any(), any(), any(), contentCaptor.capture()); - assertThat(contentCaptor.getValue().readAllBytes()).isEqualTo(MessageAttachmentTestFactory.DECODED_CONTENT.getBytes()); + assertThat(contentCaptor.getValue()).hasContent(AttachmentFileTestFactory.CONTENT); } @Test void shouldReturnFileId() { - var id = service.persistAttachment(VorgangTestFactory.ID, MessageAttachmentTestFactory.create()); + var id = service.persistAttachment(VorgangTestFactory.ID, AttachmentFileTestFactory.create()); assertThat(id).isEqualTo("42"); } @@ -377,21 +396,27 @@ class PersistPostfachMailByCommandServiceTest { class TestGetTypeByFileName { @Test void shouldReturnDocxType() { - var type = service.getTypeByFile("file.docx", "word-file"); + var attachmentFile = AttachmentFileTestFactory.createBuilder().name("file.docx").contentType("word-file").build(); + + var type = service.getTypeByFile(attachmentFile); assertThat(type).isEqualTo("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); } @Test void shouldReturnOctedStreamAsUnkown() { - var type = service.getTypeByFile("file.qtsch", "lalal"); + var attachmentFile = AttachmentFileTestFactory.createBuilder().name("file.qtsch").contentType("lalal").build(); + + var type = service.getTypeByFile(attachmentFile); assertThat(type).isEqualTo(ContentType.APPLICATION_OCTET_STREAM.toString()); } @Test void shouldReturnOdtType() { - var type = service.getTypeByFile("file.odt", "opendoc file"); + var attachmentFile = AttachmentFileTestFactory.createBuilder().name("file.odt").contentType("opendoc file").build(); + + var type = service.getTypeByFile(attachmentFile); assertThat(type).isEqualTo("application/vnd.oasis.opendocument.text"); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverterTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverterTest.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverterTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverterTest.java index f940866..0059677 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeReadConverterTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeReadConverterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import static org.assertj.core.api.Assertions.*; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverterTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverterTest.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverterTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverterTest.java index b3f3f82..26e55de 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/converter/ZonedDateTimeWriteConverterTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/converter/ZonedDateTimeWriteConverterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.converter; +package de.ozgcloud.vorgang.common.converter; import static org.assertj.core.api.Assertions.*; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CollisionVerifierTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CollisionVerifierTest.java new file mode 100644 index 0000000..05ccc5b --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CollisionVerifierTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.db; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.ConcurrentModificationException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import com.mongodb.Function; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; + +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +class CollisionVerifierTest { + + private CollisionVerifier verifier; + + @Mock + private Function<String, Boolean> doEntryWithIdExist; + + @BeforeEach + void setup() { + verifier = spy(new CollisionVerifier(doEntryWithIdExist)); + } + + @Nested + class VerifyUpdateResult { + + @Mock + private UpdateResult result; + + @Test + @DisplayName("should detect concurrent modification") + void shouldThrowConcurrentModification() { + when(result.getMatchedCount()).thenReturn(0L); + when(result.getModifiedCount()).thenReturn(0L); + when(doEntryWithIdExist.apply(anyString())).thenReturn(true); + + assertThatThrownBy(() -> verifier.verify(result, VorgangTestFactory.ID)).isInstanceOf(ConcurrentModificationException.class); + } + + @Nested + @DisplayName("should NOT throw concurrent modification exception") + class NotThrowingException { + @Test + void onSuccessfullUpdate() { + when(result.getModifiedCount()).thenReturn(1L); + + assertThatCode(() -> verifier.verify(result, VorgangTestFactory.ID)).doesNotThrowAnyException(); + } + + @Test + @DisplayName("if Vorgang does not exists.") + void onMissingVorgang() { + when(result.getMatchedCount()).thenReturn(0L); + when(result.getModifiedCount()).thenReturn(0L); + when(doEntryWithIdExist.apply(anyString())).thenReturn(false); + + assertThatCode(() -> verifier.verify(result, VorgangTestFactory.ID)).doesNotThrowAnyException(); + } + + @Test + @DisplayName("on unchanged") + void onOnchangedVorgang() { + when(result.getMatchedCount()).thenReturn(1L); + when(result.getModifiedCount()).thenReturn(0L); + + assertThatCode(() -> verifier.verify(result, VorgangTestFactory.ID)).doesNotThrowAnyException(); + } + } + + } + + @Nested + class VerifyDeleteResult { + + @Mock + private DeleteResult result; + + @BeforeEach + void setup() { + when(result.wasAcknowledged()).thenReturn(true); + } + + @Test + @DisplayName("should detect concurrent modification") + void shouldThrowConcurrentModification() { + when(doEntryWithIdExist.apply(anyString())).thenReturn(true); + when(result.getDeletedCount()).thenReturn(0L); + + assertThatThrownBy(() -> verifier.verify(result, VorgangTestFactory.ID)).isInstanceOf(ConcurrentModificationException.class); + } + + @Nested + @DisplayName("should NOT throw concurrent modification exception") + class TestNotThrowingException { + + @Test + void onSuccessfulDelete() { + when(result.getDeletedCount()).thenReturn(1L); + + assertThatCode(() -> verifier.verify(result, VorgangTestFactory.ID)).doesNotThrowAnyException(); + } + + @Test + @DisplayName("if VorgangAttachedItem does not exists.") + void onMissingVorgangAttachedItem() { + when(doEntryWithIdExist.apply(anyString())).thenReturn(false); + when(result.getDeletedCount()).thenReturn(0L); + + assertThatCode(() -> verifier.verify(result, VorgangTestFactory.ID)).doesNotThrowAnyException(); + } + + } + + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtilTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CriteriaUtilTest.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtilTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CriteriaUtilTest.java index d781fb8..0b2432f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/CriteriaUtilTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/db/CriteriaUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.common.db; import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import de.ozgcloud.vorgang.vorgang.Vorgang; + class CriteriaUtilTest { @Nested @@ -35,14 +37,14 @@ class CriteriaUtilTest { @Test void shouldContainsKey() { - var criteria = CriteriaUtil.vorgangInCreation(); + var criteria = CriteriaUtil.vorgangNotInCreation(); assertThat(criteria.getKey()).isEqualTo(Vorgang.MONGODB_FIELDNAME_IN_CREATION); } @Test void shouldCreateCriteria() { - var criteria = CriteriaUtil.vorgangInCreation(); + var criteria = CriteriaUtil.vorgangNotInCreation(); assertThat(criteria.getCriteriaObject()).containsEntry(Vorgang.MONGODB_FIELDNAME_IN_CREATION, false); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandlerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandlerTest.java similarity index 96% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandlerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandlerTest.java index 57c21a1..06f41a2 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/ExceptionHandlerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/ExceptionHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,8 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; +import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Map; @@ -34,12 +35,10 @@ import org.mockito.InjectMocks; import org.mockito.Spy; import org.springframework.security.access.AccessDeniedException; -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.errorhandling.FunctionalErrorCode; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.grpc.Status.Code; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalExceptionTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalExceptionTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalExceptionTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalExceptionTest.java index 180a935..64e28ab 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/errorhandling/FunctionalExceptionTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/errorhandling/FunctionalExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.errorhandling; +package de.ozgcloud.vorgang.common.errorhandling; import static org.assertj.core.api.Assertions.*; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributesITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributesITCase.java new file mode 100644 index 0000000..50afa9d --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M001_UpdateClientNameInClientAttributesITCase.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M001_UpdateClientNameInClientAttributes.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Map; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M001_UpdateClientNameInClientAttributesITCase { + + private static final Document OLD_CLIENT_NAME_VORGANG = RenameTestFactory.createVorgangWithClientAttributes(OLD_CLIENT_NAME); + + private final M001_UpdateClientNameInClientAttributes migration = new M001_UpdateClientNameInClientAttributes(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + public void init() { + dbTestUtils.saveVorgang(OLD_CLIENT_NAME_VORGANG); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var vorgangClientAttributes = (Document) vorgaenge.get(0).get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + assertThat(vorgangClientAttributes).hasSize(1).containsKey(NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptClientAttributesData() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var clientAttribute = getClientAttribute(vorgaenge.get(0), RenameTestFactory.DUMMY_ATTRIBUTE_NAME); + assertThat(clientAttribute).containsExactly( + Map.entry(RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_VALUE), + Map.entry(RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_VALUE), + Map.entry(RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_VALUE)); + } + + private Document getClientAttribute(Document vorgang, String name) { + var vorgangClientAttributes = (Document) vorgang.get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + var clientAttributeByClientName = (Document) vorgangClientAttributes.get(NEW_CLIENT_NAME); + return (Document) clientAttributeByClientName.get(name); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFsITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFsITCase.java new file mode 100644 index 0000000..557727c --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M002_UpdateClientNameInGridFsITCase.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.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M002_UpdateClientNameInGridFs.*; +import static org.assertj.core.api.Assertions.*; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M002_UpdateClientNameInGridFsITCase { + + private static final Document OLD_CLIENT_NAME_GRID_FS_FILE = RenameTestFactory.createGridFsFile(OLD_CLIENT_NAME); + + private final M002_UpdateClientNameInGridFs migration = new M002_UpdateClientNameInGridFs(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoOperations db; + + @BeforeEach + public void init() { + dbTestUtils.dropGridFsFilesCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + void init() { + dbTestUtils.saveGridFsFile(OLD_CLIENT_NAME_GRID_FS_FILE); + } + + @Test + void shouldUpdateClientInMetadata() { + migration.doMigration(db); + + var metadata = (Document) MapUtils.getObject(getGridFsFile(), RenameUtil.METADATA_KEY); + assertThat(metadata).contains(entry(RenameUtil.CLIENT_KEY, NEW_CLIENT_NAME)); + } + + @Test + void shouldUpdateClientInFilename() { + migration.doMigration(db); + + var filename = MapUtils.getString(getGridFsFile(), RenameUtil.FILENAME_KEY); + var expectedFilename = StringUtils.replace(RenameTestFactory.FILE_NAME_VALUE, OLD_CLIENT_NAME, NEW_CLIENT_NAME); + assertThat(filename).isEqualTo(expectedFilename); + } + + @Test + void shouldKeepBaseData() { + migration.doMigration(db); + + var gridFsFile = getGridFsFile(); + assertThat(gridFsFile).contains(entry(RenameTestFactory.LENGTH_KEY, RenameTestFactory.LENGTH_VALUE)) + .contains(entry(RenameTestFactory.CHUNK_SIZE_KEY, RenameTestFactory.CHUNK_SIZE_VALUE)) + .contains(entry(RenameTestFactory.UPLOAD_DATE_KEY, RenameTestFactory.UPLOAD_DATE_VALUE)); + } + + @Test + void shouldKeepMetadata() { + migration.doMigration(db); + + var metadata = (Document) MapUtils.getObject(getGridFsFile(), RenameUtil.METADATA_KEY); + assertThat(metadata).contains(entry(RenameTestFactory.VORGANG_ID_KEY, RenameTestFactory.VORGANG_ID_VALUE)) + .contains(entry(RenameTestFactory.FIELD_NAME_KEY, RenameTestFactory.FIELD_NAME_VALUE)) + .contains(entry(RenameTestFactory.CONTENT_TYPE_KEY, RenameTestFactory.CONTENT_TYPE_VALUE)) + .contains(entry(RenameTestFactory.NAME_KEY, RenameTestFactory.NAME_VALUE)); + } + + private Document getGridFsFile() { + return dbTestUtils.findGridFsFile(new Query()).get(0); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItemITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItemITCase.java new file mode 100644 index 0000000..df1f69e --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M003_UpdateClientNameInVorgangAttachedItemITCase.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.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M003_UpdateClientNameInVorgangAttachedItem.*; +import static de.ozgcloud.vorgang.common.migration.RenameTestFactory.*; +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M003_UpdateClientNameInVorgangAttachedItemITCase { + + private static final Document OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM = RenameTestFactory.createVorgangAttachedItem(OLD_CLIENT_NAME); + + private final M003_UpdateClientNameInVorgangAttachedItem migration = new M003_UpdateClientNameInVorgangAttachedItem(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangAttachedItemCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + void init() { + dbTestUtils.saveVorgangAttachedItem(OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()).containsEntry(RenameUtil.CLIENT_KEY, NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptOtherAttributes() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()) + .containsEntry(ITEM_NAME_KEY, ITEM_NAME_VALUE) + .containsKey(ITEM_KEY); + } + + @Test + void shouldKeepItemAttributes() { + migration.doMigration(template); + + var item = (Document) getVorgangAttachedItem().get(ITEM_KEY); + assertThat(item).containsExactly(entry(ITEM_ATTRIBUTE_KEY, ITEM_ATTRIBUTE_VALUE)); + } + + private Document getVorgangAttachedItem() { + return dbTestUtils.findVorgangAttachedItem(new Query()).get(0); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItemITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItemITCase.java new file mode 100644 index 0000000..bc57fbe --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItemITCase.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem.*; +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItemITCase { + + private static final Document OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM = RenameTestFactory.createVorgangAttachedItem(OLD_CLIENT_NAME); + + private final M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem migration = new M004_UpdateNachrichtenManagerClientNameInVorgangAttachedItem(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangAttachedItemCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + void init() { + dbTestUtils.saveVorgangAttachedItem(OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()).containsEntry(RenameUtil.CLIENT_KEY, NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptOtherAttributes() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()) + .containsEntry(RenameTestFactory.ITEM_NAME_KEY, RenameTestFactory.ITEM_NAME_VALUE) + .containsKey(RenameTestFactory.ITEM_KEY); + } + + @Test + void shouldKeepItemAttributes() { + migration.doMigration(template); + + var item = (Document) getVorgangAttachedItem().get(RenameTestFactory.ITEM_KEY); + assertThat(item).containsExactly(entry(RenameTestFactory.ITEM_ATTRIBUTE_KEY, RenameTestFactory.ITEM_ATTRIBUTE_VALUE)); + } + + private Document getVorgangAttachedItem() { + return dbTestUtils.findVorgangAttachedItem(new Query()).get(0); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributesITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributesITCase.java new file mode 100644 index 0000000..b27f644 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M005_UpdateNachrichtenManagerClientNameInClientAttributesITCase.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M005_UpdateNachrichtenManagerClientNameInClientAttributes.*; +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M005_UpdateNachrichtenManagerClientNameInClientAttributesITCase { + + private final static Document OLD_CLIENT_NAME_VORGANG = RenameTestFactory.createVorgangWithClientAttributes(OLD_CLIENT_NAME); + + private final M005_UpdateNachrichtenManagerClientNameInClientAttributes migration = new M005_UpdateNachrichtenManagerClientNameInClientAttributes(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + public void init() { + dbTestUtils.saveVorgang(OLD_CLIENT_NAME_VORGANG); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var vorgangClientAttributes = (Document) vorgaenge.get(0).get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + assertThat(vorgangClientAttributes).hasSize(1).containsKey(NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptClientAttributesData() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var clientAttribute = getClientAttribute(vorgaenge.get(0), RenameTestFactory.DUMMY_ATTRIBUTE_NAME); + assertThat(clientAttribute).containsExactly( + entry(RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_VALUE), + entry(RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_VALUE), + entry(RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_VALUE)); + } + + private Document getClientAttribute(Document vorgang, String name) { + var vorgangClientAttributes = (Document) vorgang.get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + var clientAttributeByClientName = (Document) vorgangClientAttributes.get(NEW_CLIENT_NAME); + return (Document) clientAttributeByClientName.get(name); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItemITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItemITCase.java new file mode 100644 index 0000000..71e4c98 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M006_UpdateMailServiceClientNameInVorgangAttachedItemITCase.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M006_UpdateMailServiceClientNameInVorgangAttachedItem.*; +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M006_UpdateMailServiceClientNameInVorgangAttachedItemITCase { + + private static final Document OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM = RenameTestFactory.createVorgangAttachedItem(OLD_CLIENT_NAME); + + private final M006_UpdateMailServiceClientNameInVorgangAttachedItem migration = new M006_UpdateMailServiceClientNameInVorgangAttachedItem(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangAttachedItemCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + void init() { + dbTestUtils.saveVorgangAttachedItem(OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()).containsEntry(RenameUtil.CLIENT_KEY, NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptOtherAttributes() { + migration.doMigration(template); + + assertThat(getVorgangAttachedItem()) + .containsEntry(RenameTestFactory.ITEM_NAME_KEY, RenameTestFactory.ITEM_NAME_VALUE) + .containsKey(RenameTestFactory.ITEM_KEY); + } + + @Test + void shouldKeepItemAttributes() { + migration.doMigration(template); + + var item = (Document) getVorgangAttachedItem().get(RenameTestFactory.ITEM_KEY); + assertThat(item).containsExactly(entry(RenameTestFactory.ITEM_ATTRIBUTE_KEY, RenameTestFactory.ITEM_ATTRIBUTE_VALUE)); + } + + private Document getVorgangAttachedItem() { + return dbTestUtils.findVorgangAttachedItem(new Query()).get(0); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributesITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributesITCase.java new file mode 100644 index 0000000..7d4547f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M007_UpdateMailServiceClientNameInClientAttributesITCase.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M007_UpdateMailServiceClientNameInClientAttributes.*; +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M007_UpdateMailServiceClientNameInClientAttributesITCase { + + private final static Document OLD_CLIENT_NAME_VORGANG = RenameTestFactory.createVorgangWithClientAttributes(OLD_CLIENT_NAME); + + private final M007_UpdateMailServiceClientNameInClientAttributes migration = new M007_UpdateMailServiceClientNameInClientAttributes(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoTemplate template; + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + public void init() { + dbTestUtils.saveVorgang(OLD_CLIENT_NAME_VORGANG); + } + + @Test + void shouldUpdateClientName() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var vorgangClientAttributes = (Document) vorgaenge.get(0).get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + assertThat(vorgangClientAttributes).hasSize(1).containsKey(NEW_CLIENT_NAME); + } + + @Test + void shouldKeeptClientAttributesData() { + migration.doMigration(template); + + var vorgaenge = dbTestUtils.findVorgang(new Query()); + + assertThat(vorgaenge).hasSize(1); + var clientAttribute = getClientAttribute(vorgaenge.get(0), RenameTestFactory.DUMMY_ATTRIBUTE_NAME); + assertThat(clientAttribute).containsExactly( + entry(RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_ACCESS_VALUE), + entry(RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_VALUE_VALUE), + entry(RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_KEY, RenameTestFactory.CLIENT_ATTRIBUTE_CLASS_VALUE)); + } + + private Document getClientAttribute(Document vorgang, String name) { + var vorgangClientAttributes = (Document) vorgang.get(RenameUtil.CLIENT_ATTRIBUTES_KEY); + var clientAttributeByClientName = (Document) vorgangClientAttributes.get(NEW_CLIENT_NAME); + return (Document) clientAttributeByClientName.get(name); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFsITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFsITCase.java new file mode 100644 index 0000000..49371be --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/M008_UpdateMailServiceClientNameInGridFsITCase.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.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M008_UpdateMailServiceClientNameInGridFs.*; +import static org.assertj.core.api.Assertions.*; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class M008_UpdateMailServiceClientNameInGridFsITCase { + + private static final Document OLD_CLIENT_NAME_GRID_FS_FILE = RenameTestFactory.createGridFsFile(OLD_CLIENT_NAME); + + private final M008_UpdateMailServiceClientNameInGridFs migration = new M008_UpdateMailServiceClientNameInGridFs(); + + @Autowired + private MigrationDbTestUtils dbTestUtils; + @Autowired + private MongoOperations db; + + @BeforeEach + public void init() { + dbTestUtils.dropGridFsFilesCollection(); + } + + @DisplayName("Do migration") + @Nested + class TestDoMigration { + + @BeforeEach + void init() { + dbTestUtils.saveGridFsFile(OLD_CLIENT_NAME_GRID_FS_FILE); + } + + @Test + void shouldUpdateClientInMetadata() { + migration.doMigration(db); + + var metadata = (Document) MapUtils.getObject(getGridFsFile(), RenameUtil.METADATA_KEY); + assertThat(metadata).contains(entry(RenameUtil.CLIENT_KEY, NEW_CLIENT_NAME)); + } + + @Test + void shouldUpdateClientInFilename() { + migration.doMigration(db); + + var filename = MapUtils.getString(getGridFsFile(), RenameUtil.FILENAME_KEY); + var expectedFilename = StringUtils.replace(RenameTestFactory.FILE_NAME_VALUE, OLD_CLIENT_NAME, NEW_CLIENT_NAME); + assertThat(filename).isEqualTo(expectedFilename); + } + + @Test + void shouldKeepBaseData() { + migration.doMigration(db); + + var gridFsFile = getGridFsFile(); + assertThat(gridFsFile).contains(entry(RenameTestFactory.LENGTH_KEY, RenameTestFactory.LENGTH_VALUE)) + .contains(entry(RenameTestFactory.CHUNK_SIZE_KEY, RenameTestFactory.CHUNK_SIZE_VALUE)) + .contains(entry(RenameTestFactory.UPLOAD_DATE_KEY, RenameTestFactory.UPLOAD_DATE_VALUE)); + } + + @Test + void shouldKeepMetadata() { + migration.doMigration(db); + + var metadata = (Document) MapUtils.getObject(getGridFsFile(), RenameUtil.METADATA_KEY); + assertThat(metadata).contains(entry(RenameTestFactory.VORGANG_ID_KEY, RenameTestFactory.VORGANG_ID_VALUE)) + .contains(entry(RenameTestFactory.FIELD_NAME_KEY, RenameTestFactory.FIELD_NAME_VALUE)) + .contains(entry(RenameTestFactory.CONTENT_TYPE_KEY, RenameTestFactory.CONTENT_TYPE_VALUE)) + .contains(entry(RenameTestFactory.NAME_KEY, RenameTestFactory.NAME_VALUE)); + } + + private Document getGridFsFile() { + return dbTestUtils.findGridFsFile(new Query()).get(0); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationDbTestUtils.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationDbTestUtils.java new file mode 100644 index 0000000..cc716e7 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationDbTestUtils.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import java.util.List; + +import org.bson.Document; +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Component; + +import com.mongodb.client.FindIterable; + +@Component +class MigrationDbTestUtils { + + public static final String COMMAND_COLLECTION = "command"; + public static final String GRID_FS_FILE_COLLECTION = "fs.files"; + public static final String VORGANG_COLLECTION = "vorgang"; + public static final String VORGANG_ATTACHED_ITEM_COLLECTION = "vorgangAttachedItem"; + + @Autowired + private MongoTemplate template; + @Autowired + private MongoOperations operations; + + // Command + public Document saveCommand(Document doc) { + return template.save(doc, COMMAND_COLLECTION); + } + + public Document getCommand(ObjectId id) { + return template.findById(id, Document.class, COMMAND_COLLECTION); + } + + public void dropCommandCollection() { + template.dropCollection(COMMAND_COLLECTION); + } + + // GridFs + public Document saveGridFsFile(Document doc) { + return template.save(doc, GRID_FS_FILE_COLLECTION); + } + + public List<Document> findGridFsFile(Query query) { + return template.find(query, Document.class, GRID_FS_FILE_COLLECTION); + } + + public void dropGridFsFilesCollection() { + template.dropCollection(GRID_FS_FILE_COLLECTION); + } + + public FindIterable<Document> findGridFsFile(Document doc) { + return operations.getCollection(GRID_FS_FILE_COLLECTION).find(doc); + } + + // Vorgang + public Document saveVorgang(Document doc) { + return template.save(doc, VORGANG_COLLECTION); + } + + public Document getVorgang(ObjectId id) { + return template.findById(id, Document.class, VORGANG_COLLECTION); + } + + public List<Document> findVorgang(Query query) { + return template.find(query, Document.class, VORGANG_COLLECTION); + } + + public void dropVorgangCollection() { + template.dropCollection(VORGANG_COLLECTION); + } + + // VorgangAttachedItem + public Document saveVorgangAttachedItem(Document doc) { + return template.save(doc, VORGANG_ATTACHED_ITEM_COLLECTION); + } + + public Document getVorgangAttachedItem(ObjectId id) { + return template.findById(id, Document.class, VORGANG_ATTACHED_ITEM_COLLECTION); + } + + public List<Document> findVorgangAttachedItem(Query query) { + return template.find(query, Document.class, VORGANG_ATTACHED_ITEM_COLLECTION); + } + + public void dropVorgangAttachedItemCollection() { + template.dropCollection(VORGANG_ATTACHED_ITEM_COLLECTION); + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationTestUtils.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationTestUtils.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationTestUtils.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationTestUtils.java index 31906af..db5fa7f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/migration/MigrationTestUtils.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/MigrationTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.migration; +package de.ozgcloud.vorgang.common.migration; import java.io.InputStream; import java.util.List; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameTestFactory.java new file mode 100644 index 0000000..ad163f0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameTestFactory.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static de.ozgcloud.vorgang.common.migration.M002_UpdateClientNameInGridFs.*; + +import java.util.UUID; + +import org.apache.http.entity.ContentType; +import org.bson.Document; +import org.bson.types.ObjectId; + +import com.thedeanda.lorem.LoremIpsum; + +public class RenameTestFactory { + + // VorgangAttachedItem + public static final String ITEM_NAME_KEY = "itemName"; + public static final String ITEM_NAME_VALUE = "DummyItemName"; + public static final String ITEM_KEY = "item"; + public static final String ITEM_ATTRIBUTE_KEY = "DummyKey"; + public static final String ITEM_ATTRIBUTE_VALUE = "DummyValue"; + + public static Document createVorgangAttachedItem(String clientName) { + var vorgangAttachedItem = new Document(); + vorgangAttachedItem.put(RenameUtil.CLIENT_KEY, clientName); + vorgangAttachedItem.put(ITEM_NAME_KEY, ITEM_NAME_VALUE); + vorgangAttachedItem.put(ITEM_KEY, createItem()); + + return vorgangAttachedItem; + } + + private static Document createItem() { + var item = new Document(); + item.put(ITEM_ATTRIBUTE_KEY, ITEM_ATTRIBUTE_VALUE); + + return item; + } + + // GridFsFiles + public static final String LENGTH_KEY = "length"; + public static final long LENGTH_VALUE = 2L; + + public static final String CHUNK_SIZE_KEY = "chunkSize"; + public static final int CHUNK_SIZE_VALUE = 261120; + + public static final String UPLOAD_DATE_KEY = "uploadDate"; + public static final String UPLOAD_DATE_VALUE = "2023-03-28T07:13:14.821Z"; + + public static final String VORGANG_ID_KEY = "vorgangId"; + public static final String VORGANG_ID_VALUE = UUID.randomUUID().toString(); + + public static final String FIELD_NAME_KEY = "fieldName"; + public static final String FIELD_NAME_VALUE = LoremIpsum.getInstance().getFirstName(); + + public static final String CONTENT_TYPE_KEY = "contentType"; + public static final String CONTENT_TYPE_VALUE = ContentType.APPLICATION_JSON.toString(); + + public static final String NAME_KEY = "name"; + public static final String NAME_VALUE = LoremIpsum.getInstance().getFirstName(); + + public static final String FILE_NAME_ID_VALUE = new ObjectId().toHexString(); + public static final String FILE_NAME_VALUE = String.format("%s/%s/%s/%s", FILE_NAME_ID_VALUE, OLD_CLIENT_NAME, + FIELD_NAME_VALUE, NAME_VALUE); + + public static Document createGridFsFile(String clientName) { + var file = new Document(); + file.put(RenameUtil.METADATA_KEY, createGridFsFileMetadata(clientName)); + file.put(RenameUtil.FILENAME_KEY, FILE_NAME_VALUE); + file.put(LENGTH_KEY, LENGTH_VALUE); + file.put(CHUNK_SIZE_KEY, CHUNK_SIZE_VALUE); + file.put(UPLOAD_DATE_KEY, UPLOAD_DATE_VALUE); + + return file; + } + + private static Document createGridFsFileMetadata(String clientName) { + var metadata = new Document(); + metadata.put(VORGANG_ID_KEY, VORGANG_ID_VALUE); + metadata.put(RenameUtil.CLIENT_KEY, clientName); + metadata.put(FIELD_NAME_KEY, FIELD_NAME_VALUE); + metadata.put(CONTENT_TYPE_KEY, CONTENT_TYPE_VALUE); + metadata.put(NAME_KEY, NAME_VALUE); + + return metadata; + } + + // Vorgang ClientAttributes + public final static String DUMMY_ATTRIBUTE_NAME = "dummyAttributeName"; + + public final static String CLIENT_ATTRIBUTE_ACCESS_KEY = "access"; + public final static String CLIENT_ATTRIBUTE_ACCESS_VALUE = "READ_ONLY"; + public final static String CLIENT_ATTRIBUTE_VALUE_KEY = "value"; + public final static String CLIENT_ATTRIBUTE_VALUE_VALUE = "2023-11-06"; + public final static String CLIENT_ATTRIBUTE_CLASS_VALUE = "_class"; + public final static String CLIENT_ATTRIBUTE_CLASS_KEY = "ClientAttribute"; + + public static Document createVorgangWithClientAttributes(String clientName) { + var vorgang = new Document(); + vorgang.put(RenameUtil.CLIENT_ATTRIBUTES_KEY, createClientAttribute(clientName)); + return vorgang; + } + + private static Document createClientAttribute(String clientName) { + var clientAttribute = new Document(); + clientAttribute.put(clientName, createClientAttributeByClient()); + return clientAttribute; + } + + private static Document createClientAttributeByClient() { + var attributeValue = new Document(); + attributeValue.put(CLIENT_ATTRIBUTE_ACCESS_KEY, CLIENT_ATTRIBUTE_ACCESS_VALUE); + attributeValue.put(CLIENT_ATTRIBUTE_VALUE_KEY, CLIENT_ATTRIBUTE_VALUE_VALUE); + attributeValue.put(CLIENT_ATTRIBUTE_CLASS_KEY, CLIENT_ATTRIBUTE_CLASS_VALUE); + + var clientAttributeByClient = new Document(); + clientAttributeByClient.put(DUMMY_ATTRIBUTE_NAME, attributeValue); + return clientAttributeByClient; + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameUtilITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameUtilITCase.java new file mode 100644 index 0000000..7a80e90 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/migration/RenameUtilITCase.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.migration; + +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class RenameUtilITCase { + + private static final String OLD_CLIENT_NAME = "OldClientName"; + private static final String NEW_CLIENT_NAME = "NewClientName"; + + @Autowired + private MigrationDbTestUtils dbTestUtils; + + @DisplayName("VorgangAttachedItem") + @Nested + class TestVorgangAttachedItem { + + private static final Document OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM = RenameTestFactory.createVorgangAttachedItem(OLD_CLIENT_NAME); + private static final Document NEW_CLIENT_NAME_VORGANG_ATTACHED_ITEM = RenameTestFactory.createVorgangAttachedItem(NEW_CLIENT_NAME); + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangAttachedItemCollection(); + } + + @DisplayName("Create find query") + @Nested + class TestCreateFindQuery { + + @Test + void shouldFindWithOldClientName() { + dbTestUtils.saveVorgangAttachedItem(OLD_CLIENT_NAME_VORGANG_ATTACHED_ITEM); + + var vorgang = dbTestUtils.findVorgangAttachedItem(RenameUtil.createFindVorgangAttachedItemQuery(OLD_CLIENT_NAME)); + + assertThat(vorgang).hasSize(1); + } + + @Test + void shouldNOTFindWithOtherClientName() { + dbTestUtils.saveVorgangAttachedItem(NEW_CLIENT_NAME_VORGANG_ATTACHED_ITEM); + + var vorgang = dbTestUtils.findVorgangAttachedItem(RenameUtil.createFindVorgangAttachedItemQuery(OLD_CLIENT_NAME)); + + assertThat(vorgang).isEmpty(); + } + } + } + + @DisplayName("GridFsFiles") + @Nested + class TestGridFsFiles { + + private static final Document OLD_CLIENT_NAME_GRID_FS_FILE = RenameTestFactory.createGridFsFile(OLD_CLIENT_NAME); + private static final Document NEW_CLIENT_NAME_GRID_FS_FILE = RenameTestFactory.createGridFsFile(NEW_CLIENT_NAME); + + @BeforeEach + public void init() { + dbTestUtils.dropGridFsFilesCollection(); + } + + @DisplayName("Create find query") + @Nested + class TestCreateFindQuery { + + @Test + void shouldFindWithOldClientName() { + dbTestUtils.saveGridFsFile(OLD_CLIENT_NAME_GRID_FS_FILE); + + var gridFsFiles = dbTestUtils.findGridFsFile(RenameUtil.createMetadataClientMatchingDocument(OLD_CLIENT_NAME)); + + assertThat(gridFsFiles).hasSize(1); + } + + @Test + void shouldNOTFindWithOtherClientName() { + dbTestUtils.saveGridFsFile(NEW_CLIENT_NAME_GRID_FS_FILE); + + var gridFsFiles = dbTestUtils.findGridFsFile(RenameUtil.createMetadataClientMatchingDocument(OLD_CLIENT_NAME)); + + assertThat(gridFsFiles).isEmpty(); + } + } + } + + @DisplayName("Vorgang ClientAttributes") + @Nested + class TestVorgangClientAttributes { + + private static final Document OLD_CLIENT_NAME_VORGANG = RenameTestFactory.createVorgangWithClientAttributes(OLD_CLIENT_NAME); + private static final Document NEW_CLIENT_NAME_VORGANG = RenameTestFactory.createVorgangWithClientAttributes(NEW_CLIENT_NAME); + + @BeforeEach + public void init() { + dbTestUtils.dropVorgangCollection(); + } + + @DisplayName("Create find query") + @Nested + class TestCreateFindQuery { + + @Test + void shouldFindWithOldClientName() { + dbTestUtils.saveVorgang(OLD_CLIENT_NAME_VORGANG); + + var vorgang = dbTestUtils.findVorgang(RenameUtil.createFindVorgangClientAttributesQuery(OLD_CLIENT_NAME)); + + assertThat(vorgang).hasSize(1); + } + + @Test + void shouldNOTFindWithOtherClientName() { + dbTestUtils.saveVorgang(NEW_CLIENT_NAME_VORGANG); + + var vorgang = dbTestUtils.findVorgang(RenameUtil.createFindVorgangClientAttributesQuery(OLD_CLIENT_NAME)); + + assertThat(vorgang).isEmpty(); + } + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessorTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessorTest.java new file mode 100644 index 0000000..cb2818d --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/FieldPathProcessorTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import de.ozgcloud.vorgang.common.operator.FieldPathProcessor; +import de.ozgcloud.vorgang.common.operator.UnsupportedEntityException; + +class FieldPathProcessorTest { + + @Nested + class TestProcessToCriteriaPath { + + private final static String VORGANG_FIELD_PATH = "Vorgang.long.path"; + private final static String CLIENT_ATTRIBUTE_FIELD_PATH = "ClientAttribute.clientName.frist"; + + @Nested + class GetCriteriaEntity { + @Test + void shouldReturnVorgang() { + var entity = FieldPathProcessor.getCriteriaEntity(VORGANG_FIELD_PATH); + + assertThat(entity).isEqualTo(FieldPathProcessor.CRITERIA_PATH_VORGANG); + } + + @Test + void shouldThrowExcptionForUnkownEntity() { + assertThatThrownBy(() -> FieldPathProcessor.getCriteriaEntity("stupid.path")) + .isInstanceOf(UnsupportedEntityException.class); + + } + } + + @Nested + class GetPath { + + @Test + void shouldReturnPathWithoutEntity() { + var path = FieldPathProcessor.getPath(VORGANG_FIELD_PATH); + + assertThat(path).isEqualTo("long.path"); + } + + @Test + void shouldAddValueSuffix() { + var path = FieldPathProcessor.getPath(CLIENT_ATTRIBUTE_FIELD_PATH); + + assertThat(path).endsWith(".value"); + } + } + + @Test + void shouldReturnCriteriaWithoutEntity() { + var criteria = FieldPathProcessor.processToCriteriaPath(VORGANG_FIELD_PATH); + + assertThat(criteria).isEqualTo("long.path"); + } + + @Test + void shouldReturnCriteriaWithEntity() { + var criteria = FieldPathProcessor.processToCriteriaPath(CLIENT_ATTRIBUTE_FIELD_PATH); + + assertThat(criteria).isEqualTo("clientAttributes.clientName.frist.value"); + } + } + +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParserTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParserTest.java new file mode 100644 index 0000000..7d7e1fb --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperandFunctionParserTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import java.time.LocalDate; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class OperandFunctionParserTest { + + private final OperandFunctionParser operandFunctionParser = new OperandFunctionParser(); + + @Test + void shouldMapTodayFunction() { + var date = operandFunctionParser.parse("today()"); + + Assertions.assertThat(date).isEqualTo(LocalDate.now().toString()); + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorBuilderTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorBuilderTest.java new file mode 100644 index 0000000..f6492d0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorBuilderTest.java @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.operator.EqualOperator; +import de.ozgcloud.vorgang.common.operator.GreaterThenOperator; +import de.ozgcloud.vorgang.common.operator.GreaterThenOrEqualOperator; +import de.ozgcloud.vorgang.common.operator.LessThenOperator; +import de.ozgcloud.vorgang.common.operator.LessThenOrEqualOperator; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.common.operator.UnequalOperator; +import de.ozgcloud.vorgang.statistic.VorgangStatisticBadRequestException; +import de.ozgcloud.vorgang.vorgang.Vorgang; + +class OperatorBuilderTest { + + private static final String QUERY_PATH = "Vorgang.fieldPath"; + private static final String FIELD_PATH = "fieldPath"; + private static final String OPERAND = "operand"; + + @Test + void shouldSetFieldSet() { + var builder = OperatorBuilder.from(GrpcQueryOperator.UNEQUAL).fieldPath(QUERY_PATH); + + assertThat(builder).extracting("fieldPath").isEqualTo(FIELD_PATH); + } + + @Test + void shouldSetOperator() { + var builder = OperatorBuilder.from(GrpcQueryOperator.UNEQUAL); + + assertThat(builder).extracting("grpcOperator").isEqualTo(GrpcQueryOperator.UNEQUAL); + } + + @Test + void shouldSetOperand() { + var builder = OperatorBuilder.from(GrpcQueryOperator.UNEQUAL).operand(OPERAND); + + assertThat(builder).extracting("operand").isEqualTo(OPERAND); + } + + @Nested + @DisplayName("build operator") + class TestBuild { + + @Test + void shouldBuildEqualOperator() { + var operator = buildOperator(GrpcQueryOperator.EQUAL); + + assertThat(operator).isInstanceOf(EqualOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldBuildIsEmptyOperator() { + var operator = buildOperator(GrpcQueryOperator.IS_EMPTY); + + assertThat(operator).isInstanceOf(EqualOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(StringUtils.EMPTY); + } + + @Test + void shouldBuildIsNullOperator() { + var operator = buildOperator(GrpcQueryOperator.IS_NULL); + + assertThat(operator).isInstanceOf(EqualOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isNull(); + } + + @Test + void shouldBuildUnequalOperator() { + var operator = buildOperator(GrpcQueryOperator.UNEQUAL); + + assertThat(operator).isInstanceOf(UnequalOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldBuildGreaterThenOperator() { + var operator = buildOperator(GrpcQueryOperator.GREATER_THEN); + + assertThat(operator).isInstanceOf(GreaterThenOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldBuildGreaterThenOrEqualOperator() { + var operator = buildOperator(GrpcQueryOperator.GREATER_THEN_OR_EQUAL_TO); + + assertThat(operator).isInstanceOf(GreaterThenOrEqualOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldBuildLessThenOperator() { + var operator = buildOperator(GrpcQueryOperator.LESS_THEN); + + assertThat(operator).isInstanceOf(LessThenOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldBuildLessThenOrEqualOperator() { + var operator = buildOperator(GrpcQueryOperator.LESS_THEN_OR_EQUAL_TO); + + assertThat(operator).isInstanceOf(LessThenOrEqualOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("operand").isEqualTo(OPERAND); + } + + @Test + void shouldThrowExceptionWhenUnrecognized() { + assertThrows(VorgangStatisticBadRequestException.class, () -> buildOperator(GrpcQueryOperator.UNRECOGNIZED)); + } + + @Test + void shouldBuildExistsOperator() { + var operator = buildOperator(GrpcQueryOperator.EXISTS); + + assertThat(operator).isInstanceOf(ExistsOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + } + + @Test + void shouldBuildNotExistsOperator() { + var operator = buildOperator(GrpcQueryOperator.NOT_EXIST); + + assertThat(operator).isInstanceOf(ExistsOperator.class); + assertThat(operator).extracting("fieldPath").isEqualTo(FIELD_PATH); + assertThat(operator).extracting("negate").isEqualTo(true); + } + + private Operator buildOperator(GrpcQueryOperator grpcOperator) { + return OperatorBuilder.from(grpcOperator).fieldPath(QUERY_PATH).operand(OPERAND).build(); + } + } + + @Nested + class TestParseOperand { + + private OperatorBuilder operatorBuilder = spy(OperatorBuilder.from(GrpcQueryOperator.EQUAL).fieldPath(QUERY_PATH).operand(OPERAND)); + + @Test + void shouldReturnUnmodified() { + doReturn(null).when(operatorBuilder).getFieldClass(); + + var parsedOperand = operatorBuilder.getParsedOperand(); + + assertThat(parsedOperand).isEqualTo(OPERAND); + } + + @Test + void shouldCallGetFieldClass() { + doReturn(String.class).when(operatorBuilder).getFieldClass(); + + operatorBuilder.getParsedOperand(); + + verify(operatorBuilder).getFieldClass(); + } + + @Test + void shouldCallParseValue() { + doReturn(ZonedDateTime.class).when(operatorBuilder).getFieldClass(); + doReturn(OPERAND).when(operatorBuilder).parseValue(ZonedDateTime.class); + + operatorBuilder.getParsedOperand(); + + verify(operatorBuilder).parseValue(ZonedDateTime.class); + } + } + + @Nested + class TestGetFieldClass { + + private OperatorBuilder operatorBuilder = OperatorBuilder.from(GrpcQueryOperator.EQUAL); + + @Test + void shouldReturnNull() { + var fieldClass = operatorBuilder.getFieldClass(); + + assertThat(fieldClass).isNull(); + } + + @Test + void shouldReturnNullIfFieldPathIsBlank() { + operatorBuilder.fieldPath("Vorgang."); + + var fieldClass = operatorBuilder.getFieldClass(); + + assertThat(fieldClass).isNull(); + } + + @Test + void shouldReturnRootClass() { + var fieldPath = "Vorgang.createdAt"; + operatorBuilder.fieldPath(fieldPath); + + var fieldClass = operatorBuilder.getFieldClass(); + + assertThat(fieldClass).isEqualTo(ZonedDateTime.class); + } + + @Test + void shouldReturnNestedClass() { + operatorBuilder.fieldPath("Vorgang.eingangs.header.serviceKonto.type"); + + var fieldClass = operatorBuilder.getFieldClass(); + + assertThat(fieldClass).isEqualTo(String.class); + } + + @Test + void shouldReturnNullWhenFieldNotExists() { + operatorBuilder.fieldPath("Vorgang.notExists"); + + var fieldClass = operatorBuilder.getFieldClass(); + + assertThat(fieldClass).isNull(); + } + } + + @Nested + class TestParseValue { + + @Test + void shouldReturnZonedDateTime() { + var operatorBuilder = OperatorBuilder.from(GrpcQueryOperator.EQUAL).fieldPath(QUERY_PATH).operand("2024-01-01T00:00:00Z"); + + var parsedValue = operatorBuilder.parseValue(ZonedDateTime.class); + + assertThat(parsedValue).isInstanceOf(ZonedDateTime.class); + } + + @Test + void shouldReturnLocalDate() { + var operatorBuilder = OperatorBuilder.from(GrpcQueryOperator.EQUAL).fieldPath(QUERY_PATH).operand("2024-01-01"); + + var parsedValue = operatorBuilder.parseValue(LocalDate.class); + + assertThat(parsedValue).isInstanceOf(LocalDate.class); + } + + @Test + void shouldReturnLocalDateTime() { + var operatorBuilder = OperatorBuilder.from(GrpcQueryOperator.EQUAL).fieldPath(QUERY_PATH).operand("2024-01-01T00:00:00"); + + var parsedValue = operatorBuilder.parseValue(LocalDateTime.class); + + assertThat(parsedValue).isInstanceOf(LocalDateTime.class); + } + + @Test + void shouldReturnUnmodified() { + var operatorBuilder = OperatorBuilder.from(GrpcQueryOperator.EQUAL).fieldPath(QUERY_PATH).operand(1); + + var parsedValue = operatorBuilder.parseValue(String.class); + + assertThat(parsedValue).isInstanceOf(Integer.class); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorTestFactory.java new file mode 100644 index 0000000..0996dbc --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/operator/OperatorTestFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.operator; + +import de.ozgcloud.vorgang.common.operator.EqualOperator.EqualOperatorBuilder; +import de.ozgcloud.vorgang.common.operator.LessThenOperator.LessThenOperatorBuilder; + +public class OperatorTestFactory { + + public static final String PATH = "field"; + public static final String STRING_VALUE = "value"; + public static final int INT_VALUE = 1; + + public static Operator createEqualOperator() { + return createEqualOperatorBuilder().build(); + } + + public static EqualOperatorBuilder createEqualOperatorBuilder() { + return EqualOperator.builder() + .fieldPath(PATH) + .operand(STRING_VALUE); + } + + public static Operator createLessThenOperator() { + return createLessThenOperatorBuilder().build(); + } + + public static LessThenOperatorBuilder createLessThenOperatorBuilder() { + return LessThenOperator.builder() + .fieldPath(PATH) + .operand(INT_VALUE); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapperTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapperTest.java index 6d97a82..428dc8a 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,18 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.AntragstellerTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.AntragstellerTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; class IndexedVorgangMapperTest { private IndexedVorgangMapper mapper = Mappers.getMapper(IndexedVorgangMapper.class); @@ -162,4 +162,5 @@ class IndexedVorgangMapperTest { assertThat(vorgang.getAssignedTo()).isEqualTo(IndexedVorgangTestFactory.ASSIGNED_TO); } } + } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangTestFactory.java similarity index 80% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangTestFactory.java index facf472..3abecfc 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/IndexedVorgangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/IndexedVorgangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,20 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.time.ZonedDateTime; -import java.util.UUID; -import de.itvsh.ozg.pluto.vorgang.AntragstellerTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.AntragstellerTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; class IndexedVorgangTestFactory { static final String AKTENZEICHEN = VorgangTestFactory.AKTENZEICHEN; static final String ANTRAGSTELLER_NAME = AntragstellerTestFactory.NACHNAME; static final String ANTRAGSTELLER_VORNAME = AntragstellerTestFactory.VORNAME; - static final String ASSIGNED_TO = UUID.randomUUID().toString(); + static final String ASSIGNED_TO = UserTestFactory.ID; static final ZonedDateTime CREATED_AT = VorgangTestFactory.CREATED_AT; static final String NAME = VorgangTestFactory.NAME; static final String VORGANG_NUMMER = VorgangTestFactory.VORGANG_NUMMER; @@ -59,4 +59,8 @@ class IndexedVorgangTestFactory { .status(STATUS) .vorgangId(ID); } + + public static String createScriptRemoveFields(String field) { + return "ctx._source.remove('%s')".formatted(field); + } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchConfigTest.java similarity index 51% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListenerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchConfigTest.java index 9d2e418..ab7c656 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangEventListenerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,46 +21,65 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.common.search; import static org.mockito.Mockito.*; +import javax.net.ssl.SSLContext; + +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 de.itvsh.ozg.pluto.vorgang.redirect.VorgangForwardFailedEventTestFactory; -import de.itvsh.ozg.pluto.vorgang.redirect.VorgangRedirectedEventTestFactory; +import lombok.SneakyThrows; -class VorgangEventListenerTest { +class SearchConfigTest { + @Spy @InjectMocks - private VorgangEventListener listener; + private SearchConfig searchConfig; @Mock - private VorgangService service; + private SearchProperties properties; @Nested - class OnVorgangRedirectedEvent { + class TestClientConfiguration { - @Test - void shouldSetStatus() { - listener.updateStatus(VorgangRedirectedEventTestFactory.create()); + @BeforeEach + void setup() { + when(properties.getAddress()).thenReturn("address:9200"); + when(properties.getUsername()).thenReturn("username"); + when(properties.getPassword()).thenReturn(""); + } - verify(service).setStatusToWeitergeleitet(VorgangRedirectedEventTestFactory.SOURCE); + @Test + void shouldCallGetAddress() { + searchConfig.clientConfiguration(); + + verify(properties).getAddress(); } - } - @Nested - class TestUpdateStatusOnVorgangForwardFailedEvent { + @Test + void shouldCallBuildHeaders() { + searchConfig.clientConfiguration(); + + verify(searchConfig).buildHeaders(); + } + @SneakyThrows @Test - void shouldSetStatus() { - listener.updateStatus(VorgangForwardFailedEventTestFactory.create()); + void shouldSetSslContext() { + doReturn(mock(SSLContext.class)).when(searchConfig).createSslContext(); + when(properties.isUseSsl()).thenReturn(true); - verify(service).setStatusToInBearbeitung(VorgangForwardFailedEventTestFactory.SOURCE.getId(), - VorgangForwardFailedEventTestFactory.SOURCE.getVorgangId()); + searchConfig.clientConfiguration(); + + verify(searchConfig).createSslContext(); } + } -} \ No newline at end of file + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchEventListenerTest.java similarity index 54% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchEventListenerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchEventListenerTest.java index 56b56af..afdc70f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchEventListenerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchEventListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; @@ -34,17 +36,18 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandService; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; -import de.itvsh.ozg.pluto.common.search.SearchEventListener; -import de.itvsh.ozg.pluto.common.search.SearchService; -import de.itvsh.ozg.pluto.vorgang.StatusChangedEvent; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangAssignedEvent; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.status.StatusChangedEvent; +import de.ozgcloud.vorgang.vorgang.SetAktenzeichenCompletedEvent; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangAssignedEvent; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEvent; +import de.ozgcloud.vorgang.vorgang.VorgangDeletedEventTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class SearchEventListenerTest { @@ -52,11 +55,9 @@ class SearchEventListenerTest { private SearchEventListener eventListener; @Mock - private SearchService elasticsearchService; - + private SearchService service; @Mock private CommandService commandService; - @Mock private VorgangService vorgangService; @@ -79,7 +80,7 @@ class SearchEventListenerTest { eventListener.onNewVorgang(vorgangCreatedEvent); - verify(elasticsearchService).addVorgang(any()); + verify(service).addVorgang(any()); } } @@ -100,7 +101,7 @@ class SearchEventListenerTest { void shouldUpdateVorgang() { eventListener.onVorgangAssigned(vorgangAssignedEvent); - verify(elasticsearchService).updateVorgang(any()); + verify(service).updateVorgang(any()); } } @@ -111,18 +112,57 @@ class SearchEventListenerTest { @BeforeEach void init() { - when(vorgangUpdatedEvent.getSource()).thenReturn("commandId"); - Command command = CommandTestFactory.create(); - when(commandService.findCommand(anyString())).thenReturn(Optional.of(command)); - + when(commandService.findCommand(any())).thenReturn(Optional.of(CommandTestFactory.create())); when(vorgangService.getById(anyString())).thenReturn(vorgang); } @Test - void shouldUpdateVorgangInSolr() { + void shouldUpdateVorgangInSearchService() { eventListener.onVorgangStatusChanged(vorgangUpdatedEvent); - verify(elasticsearchService).updateVorgang(any()); + verify(service).updateVorgang(any()); + } + } + + @Nested + class TestOnDeletedVorgang { + + private VorgangDeletedEvent event = VorgangDeletedEventTestFactory.create(); + + @Test + void shouldCallService() { + eventListener.onVorgangDeleted(event); + + verify(service).deleteVorgang(any()); + } + + @Test + void shouldCatchException() { + doThrow(RuntimeException.class).when(service).deleteVorgang(any()); + + assertThatCode(() -> eventListener.onVorgangDeleted(event)).doesNotThrowAnyException(); + } + } + + @Nested + class TestOnSetAktenzeichenCompleted { + + private SetAktenzeichenCompletedEvent event; + private Command command; + + @BeforeEach + void setup() { + command = CommandTestFactory.createBuilder().bodyObject(Map.of(VorgangService.BODY_OBJECT_AKTENZEICHEN, VorgangTestFactory.AKTENZEICHEN)) + .build(); + event = new SetAktenzeichenCompletedEvent(command); } + + @Test + void shouldCallService() { + eventListener.onSetAktenzeichenCompletedEvent(event); + + verify(service).setAktenzeichen(command.getVorgangId(), VorgangTestFactory.AKTENZEICHEN); + } + } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchITCase.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchITCase.java index dd82437..6e5c53d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -29,10 +29,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; -import de.itvsh.kop.common.test.ITCase; +import de.ozgcloud.common.test.ITCase; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @@ -40,7 +39,6 @@ import de.itvsh.kop.common.test.ITCase; @ITCase @ContextConfiguration(initializers = { SearchInitializer.class }) -@ActiveProfiles({ "itcase" }) public @interface SearchITCase { } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexEnabledInitializer.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexEnabledInitializer.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexEnabledInitializer.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexEnabledInitializer.java index 7b97e36..3400666 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexEnabledInitializer.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexEnabledInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; @@ -32,6 +32,6 @@ class SearchIndexEnabledInitializer extends SearchInitializer { protected void setProperties(ElasticsearchContainer container, ConfigurableApplicationContext applicationContext) { super.setProperties(container, applicationContext); - TestPropertyValues.of("kop.elasticsearch.initEnabled=true").applyTo(applicationContext.getEnvironment()); + TestPropertyValues.of("ozgcloud.elasticsearch.initEnabled=true").applyTo(applicationContext.getEnvironment()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializerITCase.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializerITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializerITCase.java index 1d46f9a..3a35825 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchIndexInitializerITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchIndexInitializerITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.after; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.verify; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; import java.io.IOException; @@ -40,13 +38,15 @@ import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.DisabledIf; -import de.itvsh.kop.common.test.DbInitializer; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DbInitializer; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +@DisabledIf(expression = "${elasticTests.disabled:false}", reason = "Wegen hohem Speicherverbrauch des testcontainers") class SearchIndexInitializerITCase { private static final int FOR_500_MS = 500; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchInitializer.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchInitializer.java similarity index 82% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchInitializer.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchInitializer.java index c6b0d33..32cf32d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchInitializer.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import java.time.Duration; @@ -41,7 +41,7 @@ class SearchInitializer implements ApplicationContextInitializer<ConfigurableApp private static ElasticsearchContainer elasticsearchContainer; - private final static String PASSWORD = "sUpers3cret!"; + private final static String PASSWORD = ""; private static final String USERNAME = "elastic"; @Override @@ -70,13 +70,14 @@ class SearchInitializer implements ApplicationContextInitializer<ConfigurableApp } protected void setProperties(ElasticsearchContainer container, ConfigurableApplicationContext applicationContext) { - var uriString = String.format("http://%s:%d", container.getHost(), container.getFirstMappedPort()); - LOG.info("Uri: {} ", uriString); + var elasticAddress = container.getHost() + ":" + container.getFirstMappedPort(); + LOG.info("address: {} ", elasticAddress); TestPropertyValues.of( - "spring.elasticsearch.uris= http://" + container.getHost() + ":" + container.getFirstMappedPort(), - "spring.elasticsearch.username= " + USERNAME, - "spring.elasticsearch.password= " + PASSWORD, - "kop.elasticsearch.index=test").applyTo(applicationContext); + "ozgcloud.elasticsearch.address=" + elasticAddress, + "ozgcloud.elasticsearch.username=" + USERNAME, + "ozgcloud.elasticsearch.password=" + PASSWORD, + "ozgcloud.elasticsearch.useSsl=false", + "ozgcloud.elasticsearch.index=test").applyTo(applicationContext); } } diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceITCase.java new file mode 100644 index 0000000..cf61508 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceITCase.java @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.search; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.test.context.junit.jupiter.DisabledIf; + +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.vorgang.AntragstellerTestFactory; +import de.ozgcloud.vorgang.vorgang.FilterCriteria; +import de.ozgcloud.vorgang.vorgang.FilterCriteriaTestFactory; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequestTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@DisabledIf(expression = "${elasticTests.disabled:false}", reason = "Wegen hohem Speicherverbrauch des testcontainers") +@SearchITCase +public class SearchServiceITCase { + + @Autowired + private SearchService searchService; + + @Autowired + private SearchVorgangRepository repository; + + @Autowired + private ElasticsearchOperations elasticsearchOperations; + + @MockBean + private CommandService commandService; + + @Nested + class TestAddVorgang { + @BeforeEach + void init() { + elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); + } + + @Test + void shouldAdd() throws IOException { + searchService.addVorgang(VorgangTestFactory.create()); + + Iterable<IndexedVorgang> vorgangs = repository.findAll(); + assertThat(vorgangs).isNotEmpty(); + } + } + + @Nested + class TestUpdateVorgang { + @BeforeEach + void init() { + Command cmd = CommandTestFactory.createBuilder().build(); + when(commandService.findCommand(CommandTestFactory.ID)).thenReturn(Optional.of(cmd)); + + elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); + + searchService.addVorgang(VorgangTestFactory.create()); + } + + @Test + void shouldUpdate() throws IOException { + var vorgang = VorgangTestFactory.createBuilder().status(Status.ABGESCHLOSSEN).build(); + searchService.updateVorgang(vorgang); + + Iterable<IndexedVorgang> vorgangs = repository.findAll(); + assertThat(vorgangs).isNotEmpty().hasSize(1); + assertThat(vorgangs.iterator().next().getStatus()).isEqualTo(Status.ABGESCHLOSSEN.name()); + } + } + + @DisplayName("Find") + @Nested + class TestFind { + + @BeforeEach + void init() { + var indexOperations = elasticsearchOperations.indexOps(IndexedVorgang.class); + indexOperations.delete(); + indexOperations.create(); + indexOperations.putMapping(IndexedVorgang.class); + } + + @DisplayName("with hyphen") + @Nested + class TestWithHyphen { + + @DisplayName("in vorgangNummer") + @Test + void shouldFindInVorgangNummer() { + var vorgangNummer = "Vorgang-Nummer"; + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().vorgangNummer(vorgangNummer).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = searchService.find( + FindVorgangRequestTestFactory.createBuilder().searchBy(vorgangNummer).build()).getContent(); + + assertThat(vorgangHeaders).hasSize(1).first().extracting("nummer").isEqualTo(vorgangNummer); + } + + @DisplayName("in vorgangName") + @Test + void shouldFindInVorgangName() { + var vorgangName = "VorgangName"; + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().vorgangName(vorgangName).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = searchService.find( + FindVorgangRequestTestFactory.createBuilder().searchBy(vorgangName).build()).getContent(); + + assertThat(vorgangHeaders).hasSize(1).first().extracting("name").isEqualTo(vorgangName); + + } + + @DisplayName("in aktenzeichen") + @Test + void shouldFindInAktenzeichen() { + var aktenzeichen = "Akten-zeichen"; + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().aktenzeichen(aktenzeichen).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = searchService.find( + FindVorgangRequestTestFactory.createBuilder().searchBy("kten").build()).getContent(); + + assertThat(vorgangHeaders).hasSize(1).first().extracting("aktenzeichen").isEqualTo(aktenzeichen); + } + + @DisplayName("in antragstellerName") + @Test + void shouldFindInAntragstellerName() { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().antragstellerName("Antragsteller-Name").build()); + repository.save(IndexedVorgangTestFactory.createBuilder().vorgangId("123").build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = searchService.find(FindVorgangRequestTestFactory.createBuilder().searchBy("steller-na").build()).getContent(); + + assertThat(vorgangHeaders).hasSize(1); + } + + @DisplayName("in antragstellerVorname") + @Test + void shouldFindInAntragstellerVorname() { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().antragstellerVorname("Antragsteller-Vorname").build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = searchService.find(FindVorgangRequestTestFactory.createBuilder().searchBy("name").build()) + .getContent(); + + assertThat(vorgangHeaders).hasSize(1); + } + } + + @Nested + class filteredByOrganisationseinheitenId { + + @BeforeEach + void init() { + searchService.addVorgang(VorgangTestFactory.create()); + searchService.addVorgang( + VorgangTestFactory.createBuilder().id(null).aktenzeichen("test").assignedTo(UUID.randomUUID().toString()).build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).aktenzeichen("vors").build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).aktenzeichen("vOrsi").build()); + } + + @Test + void shouldFindByAktenzeichen() { + var res = searchService.find(FindVorgangRequestTestFactory.createBuilder() + .searchBy("vors") + .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().filterByAssignedTo(false).build()) + .build()); + + assertThat(res).hasSize(2); + } + + @Test + void shouldFindByAntragstellerName() { + var res = searchService + .find(FindVorgangRequestTestFactory.createBuilder() + .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) + .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().filterByAssignedTo(false).build()) + .build()); + + assertThat(res).hasSize(4); + } + + @Test + void shouldFindByAntragstellerNameAndAktenzeichen() { + var res = searchService + .find(FindVorgangRequestTestFactory.createBuilder() + .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME + " tes") + .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().filterByAssignedTo(false).build()) + .build()); + + assertThat(res).hasSize(1); + } + + @Test + void shouldFindByAntragstellerNameAndereOrganisationEinheitId() { + searchService + .addVorgang( + VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); + + var res = searchService.find(FindVorgangRequestTestFactory.createBuilder() + .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME).filterBy( + FilterCriteriaTestFactory.createBuilder() + .clearOrganisationseinheitIds() + .organisationseinheitIds(List.of("12345678")) + .clearStatus().build()) + .build()); + + assertThat(res).hasSize(1); + } + + @Test + void shouldDoPageination() { + var res = searchService + .find(FindVorgangRequestTestFactory.createBuilder() + .searchBy(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME) + .limit(2) + .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().build()) + .build()); + + assertThat(res).hasSize(2); + assertThat(res.getTotalPages()).isEqualTo(2); + } + } + + @DisplayName("filter by status only") + @Nested + class TestFilterByStatus { + + @BeforeEach + void init() { + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).status(Status.ANGENOMMEN).build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).build()); + searchService.addVorgang(VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(null).build()); + } + + @Test + void shouldFindByAntragstellerName() { + var request = createRequest(IndexedVorgangTestFactory.ANTRAGSTELLER_NAME, + FilterCriteriaTestFactory.createBuilder().filterByOrganisationseinheitenId(false).build()); + + var res = searchService.find(request); + + assertThat(res).hasSize(2); + } + } + + @DisplayName("filter by organisationsEinheitId and status") + @Nested + class TestFilterByOrganisationsEinheitIdAndStatus { + + @BeforeEach + void init() { + searchService.addVorgang(VorgangTestFactory.create()); + searchService.addVorgang( + VorgangTestFactory.createBuilder().id(null).aktenzeichen("test").assignedTo(UUID.randomUUID().toString()).build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).aktenzeichen("vors").build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).aktenzeichen("vOrsi").build()); + searchService + .addVorgang( + VorgangTestFactory.createWithOrganisationEinheitId("12345678").toBuilder().id(UUID.randomUUID().toString()).build()); + searchService + .addVorgang(VorgangTestFactory.createBuilder().status(Status.ANGENOMMEN).id(UUID.randomUUID().toString()).build()); + } + + @Test + void shouldFindByAktenzeichen() { + var request = createRequest("test", FilterCriteriaTestFactory.createBuilder().filterByAssignedTo(false).build()); + + var res = searchService.find(request); + + assertThat(res).hasSize(1); + } + + @Test + void shouldFindByAntragstellerName() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, + FilterCriteriaTestFactory.createBuilder().filterByAssignedTo(false).build()); + + var res = searchService.find(request); + + assertThat(res).hasSize(4); + } + } + + private FindVorgangRequest createRequest(String searchBy, FilterCriteria filterCriteria) { + return FindVorgangRequestTestFactory.createBuilder().searchBy(searchBy).filterBy(filterCriteria).build(); + } + } + + @DisplayName("Filter") + @Nested + class TestFilter { + + @BeforeEach + void init() { + elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); + elasticsearchOperations.indexOps(IndexedVorgang.class).create(); + } + + @DisplayName("by organisationsEinheitId") + @Nested + class TestByOrganisationsEinheitId { + + private static final String NAME = "shouldBeFound"; + + @BeforeEach + void init() { + searchService.addVorgang(VorgangTestFactory.createWithOrganisationEinheitId("132").toBuilder().id(null).build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).name(NAME).assignedTo(null).build()); + } + + @Test + void shouldReturnMatchingId() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, + FilterCriteriaTestFactory.createBuilder().filterByAssignedTo(false).build()); + + var result = searchService.find(request); + assertThat(result).hasSize(1); + assertThat(result.getContent().get(0).getName()).isEqualTo(NAME); + } + + @Test + void shouldReturnUnfiltered() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, FilterCriteriaTestFactory.createBuilder().filterByAssignedTo(false) + .filterByOrganisationseinheitenId(false).organisationseinheitIds(List.of("123")) + .build()); + + var result = searchService.find(request); + assertThat(result).hasSize(2); + } + } + + @DisplayName("by assignedTo") + @Nested + class TestByAssignedTo { + + private static final String NAME = "shouldBeFound"; + + @BeforeEach + void init() { + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).build()); + searchService.addVorgang(VorgangTestFactory.createBuilder().id(null).name(NAME).assignedTo(null).build()); + } + + @Test + void shouldReturnUnassigned() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, + FilterCriteriaTestFactory.createBuilder().assignedTo(StringUtils.EMPTY).build()); + + var result = searchService.find(request); + + assertThat(result).hasSize(1); + assertThat(result.getContent().get(0).getName()).isEqualTo(NAME); + } + + @Test + void shouldReturnMatchingAssigned() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, FilterCriteriaTestFactory.createBuilder().build()); + + var result = searchService.find(request); + + assertThat(result).hasSize(1); + assertThat(result.getContent().get(0).getName()).isEqualTo(VorgangTestFactory.NAME); + } + + @Test + void shouldReturnUnfiltered() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, + FilterCriteriaTestFactory.createBuilder().filterByAssignedTo(false).build()); + + var result = searchService.find(request); + + assertThat(result).hasSize(2); + } + + @Test + void shouldFilterByAssignedToOnly() { + var request = createRequest(AntragstellerTestFactory.NACHNAME, + FilterCriteriaTestFactory.createBuilder().filterByOrganisationseinheitenId(false).build()); + + var result = searchService.find(request); + + assertThat(result).hasSize(1); + } + } + + private FindVorgangRequest createRequest(String searchBy, FilterCriteria filterCriteria) { + return FindVorgangRequestTestFactory.createBuilder().searchBy(searchBy).filterBy(filterCriteria).build(); + } + } + + @Nested + class TestAktenzeichen { + + @Test + void shouldSetAktenzeichenOnly() { + var newAktenzeichen = "new-aktenzeichen"; + var vorgang = elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().vorgangId(null).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + searchService.setAktenzeichen(vorgang.getVorgangId(), newAktenzeichen); + + var indexedVorgang = elasticsearchOperations.get(vorgang.getVorgangId(), IndexedVorgang.class); + assertThat(indexedVorgang).usingRecursiveComparison().ignoringFields("vorgangId").isEqualTo(IndexedVorgangTestFactory.createBuilder().aktenzeichen(newAktenzeichen).build()); + } + + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceTest.java similarity index 72% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceTest.java index 76a41bd..be5441e 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.Map; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -35,18 +37,19 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.dao.DataAccessResourceFailureException; -import de.itvsh.ozg.pluto.common.errorhandling.SearchServiceUnavailableException; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequestTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.common.errorhandling.SearchServiceUnavailableException; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequestTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class SearchServiceTest { @InjectMocks private SearchService searchService; @Mock - private SearchVorgangRepostitory repository; + private SearchVorgangRepository repository; @Mock - private SearchVorgangCustomRepostitory searchRepository; + private SearchVorgangCustomRepository searchRepository; @Mock private IndexedVorgangMapper mapper; @@ -97,7 +100,7 @@ class SearchServiceTest { void shouldCallRepositorySearch() { searchService.find(FindVorgangRequestTestFactory.create()); - verify(searchRepository).searchBy(any(SearchRequest.class)); + verify(searchRepository).searchBy(any(FindVorgangRequest.class)); } @DisplayName("on unavailable search service") @@ -116,4 +119,26 @@ class SearchServiceTest { } } } -} + + @Nested + class TestDeleteVorgang { + @Test + void shouldDeleteVorgang() { + searchService.deleteVorgang(VorgangTestFactory.ID); + + verify(repository).deleteById(VorgangTestFactory.ID); + } + } + + @Nested + class TestSetAktenzeichen { + + @Test + void shouldCallRepository() { + searchService.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.AKTENZEICHEN); + + verify(searchRepository).update(VorgangTestFactory.ID, Map.of(IndexedVorgang.FIELD_AKTENZEICHEN, VorgangTestFactory.AKTENZEICHEN)); + } + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryITCase.java new file mode 100644 index 0000000..20275fc --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryITCase.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.search; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.test.context.junit.jupiter.DisabledIf; + +import de.ozgcloud.vorgang.vorgang.FilterCriteria; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest; + +@DisabledIf(expression = "${elasticTests.disabled:false}", reason = "Wegen hohem Speicherverbrauch des testcontainers") +@SearchITCase +public class SearchVorgangCustomRepositoryITCase { + + @Autowired + private SearchVorgangCustomRepository repostitory; + + @Autowired + private ElasticsearchOperations elasticsearchOperations; + + @Nested + class TestSpecialCharacters { + + private static final String VALUE_PATTERN = "AbC%sTest"; + private static final String SEARCH_BY_PATTERN = "bc%st"; + + @BeforeEach + void init() { + var indexOperations = elasticsearchOperations.indexOps(IndexedVorgang.class); + indexOperations.delete(); + indexOperations.create(); + indexOperations.putMapping(IndexedVorgang.class); + } + + @DisplayName("should find vorgang when vorgangName") + @ParameterizedTest(name = "contains {0}") + @ValueSource(strings = { "_", "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/", "<", + ">", "$", "%", "&", "#", "@" }) + void shouldFindInVorgangName(String character) { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().vorgangName(VALUE_PATTERN.formatted(character)).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = repostitory.searchBy(searchRequest(character)); + + Assertions.assertThat(vorgangHeaders.getContent()).hasSize(1).first() + .extracting("name").isEqualTo(VALUE_PATTERN.formatted(character)); + } + + @DisplayName("should find vorgang when vorgangNummer") + @ParameterizedTest(name = "contains {0}") + @ValueSource(strings = { "_", "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/", "<", + ">", "$", "%", "&", "#", "@" }) + void shouldFindInVorgangNummer(String character) { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().vorgangNummer(VALUE_PATTERN.formatted(character)).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = repostitory.searchBy(searchRequest(character)); + + Assertions.assertThat(vorgangHeaders.getContent()).hasSize(1).first() + .extracting("nummer").isEqualTo(VALUE_PATTERN.formatted(character)); + } + + @DisplayName("should find vorgang when antragstellerName") + @ParameterizedTest(name = "contains {0}") + @ValueSource(strings = { "_", "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/", "<", + ">", "$", "%", "&", "#", "@" }) + void shouldFindInAntragstellerName(String character) { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().antragstellerName(VALUE_PATTERN.formatted(character)).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = repostitory.searchBy(searchRequest(character)); + + Assertions.assertThat(vorgangHeaders.getContent()).hasSize(1); + } + + @DisplayName("should find vorgang when antragstellerVorname") + @ParameterizedTest(name = "contains {0}") + @ValueSource(strings = { "_", "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/", "<", + ">", "$", "%", "&", "#", "@" }) + void shouldFindInAntragstellerVorname(String character) { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().antragstellerVorname(VALUE_PATTERN.formatted(character)).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = repostitory.searchBy(searchRequest(character)); + + Assertions.assertThat(vorgangHeaders.getContent()).hasSize(1); + } + + @DisplayName("should find vorgang when aktenzeichen") + @ParameterizedTest(name = "contains {0}") + @ValueSource(strings = { "_", "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/", "<", + ">", "$", "%", "&", "#", "@" }) + void shouldFindInAktenzeichen(String character) { + elasticsearchOperations.save(IndexedVorgangTestFactory.createBuilder().aktenzeichen(VALUE_PATTERN.formatted(character)).build()); + elasticsearchOperations.indexOps(IndexedVorgang.class).refresh(); + + var vorgangHeaders = repostitory.searchBy(searchRequest(character)); + + Assertions.assertThat(vorgangHeaders.getContent()).hasSize(1).first() + .extracting("aktenzeichen").isEqualTo(VALUE_PATTERN.formatted(character)); + } + + private FindVorgangRequest searchRequest(String character) { + return FindVorgangRequest.builder().filterBy(FilterCriteria.builder().build()).searchBy(SEARCH_BY_PATTERN.formatted(character)).build(); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImplTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImplTest.java new file mode 100644 index 0000000..03d9fa2 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangCustomRepositoryImplTest.java @@ -0,0 +1,553 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.search; + +import static de.ozgcloud.vorgang.common.search.IndexedVorgangTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.assertj.core.data.MapEntry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.client.elc.NativeQuery; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.ScriptType; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; + +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.FilterCriteriaTestFactory; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequestTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangHeader; +import de.ozgcloud.vorgang.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; + +class SearchVorgangCustomRepositoryImplTest { + + @Spy + @InjectMocks + private SearchVorgangCustomRepositoryImpl searchRepostitory; + + @Mock + private IndexedVorgangMapper mapper; + + @Mock + private SearchProperties properties; + + @Mock + private ElasticsearchOperations operations; + + @Nested + class TestSearch { + + @Mock + private SearchHits<IndexedVorgang> searchHits; + @Mock + private SearchHit<IndexedVorgang> searchHit; + + @BeforeEach + void init() { + when(searchHit.getContent()).thenReturn(IndexedVorgangTestFactory.create()); + when(searchHits.get()).thenReturn(List.of(searchHit).stream()); + when(operations.search(any(NativeQuery.class), eq(IndexedVorgang.class))).thenReturn(searchHits); + } + + @Test + void shouldCallSearch() { + searchRepostitory.searchBy(FindVorgangRequestTestFactory.create()); + + verify(mapper, atLeastOnce()).toVorgangHeader(any()); + verify(operations).search(any(NativeQuery.class), eq(IndexedVorgang.class)); + } + + @Test + void shouldMapResult() { + when(mapper.toVorgangHeader(any())).thenReturn(VorgangHeaderTestFactory.create()); + + var res = searchRepostitory.searchBy(FindVorgangRequestTestFactory.create()); + + assertThat(res).isNotEmpty().hasAtLeastOneElementOfType(VorgangHeader.class); + } + } + + @Nested + class TestQuery { + + @Test + void shouldHavePaging() { + var pageable = searchRepostitory.buildPageable(FindVorgangRequestTestFactory.create()); + + assertThat(pageable).isNotNull(); + assertThat(pageable.getOffset()).isZero(); + assertThat(pageable.getPageSize()).isEqualTo(FindVorgangRequestTestFactory.LIMIT); + assertThat(pageable.getSort()).isEqualTo(Sort.unsorted()); + } + + @Test + void shouldHaveFirstPageNumber() { + var pageable = searchRepostitory.buildPageable(FindVorgangRequestTestFactory.create()); + + assertThat(pageable.getPageNumber()).isZero(); + } + + @Test + void shouldHaveSecondPageNumber() { + var pageable = searchRepostitory.buildPageable( + FindVorgangRequestTestFactory.createBuilder() + .offset(FindVorgangRequestTestFactory.LIMIT) + .build()); + + assertThat(pageable.getPageNumber()).isEqualTo(1); + } + + @Test + void shouldHaveFieldsWithWights() { + var query = searchRepostitory.buildQueryBuilder(FindVorgangRequestTestFactory.create()).build(); + + assertThat(query.getQuery()).isNotNull(); + assertThat(query.getQuery()).asString().contains("aktenzeichen^2.0"); + assertThat(query.getQuery()).asString().contains("antragstellerName^1.0"); + assertThat(query.getQuery()).asString().contains("antragstellerVorname^1.0"); + assertThat(query.getQuery()).asString().contains("vorgangName^0.5"); + assertThat(query.getQuery()).asString().contains("vorgangNummer^2.0"); + } + + @Test + void shouldHaveSimpleQuery() { + var request = FindVorgangRequestTestFactory.createBuilder().searchBy("vors").build(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getQuery()).asString().contains("\"query\":\"(*vors*)\""); + } + + @Test + void shouldHaveQuery() { + var request = FindVorgangRequestTestFactory.createBuilder().searchBy("vors test").build(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getQuery()).asString().contains("\"query\":\"(*vors*) AND (*test*)\""); + } + + @Nested + class TestBuildSearchByQueryBuilder { + + @Test + void shouldCallAdjustSearchTerm() { + var request = FindVorgangRequestTestFactory.createBuilder().searchBy("vors test").build(); + + searchRepostitory.buildSearchByQueryBuilder(request); + + verify(searchRepostitory, times(2)).adjustSearchTerm(any()); + } + } + + @Nested + class TestEscapingCharacters { + + private static final String SEARCH_TERM_PATTERN = "Ab%sT"; + private static final String ESCAPED_SEARCH_TERM_PATTERN = "(*Ab\\%sT*)"; + + @ParameterizedTest(name = "should escape {0}") + @ValueSource(strings = { "+", "-", "=", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\", "/" }) + void shouldFindWithSpecialCharacters(String character) { + var result = searchRepostitory.adjustSearchTerm(SEARCH_TERM_PATTERN.formatted(character)); + + assertThat(result).isEqualTo(ESCAPED_SEARCH_TERM_PATTERN.formatted(character)); + } + + @ParameterizedTest(name = "should replace {0}") + @ValueSource(strings = { "<", ">" }) + void shouldRemoveSpecialCharacters(String character) { + var result = searchRepostitory.adjustSearchTerm(SEARCH_TERM_PATTERN.formatted(character)); + + assertThat(result).isEqualTo("(*" + SEARCH_TERM_PATTERN.formatted("?") + "*)"); + } + + @Test + void shouldReplaceAllCharacters() { + var searchTerm = "abc/123+z"; + var expectedResult = "(*abc\\/123\\+z*)"; + + var result = searchRepostitory.adjustSearchTerm(searchTerm); + + assertThat(result).isEqualTo(expectedResult); + } + } + + @Nested + class forRolePoststelle { + @Test + void shouldHaveStatusFilterOnly() { + var request = FindVorgangRequestTestFactory.createBuilder().filterBy( + FilterCriteriaTestFactory.createBuilder() + .filterByOrganisationseinheitenId(false).clearOrganisationseinheitIds() + .clearStatus().singleStatus(Status.ABGESCHLOSSEN) + .build()) + .build(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getFilter()).isNotNull(); + assertThat(query.getFilter()).asString().contains("status"); + assertThat(query.getFilter()).asString().contains(Status.ABGESCHLOSSEN.name()); + assertThat(query.getFilter()).asString().doesNotContain("organisationseinheitenId"); + } + + @Test + void shouldHaveOrganisationseinheitenIdFilterOnly() { + var request = FindVorgangRequestTestFactory.create(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getFilter()).isNotNull(); + assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); + assertThat(query.getFilter()).asString().contains(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + } + + @Test + void shouldHaveOrganisationseinheitenAndStatusFilter() { + var request = FindVorgangRequestTestFactory.createBuilder().filterBy( + FilterCriteriaTestFactory.createBuilder().clearStatus().singleStatus(Status.ABGESCHLOSSEN).build()) + .build(); + + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getFilter()).isNotNull(); + assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); + assertThat(query.getFilter()).asString().contains(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + assertThat(query.getFilter()).asString().contains("status"); + assertThat(query.getFilter()).asString().contains(Status.ABGESCHLOSSEN.name()); + } + } + + @Nested + class forOtherRoles { + @Test + void shouldHaveOrganisationseinheitenIdFilter() { + var request = FindVorgangRequestTestFactory.create(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getFilter()).isNotNull(); + assertThat(query.getFilter()).asString().contains("organisationseinheitenId"); + assertThat(query.getFilter()).asString().contains(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + } + + @Test + void shouldHaveAssignedToFilter() { + var request = FindVorgangRequestTestFactory.create(); + var query = searchRepostitory.buildQueryBuilder(request).build(); + + assertThat(query.getFilter()).isNotNull(); + assertThat(query.getFilter()).asString().contains("assignedTo"); + assertThat(query.getFilter()).asString().contains(UserTestFactory.ID); + } + } + } + + @Nested + class TestPartialUpdate { + + @Nested + class TestUpdate { + + private static final Set<String> FIELDS_TO_REMOVE = Set.of(IndexedVorgang.FIELD_AKTENZEICHEN); + private static final Map<String, Object> FIELDS_TO_UPDATE = Map.of(IndexedVorgang.FIELD_AKTENZEICHEN, + AKTENZEICHEN); + + @Mock + private UpdateQuery updateQuery; + + @Test + void shouldCallExecuteUpdate() { + doNothing().when(searchRepostitory).executeUpdate(any()); + doReturn(FIELDS_TO_REMOVE).when(searchRepostitory).getFieldsToRemove(any()); + doReturn(FIELDS_TO_UPDATE).when(searchRepostitory).getFieldsToUpdate(any()); + + searchRepostitory.update(IndexedVorgangTestFactory.ID, Collections.emptyMap()); + + verify(searchRepostitory, times(2)).executeUpdate(any()); + } + + @Test + void shouldNotCallExecuteUpdate() { + doReturn(Collections.emptySet()).when(searchRepostitory).getFieldsToRemove(any()); + doReturn(Collections.emptyMap()).when(searchRepostitory).getFieldsToUpdate(any()); + + searchRepostitory.update(IndexedVorgangTestFactory.ID, createMap()); + + verify(searchRepostitory, never()).executeUpdate(any()); + } + + Map<String, Object> createMap() { + var map = new HashMap<String, Object>(); + map.put(IndexedVorgang.FIELD_ANTRAGSTELLER_NAME, IndexedVorgangTestFactory.ANTRAGSTELLER_NAME); + map.put(IndexedVorgang.FIELD_AKTENZEICHEN, null); + return map; + } + + @Nested + class TestUpdateWithScript { + + @BeforeEach + void setup() { + doNothing().when(searchRepostitory).executeUpdate(any()); + doReturn(FIELDS_TO_REMOVE).when(searchRepostitory).getFieldsToRemove(any()); + } + + @Test + void shouldCallBuildRemoveFieldScript() { + searchRepostitory.update(IndexedVorgangTestFactory.ID, createMap()); + + verify(searchRepostitory).buildRemoveFieldScript(FIELDS_TO_REMOVE); + } + + @Test + void shouldCallBuildUpdateQueryWithScript() { + var createdScript = "script"; + doReturn(createdScript).when(searchRepostitory).buildRemoveFieldScript(any()); + + searchRepostitory.update(IndexedVorgangTestFactory.ID, createMap()); + + verify(searchRepostitory).buildUpdateQueryWithScript(IndexedVorgangTestFactory.ID, createdScript); + } + + @Test + void shouldCallExecuteUpdate() { + doReturn(updateQuery).when(searchRepostitory).buildUpdateQueryWithScript(any(), any()); + + searchRepostitory.update(IndexedVorgangTestFactory.ID, createMap()); + + verify(searchRepostitory).executeUpdate(updateQuery); + } + + private Map<String, Object> createMap() { + var map = new HashMap<String, Object>(); + map.put(IndexedVorgang.FIELD_AKTENZEICHEN, null); + return map; + } + } + + @Nested + class TestUpdateWithDocument { + + @BeforeEach + void setup() { + doNothing().when(searchRepostitory).executeUpdate(any()); + doReturn(FIELDS_TO_UPDATE).when(searchRepostitory).getFieldsToUpdate(any()); + } + + @Test + void shouldCallBuildUpdateQueryWithDocument() { + searchRepostitory.update(IndexedVorgangTestFactory.ID, FIELDS_TO_UPDATE); + + verify(searchRepostitory).buildUpdateQueryWithDocument(IndexedVorgangTestFactory.ID, FIELDS_TO_UPDATE); + } + + @Test + void shouldCallExecuteUpdate() { + doReturn(updateQuery).when(searchRepostitory).buildUpdateQueryWithDocument(any(), any()); + + searchRepostitory.update(IndexedVorgangTestFactory.ID, FIELDS_TO_UPDATE); + + verify(searchRepostitory).executeUpdate(updateQuery); + } + } + + } + + @Nested + class TestGetFieldsToRemove { + + @Test + void shouldReturnFieldsToRemove() { + var fieldsToRemove = searchRepostitory.getFieldsToRemove(createMap(null)); + + assertThat(fieldsToRemove).containsOnly(IndexedVorgang.FIELD_AKTENZEICHEN); + } + + @Test + void shouldReturnEmptyFieldsToRemove() { + var fieldsToRemove = searchRepostitory.getFieldsToRemove(createMap(AKTENZEICHEN)); + + assertThat(fieldsToRemove).isEmpty(); + } + + private Map<String, Object> createMap(Object value) { + var map = new HashMap<String, Object>(); + map.put(IndexedVorgang.FIELD_AKTENZEICHEN, value); + return map; + } + } + + @Nested + class TestBuildRemoveFieldScript { + + @Test + void shouldBuildScript() { + var removeAktenzeichenScript = createScriptRemoveFields(IndexedVorgang.FIELD_AKTENZEICHEN); + var removeAssignedToScript = createScriptRemoveFields(IndexedVorgang.FIELD_ASSIGNED_TO); + + var script = searchRepostitory.buildRemoveFieldScript(Set.of(IndexedVorgang.FIELD_AKTENZEICHEN, IndexedVorgang.FIELD_ASSIGNED_TO)); + + assertThat(script).contains(removeAktenzeichenScript, removeAssignedToScript); + } + } + + @Nested + class TestBuildUpdateQueryWithScript { + + @Mock + private UpdateQuery.Builder updateQuery; + + @BeforeEach + void setup() { + when(updateQuery.withScript(any())).thenReturn(updateQuery); + when(updateQuery.withScriptType(any())).thenReturn(updateQuery); + doReturn(updateQuery).when(searchRepostitory).createUpdateBuilder(any()); + } + + @Test + void shouldSetScriptType() { + searchRepostitory.buildUpdateQueryWithScript(IndexedVorgangTestFactory.ID, "script"); + + verify(updateQuery).withScriptType(ScriptType.INLINE); + } + + @Test + void shouldSetScript() { + var script = "script"; + + searchRepostitory.buildUpdateQueryWithScript(IndexedVorgangTestFactory.ID, script); + + verify(updateQuery).withScript(script); + } + + @Test + void shouldCallBuild() { + searchRepostitory.buildUpdateQueryWithScript(IndexedVorgangTestFactory.ID, "script"); + + verify(updateQuery).build(); + } + } + + @Nested + class TestGetFieldsToUpdate { + + @Test + void shouldReturnFieldsToUpdate() { + var fieldsToUpdate = searchRepostitory.getFieldsToUpdate(createMap(IndexedVorgang.FIELD_AKTENZEICHEN, AKTENZEICHEN)); + + assertThat(fieldsToUpdate).containsOnly(MapEntry.entry(IndexedVorgang.FIELD_AKTENZEICHEN, AKTENZEICHEN)); + } + + @Test + void shouldReturnEmptyFieldsToUpdate() { + var fieldsToUpdate = searchRepostitory.getFieldsToUpdate(createMap(IndexedVorgang.FIELD_ASSIGNED_TO, null)); + + assertThat(fieldsToUpdate).isEmpty(); + } + + private Map<String, Object> createMap(String key, Object value) { + var map = new HashMap<String, Object>(); + map.put(key, value); + return map; + } + } + + @Nested + class TestBuildUpdateQueryWithDocument { + + @Mock + private UpdateQuery.Builder updateQuery; + @Mock + private Document document; + + @BeforeEach + void setup() { + when(updateQuery.withDocument(any())).thenReturn(updateQuery); + doReturn(updateQuery).when(searchRepostitory).createUpdateBuilder(any()); + } + + @Test + void shouldSetDocument() { + Map<String, Object> patch = Map.of(IndexedVorgang.FIELD_AKTENZEICHEN, AKTENZEICHEN); + try(var fromMock = mockStatic(Document.class)) { + fromMock.when(() -> Document.from(any())).thenReturn(document); + + searchRepostitory.buildUpdateQueryWithDocument(IndexedVorgangTestFactory.ID, patch); + + verify(updateQuery).withDocument(document); + } + } + + @Test + void shouldCallBuild() { + searchRepostitory.buildUpdateQueryWithDocument(IndexedVorgangTestFactory.ID, Map.of()); + + verify(updateQuery).build(); + } + } + + @Nested + class TestExecuteUpdate { + + @Mock + private UpdateQuery updateQuery; + @Mock + private IndexOperations indexOperations; + @Mock + private IndexCoordinates indexCoordinates; + + @BeforeEach + void setup() { + when(indexOperations.getIndexCoordinates()).thenReturn(indexCoordinates); + when(operations.indexOps(any(Class.class))).thenReturn(indexOperations); + } + + @Test + void shouldCallUpdate() { + searchRepostitory.executeUpdate(updateQuery); + + verify(operations).update(updateQuery, indexCoordinates); + } + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepositoryITCase.java similarity index 74% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepositoryITCase.java index 8d7a034..b72029c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/search/SearchVorgangRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/search/SearchVorgangRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,27 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.search; +package de.ozgcloud.vorgang.common.search; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; + +import java.util.List; -import org.elasticsearch.core.List; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.test.context.ContextConfiguration; - -import de.itvsh.kop.common.test.ITCase; +import org.springframework.test.context.junit.jupiter.DisabledIf; -@ITCase -@ContextConfiguration(initializers = SearchInitializer.class) -@Disabled("Wegen hohem Speicherverbrauch des testcontainers") +@DisabledIf(expression = "${elasticTests.disabled:false}", reason = "Wegen hohem Speicherverbrauch des testcontainers") +@SearchITCase class SearchVorgangRepositoryITCase { + @Autowired - private SearchVorgangRepostitory repostitory; + private SearchVorgangRepository repostitory; @Autowired private ElasticsearchOperations elasticsearchOperations; @@ -50,7 +48,7 @@ class SearchVorgangRepositoryITCase { void initDatabase() { elasticsearchOperations.indexOps(IndexedVorgang.class).delete(); - repostitory.saveAll(List.of(IndexedVorgangTestFactory.create())); + repostitory.save(IndexedVorgangTestFactory.create()); } @Nested diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryITCase.java similarity index 77% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryITCase.java index fd38e73..c303292 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.security; +package de.ozgcloud.vorgang.common.security; import static org.assertj.core.api.Assertions.*; import java.util.List; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -34,15 +35,16 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.files.GridFsTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.files.GridFsTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; @DataITCase class PolicyRepositoryITCase { @@ -124,6 +126,19 @@ class PolicyRepositoryITCase { assertThat(result).isFalse(); } + + @Test + void shouldThrowNotFoundIfDeleted() { + var vorgangAttachedItem = mongoOperations.save( + VorgangAttachedItemTestFactory.createBuilder().id(null).deleted(true).version(0).build()); + var id = vorgangAttachedItem.getId(); + + Assertions.assertThrows(NotFoundException.class, () -> existsByVorgangAttachedItem(id)); + } + + private void existsByVorgangAttachedItem(String vorgangAttachedItemId) { + repository.existsByVorgangAttachedItem(vorgangAttachedItemId, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + } } @DisplayName("by file id") diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryTest.java new file mode 100644 index 0000000..a56ccd3 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyRepositoryTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.security; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.bson.Document; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.data.mongodb.core.MongoTemplate; + +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; + +class PolicyRepositoryTest { + + @InjectMocks + private PolicyRepository repository; + + @Mock + private MongoTemplate mongoTemplate; + + @Nested + class TestEvaluateOrganisationseinheitId { + + @Nested + class TestMatch { + + @Test + void shouldEvaluateVorgang() { + var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, + List.of(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID))); + + var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + assertThat(result).isTrue(); + } + + @Test + void shouldEvaluateVorgangStub() { + var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, + List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + assertThat(result).isTrue(); + } + } + + @Test + void shouldReturnFalseIfNoMatch() { + var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, + List.of(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID))); + + var result = repository.evaluateOrganisationseinheitId(document, List.of("otherId")); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseIfEmpty() { + var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, List.of()); + + var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseIfNestedEmpty() { + var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, List.of(List.of())); + + var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + assertThat(result).isFalse(); + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyServiceTest.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyServiceTest.java index 487aa29..92e1eda 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/common/security/PolicyServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/security/PolicyServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.common.security; +package de.ozgcloud.vorgang.common.security; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -44,17 +44,17 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.security.access.AccessDeniedException; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUser; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.files.GridFsTestFactory; -import de.itvsh.ozg.pluto.files.OzgFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextUser; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.files.GridFsTestFactory; +import de.ozgcloud.vorgang.files.OzgFileTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class PolicyServiceTest { @@ -160,7 +160,7 @@ class PolicyServiceTest { } @Test - void shouldThrowAccessDeniedExceptionOnAllNonMatch() { + void shouldThrowNotFoundException() { when(repository.existsByVorgangAttachedItem(any(), any())).thenReturn(false); assertThrows(AccessDeniedException.class, () -> service.checkPermissionByVorgangAttachedItem(VorgangAttachedItemTestFactory.ID)); diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/GrpcGetSupportedOrganisationEinheitenResponseTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/GrpcGetSupportedOrganisationEinheitenResponseTestFactory.java new file mode 100644 index 0000000..a8913f2 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/GrpcGetSupportedOrganisationEinheitenResponseTestFactory.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.vorgang.common.userconfig; + +import de.ozgcloud.user.grpc.organisationseinheit.GrpcGetSupportedOrganisationsEinheitenResponse; +import de.ozgcloud.user.organisationseinheit.GrpcOrganisationsEinheit; + +public class GrpcGetSupportedOrganisationEinheitenResponseTestFactory { + public static String ORGANISATIONS_EINHEIT_ID = "123456"; + + public static GrpcGetSupportedOrganisationsEinheitenResponse create() { + return createBuilder().build(); + } + + public static GrpcGetSupportedOrganisationsEinheitenResponse.Builder createBuilder() { + return GrpcGetSupportedOrganisationsEinheitenResponse.newBuilder() + .addOrganisationseinheiten(GrpcOrganisationsEinheit.newBuilder().setOrganisationsEinheitId(ORGANISATIONS_EINHEIT_ID).build()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteServiceTest.java new file mode 100644 index 0000000..559d81d --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigRemoteServiceTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.userconfig; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 de.ozgcloud.user.grpc.organisationseinheit.OrganisationsEinheitServiceGrpc.OrganisationsEinheitServiceBlockingStub; +import de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor; + +class UserConfigRemoteServiceTest { + @Spy + @InjectMocks + private UserConfigRemoteService remoteService; + + @Mock + private OrganisationsEinheitServiceBlockingStub stub; + + @DisplayName("Test getting Organsiationseinheiten Ids of the users") + @Nested + class TestGettingOrganisationsEinheitenIds { + @BeforeEach + void init() { + when(stub.getSupportedOrganisationsEinheiten(any())) + .thenReturn(GrpcGetSupportedOrganisationEinheitenResponseTestFactory.create()); + when(stub.withInterceptors(any())).thenReturn(stub); + } + + @Test + void shouldGetOrganisationsEinheiten() { + var organisationsEinheiten = remoteService.getSupportedOrganisationsEinheiten(); + + assertThat(organisationsEinheiten).hasSize(1) + .contains(GrpcGetSupportedOrganisationEinheitenResponseTestFactory.ORGANISATIONS_EINHEIT_ID); + } + + @Test + void shouldUseInterceptor() { + remoteService.getSupportedOrganisationsEinheiten(); + + verify(stub).withInterceptors(any(VorgangManagerClientCallContextAttachingInterceptor.class)); + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigServiceTest.java similarity index 64% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandEventListenerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigServiceTest.java index a13e3fb..357659d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/command/CommandEventListenerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/common/userconfig/UserConfigServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,32 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.command; +package de.ozgcloud.vorgang.common.userconfig; import static org.mockito.Mockito.*; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; -class CommandEventListenerTest { - - @InjectMocks // NOSONAR - private CommandEventListener listener; +class UserConfigServiceTest { + @Spy + @InjectMocks + private UserConfigService userConfigService; @Mock - private CommandService commandService; + private UserConfigRemoteService userConfigRemoteService; + @DisplayName("Test invocation of user config remote service") @Nested - class TestCommandExecutedEventListener { - + class TestUserConfigService { @Test - void shouldSetStatusFinished() { - listener.setStatusFinished( - CommandExecutedEventTestFactory.createFor(CommandTestFactory.create())); + void shouldCallUserConfigRemoteService() { + userConfigService.getSupportedOrganisationsEinheiten(); - verify(commandService).setCommandFinished(CommandTestFactory.ID); + verify(userConfigRemoteService).getSupportedOrganisationsEinheiten(); } } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileITCase.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileITCase.java index 4b2c66f..6b62448 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -54,18 +54,18 @@ import org.springframework.test.annotation.DirtiesContext; import com.google.protobuf.ByteString; import com.mongodb.client.gridfs.model.GridFSFile; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.common.callcontext.TestCallContextAttachingInterceptor; -import de.itvsh.ozg.pluto.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub; -import de.itvsh.ozg.pluto.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcFindFilesResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileMetaData; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileResponse; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.TestCallContextAttachingInterceptor; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.StatusRuntimeException; import io.grpc.stub.StreamObserver; import lombok.AccessLevel; @@ -122,9 +122,6 @@ public class BinaryFileITCase { assertThat(file.getId()).isEqualTo(fileId.toHexString()); assertThat(file.getName()).isEqualTo(OzgFileTestFactory.NAME); - // FIXME - // assertThat(file.getSize()).isEqualTo(OzgFileTestFactory.SIZE); - // assertThat(file.getContentType()).isEqualTo(OzgFileTestFactory.CONTENT_TYPE); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryITCase.java similarity index 73% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryITCase.java index b81dd7d..94cd6a4 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; @@ -40,19 +40,26 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @DataITCase class BinaryFileRepositoryITCase { @Autowired - private BinaryFileRepository gridFsService; + private BinaryFileRepository repository; @Autowired private MongoTemplate template; + @BeforeEach + void clearDB() { + template.dropCollection("fs.files"); + template.dropCollection("fs.chunks"); + } + @Nested class TestUploadFile { private UploadedFilesReference ref; @@ -60,9 +67,6 @@ class BinaryFileRepositoryITCase { @BeforeEach void init() { - template.dropCollection("fs.files"); - template.dropCollection("fs.chunks"); - ref = UploadedFilesReference.builder() .client("client") .name("test.file") @@ -75,7 +79,7 @@ class BinaryFileRepositoryITCase { void shouldStoreFiles() throws IOException { FileId id = storeFile(45); - assertThat(gridFsService.getFileContent(id)).isNotEmpty(); + assertThat(repository.getFileContent(id)).isNotEmpty(); } @Test @@ -85,7 +89,7 @@ class BinaryFileRepositoryITCase { FileId id = storeFile(savedFileMB); - InputStream in = gridFsService.getFileContent(id); + InputStream in = repository.getFileContent(id); byte[] buffer = in.readAllBytes(); assertThat(buffer).hasSize(fileSizeInBytes); @@ -94,7 +98,7 @@ class BinaryFileRepositoryITCase { private FileId storeFile(int sizeInMB) throws IOException { InputStream stream = IncomingFileTestFactory.createContentStreamInMB(sizeInMB); - FileId id = gridFsService.addContentStream(ref, file, Optional.empty(), stream); + FileId id = repository.addContentStream(ref, file, Optional.empty(), stream); stream.close(); return id; } @@ -105,12 +109,6 @@ class BinaryFileRepositoryITCase { private FileId fileId; - @BeforeEach - void deleteAll() { - template.dropCollection("fs.files"); - template.dropCollection("fs.chunks"); - } - @Nested class TestSingleMetaData { @@ -170,12 +168,42 @@ class BinaryFileRepositoryITCase { } private FileId initContentStream(OzgFile ozgFile) { - return gridFsService.addContentStream(UploadedFilesReferenceTestFactory.create(), ozgFile, Optional.of(UserTestFactory.ID), + return repository.addContentStream(UploadedFilesReferenceTestFactory.create(), ozgFile, Optional.of(UserTestFactory.ID), new ByteArrayInputStream(OzgFileTestFactory.CONTENT)); } private Stream<OzgFile> callRepository(Collection<String> fileIds) { - return gridFsService.getAll(fileIds); + return repository.getAll(fileIds); + } + } + + @Nested + class TestDeleteByVorgang { + @Test + void shouldDeleteFiles() { + var fileId = persistFile(); + + repository.deleteAllByVorgang(VorgangTestFactory.ID); + + var loaded = repository.getFile(fileId); + assertThat(loaded).isNull(); + } + + @Test + void shouldNotDeleteOtherFiles() { + var fileId = persistFile(); + + repository.deleteAllByVorgang("other"); + + var loaded = repository.getFile(fileId); + assertThat(loaded).isNotNull(); + } + + private FileId persistFile() { + return repository.addContentStream(UploadedFilesReferenceTestFactory.create(), + OzgFileTestFactory.create(), + Optional.of(UserTestFactory.ID), + new ByteArrayInputStream(OzgFileTestFactory.CONTENT)); } } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryTest.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryTest.java index 7f60918..021205d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/BinaryFileRepositoryTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/BinaryFileRepositoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collections; +import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.bson.Document; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -38,10 +41,10 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate; import static org.assertj.core.api.Assertions.*; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class BinaryFileRepositoryTest { @@ -145,6 +148,22 @@ class BinaryFileRepositoryTest { assertThat(files).hasSize(1); } + @Test + @DisplayName("should not map to OZG File when FileId is empty") + void shouldNotMapWhenFileIdEmpty() { + grisFsService.getAll(List.of(StringUtils.EMPTY)).toList(); + + verify(grisFsService, never()).mapToOzgFile(any()); + } + + @Test + @DisplayName("should not map to OZG File when FileId is null") + void shouldNotMapWhenFileIdNull() { + grisFsService.getAll(Collections.singletonList(null)).toList(); + + verify(grisFsService, never()).mapToOzgFile(any()); + } + @Nested class TestMapToOzgFile { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/EingangFilesRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/EingangFilesRepositoryITCase.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/EingangFilesRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/EingangFilesRepositoryITCase.java index ac2ca8c..2361337 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/EingangFilesRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/EingangFilesRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; @@ -33,13 +33,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFile; -import de.itvsh.ozg.pluto.vorgang.IncomingFileGroupTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFile; +import de.ozgcloud.vorgang.vorgang.IncomingFileGroupTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; @DataITCase class EingangFilesRepositoryITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileITCase.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileITCase.java index 8382210..748a5a6 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -37,17 +37,17 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetAttachmentsRequest; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetAttachmentsResponse; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetRepresentationsRequest; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetRepresentationsResponse; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFile; -import de.itvsh.ozg.pluto.vorgang.IncomingFileGroupTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest; +import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsResponse; +import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest; +import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsResponse; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFile; +import de.ozgcloud.vorgang.vorgang.IncomingFileGroupTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; @DataITCase diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileServiceTest.java similarity index 61% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileServiceTest.java index 1243b2c..f6e6b71 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/FileServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/FileServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,28 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.util.Collection; import java.util.Collections; import java.util.Optional; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; 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 de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; class FileServiceTest { + @Spy @InjectMocks private FileService service; @@ -53,10 +58,38 @@ class FileServiceTest { @Mock private FileIdMapper fileIdMapper; + private final UploadedFilesReference ref = UploadedFilesReferenceTestFactory.create(); + private final Optional<String> user = Optional.empty(); + private final OzgFile file = OzgFileTestFactory.create(); + private final InputStream contentStream = new ByteArrayInputStream(IncomingFileTestFactory.CONTENT); + + @DisplayName("Upload filestream") + @Nested + class TestUploadFileStream { + + @Test + void shouldCallUploadFile() { + service.uploadFileStream(ref, file, user, contentStream); + + verify(service).uploadFile(ref, file, user, contentStream); + } + } + + @DisplayName("upload filestream async") + @Nested + class TestUploadFileStreamAsync { + + @Test + void shouldCallUploadFile() { + service.uploadFileStream(ref, file, user, contentStream); + + verify(service).uploadFile(ref, file, user, contentStream); + } + } + + @DisplayName("Upload file") @Nested - class TestUploadFileAsStream { - private UploadedFilesReference ref = UploadedFilesReferenceTestFactory.create(); - private OzgFile file = OzgFileTestFactory.create(); + class TestUploadFile { @BeforeEach void init() { @@ -65,21 +98,21 @@ class FileServiceTest { @Test void shouldCallAddContentSream() { - service.uploadFileStream(ref, file, Optional.empty(), new ByteArrayInputStream(IncomingFileTestFactory.CONTENT)); + service.uploadFileStream(ref, file, user, contentStream); - verify(binaryFileRepository).addContentStream(any(), any(), any(), any()); + verify(binaryFileRepository).addContentStream(ref, file, user, contentStream); } @Test void shouldAddContent() { - service.uploadFileStream(ref, file, Optional.empty(), new ByteArrayInputStream(IncomingFileTestFactory.CONTENT)); + service.uploadFileStream(ref, file, user, contentStream); - verify(binaryFileRepository).addContentStream(any(), any(), any(), any()); + verify(binaryFileRepository).addContentStream(ref, file, user, contentStream); } @Test void shouldReturnId() throws Exception { - var id = service.uploadFileStream(ref, file, Optional.empty(), new ByteArrayInputStream(IncomingFileTestFactory.CONTENT)).get(5, + var id = service.uploadFileStream(ref, file, user, contentStream).get(5, TimeUnit.SECONDS); assertThat(id).isEqualTo(IncomingFileTestFactory.ID); @@ -121,4 +154,14 @@ class FileServiceTest { verify(binaryFileRepository).getAll(Collections.singletonList(OzgFileTestFactory.ID.toString())); } } + + @Nested + class TestDeleteAllByVorgang { + @Test + void shouldCallRepository() { + service.deleteAllByVorgang(VorgangTestFactory.ID); + + verify(binaryFileRepository).deleteAllByVorgang(VorgangTestFactory.ID); + } + } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GridFsTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GridFsTestFactory.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GridFsTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GridFsTestFactory.java index 813880b..0285a2d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GridFsTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GridFsTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.io.ByteArrayInputStream; import java.util.Date; @@ -33,9 +33,9 @@ import org.springframework.data.mongodb.util.BsonUtils; import com.mongodb.client.gridfs.model.GridFSFile; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class GridFsTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFileServiceTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFileServiceTest.java index 2deb779..294bf00 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFileServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFileServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -36,6 +36,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -45,13 +46,13 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcFindFilesResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataResponse; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileMetaData; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataResponse; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; import io.grpc.stub.CallStreamObserver; import io.grpc.stub.ServerCallStreamObserver; import io.grpc.stub.StreamObserver; @@ -114,8 +115,10 @@ class GrpcBinaryFileServiceTest { } } + @DisplayName("Upload filestream async") @Nested - class TestUploadFileStream { + class TestUploadFileStreamAsync { + private static final int FILE_SIZE = 5 * 1_000_000; @Mock @@ -129,14 +132,14 @@ class GrpcBinaryFileServiceTest { @BeforeEach void init() { - when(service.uploadFileStream(any(), any(), any(), any())).thenReturn(CompletableFuture.supplyAsync(() -> FileId.createNew())); + when(service.uploadFileStreamAsync(any(), any(), any(), any())).thenReturn(CompletableFuture.supplyAsync(() -> FileId.createNew())); } @Test void shouldCallService() throws IOException { uploadFile(FILE_SIZE); - verify(service, timeout(500)).uploadFileStream(any(), any(), any(), any()); + verify(service, timeout(500)).uploadFileStreamAsync(any(), any(), any(), any()); } @Test diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFilesRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFilesRequestTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFilesRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFilesRequestTestFactory.java index 2790309..278c394 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcBinaryFilesRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcBinaryFilesRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcBinaryFilesRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcBinaryFilesRequest; public class GrpcBinaryFilesRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetAttachmentsRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetAttachmentsRequestTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetAttachmentsRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetAttachmentsRequestTestFactory.java index b0c40eb..531b254 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetAttachmentsRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetAttachmentsRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetAttachmentsRequest; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; public class GrpcGetAttachmentsRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetBinaryFileDataRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetBinaryFileDataRequestTestFactory.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetBinaryFileDataRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetBinaryFileDataRequestTestFactory.java index 3f0e881..21a925c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetBinaryFileDataRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetBinaryFileDataRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.command.GrpcCallContextTestFactory; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataRequest; +import de.ozgcloud.vorgang.command.GrpcCallContextTestFactory; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataRequest; class GrpcGetBinaryFileDataRequestTestFactory { static final String FILE_ID = FileId.createNew().toString(); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetRepresentationsRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetRepresentationsRequestTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetRepresentationsRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetRepresentationsRequestTestFactory.java index 3d04ab0..91a7b56 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcGetRepresentationsRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcGetRepresentationsRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.grpc.file.GrpcGetRepresentationsRequest; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; public class GrpcGetRepresentationsRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapperTest.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapperTest.java index dabe7ff..37fc98e 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcOzgFileMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcOzgFileMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; @@ -32,7 +32,7 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Spy; -import de.itvsh.ozg.pluto.grpc.file.GrpcOzgFile; +import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile; class GrpcOzgFileMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileMetaDataTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileMetaDataTestFactory.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileMetaDataTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileMetaDataTestFactory.java index 4d52585..08ff404 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileMetaDataTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileMetaDataTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.command.GrpcCallContextTestFactory; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileMetaData; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.command.GrpcCallContextTestFactory; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class GrpcUploadBinaryFileMetaDataTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileRequestTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileRequestTestFactory.java index 4cc88a2..29dbb42 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadBinaryFileRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadBinaryFileRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import com.google.protobuf.ByteString; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; public class GrpcUploadBinaryFileRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadedFilesReferencesTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadedFilesReferencesTestFactory.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadedFilesReferencesTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadedFilesReferencesTestFactory.java index 43cc82d..604a209 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/GrpcUploadedFilesReferencesTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/GrpcUploadedFilesReferencesTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; public class GrpcUploadedFilesReferencesTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/OzgFileTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/OzgFileTestFactory.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/OzgFileTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/OzgFileTestFactory.java index 6cda8f7..209887e 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/OzgFileTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/OzgFileTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,14 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Random; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class OzgFileTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadStreamObserverTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadStreamObserverTest.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadStreamObserverTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadStreamObserverTest.java index 3e961bc..ce72708 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadStreamObserverTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadStreamObserverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -43,12 +43,12 @@ import org.mockito.Mock; import com.google.protobuf.ByteString; -import de.itvsh.kop.common.errorhandling.TechnicalException; -import de.itvsh.ozg.pluto.common.security.PolicyService; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileRequest; -import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcUploadBinaryFileResponse; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.common.security.PolicyService; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; class UploadStreamObserverTest { @@ -153,7 +153,7 @@ class UploadStreamObserverTest { @BeforeEach void init() { - when(service.uploadFileStream(any(), any(), any(), any())).thenReturn(CompletableFuture.completedFuture(FileId.createNew())); + when(service.uploadFileStreamAsync(any(), any(), any(), any())).thenReturn(CompletableFuture.completedFuture(FileId.createNew())); } @Test @@ -176,7 +176,7 @@ class UploadStreamObserverTest { uploadStreamObserver.storeFileMetaData(fileUploadRequest, uploadStreamObserver.getPipedInput(), uploadStreamObserver.getPipedOutput()); - verify(service).uploadFileStream(any(), any(), any(), any()); + verify(service).uploadFileStreamAsync(any(), any(), any(), any()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadedFilesReferenceTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadedFilesReferenceTestFactory.java similarity index 86% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadedFilesReferenceTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadedFilesReferenceTestFactory.java index e999d0c..6ba1719 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/files/UploadedFilesReferenceTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/files/UploadedFilesReferenceTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.files; +package de.ozgcloud.vorgang.files; -import de.itvsh.ozg.pluto.common.callcontext.CallContextTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class UploadedFilesReferenceTestFactory { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/GrpcRegistrationResponseTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/GrpcRegistrationResponseTestFactory.java new file mode 100644 index 0000000..09aa437 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/GrpcRegistrationResponseTestFactory.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.vorgang.registry; + +import de.ozgcloud.zufi.grpc.registration.GrpcVorgangManagerRegistrationResponse; + +public class GrpcRegistrationResponseTestFactory { + public static GrpcVorgangManagerRegistrationResponse create() { + return createBuilder().build(); + } + + public static GrpcVorgangManagerRegistrationResponse.Builder createBuilder() { + return GrpcVorgangManagerRegistrationResponse.newBuilder().setSuccess(true); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistrySchedulerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistrySchedulerTest.java new file mode 100644 index 0000000..5b53cc9 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistrySchedulerTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +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 de.ozgcloud.vorgang.common.userconfig.UserConfigService; +import io.grpc.StatusRuntimeException; + +class RegistrySchedulerTest { + private static final String ORGANISATION_EINHEITEN_ID = "123456"; + private static final List<String> ORGANISATION_EINHEITEN_IDS = List.of(ORGANISATION_EINHEITEN_ID); + + @Spy + @InjectMocks + private RegistryScheduler registryScheduler; + + @Mock + private RegistryService registryService; + + @Mock + private UserConfigService userConfigService; + + @DisplayName("Test the registering the VorgangManager") + @Nested + class TestScheduler { + + @Test + void shouldCallService() { + when(userConfigService.getSupportedOrganisationsEinheiten()).thenReturn(ORGANISATION_EINHEITEN_IDS); + + registryScheduler.register(); + + verify(registryService).registerVorgangManager(anyList()); + } + + @Test + void shouldHandleExceptionWhenLoadingOrganisationEinheiten() { + when(userConfigService.getSupportedOrganisationsEinheiten()).thenThrow(StatusRuntimeException.class); + + registryScheduler.register(); + + verify(registryService, never()).registerVorgangManager(anyList()); + } + + @Test + void shouldCallGetOrganisationEinheitenIds() { + when(userConfigService.getSupportedOrganisationsEinheiten()).thenReturn(ORGANISATION_EINHEITEN_IDS); + + registryScheduler.register(); + + verify(userConfigService).getSupportedOrganisationsEinheiten(); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistryServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistryServiceTest.java new file mode 100644 index 0000000..6404824 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/RegistryServiceTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 org.springframework.test.util.ReflectionTestUtils; + +class RegistryServiceTest { + private static final String ORGANISATION_EINHEITEN_ID = "123456"; + private static final List<String> ORGANISATION_EINHEITEN_IDS = List.of(ORGANISATION_EINHEITEN_ID); + private static final Optional<String> VORGANG_MANAGER_ADDRESS = Optional.of("address"); + + @Spy + @InjectMocks + private RegistryService registryService; + + @Mock + private ZufiRemoteService zufiRemoteService; + + @DisplayName("Test registering the VorgangManager") + @Nested + class TestRegistryVorgangManager { + @BeforeEach + void initVorgangManagerAddress() { + ReflectionTestUtils.setField(registryService, "vorgangManagerAddress", VORGANG_MANAGER_ADDRESS); + } + + @Test + void shouldCallZuFiRemoteService() { + registryService.registerVorgangManager(ORGANISATION_EINHEITEN_IDS); + + verify(zufiRemoteService).registerVorgangManager(anyList(), any()); + } + + @Test + void shouldNotCallZuFiRemoteServiceOnEmptyOrganisationsEinheitenIds() { + registryService.registerVorgangManager(Collections.emptyList()); + + verify(zufiRemoteService, never()).registerVorgangManager(anyList(), any()); + } + + @Test + void shouldNotCallServiceStub() { + registryService.registerAddress(ORGANISATION_EINHEITEN_IDS, Optional.empty()); + + verify(zufiRemoteService, never()).registerVorgangManager(any(), any()); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/ZufiRemoteServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/ZufiRemoteServiceTest.java new file mode 100644 index 0000000..094dbeb --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/registry/ZufiRemoteServiceTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.registry; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor; +import de.ozgcloud.zufi.grpc.registration.GrpcVorgangManagerRegistrationRequest; +import de.ozgcloud.zufi.grpc.registration.VorgangManagerRegistrationServiceGrpc.VorgangManagerRegistrationServiceBlockingStub; + +class ZufiRemoteServiceTest { + private static final String ORGANISATIONS_EINHEITEN_ID = "123456"; + private static final List<String> ORGANISATIONS_EINHEITEN_IDS = List.of(ORGANISATIONS_EINHEITEN_ID); + private static final String VORGANG_MANAGER_ADDRESS = "address"; + + @Spy + @InjectMocks + private ZufiRemoteService zufiRemoteService; + + @Mock + private VorgangManagerRegistrationServiceBlockingStub serviceStub; + + @DisplayName("Test ZuFiRemoteService when VorgangManager address is configured") + @Nested + class TestRegisteringVorgangManager { + @BeforeEach + void init() { + when(serviceStub.withInterceptors(any())).thenReturn(serviceStub); + when(serviceStub.register(any(GrpcVorgangManagerRegistrationRequest.class))).thenReturn(GrpcRegistrationResponseTestFactory.create()); + } + + @Test + void shouldCallServiceStub() { + zufiRemoteService.registerVorgangManager(ORGANISATIONS_EINHEITEN_IDS, VORGANG_MANAGER_ADDRESS); + + verify(serviceStub).register(any(GrpcVorgangManagerRegistrationRequest.class)); + } + + @Test + void shouldUseInterceptor() { + zufiRemoteService.registerVorgangManager(ORGANISATIONS_EINHEITEN_IDS, VORGANG_MANAGER_ADDRESS); + + verify(serviceStub).withInterceptors(any(VorgangManagerClientCallContextAttachingInterceptor.class)); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcPostfachAddressTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcPostfachAddressTestFactory.java new file mode 100644 index 0000000..6b21f6b --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcPostfachAddressTestFactory.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; + +public class GrpcPostfachAddressTestFactory { + + public static GrpcPostfachAddress create() { + return createBuilder().build(); + } + + public static GrpcPostfachAddress.Builder createBuilder() { + return GrpcPostfachAddress.newBuilder() + .setType(PostfachAddressTestFactory.TYPE) + .setIdentifier(createStringBasedIdentifier()) + .setVersion(PostfachAddressTestFactory.VERSION); + } + + private static GrpcObject createStringBasedIdentifier() { + return GrpcObject.newBuilder() + .addProperty(GrpcProperty.newBuilder() + .setName(PostfachAddress.IDENTIFIER_POSTFACH_ID_FIELD) + .addValue(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build()) + .build(); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcServiceKontoTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcServiceKontoTestFactory.java new file mode 100644 index 0000000..a3198d5 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/GrpcServiceKontoTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; + +public class GrpcServiceKontoTestFactory { + + public static GrpcServiceKonto create() { + return createBuilder().build(); + } + + public static GrpcServiceKonto.Builder createBuilder() { + return GrpcServiceKonto.newBuilder() + .setType(ServiceKontoTestFactory.TYPE) + .addPostfachAddresses(GrpcPostfachAddressTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/PostfachAddressTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/PostfachAddressTestFactory.java new file mode 100644 index 0000000..280f10c --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/PostfachAddressTestFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +import java.util.Map; +import java.util.UUID; + +public class PostfachAddressTestFactory { + + public final static int TYPE = 1; + public static final String STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE = UUID.randomUUID().toString(); + public static final Map<String, Object> IDENTIFIER = Map.of(PostfachAddress.IDENTIFIER_POSTFACH_ID_FIELD, + STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + public static final String VERSION = "1.0"; + + public static PostfachAddress create() { + return createBuilder().build(); + } + + public static PostfachAddress.PostfachAddressBuilder createBuilder() { + return PostfachAddress.builder() + .type(TYPE) + .identifier(IDENTIFIER) + .version(VERSION); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapperTest.java new file mode 100644 index 0000000..a2a6f5f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoMapperTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +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 org.mockito.InjectMocks; +import org.mockito.Spy; + +import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.vorgang.GrpcServiceKonto; + +class ServiceKontoMapperTest { + + @InjectMocks + private ServiceKontoMapper mapper = Mappers.getMapper(ServiceKontoMapper.class); + @Spy + private GrpcObjectMapper grpcObjectMapper = Mappers.getMapper(GrpcObjectMapper.class); + + @DisplayName("From serviceKonto") + @Nested + class TestFromServiceKonto { + + @Test + void shouldMapFields() { + var serviceKonto = fromServiceKonto(); + + assertThat(serviceKonto).usingRecursiveComparison().isEqualTo(ServiceKontoTestFactory.create()); + } + + private ServiceKonto fromServiceKonto() { + return mapper.fromServiceKonto(GrpcServiceKontoTestFactory.create()); + } + } + + @DisplayName("to serviceKonto") + @Nested + class TestToServiceKonto { + + @Test + void shouldMapFields() { + var serviceKonto = toServiceKonto(); + + assertThat(serviceKonto).usingRecursiveComparison().isEqualTo(GrpcServiceKontoTestFactory.create()); + } + + private GrpcServiceKonto toServiceKonto() { + return mapper.toServiceKonto(ServiceKontoTestFactory.create()); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoTestFactory.java new file mode 100644 index 0000000..1235c5f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/servicekonto/ServiceKontoTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.servicekonto; + +public class ServiceKontoTestFactory { + + public final static String TYPE = "OSI"; + + public static ServiceKonto create() { + return createBuilder().build(); + } + + public static ServiceKonto.ServiceKontoBuilder createBuilder() { + return ServiceKonto.builder() + .type(TYPE) + .postfachAddress(PostfachAddressTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTest.java new file mode 100644 index 0000000..e7cc5fc --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTest.java @@ -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. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class CountByPathTest { + + @Test + void shouldSetFieldPath() { + var countByPath = CountByPath.fromStatisticRequest(VorgangStatisticRequestTestFactory.create()); + + assertThat(countByPath.getFieldPath()).isEqualTo(VorgangStatisticRequestTestFactory.REQUEST_FIELD_PATH); + } + + @Test + void shouldSetAlias() { + var countByPath = CountByPath.fromStatisticRequest(VorgangStatisticRequestTestFactory.create()); + + assertThat(countByPath.getAlias()).isEqualTo(VorgangStatisticRequestTestFactory.RESULT_NAME); + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTestFactory.java new file mode 100644 index 0000000..41e9409 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountByPathTestFactory.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.vorgang.statistic; + +import de.ozgcloud.vorgang.statistic.CountByPath.CountByPathBuilder; + +public class CountByPathTestFactory { + public static final String ALIAS = "attribute"; + public static final String FIELD_PATH = "Vorgang.name"; + + public static final CountByPath create() { + return createBuilder().build(); + } + + public static final CountByPathBuilder createBuilder() { + return CountByPath.builder() + .alias(ALIAS); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountPathRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountPathRequestTestFactory.java new file mode 100644 index 0000000..58306eb --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountPathRequestTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.statistic.CountByPath.CountByPathBuilder; + +public class CountPathRequestTestFactory { + + public static final String FIELD_PATH = "path"; + + public static CountByPath create() { + return createRequest().build(); + } + + public static CountByPathBuilder createRequest() { + return CountByPath.builder().fieldPath(FIELD_PATH).alias(CountResultTestFactory.NAME); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountResultTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountResultTestFactory.java new file mode 100644 index 0000000..8941a6e --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountResultTestFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +public class CountResultTestFactory { + + public static final String NAME = CountByPathTestFactory.ALIAS; + public static final int VALUE = 1; + + public static CountResult create() { + return createBuilder().build(); + } + + public static CountResult.CountResultBuilder createBuilder() { + return CountResult.builder().name(NAME).value(VALUE); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountStatisticMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountStatisticMapperTest.java new file mode 100644 index 0000000..1f65d6f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/CountStatisticMapperTest.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; + +class CountStatisticMapperTest { + + @Spy + private CountStatisticMapper mapper = new CountStatisticMapper(); + + @DisplayName("Map to") + @Nested + class TestMapTo { + + @DisplayName("path count result") + @Nested + class TestPathCountResult { + + @Test + void shouldHaveSize() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getPathCountResultList()).hasSize(1); + } + + @Test + void shouldHaveSetName() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getPathCountResultList().get(0).getName()).isEqualTo(StatisticTestFactory.FIELD_PATH_ALIAS); + } + + @Test + void shouldHaveSetValue() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getPathCountResultList().get(0).getValue()).isEqualTo(StatisticTestFactory.FIELD_PATH_VALUE); + } + } + + @Nested + @DisplayName("by status") + class TestMapByStatus { + + @Test + @DisplayName("should map NEU status") + void shouldMapNeu() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getNeu()).isEqualTo(StatisticTestFactory.NEU_COUNT); + } + + @Test + @DisplayName("should map ANGENOMMEN status") + void shouldMapAngenommen() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getAngenommen()).isEqualTo(StatisticTestFactory.ANGENOMMEN_COUNT); + } + + @Test + @DisplayName("should map VERWORFEN status") + void shouldMapVerworfen() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getVerworfen()).isEqualTo(StatisticTestFactory.VERWORFEN_COUNT); + } + + @Test + @DisplayName("should map IN_BEARBEITUNG status") + void shouldMapInBearbeitung() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getInBearbeitung()).isEqualTo(StatisticTestFactory.IN_BEARBEITUNG_COUNT); + } + + @Test + @DisplayName("should map BESCHIEDEN status") + void shouldMapBeschieden() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getBeschieden()).isEqualTo(StatisticTestFactory.BESCHIEDEN_COUNT); + } + + @Test + @DisplayName("should map ABGESCHLOSSEN status") + void shouldMapAbgeschlossen() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getAbgeschlossen()).isEqualTo(StatisticTestFactory.ABGESCHLOSSEN_COUNT); + } + + @Test + @DisplayName("should map WEITERGELEITET status") + void shouldMapWeitergeleitet() { + var response = mapper.mapTo(StatisticTestFactory.create()); + + assertThat(response.getByStatus().getWeitergeleitet()).isEqualTo(StatisticTestFactory.WEITERGELEITET_COUNT); + } + } + } + + @DisplayName("Map from gRPC request") + @Nested + class TestMapToRequest { + + private final String countPath = CountResultTestFactory.NAME + ":" + CountPathRequestTestFactory.FIELD_PATH; + + @Test + void shouldMapPath() { + var countRequest = mapper.mapPathCountRequest(countPath); + + assertThat(countRequest).usingRecursiveComparison().isEqualTo(CountPathRequestTestFactory.create()); + } + + @Test + void shouldMapGrpcRequest() { + doReturn(CountPathRequestTestFactory.create()).when(mapper).mapPathCountRequest(anyString()); + var grpcRequest = GrpcVorgangCountRequest.newBuilder().addCountByPath(countPath).build(); + + var request = mapper.mapFromVorgangCountRequest(grpcRequest); + + assertThat(request.getCountByPaths()).hasSize(1).first().usingRecursiveComparison().isEqualTo(CountPathRequestTestFactory.create()); + } + + @Nested + @DisplayName("Extract request parts") + class TestExtract { + + @Test + void shouldExtractFieldPath() { + var fieldPath = mapper.extractFieldPath(countPath); + + assertThat(fieldPath).isEqualTo(CountPathRequestTestFactory.FIELD_PATH); + } + + @Test + void shouldThrowExceptionOnInvalidPath() { + assertThrows(VorgangStatisticBadRequestException.class, () -> mapper.extractFieldPath("")); + } + + @Test + void shouldExtractAlias() { + var alias = mapper.extractAlias(countPath); + + assertThat(alias).isEqualTo(CountResultTestFactory.NAME); + } + + @Test + void shouldThrowExceptionOnInvalidAlias() { + assertThrows(VorgangStatisticBadRequestException.class, () -> mapper.extractAlias("invalid")); + } + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticQueryTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticQueryTestFactory.java new file mode 100644 index 0000000..d66e876 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticQueryTestFactory.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery.GroupMethod; + +public class GrpcVorgangStatisticQueryTestFactory { + + static final String OPERAND_STRING_VALUE = "NEU"; + static final GroupMethod GROUP_METHOD = GroupMethod.COUNT; + static final String QUERY_PATH = "Vorgang.status"; + static final String PATH = "status"; + static final String RESULT_NAME = "countByStatusNeu"; + + static GrpcVorgangStatisticQuery create() { + return createBuilder().build(); + } + + static GrpcVorgangStatisticQuery.Builder createBuilder() { + return GrpcVorgangStatisticQuery.newBuilder() + .setResultName(RESULT_NAME) + .setGroupMethod(GROUP_METHOD) + .setPath(QUERY_PATH) + .setOperator(GrpcQueryOperator.EQUAL) + .setOperandStringValue(OPERAND_STRING_VALUE); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticRequestTestFactory.java new file mode 100644 index 0000000..afd7059 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticRequestTestFactory.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.vorgang.statistic; + +class GrpcVorgangStatisticRequestTestFactory { + + static GrpcVorgangStatisticRequest create() { + return createBuilder().build(); + } + + static GrpcVorgangStatisticRequest.Builder createBuilder() { + return GrpcVorgangStatisticRequest.newBuilder() + .addQuery(GrpcVorgangStatisticQueryTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResponseTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResponseTestFactory.java new file mode 100644 index 0000000..0553a56 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResponseTestFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +class GrpcVorgangStatisticResponseTestFactory { + + static GrpcVorgangStatisticResponse create() { + return createBuilder().build(); + } + + static GrpcVorgangStatisticResponse.Builder createBuilder() { + return GrpcVorgangStatisticResponse.newBuilder() + .addResult(GrpcVorgangStatisticResultTestFactory.create()); + } + +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResultTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResultTestFactory.java new file mode 100644 index 0000000..26df9e6 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/GrpcVorgangStatisticResultTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +class GrpcVorgangStatisticResultTestFactory { + + static final int RESULT_INT_VALUE = 42; + + static GrpcVorgangStatisticResult create() { + return createBuilder().build(); + } + + static GrpcVorgangStatisticResult.Builder createBuilder() { + return GrpcVorgangStatisticResult.newBuilder() + .setName(GrpcVorgangStatisticQueryTestFactory.RESULT_NAME) + .setResultIntValue(RESULT_INT_VALUE); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/OperatorTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/OperatorTestFactory.java new file mode 100644 index 0000000..05b8aa0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/OperatorTestFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; + +public class OperatorTestFactory { + + public static Operator create() { + return createBuilder().build(); + } + + public static OperatorBuilder createBuilder() { + return OperatorBuilder + .from(GrpcQueryOperator.UNEQUAL) + .fieldPath(VorgangStatisticRequestTestFactory.REQUEST_FIELD_PATH); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticGrpcServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticGrpcServiceTest.java new file mode 100644 index 0000000..373ebb4 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticGrpcServiceTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 StatisticGrpcServiceTest { + + @Spy + @InjectMocks + private StatisticGrpcService grpcStatisticService; + + @Mock + private StatisticService statisticService; + @Mock + private CountStatisticMapper countStatisticMapper; + @Mock + private StatisticMapper statisticMapper; + + @DisplayName("Count vorgang") + @Nested + class TestCountVorgang { + + @Mock + private GrpcVorgangCountRequest grpcRequest; + @Mock + private StreamObserver<GrpcVorgangCountResponse> responseStreamObserver; + @Mock + private GrpcVorgangCountResponse grpcResponse; + + private Statistic statistic = StatisticTestFactory.create(); + private VorgangCountRequest request = VorgangCountRequest.builder().build(); + + @BeforeEach + void setUp() { + when(statisticService.countVorgang(any())).thenReturn(statistic); + when(countStatisticMapper.mapFromVorgangCountRequest(any())).thenReturn(request); + } + + @Test + void shouldCallMapFrom() { + grpcStatisticService.countVorgang(grpcRequest, responseStreamObserver); + + verify(countStatisticMapper).mapFromVorgangCountRequest(grpcRequest); + } + + @Test + void shouldCallService() { + grpcStatisticService.countVorgang(grpcRequest, responseStreamObserver); + + verify(statisticService).countVorgang(request); + } + + @Test + void shouldCallMapTo() { + grpcStatisticService.countVorgang(grpcRequest, responseStreamObserver); + + verify(countStatisticMapper).mapTo(statistic); + } + + @Test + void shouldSetResponse() { + when(countStatisticMapper.mapTo(any())).thenReturn(grpcResponse); + + grpcStatisticService.countVorgang(grpcRequest, responseStreamObserver); + + verify(responseStreamObserver).onNext(grpcResponse); + } + + @Test + void shouldCompleteResponse() { + grpcStatisticService.countVorgang(grpcRequest, responseStreamObserver); + + verify(responseStreamObserver).onCompleted(); + } + } + + @Nested + class TestGetVorgangStatistic { + + @Mock + private StreamObserver<GrpcVorgangStatisticResponse> responseObserver; + + private GrpcVorgangStatisticRequest request = GrpcVorgangStatisticRequestTestFactory.create(); + private GrpcVorgangStatisticResponse response = GrpcVorgangStatisticResponseTestFactory.create(); + + @BeforeEach + void init() { + doReturn(response).when(statisticMapper).mapToVorgangStatisticResponse(any()); + } + + @Test + void shouldSetResponse() { + grpcStatisticService.getVorgangStatistic(request, responseObserver); + + verify(responseObserver).onNext(response); + } + + @Test + void shouldCompleteResponse() { + grpcStatisticService.getVorgangStatistic(request, responseObserver); + + verify(responseObserver).onCompleted(); + } + + @Test + void shouldCallMapFromStatisticRequest() { + grpcStatisticService.getVorgangStatistic(request, responseObserver); + + verify(statisticMapper).mapFromVorgangStatisticRequest(request); + } + + @Test + void shouldCallStatisticService() { + var statisticRequests = List.of(VorgangStatisticRequestTestFactory.create()); + when(statisticMapper.mapFromVorgangStatisticRequest(any())).thenReturn(statisticRequests); + + grpcStatisticService.getVorgangStatistic(request, responseObserver); + + verify(statisticService).collectStatistic(statisticRequests); + } + + @Test + void shouldCallMapToStatisticRequest() { + var statistic = StatisticTestFactory.create(); + when(statisticService.collectStatistic(any())).thenReturn(statistic); + + grpcStatisticService.getVorgangStatistic(request, responseObserver); + + verify(statisticMapper).mapToVorgangStatisticResponse(statistic); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticMapperTest.java new file mode 100644 index 0000000..e70be63 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticMapperTest.java @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 de.ozgcloud.vorgang.common.operator.OperandFunctionParser; + +class StatisticMapperTest { + + @Spy + @InjectMocks + private StatisticMapper mapper; + + @Mock + private OperandFunctionParser operandFunctionParser; + + @Nested + class TestMapFromVorgangStatisticRequest { + + @Test + void shouldCallMapFromVorgangStatisticQuery() { + var statisticQuery = GrpcVorgangStatisticQuery.newBuilder().setPath(VorgangStatisticRequestTestFactory.REQUEST_FIELD_PATH) + .setOperandIntValue(1).build(); + var grpcRequest = GrpcVorgangStatisticRequest.newBuilder().addQuery(statisticQuery).build(); + + mapper.mapFromVorgangStatisticRequest(grpcRequest); + + verify(mapper).mapFromVorgangStatisticQuery(statisticQuery); + } + + @Nested + @DisplayName("Map from VorgangStatisticQuery") + class TestMapFromVorgangStatisticQuery { + + @BeforeEach + void setup() { + } + + @Test + void shouldSetResultName() { + var vorgangStatisticRequest = mapper.mapFromVorgangStatisticQuery(GrpcVorgangStatisticQueryTestFactory.create()); + + assertThat(vorgangStatisticRequest.getResultName()).isEqualTo(GrpcVorgangStatisticQueryTestFactory.RESULT_NAME); + } + + @Test + void shouldCallGetFieldPath() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.create(); + + mapper.mapFromVorgangStatisticQuery(statisticQuery); + + verify(mapper, times(1)).getFieldPath(statisticQuery); + } + + @Test + void shouldSetGroupMethod() { + var vorgangStatisticRequest = mapper.mapFromVorgangStatisticQuery(GrpcVorgangStatisticQueryTestFactory.create()); + + assertThat(vorgangStatisticRequest.getStatisticGroupMethod()).isEqualTo( + StatisticGroupMethod.from(GrpcVorgangStatisticQueryTestFactory.GROUP_METHOD)); + } + + @Test + void shouldCallBuildStatisticFilter() { + GrpcVorgangStatisticQuery statisticQuery = GrpcVorgangStatisticQueryTestFactory.create(); + + mapper.mapFromVorgangStatisticQuery(statisticQuery); + + verify(mapper).buildOperator(statisticQuery); + } + + @Nested + class TestGetFieldPath { + + @Test + void shouldReturnOriginPath() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.create(); + + var fieldPath = mapper.getFieldPath(statisticQuery); + + assertThat(fieldPath).isEqualTo(GrpcVorgangStatisticQueryTestFactory.QUERY_PATH); + } + + @Test + @DisplayName("should extend field path by '.value' parameter begins with 'clientAttributes'") + void shouldExtendPath() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setPath("clientAttributes.path").build(); + + var fieldPath = mapper.getFieldPath(statisticQuery); + + assertThat(fieldPath).endsWith(".value"); + } + } + } + + @Nested + class TestBuildOperator { + + @Test + void shouldSetFieldPath() { + var operator = mapper.buildOperator(GrpcVorgangStatisticQueryTestFactory.create()); + + assertThat(operator).extracting("fieldPath").isEqualTo(GrpcVorgangStatisticQueryTestFactory.PATH); + } + + @Test + void shouldExtendFieldPathWhenClientAttribute() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setPath("ClientAttribute.path").build(); + + var operator = mapper.buildOperator(statisticQuery); + + assertThat(operator).extracting("fieldPath").isEqualTo("clientAttributes.path.value"); + } + + @Test + void shouldSetOperand() { + var operator = mapper.buildOperator(GrpcVorgangStatisticQueryTestFactory.create()); + + assertThat(operator).extracting("operand").isEqualTo(GrpcVorgangStatisticQueryTestFactory.OPERAND_STRING_VALUE); + } + + } + + @Nested + class TestGetValue { + + @Test + void shouldReturnNullWhenNotSet() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().clearOperandStringValue().build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isNull(); + } + + @Test + void shouldCallGetStringValue() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.create(); + + mapper.getValue(statisticQuery); + + verify(mapper).getStringValue(statisticQuery); + } + + @Test + void shouldReturnInteger() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setOperandIntValue(1).build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isEqualTo(1); + } + + @Test + void shouldReturnBoolean() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setOperandBoolValue(true).build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isEqualTo(true); + } + + @Nested + class TestGetStringValue { + + @Test + void shouldCallOperandFunctionParser() { + var functionValue = "function()"; + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setOperandStringValue(functionValue).build(); + + mapper.getStringValue(statisticQuery); + + verify(operandFunctionParser).parse(functionValue); + } + + @Test + void shouldReturnNull() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder().setOperandStringValue("null").build(); + + var value = mapper.getStringValue(statisticQuery); + + assertThat(value).isNull(); + } + + @Test + void shouldReturnStringValue() { + var statisticQuery = GrpcVorgangStatisticQueryTestFactory.create(); + + var value = mapper.getStringValue(statisticQuery); + + assertThat(value).isEqualTo(GrpcVorgangStatisticQueryTestFactory.OPERAND_STRING_VALUE); + } + } + } + } + + @Nested + @DisplayName("Map to VorgangStatisticResponse") + class TestMapToVorgangStatisticResponse { + + @Test + void shouldCallMapCountByPathStatistic() { + mapper.mapToVorgangStatisticResponse(StatisticTestFactory.create()); + + verify(mapper).mapCountByPathStatistic(StatisticTestFactory.BY_PATH_MAP); + } + + @Test + void shouldCallMapIsFieldExistsStatistic() { + mapper.mapToVorgangStatisticResponse(StatisticTestFactory.create()); + + verify(mapper).mapIsFieldExistsStatistic(StatisticTestFactory.FIELD_EXISTS_MAP); + } + + @Test + void shouldSetStatisticResults() { + var countByPathStatisticResult = GrpcVorgangStatisticResultTestFactory.create(); + var isFieldExistsStatisticResult = GrpcVorgangStatisticResultTestFactory.createBuilder().setResultBoolValue(true).build(); + init(countByPathStatisticResult, isFieldExistsStatisticResult); + + var response = mapper.mapToVorgangStatisticResponse(StatisticTestFactory.create()); + + assertThat(response.getResultList()).containsExactly(countByPathStatisticResult, isFieldExistsStatisticResult); + } + + private void init(GrpcVorgangStatisticResult countByPathStatisticResult, GrpcVorgangStatisticResult isFieldExistsStatisticResult) { + var list = new ArrayList<GrpcVorgangStatisticResult>(); + list.add(countByPathStatisticResult); + doReturn(list).when(mapper).mapCountByPathStatistic(anyMap()); + doReturn(List.of(isFieldExistsStatisticResult)).when(mapper).mapIsFieldExistsStatistic(anyMap()); + } + + @Nested + @DisplayName("Map CountByPathStatistic") + class TestMapByPathStatistic { + + @Test + void shouldCallMapToCountResult() { + mapper.mapCountByPathStatistic(StatisticTestFactory.BY_PATH_MAP); + + verify(mapper).mapToCountResult(StatisticTestFactory.FIELD_PATH_ALIAS, StatisticTestFactory.FIELD_PATH_VALUE); + } + + @Test + void shouldGetEmptyList() { + var result = mapper.mapCountByPathStatistic(Collections.emptyMap()); + + assertThat(result).isEmpty(); + } + + @Nested + @DisplayName("Map to CountResult") + class TestMapToCountResult { + + @Test + void shouldSetName() { + var result = mapper.mapToCountResult(StatisticTestFactory.FIELD_PATH_ALIAS, StatisticTestFactory.FIELD_PATH_VALUE); + + assertThat(result.getName()).isEqualTo(StatisticTestFactory.FIELD_PATH_ALIAS); + } + + @Test + void shouldSetIntValue() { + var result = mapper.mapToCountResult(StatisticTestFactory.FIELD_PATH_ALIAS, StatisticTestFactory.FIELD_PATH_VALUE); + + assertThat(result.getResultIntValue()).isEqualTo(StatisticTestFactory.FIELD_PATH_VALUE); + } + } + } + + @Nested + @DisplayName("Map IsFieldExistsStatistic") + class TestMapIsFieldExistsStatistic { + + @Test + void shouldCallMapToIsFieldExistsResult() { + mapper.mapIsFieldExistsStatistic(StatisticTestFactory.FIELD_EXISTS_MAP); + + verify(mapper).mapToIsFieldExistsResult(StatisticTestFactory.FIELD_PATH_ALIAS, true); + } + + @Test + void shouldGetEmptyList() { + var result = mapper.mapIsFieldExistsStatistic(Collections.emptyMap()); + + assertThat(result).isEmpty(); + } + + @Nested + @DisplayName("Map to IsFieldExistsResult") + class TestMapToIsFieldExistsResult { + + @Test + void shouldSetName() { + var result = mapper.mapToIsFieldExistsResult(StatisticTestFactory.FIELD_PATH_ALIAS, true); + + assertThat(result.getName()).isEqualTo(StatisticTestFactory.FIELD_PATH_ALIAS); + } + + @Test + void shouldSetBoolValue() { + var result = mapper.mapToIsFieldExistsResult(StatisticTestFactory.FIELD_PATH_ALIAS, true); + + assertThat(result.getResultBoolValue()).isTrue(); + } + } + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryITCase.java new file mode 100644 index 0000000..60cb4a0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryITCase.java @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static de.ozgcloud.vorgang.statistic.CountByPathTestFactory.*; +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangStubTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; + +@DataITCase +class StatisticRepositoryITCase { + + @Autowired + private StatisticRepository statisticRepository; + @Autowired + private MongoOperations mongoOperations; + + @Nested + @DisplayName("Count by status") + class TestByStatus { + + @Nested + @DisplayName("with filters") + class TestFilters { + private static final String ANOTHER_ORGA_ID = "another-orga-id"; + + private Vorgang vorgangInBearbeitung = VorgangTestFactory.createBuilder().id(null).status(Vorgang.Status.IN_BEARBEITUNG).build(); + + @BeforeEach + void setUp() { + mongoOperations.dropCollection(Vorgang.class); + + var vorgangNeu = VorgangTestFactory.createBuilder().id(null).build(); + var zustaendigeStelle = ZustaendigeStelleTestFactory.createBuilder().organisationseinheitenId(ANOTHER_ORGA_ID).build(); + var eingang = EingangTestFactory.createBuilder().zustaendigeStelle(zustaendigeStelle).build(); + var vorgangNeuAnotherOrgaId = VorgangTestFactory.createBuilder().id(null).clearEingangs().eingang(eingang).build(); + mongoOperations.insertAll(List.of(vorgangNeu, vorgangNeuAnotherOrgaId, vorgangInBearbeitung)); + } + + @Test + void shouldCountAllVorgang() { + var statusCounts = statisticRepository.countVorgangByStatus(StatisticFilter.builder().build()); + + assertThat(statusCounts).containsOnly( + CountResultTestFactory.createBuilder().name(Vorgang.Status.NEU.toString()).value(2).build(), + CountResultTestFactory.createBuilder().name(Vorgang.Status.IN_BEARBEITUNG.toString()).build()); + } + + @Test + void shouldCountAllVorgangByOrganisatorischeEinheitenIds() { + var filter = StatisticFilter.builder() + .organisationsEinheitIds(List.of(ANOTHER_ORGA_ID, ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)).build(); + + var statusCounts = statisticRepository.countVorgangByStatus(filter); + + assertThat(statusCounts).containsOnly( + CountResultTestFactory.createBuilder().name(Vorgang.Status.NEU.toString()).value(2).build(), + CountResultTestFactory.createBuilder().name(Vorgang.Status.IN_BEARBEITUNG.toString()).build()); + } + + @Test + void shouldFilterByOrganisatorischeEinheitenId() { + var filter = StatisticFilter.builder().organisationsEinheitIds(List.of(ANOTHER_ORGA_ID)).build(); + + var statusCounts = statisticRepository.countVorgangByStatus(filter); + + assertThat(statusCounts).containsOnly(CountResult.builder().name(Vorgang.Status.NEU.toString()).value(1).build()); + } + + @Test + void shouldNotCountInCreation() { + mongoOperations.dropCollection(Vorgang.class); + var vorgangInCreation = VorgangTestFactory.createBuilder().id(null).inCreation(true).build(); + mongoOperations.insert(vorgangInCreation); + + var statusCounts = statisticRepository.countVorgangByStatus(StatisticFilter.builder().build()); + + assertThat(statusCounts).isEmpty(); + } + } + + @DisplayName("per status") + @Nested + class TestPerStatus { + + @BeforeEach + void setUp() { + mongoOperations.dropCollection(Vorgang.class); + } + + @Test + void shouldCountAngenommen() { + initTestWithStatus(Vorgang.Status.ANGENOMMEN); + + var statusCounts = statisticRepository.countVorgangByStatus(StatisticFilter.builder().build()); + + assertThat(statusCounts).hasSize(1).first().isEqualTo(buildCountResultForStatus(Vorgang.Status.ANGENOMMEN)); + } + + @Test + void shouldCountVerworfen() { + initTestWithStatus(Vorgang.Status.VERWORFEN); + + var statusCounts = countVorgangByStatus(); + + assertThat(statusCounts).hasSize(1).first().isEqualTo(buildCountResultForStatus(Vorgang.Status.VERWORFEN)); + + } + + @Test + void shouldCountAbgeschlossen() { + initTestWithStatus(Vorgang.Status.ABGESCHLOSSEN); + + var statusCounts = countVorgangByStatus(); + + assertThat(statusCounts).hasSize(1).first().isEqualTo(buildCountResultForStatus(Vorgang.Status.ABGESCHLOSSEN)); + + } + + @Test + void shouldCountWeitergeleitet() { + initTestWithStatus(Vorgang.Status.WEITERGELEITET); + + var statusCounts = countVorgangByStatus(); + + assertThat(statusCounts).hasSize(1).first().isEqualTo(buildCountResultForStatus(Vorgang.Status.WEITERGELEITET)); + + } + + @Test + void shouldCountBeschieden() { + initTestWithStatus(Vorgang.Status.BESCHIEDEN); + + var statusCounts = countVorgangByStatus(); + + assertThat(statusCounts).hasSize(1).first().isEqualTo(buildCountResultForStatus(Vorgang.Status.BESCHIEDEN)); + } + + private void initTestWithStatus(Vorgang.Status status) { + var vorgang = VorgangTestFactory.createBuilder().id(null).status(status).build(); + mongoOperations.save(vorgang); + } + + private CountResult buildCountResultForStatus(Vorgang.Status status) { + return CountResultTestFactory.createBuilder().name(status.toString()).build(); + } + } + + private List<CountResult> countVorgangByStatus() { + return statisticRepository.countVorgangByStatus(StatisticFilter.builder().build()); + } + } + + @Nested + class TestByPath { + + private final String FIELD_NAME = "nextFrist"; + private final String FIELD_PATH = "ClientAttribute.%s.%s".formatted(ClientAttributeTestFactory.CLIENT_NAME, + FIELD_NAME); + + private final static Vorgang DEFAULT_VORGANG = VorgangTestFactory.createBuilder().id(null).build(); + + private StatisticFilter statisticFilter = StatisticFilter.builder().build(); + + @BeforeEach + void setup() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + mongoOperations.save(DEFAULT_VORGANG); + + var nextWiedervorlageAttribute = ClientAttributeTestFactory.createBuilder().attributeName(FIELD_NAME).build(); + var vorgangWithNextFrist = VorgangTestFactory.createBuilder().id(null) + .clientAttributes(ClientAttributesMapTestFactory.createWithAttribute(nextWiedervorlageAttribute)) + .build(); + mongoOperations.save(vorgangWithNextFrist); + } + + @Test + void shouldCountVorgangsByPath() { + var countRequest = CountByPathTestFactory.createBuilder().fieldPath(FIELD_PATH).build(); + var operator = OperatorBuilder.from(GrpcQueryOperator.UNEQUAL).fieldPath(FIELD_PATH).operand(null).build(); + + var countEntries = statisticRepository.countVorgangByPath(countRequest, operator, statisticFilter); + + assertThat(countEntries).hasSize(1).first().isEqualTo(CountResultTestFactory.create()); + } + + @Test + void shouldReturnZeroWhenNotFound() { + var countRequest = CountByPathTestFactory.createBuilder().fieldPath(FIELD_NAME).build(); + var operator = OperatorBuilder.from(GrpcQueryOperator.UNEQUAL).fieldPath("ClientAttribute." + FIELD_NAME + 1) + .operand(null).build(); + + var countEntries = statisticRepository.countVorgangByPath(countRequest, operator, statisticFilter); + + assertThat(countEntries).hasSize(1).first().isEqualTo(CountResultTestFactory.createBuilder().value(0).build()); + } + + @Test + void shouldReturnCountVorgangByPathWithCondition() { + saveVorgangDateClientAttribute(LocalDate.now()); + var countRequest = CountByPathTestFactory.createBuilder().fieldPath(FIELD_PATH).build(); + // TODO hier müssen wir noch mal ran - im Repository-Code dürfen wir keine + // Abhängigkeit auf gRPC Code haben + var operator = OperatorBuilder.from(GrpcQueryOperator.LESS_THEN).fieldPath("Vorgang." + FIELD_PATH) + .operand(LocalDate.now().minusDays(2).toString()).build(); + + var countEntries = statisticRepository.countVorgangByPath(countRequest, operator, statisticFilter); + + assertThat(countEntries).hasSize(1).first().usingRecursiveComparison() + .isEqualTo(CountResultTestFactory.createBuilder().value(3).name(ALIAS).build()); + } + + @Test + void shouldNotCountDELETEDVorgang() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + mongoOperations.save(VorgangStubTestFactory.create()); + + var statistic = statisticRepository.countVorgangByPath(CountByPathTestFactory.create(), + OperatorTestFactory.createBuilder().fieldPath(CountByPathTestFactory.FIELD_PATH).operand("other").build(), statisticFilter); + + assertThat(statistic).hasSize(1).first().usingRecursiveComparison() + .isEqualTo(CountResultTestFactory.createBuilder().value(0).build()); + } + + @Test + void shouldReturnZeroOnEmptyCollection() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + + var statistic = statisticRepository.countVorgangByPath(CountByPathTestFactory.create(), OperatorTestFactory.create(), statisticFilter); + + assertThat(statistic).hasSize(1).first().usingRecursiveComparison() + .isEqualTo(CountResultTestFactory.createBuilder().value(0).build()); + } + + private void saveVorgangDateClientAttribute(LocalDate date) { + var nextWiedervorlageAttribute = ClientAttributeTestFactory.createBuilder().attributeName(FIELD_NAME) + .stringValue(Optional.of(date.toString())).build(); + var vorgangWithNextFrist = VorgangTestFactory.createBuilder().id(null) + .clientAttributes(ClientAttributesMapTestFactory.createWithAttribute(nextWiedervorlageAttribute)) + .build(); + mongoOperations.save(vorgangWithNextFrist); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryTest.java new file mode 100644 index 0000000..bfe89cd --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticRepositoryTest.java @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Set; + +import org.assertj.core.data.MapEntry; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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 org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.aggregation.AggregationResults; +import org.springframework.data.mongodb.core.query.Query; + +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; + +class StatisticRepositoryTest { + + @InjectMocks + @Spy + private StatisticRepository statisticRepository; + + @Mock + private MongoOperations mongoOperations; + + private final StatisticFilter ORGANISATIONSEINHEIT_IDS_FILTER = StatisticFilter.builder() + .organisationsEinheitId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID).build(); + + @Nested + @DisplayName("Count vorgang") + class TestCount { + + @Nested + @DisplayName("by status") + class TestByStatus { + + @Mock + private AggregationResults aggregationResults; + + @BeforeEach + void setUp() { + doReturn(aggregationResults).when(statisticRepository).executeAggregation(any(), any()); + } + + @Test + @DisplayName("should call initAggregationOperations") + void shouldCallExecuteAggregationAll() { + statisticRepository.countVorgangByStatus(ORGANISATIONSEINHEIT_IDS_FILTER); + + verify(statisticRepository).initAggregationOperations(ORGANISATIONSEINHEIT_IDS_FILTER); + } + + @Test + @DisplayName("should call executeAggregation") + void shouldCallExecuteAggregation() { + statisticRepository.countVorgangByStatus(ORGANISATIONSEINHEIT_IDS_FILTER); + + verify(statisticRepository).executeAggregation(any(), any()); + } + + @Test + @DisplayName("should call get results") + void shouldCallGetResults() { + statisticRepository.countVorgangByStatus(ORGANISATIONSEINHEIT_IDS_FILTER); + + verify(aggregationResults).getMappedResults(); + } + } + + @Nested + @DisplayName("by path") + class TestByPath { + + private final static CountByPath COUNT_PATH_REQUEST = CountPathRequestTestFactory.create(); + + @Mock + private Document document; + @Mock + private AggregationResults aggregationResults; + + private Operator statisticQuery = OperatorTestFactory.create(); + + @BeforeEach + void setup() { + when(aggregationResults.getUniqueMappedResult()).thenReturn(document).getMock(); + doReturn(aggregationResults).when(statisticRepository).executeAggregation(any(), any()); + } + + @Test + @DisplayName("should call initAggregationOperations") + void shouldCallExecuteAggregationAll() { + statisticRepository.countVorgangByPath(COUNT_PATH_REQUEST, statisticQuery, ORGANISATIONSEINHEIT_IDS_FILTER); + + verify(statisticRepository).initAggregationOperations(ORGANISATIONSEINHEIT_IDS_FILTER); + } + + @Test + @DisplayName("should call executeAggregation") + void shouldCallExecuteAggregation() { + statisticRepository.countVorgangByPath(COUNT_PATH_REQUEST, statisticQuery, ORGANISATIONSEINHEIT_IDS_FILTER); + + verify(statisticRepository).executeAggregation(any(), any()); + } + + @Test + @DisplayName("should call get results") + void shouldCallGetResults() { + statisticRepository.countVorgangByPath(COUNT_PATH_REQUEST, statisticQuery, StatisticFilter.builder().build()); + + verify(aggregationResults).getUniqueMappedResult(); + } + + @Test + @DisplayName("should call map count results") + void shouldCallMapCountResults() { + statisticRepository.countVorgangByPath(COUNT_PATH_REQUEST, statisticQuery, StatisticFilter.builder().build()); + + verify(statisticRepository).mapCountByPathResults(document, CountByPathTestFactory.ALIAS); + } + } + } + + @Nested + class TestMapByPathResults { + + @Mock + private Document document; + + @Test + void shouldFilterIdField() { + when(document.entrySet()).thenReturn(Set.of(MapEntry.entry("_id", "id"))); + + var result = statisticRepository.mapCountByPathResults(document, CountByPathTestFactory.ALIAS); + + assertThat(result).isEmpty(); + } + + @Test + void shouldCallMapCountResult() { + var entry = MapEntry.<String, Object>entry("key", 1); + when(document.entrySet()).thenReturn(Set.of(entry)); + + statisticRepository.mapCountByPathResults(document, CountByPathTestFactory.ALIAS); + + verify(statisticRepository, times(1)).mapCountResult(entry); + } + + @Test + void shouldReturnResult() { + var entry = MapEntry.<String, Object>entry(CountResultTestFactory.NAME, CountResultTestFactory.VALUE); + when(document.entrySet()).thenReturn(Set.of(entry)); + doReturn(CountResultTestFactory.create()).when(statisticRepository).mapCountResult(entry); + + var results = statisticRepository.mapCountByPathResults(document, CountByPathTestFactory.ALIAS); + + assertThat(results).containsExactly(CountResultTestFactory.create()); + } + + @Test + void shouldZeroResultOnNull() { + var results = statisticRepository.mapCountByPathResults(null, CountByPathTestFactory.ALIAS); + + assertThat(results).hasSize(1).first().usingRecursiveComparison().isEqualTo(CountResultTestFactory.createBuilder().value(0).build()); + } + } + + @Nested + class TestMapCountResults { + + @Test + void shouldMapValue() { + var entry = MapEntry.<String, Object>entry(CountResultTestFactory.NAME, CountResultTestFactory.VALUE); + + var result = statisticRepository.mapCountResult(entry); + + assertThat(result.getName()).isEqualTo(CountResultTestFactory.NAME); + } + + @Test + void shouldMapCount() { + var entry = MapEntry.<String, Object>entry(CountResultTestFactory.NAME, CountResultTestFactory.VALUE); + + var result = statisticRepository.mapCountResult(entry); + + assertThat(result.getValue()).isEqualTo(CountResultTestFactory.VALUE); + } + } + + @Nested + @DisplayName("Init aggregation operations") + class TestInitAggregationOperation { + + @Test + void addInCreationCriteria() { + var result = statisticRepository.initAggregationOperations(StatisticFilter.builder().build()); + + assertThat(result).hasSize(1); + } + + } + + @Nested + class TestIsFieldExists { + + @Spy + private StatisticFilter filter = StatisticFilter.builder().build(); + + @Test + void shouldCallExists() { + statisticRepository.isFieldsExists(filter); + + verify(mongoOperations).exists(any(Query.class), eq(Vorgang.COLLECTION_NAME)); + } + + @Test + void shouldCallGetCriteria() { + statisticRepository.isFieldsExists(filter); + + verify(filter).getCriteria(); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticServiceTest.java new file mode 100644 index 0000000..4b0c62a --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticServiceTest.java @@ -0,0 +1,437 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.data.mongodb.core.query.Criteria; + +import de.ozgcloud.vorgang.callcontext.CallContextUser; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.common.operator.Operator; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.common.operator.OperatorFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; + +class StatisticServiceTest { + + @Spy + @InjectMocks + private StatisticService statisticService; + + @Mock + private StatisticRepository statisticRepository; + @Mock + private OperatorFactory operatorFactory; + @Mock + private CurrentUserService currentUserService; + @Mock + private CallContextUser user; + + private final VorgangCountRequest request = VorgangCountRequestTestFactory.create(); + + @DisplayName("Count vorgang") + @Nested + class TestCountVorgang { + + @Mock + private OperatorBuilder operatorBuilder; + + @BeforeEach + void setUp() { + when(currentUserService.getUser()).thenReturn(user); + } + + @Test + void shouldCallBuildStatistic() { + when(operatorBuilder.fieldPath(any())).thenReturn(operatorBuilder); + when(operatorBuilder.operand(any())).thenReturn(operatorBuilder); + when(operatorFactory.newUnequalOperatorBuilder()).thenReturn(operatorBuilder); + statisticService.countVorgang(request); + + verify(statisticService).countVorgang(request); + } + + @DisplayName("Get organisationsEinheitenIds") + @Nested + class TestGetOrganisationsEinheitenIds { + + @BeforeEach + void setup() { + lenient().when(operatorBuilder.fieldPath(any())).thenReturn(operatorBuilder); + lenient().when(operatorBuilder.operand(any())).thenReturn(operatorBuilder); + lenient().when(operatorFactory.newUnequalOperatorBuilder()).thenReturn(operatorBuilder); + } + + @DisplayName("should return organisationsEinheitIds when check is necessary") + @Test + void shouldReturnOrganisationsEinheitIds() { + var expectedOrganisationsEinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + when(user.isOrganisationEinheitenIdCheckNecessary()).thenReturn(true); + when(user.getOrganisatorischeEinheitenIds()).thenReturn(expectedOrganisationsEinheitIds); + + var organisationsEinheitIds = statisticService.getOrganisationsEinheitIds(); + + assertThat(organisationsEinheitIds).isPresent().get().isEqualTo(expectedOrganisationsEinheitIds); + } + + @DisplayName("should return empty list when check is not necessary") + @Test + void shouldReturnEmptyCollection() { + var organisationsEinheitIds = statisticService.getOrganisationsEinheitIds().get(); + + assertThat(organisationsEinheitIds).isEmpty(); + } + + @DisplayName("should return empty optional when check necessary but no organisationsEinheitIds") + @Test + void shouldThrowException() { + when(user.isOrganisationEinheitenIdCheckNecessary()).thenReturn(true); + when(user.getOrganisatorischeEinheitenIds()).thenReturn(Collections.emptyList()); + + var organisationsEinheitIds = statisticService.getOrganisationsEinheitIds(); + + assertThat(organisationsEinheitIds).isEmpty(); + } + } + } + + @DisplayName("Build statistic") + @Nested + class TestBuildStatistic { + + @Mock + private OperatorBuilder operatorBuilder; + + @BeforeEach + void setUp() { + when(currentUserService.getUser()).thenReturn(user); + when(user.isOrganisationEinheitenIdCheckNecessary()).thenReturn(true); + when(user.getOrganisatorischeEinheitenIds()).thenReturn(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + } + + @Test + void shouldSetCountByStatus() { + var resultsCountByStatus = Map.of(Vorgang.Status.NEU, 1); + doReturn(resultsCountByStatus).when(statisticService).countVorgangByStatus(); + when(operatorBuilder.fieldPath(any())).thenReturn(operatorBuilder); + when(operatorBuilder.operand(any())).thenReturn(operatorBuilder); + when(operatorFactory.newUnequalOperatorBuilder()).thenReturn(operatorBuilder); + + var statistic = statisticService.countVorgang(request); + + assertThat(statistic.getCountByStatus()).isEqualTo(resultsCountByStatus); + } + + @Test + void shouldSetCountByPaths() { + var resultsCountByPath = Map.of(CountResultTestFactory.NAME, 1); + doReturn(resultsCountByPath).when(statisticService).countVorgangByPathsOld(any()); + + var statistic = statisticService.countVorgang(request); + + assertThat(statistic.getCountResult()).isEqualTo(resultsCountByPath); + } + } + + @Nested + class TestFilterByGroupMethod { + + private VorgangStatisticRequest existsRequest = VorgangStatisticRequestTestFactory.createBuilder() + .statisticGroupMethod(StatisticGroupMethod.EXISTS).build(); + private VorgangStatisticRequest countRequest = VorgangStatisticRequestTestFactory.create(); + + @Test + void shouldReturnCountRequests() { + var statisticRequests = List.of(countRequest, existsRequest); + + var countRequests = statisticService.getCountRequests(statisticRequests); + + assertThat(countRequests).hasSize(1).first().isEqualTo(countRequest); + } + + @Test + void shouldReturnExistsRequests() { + var statisticRequests = List.of(existsRequest, countRequest); + + var existsRequests = statisticService.getExistsRequests(statisticRequests); + + assertThat(existsRequests).hasSize(1).first().isEqualTo(existsRequest); + } + } + + @DisplayName("By status") + @Nested + class TestCountByStatus { + + @BeforeEach + void setUp() { + when(currentUserService.getUser()).thenReturn(user); + when(user.isOrganisationEinheitenIdCheckNecessary()).thenReturn(true); + when(user.getOrganisatorischeEinheitenIds()).thenReturn(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + } + + @Test + void shouldSetStatusStatistic() { + var expectedStatus = Vorgang.Status.NEU; + var countResults = List.of(CountResultTestFactory.createBuilder().name(expectedStatus.toString()).build()); + when(statisticRepository.countVorgangByStatus(any())).thenReturn(countResults); + + var countByStatus = statisticService.countVorgangByStatus(); + + assertThat(countByStatus).containsEntry(expectedStatus, CountResultTestFactory.VALUE); + } + + @Test + void shouldReturnDefaultValues() { + + var countByStatus = statisticService.countVorgangByStatus(); + + assertContainsAllStatusExcepting(countByStatus); + } + + } + + @Nested + class TestFillMissingStatusCounter { + + @Test + void shouldAddMissingCounters() { + var filledCountByStatus = statisticService.fillMissingStatusCounters(Map.of(Vorgang.Status.NEU, 1)); + + assertThat(filledCountByStatus).containsEntry(Vorgang.Status.NEU, 1); + assertContainsAllStatusExcepting(filledCountByStatus, Vorgang.Status.NEU); + } + + @Test + void shouldFillEmptyMap() { + var countByStatus = statisticService.fillMissingStatusCounters(Collections.emptyMap()); + + assertContainsAllStatusExcepting(countByStatus); + } + + } + + private void assertContainsAllStatusExcepting(Map<Vorgang.Status, Integer> countByStatus, Vorgang.Status... exceptStatus) { + Arrays.stream(Vorgang.Status.values()).filter(status -> !ArrayUtils.contains(exceptStatus, status)) + .forEach(status -> assertThat(countByStatus).containsEntry(status, 0)); + } + + @DisplayName("By path") + @Nested + class TestCountByPath { + + @Mock + private OperatorBuilder operatorBuilder; + + @BeforeEach + void setup() { + when(operatorBuilder.fieldPath(any())).thenReturn(operatorBuilder); + when(operatorBuilder.operand(any())).thenReturn(operatorBuilder); + when(operatorFactory.newUnequalOperatorBuilder()).thenReturn(operatorBuilder); + } + + private final CountByPath countByPath = CountPathRequestTestFactory.create(); + + @Test + void shouldCallRepository() { + doReturn(Optional.of(Collections.emptyList())).when(statisticService).getOrganisationsEinheitIds(); + + statisticService.countVorgangByPathsOld(List.of(countByPath)); + + verify(statisticRepository).countVorgangByPath(eq(countByPath), any(), any()); + } + + @Test + void shouldReturnCountResults() { + doReturn(Optional.of(Collections.emptyList())).when(statisticService).getOrganisationsEinheitIds(); + when(statisticRepository.countVorgangByPath(any(), any(), any())).thenReturn(List.of(CountResultTestFactory.create())); + + var countResults = statisticService.countVorgangByPathsOld(List.of(countByPath)); + + assertThat(countResults).hasSize(1).containsEntry(CountResultTestFactory.NAME, CountResultTestFactory.VALUE); + } + } + + @Nested + @DisplayName("Collect Statistic") + class TestCollectStatistic { + + private final List<String> expectedOrganisationsEinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + + @Captor + private ArgumentCaptor<Set<VorgangStatisticRequest>> statisticCountRequestCaptor; + + @BeforeEach + void setUp() { + lenient().when(currentUserService.getUser()).thenReturn(user); + lenient().when(user.isOrganisationEinheitenIdCheckNecessary()).thenReturn(true); + lenient().when(user.getOrganisatorischeEinheitenIds()).thenReturn(expectedOrganisationsEinheitIds); + } + + @Test + void shouldCallCountVorgangByPaths() { + var statisticCountRequest = VorgangStatisticRequestTestFactory.create(); + + statisticService.collectStatistic(List.of(statisticCountRequest)); + + verify(statisticService).countVorgangByPaths(statisticCountRequestCaptor.capture()); + assertThat(statisticCountRequestCaptor.getValue()).hasSize(1).contains(statisticCountRequest); + } + + @Test + void shouldReturnStatistic() { + var statisticCountRequest = VorgangStatisticRequestTestFactory.createBuilder().statisticGroupMethod(StatisticGroupMethod.EXISTS).build(); + + statisticService.collectStatistic(List.of(statisticCountRequest)); + + verify(statisticService).collectFieldExistsStatistic(statisticCountRequestCaptor.capture()); + assertThat(statisticCountRequestCaptor.getValue()).hasSize(1).contains(statisticCountRequest); + + } + + @Test + void shouldSetCountByPath() { + doReturn(StatisticTestFactory.BY_PATH_MAP).when(statisticService).countVorgangByPaths(any()); + + var statistic = statisticService.collectStatistic(List.of(VorgangStatisticRequestTestFactory.create())); + + assertThat(statistic.getCountResult()).isEqualTo(StatisticTestFactory.BY_PATH_MAP); + } + + @Test + void shouldSetFieldExistsStatistic() { + var resultMap = Map.of(VorgangStatisticRequestTestFactory.RESULT_NAME, true); + doReturn(resultMap).when(statisticService).collectFieldExistsStatistic(any()); + doReturn(Collections.emptyMap()).when(statisticService).countVorgangByPaths(any()); + + var statistic = statisticService.collectStatistic(List.of(VorgangStatisticRequestTestFactory.create())); + + assertThat(statistic.getExistsResult()).isEqualTo(resultMap); + } + + @Nested + class TestCollectFieldExistsStatistic { + + @Captor + private ArgumentCaptor<StatisticFilter> statisticFilterCaptor; + + @Test + void shouldCallIsFieldExists() { + var statisticCountRequest = VorgangStatisticRequestTestFactory.createBuilder().statisticGroupMethod(StatisticGroupMethod.EXISTS) + .build(); + + statisticService.collectFieldExistsStatistic(List.of(statisticCountRequest)); + + verify(statisticService).isFieldExists(statisticCountRequest); + } + + @Test + void shouldAddOrganisationsEinheitIds() { + var organisationsEinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); + doReturn(Optional.of(organisationsEinheitIds)).when(statisticService).getOrganisationsEinheitIds(); + + statisticService.isFieldExists(VorgangStatisticRequestTestFactory.create()); + + verify(statisticRepository).isFieldsExists(statisticFilterCaptor.capture()); + assertThat(statisticFilterCaptor.getValue()).extracting("organisationsEinheitIds").isEqualTo(organisationsEinheitIds); + } + + @Test + void shouldAddFilterCriteria() { + var expectedCriteria = Criteria.where("field").exists(true); + Operator operator = when(mock(Operator.class).getCriteria()).thenReturn(expectedCriteria).getMock(); + var statisticRequest = VorgangStatisticRequestTestFactory.createBuilder().operator(operator).build(); + + statisticService.isFieldExists(statisticRequest); + + verify(statisticRepository).isFieldsExists(statisticFilterCaptor.capture()); + assertThat(statisticFilterCaptor.getValue()).extracting("filterCriteria").isEqualTo(expectedCriteria); + } + + } + + @Nested + @DisplayName("Count Vorgang by paths") + class TestCountVorgangByPaths { + + @Captor + private ArgumentCaptor<StatisticFilter> statisticFilterArgumentCaptor; + + @BeforeEach + void setUp() { + lenient().doReturn(Optional.of(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID))).when(statisticService) + .getOrganisationsEinheitIds(); + } + + @Test + void shouldCallCountVorgangByPathForRequest() { + var vorgangStatisticRequest = VorgangStatisticRequestTestFactory.create(); + + statisticService.countVorgangByPaths(List.of(vorgangStatisticRequest)); + + verify(statisticService).countVorgangByPath(vorgangStatisticRequest); + } + + @Test + void shouldSetOrganisationsEinheitIds() { + var statisticRequest = VorgangStatisticRequestTestFactory.create(); + + statisticService.countVorgangByPath(statisticRequest); + + verify(statisticRepository).countVorgangByPath(any(), any(), statisticFilterArgumentCaptor.capture()); + assertThat(statisticFilterArgumentCaptor.getValue()).extracting("organisationsEinheitIds").isEqualTo(expectedOrganisationsEinheitIds); + } + + @Test + void shouldReturnCountResults() { + doReturn(Stream.of(CountResultTestFactory.create())).when(statisticService).countVorgangByPath(any()); + + var countResults = statisticService.countVorgangByPaths(List.of(VorgangStatisticRequestTestFactory.create())); + + assertThat(countResults).hasSize(1).containsEntry(CountResultTestFactory.NAME, CountResultTestFactory.VALUE); + } + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticTestFactory.java new file mode 100644 index 0000000..a2158f1 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/StatisticTestFactory.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +import java.util.Map; + +import de.ozgcloud.vorgang.vorgang.Vorgang; + +public class StatisticTestFactory { + + public static final Integer NEU_COUNT = 1; + public static final Integer ANGENOMMEN_COUNT = 2; + public static final Integer IN_BEARBEITUNG_COUNT = 3; + public static final Integer BESCHIEDEN_COUNT = 4; + public static final Integer ABGESCHLOSSEN_COUNT = 5; + public static final Integer VERWORFEN_COUNT = 6; + public static final Integer WEITERGELEITET_COUNT = 7; + + private static final Map<Vorgang.Status, Integer> BY_STATUS_MAP = Map.of( + Vorgang.Status.NEU, NEU_COUNT, + Vorgang.Status.ANGENOMMEN, ANGENOMMEN_COUNT, + Vorgang.Status.IN_BEARBEITUNG, IN_BEARBEITUNG_COUNT, + Vorgang.Status.BESCHIEDEN, BESCHIEDEN_COUNT, + Vorgang.Status.ABGESCHLOSSEN, ABGESCHLOSSEN_COUNT, + Vorgang.Status.VERWORFEN, VERWORFEN_COUNT, + Vorgang.Status.WEITERGELEITET, WEITERGELEITET_COUNT); + + public static final String FIELD_PATH_ALIAS = "countByPathAlias"; + public static final Integer FIELD_PATH_VALUE = 10; + + public static final Map<String, Integer> BY_PATH_MAP = Map.of(FIELD_PATH_ALIAS, FIELD_PATH_VALUE); + + public static final Map<String, Boolean> FIELD_EXISTS_MAP = Map.of(FIELD_PATH_ALIAS, true); + + public static Statistic create() { + return createBuilder().build(); + } + + public static Statistic.StatisticBuilder createBuilder() { + return Statistic.builder() + .countByStatus(BY_STATUS_MAP) + .countResult(BY_PATH_MAP) + .existsResult(FIELD_EXISTS_MAP); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangCountRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangCountRequestTestFactory.java new file mode 100644 index 0000000..5426ab6 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangCountRequestTestFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.statistic; + +public class VorgangCountRequestTestFactory { + + public static VorgangCountRequest create() { + return createBuilder().build(); + } + + public static VorgangCountRequest.VorgangCountRequestBuilder createBuilder() { + return VorgangCountRequest.builder().countByPath(CountPathRequestTestFactory.create()); + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequestTestFactory.java new file mode 100644 index 0000000..a7ff722 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/statistic/VorgangStatisticRequestTestFactory.java @@ -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. + */ +package de.ozgcloud.vorgang.statistic; + +import de.ozgcloud.vorgang.statistic.VorgangStatisticRequest.VorgangStatisticRequestBuilder; + +public class VorgangStatisticRequestTestFactory { + + public static final String RESULT_NAME = "resultName"; + public static final String REQUEST_FIELD_PATH = "Vorgang.fieldPath"; + public static final String FIELD_PATH = "fieldPath"; + public static final StatisticGroupMethod STATISTIC_GROUP_METHOD = StatisticGroupMethod.COUNT; + + public static VorgangStatisticRequest create() { + return createBuilder().build(); + } + + public static VorgangStatisticRequestBuilder createBuilder() { + return VorgangStatisticRequest.builder() + .resultName(RESULT_NAME) + .fieldPath(REQUEST_FIELD_PATH) + .statisticGroupMethod(STATISTIC_GROUP_METHOD) + .operator(OperatorTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerITCase.java new file mode 100644 index 0000000..21d6bcc --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerITCase.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static org.awaitility.Awaitility.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@ITCase +class StatusEventListenerITCase { + @Autowired + private ApplicationEventPublisher publisher; + + @MockBean + private StatusService statusService; + + @MockBean + private VorgangService vorgangService; + + @MockBean + private CommandService commandService; + + @BeforeEach + void init() { + when(vorgangService.getById(anyString())).thenReturn(VorgangTestFactory.create()); + + when(commandService.findCommand(anyString())).thenReturn(Optional.of(CommandTestFactory.create())); + } + + @DisplayName("Test creating status events") + @Nested + class TestStatusEvents { + + @Test + void shouldCreateStatusChangeEventForVorgangAnnehmen() { + publishCommandCreatedEvent(Order.VORGANG_ANNEHMEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).annehmen(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangAbschliessen() { + publishCommandCreatedEvent(Order.VORGANG_ABSCHLIESSEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).abschliessen(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangBearbeiten() { + publishCommandCreatedEvent(Order.VORGANG_BEARBEITEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).bearbeiten(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangBescheiden() { + publishCommandCreatedEvent(Order.VORGANG_BESCHEIDEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).bescheiden(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangVerwerfen() { + publishCommandCreatedEvent(Order.VORGANG_VERWERFEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).verwerfen(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangWiedereroeffnen() { + publishCommandCreatedEvent(Order.VORGANG_WIEDEREROEFFNEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).wiedereroeffnen(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangZurueckholen() { + publishCommandCreatedEvent(Order.VORGANG_ZURUECKHOLEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).setStatusNeu(any())); + } + + @Test + void shouldCreateStatusChangeEventForVorgangZurueckstellen() { + publishCommandCreatedEvent(Order.VORGANG_ZURUECKSTELLEN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).annehmen(any())); + } + + @Nested + class ZumLoeschenMarkieren { + @Test + void shouldCallService() { + publishCommandCreatedEvent(Order.VORGANG_ZUM_LOESCHEN_MARKIEREN); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).zumLoeschenMarkieren(any())); + } + } + + private void publishCommandCreatedEvent(Order order) { + publisher.publishEvent(CommandCreatedEventTestFactory.create( + CommandTestFactory.createBuilder().order(order.name()).build())); + } + } + + @Nested + class TestRevokeStatusEvent { + + @BeforeEach + void init() { + when(vorgangService.getById(anyString())).thenReturn(VorgangTestFactory.create()); + } + + @Test + void shouldSkipRevokeStatusEvents() { + var command = CommandTestFactory.createBuilder().order(Order.REDIRECT_VORGANG.name()).build(); + + publisher.publishEvent(new RevokeCommandEvent(command)); + + verify(statusService, never()).revokeStatusChange(any(PersistedCommand.class)); + } + + @DisplayName("Test revoking status events") + @ParameterizedTest(name = "should revoke status change event for {0}") + @ValueSource(strings = { "VORGANG_ANNEHMEN", "VORGANG_ABSCHLIESSEN", "VORGANG_BEARBEITEN", + "VORGANG_BESCHEIDEN", "VORGANG_VERWERFEN", "VORGANG_WIEDEREROEFFNEN", "VORGANG_ZURUECKHOLEN", + "VORGANG_ZURUECKSTELLEN", "VORGANG_ZUM_LOESCHEN_MARKIEREN" }) + void shouldRevokeStatusChangeEvent(String orderName) { + var command = CommandTestFactory.createBuilder().order(orderName).build(); + + publisher.publishEvent(new RevokeCommandEvent(command)); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(statusService).revokeStatusChange(any(PersistedCommand.class))); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerTest.java new file mode 100644 index 0000000..8b9e68f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusEventListenerTest.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokeFailedEvent; +import de.ozgcloud.command.RevokeCommandEvent; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemService; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; + +class StatusEventListenerTest { + + @Spy + @InjectMocks + private StatusEventListener eventListener; + + @Mock + private StatusService statusService; + @Mock + private VorgangService vorgangService; + @Mock + private VorgangAttachedItemService attachedItemService; + + @Mock + private CommandService commandService; + @Mock + private CommandCreatedEvent event; + @Mock + private Command command; + + @Mock + private ApplicationEventPublisher publisher; + + @DisplayName("Test handling Vorgang status events") + @Nested + class TestVorgangStatusEvents { + + @BeforeEach + void init() { + when(event.getSource()).thenReturn(command); + when(vorgangService.getById(any())).thenReturn(VorgangTestFactory.create()); + when(commandService.findCommand(any())).thenReturn(Optional.of(CommandTestFactory.create())); + } + + @Test + void shouldCallVorgangService() { + eventListener.abschiessen(event); + + verify(vorgangService).getById(any()); + } + + @Test + void shouldCallCommandService() { + eventListener.abschiessen(event); + + verify(commandService).findCommand(any()); + } + + @Test + void shouldHandleVorgangAbschliessen() { + eventListener.abschiessen(event); + + verify(statusService).abschliessen(any()); + } + + @Test + void shouldHandleVorgangAnnehmen() { + eventListener.annehmen(event); + + verify(statusService).annehmen(any()); + } + + @Test + void shouldHandleVorgangBearbeiten() { + eventListener.bearbeiten(event); + + verify(statusService).bearbeiten(any()); + } + + @Test + void shouldHandleVorgangBescheiden() { + eventListener.bescheiden(event); + + verify(statusService).bescheiden(any()); + } + + @Test + void shouldHandleVorgangVerwerfen() { + eventListener.verwerfen(event); + + verify(statusService).verwerfen(any()); + } + + @Test + void shouldHandleVorgangWiedereroeffnen() { + eventListener.wiedereroeffnen(event); + + verify(statusService).wiedereroeffnen(any()); + } + + @Test + void shouldHandleVorgangZurueckholen() { + eventListener.zurueckholen(event); + + verify(statusService).setStatusNeu(any()); + } + + @Test + void shouldHandleVorgangZurueckstellen() { + eventListener.zurueckstellen(event); + + verify(statusService).annehmen(any()); + } + + @Test + void shouldHandleZuLoeschenMarkieren() { + eventListener.zuLoeschenMarkieren(event); + + verify(statusService).zumLoeschenMarkieren(notNull()); + } + } + + @DisplayName("Test setting the previous state value") + @Nested + class TestPreviousStatus { + + @Test + void shouldSetPreviousStatusNeu() { + var map = eventListener.getPreviousStateMap(VorgangTestFactory.create()); + + assertThat(map).containsEntry(Vorgang.MONGODB_FIELDNAME_STATUS, Status.NEU); + } + + @Test + void shouldSetPreviousStatusAbgeschlossen() { + var map = eventListener.getPreviousStateMap(VorgangTestFactory.createBuilder().status(Status.ABGESCHLOSSEN).build()); + + assertThat(map).containsEntry(Vorgang.MONGODB_FIELDNAME_STATUS, Status.ABGESCHLOSSEN); + } + } + + @DisplayName("Test handling status revoked events") + @Nested + class TestStatusRevokedEvent { + + @Test + void shouldHandleStatusRevokedEvent() { + eventListener.statusRevokedEvent(new RevokeCommandEvent(CommandTestFactory.create())); + + verify(statusService).revokeStatusChange(any(PersistedCommand.class)); + } + + @Test + void shouldPublishFailedEventOnException() { + doThrow(new RuntimeException()).when(statusService).revokeStatusChange(any()); + + eventListener.statusRevokedEvent(new RevokeCommandEvent(CommandTestFactory.create())); + + verify(publisher).publishEvent(any(CommandRevokeFailedEvent.class)); + } + } + + @DisplayName("Test handling exceptions") + @Nested + class TestExceptionHandling { + + @Test + void shouldHandleNoSuchElementException() { + when(commandService.findCommand(any())).thenReturn(Optional.empty()); + when(vorgangService.getById(any())).thenReturn(VorgangTestFactory.create()); + + eventListener.annehmen(CommandCreatedEventTestFactory.create(CommandTestFactory.create())); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + + @Test + void shouldHandleNotFoundException() { + when(vorgangService.getById(any())).thenThrow(NotFoundException.class); + + eventListener.annehmen(CommandCreatedEventTestFactory.create(CommandTestFactory.create())); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + } + + @DisplayName("Test predicated for filtering CommandCreatedEvents") + @Nested + class TestPredicates { + + @ParameterizedTest + @MethodSource("knownOrdersAndMatchingPredicated") + void shouldFilter(Order order, Predicate<Command> predicate) { + assertThat(predicate.test(CommandTestFactory.createBuilder().order(order.name()).build())).isTrue(); + } + + @ParameterizedTest + @MethodSource("knownOrdersAndMatchingPredicated") + void shouldNotFilter(Order order, Predicate<Command> predicate) { + assertThat(predicate.test(CommandTestFactory.createBuilder().order(Order.ASSIGN_USER.name()).build())).isFalse(); + } + + private static Stream<Arguments> knownOrdersAndMatchingPredicated() { + return Stream.of( + Arguments.of(Order.VORGANG_ABSCHLIESSEN, StatusEventListener.IS_ABSCHLIESSEN_EVENT), + Arguments.of(Order.VORGANG_ANNEHMEN, StatusEventListener.IS_ANNEHMEN_EVENT), + Arguments.of(Order.VORGANG_BEARBEITEN, StatusEventListener.IS_BEARBEITEN_EVENT), + Arguments.of(Order.VORGANG_BESCHEIDEN, StatusEventListener.IS_BESCHEIDEN_EVENT), + Arguments.of(Order.VORGANG_VERWERFEN, StatusEventListener.IS_VERWERFEN_EVENT), + Arguments.of(Order.VORGANG_WIEDEREROEFFNEN, StatusEventListener.IS_WIEDEREROEFFNEN_EVENT), + Arguments.of(Order.VORGANG_ZURUECKHOLEN, StatusEventListener.IS_ZURUECKHOLEN_EVENT), + Arguments.of(Order.VORGANG_ZURUECKSTELLEN, StatusEventListener.IS_ZURUECKSTELLEN_EVENT)); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryITCase.java new file mode 100644 index 0000000..e3149e7 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryITCase.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static org.assertj.core.api.Assertions.*; + +import java.util.ConcurrentModificationException; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@DataITCase +class StatusRepositoryITCase { + + @Autowired + private StatusRepository repository; + @Autowired + private MongoOperations mongoOperations; + + @Nested + class TestUpdateStatus { + + @BeforeEach + void init() { + mongoOperations.dropCollection(Vorgang.class); + + mongoOperations.save(VorgangTestFactory.create()); + } + + @Test + void shouldUpdateVorgangStatus() { + repository.patch(VorgangTestFactory.ID, VorgangTestFactory.VERSION, Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Status.IN_BEARBEITUNG)); + + assertThat(mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class).getStatus()).isEqualTo(Status.IN_BEARBEITUNG); + } + + @Test + void shouldUpdateVorgangVersion() { + repository.patch(VorgangTestFactory.ID, VorgangTestFactory.VERSION, Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Status.ANGENOMMEN)); + + assertThat(mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class).getVersion()).isEqualTo(VorgangTestFactory.VERSION + 1); + } + + @Test + void shouldNotUpdateOnVersionMismatch() { + Map<String, Object> patch = Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Status.VERWORFEN.toString()); + + assertThatThrownBy(() -> repository.patch(VorgangTestFactory.ID, VorgangTestFactory.VERSION + 5, patch)) + .isInstanceOf(ConcurrentModificationException.class); + + var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); + assertThat(vorgang.getVersion()).isEqualTo(VorgangTestFactory.VERSION); + assertThat(vorgang.getStatus()).isEqualTo(VorgangTestFactory.STATUS); + } + } + + @Nested + class TestUpdateStatusWithoutVersionCheck { + + @BeforeEach + void init() { + mongoOperations.dropCollection(Vorgang.class); + + mongoOperations.save(VorgangTestFactory.create()); + } + + @Test + void shouldUpdateVorgangStatus() { + repository.updateStatusWithoutVersionCheck(VorgangTestFactory.ID, Status.VERWORFEN); + + assertThat(mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class).getStatus()).isEqualTo(Status.VERWORFEN); + } + + @Test + void shouldUpdateVorgangVersion() { + repository.updateStatusWithoutVersionCheck(VorgangTestFactory.ID, Status.VERWORFEN); + + assertThat(mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class).getVersion()).isEqualTo(VorgangTestFactory.VERSION + 1); + } + } + + @Nested + class TestStatusChangeWithCollision { + + private final Map<String, Object> STATUS_PATCH = Map.of("status", Vorgang.Status.BESCHIEDEN.toString()); + + @Test + void shouldThrowException() { + mongoOperations.save(VorgangTestFactory.create()); + + assertThatThrownBy(() -> repository.patch(VorgangTestFactory.ID, VorgangTestFactory.VERSION - 1, STATUS_PATCH)) + .isInstanceOf(ConcurrentModificationException.class); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryTest.java new file mode 100644 index 0000000..ede0bdb --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusRepositoryTest.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.vorgang.status; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.data.mongodb.core.MongoOperations; + +import com.mongodb.client.result.UpdateResult; + +import de.ozgcloud.vorgang.common.db.CollisionVerifier; + +class StatusRepositoryTest { + + @InjectMocks + @Spy + private StatusRepository repository; + + @Mock + private MongoOperations mongoOperations; + @Mock + private CollisionVerifier collisionVerifier; + + @Test + void shouldCallCollisionVerifier() { + var updateResult = mock(UpdateResult.class); + when(mongoOperations.updateFirst(any(), any(), any(Class.class))).thenReturn(updateResult); + + repository.patch("vorgangId", 1, Map.of()); + + verify(collisionVerifier).verify(any(UpdateResult.class), eq("vorgangId")); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusServiceTest.java new file mode 100644 index 0000000..48402f8 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/status/StatusServiceTest.java @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.status; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.ConcurrentModificationException; +import java.util.Map; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +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 org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.CommandRevokedEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +class StatusServiceTest { + + @DisplayName("Test handling vorgang status changes") + @Nested + class TestVorgangStatusChanges { + @Spy + @InjectMocks + private StatusService service; + + @Mock + private StatusRepository repository; + + @Mock + private ApplicationEventPublisher publisher; + + private PersistedCommand command = CommandTestFactory.create(); + + @DisplayName("Test Vorgang ABSCHLIESSEN events") + @Nested + class OnVorgangAbschliessen { + + @Test + void shouldHandleVorgangAbschliessen() { + service.abschliessen(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.abschliessen(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.ABGESCHLOSSEN.name()))); + } + } + + @DisplayName("Test Vorgang ANNEHMEN events") + @Nested + class OnVorgangAnnehmen { + @Test + void shouldHandleVorgangAnnehmen() { + service.annehmen(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.annehmen(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.ANGENOMMEN.name()))); + } + } + + @DisplayName("Test Vorgang IN_BEARBEITUNG events") + @Nested + class OnVorgangBearbieten { + @Test + void shouldHandleVorgangBearbeiten() { + service.bearbeiten(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.bearbeiten(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.IN_BEARBEITUNG.name()))); + } + } + + @DisplayName("Test Vorgang BESCHIEDEN events") + @Nested + class OnVorgangBescheiden { + @Test + void shouldHandleVorgangBeschieden() { + service.bescheiden(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.bescheiden(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.BESCHIEDEN.name()))); + } + } + + @DisplayName("Test Vorgang VERWORFEN events") + @Nested + class OnVorgangVerwerfen { + @Test + void shouldHandleVorgangVerworfen() { + service.verwerfen(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.verwerfen(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.VERWORFEN.name()))); + } + } + + @DisplayName("Test Vorgang WIEDEREROEFFNEN events") + @Nested + class OnVorgangWiedereroeffnen { + @Test + void shouldHandleVorgangWiedereroeffnen() { + service.wiedereroeffnen(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.bearbeiten(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.IN_BEARBEITUNG.name()))); + } + } + + @DisplayName("Test Vorgang ZURUECKHOLEN events") + @Nested + class OnVorgangZurueckholen { + @Test + void shouldHandleVorgangZurueckholen() { + service.setStatusNeu(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.setStatusNeu(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.NEU.name()))); + } + } + + @DisplayName("Test Vorgang ZURUECKSTELLEN events") + @Nested + class OnVorgangZurueckstellen { + @Test + void shouldHandleVorgangZurueckStellen() { + service.annehmen(command); + + verify(repository).patch(anyString(), anyLong(), any()); + } + + @Test + void shouldUpdateStatus() { + service.annehmen(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.ANGENOMMEN.name()))); + } + } + + @DisplayName("Test Vorgang ZUM LOESCHEN MARKIEREN events") + @Nested + class OnVorgangZumLoeschenMarkieren { + @Test + void shouldHandleVorgangZumLoeschenMarkieren() { + service.zumLoeschenMarkieren(command); + + verify(service).executeStatusChangeCommand(command, Status.ZU_LOESCHEN); + } + } + + @Nested + @DisplayName("Changing status by command") + class TestExecuteStatsuChangeByCommand { + + private Command command = CommandTestFactory.create(); + + @Test + @DisplayName("should trigger status change") + void shouldTriggerUpdate() { + service.executeStatusChangeCommand(command, Status.ANGENOMMEN); + + verify(service).doUpdateStatus(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION, Status.ANGENOMMEN.toString()); + } + + @Test + @DisplayName("should publish status changed event") + void shouldPublishEvent() { + service.executeStatusChangeCommand(command, Status.ANGENOMMEN); + + verify(publisher).publishEvent(any(StatusChangedEvent.class)); + } + + @Test + @DisplayName("should publish failed event on error") + void shouldPublishFailedEvent() { + doThrow(ConcurrentModificationException.class).when(service).doUpdateStatus(anyString(), anyLong(), anyString()); + + service.executeStatusChangeCommand(command, Status.ANGENOMMEN); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + } + + } + + @DisplayName("Test status changes when a Vorgang is forwarded") + @Nested + class TestVorgangWeiterleiten { + @Spy + @InjectMocks + private StatusService service; + + @Mock + private StatusRepository repository; + + @Mock + private ApplicationEventPublisher publisher; + + @Mock + private PersistedCommand command; + + @Test + void shouldNotUpdateVersionOnWeitergeleitet() { + service.setStatusToWeitergeleitet(VorgangTestFactory.ID, CommandTestFactory.ID); + + verify(repository).updateStatusWithoutVersionCheck(anyString(), eq(Vorgang.Status.WEITERGELEITET)); + } + + @Test + void shouldNotUpdateVersionOnBearbeitet() { + service.setStatusToInBearbeitung(VorgangTestFactory.ID, CommandTestFactory.ID); + + verify(repository).updateStatusWithoutVersionCheck(anyString(), eq(Vorgang.Status.IN_BEARBEITUNG)); + } + + @Test + void shouldPatchOnInBearbeitung() { + service.setStatusToInBearbeitung(VorgangTestFactory.ID, VorgangTestFactory.VERSION); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.IN_BEARBEITUNG.name()))); + } + } + + @DisplayName("Test handling revoke command status changes") + @Nested + class TestRevokeStatusChanges { + @Spy + @InjectMocks + private StatusService service; + + @Mock + private StatusRepository repository; + + @Mock + private ApplicationEventPublisher publisher; + + private static final String PREVIOUS_STATUS = Vorgang.Status.BESCHIEDEN.name(); + private PersistedCommand command = CommandTestFactory.createBuilder() + .previousState(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, PREVIOUS_STATUS)).build(); + + @Test + void shouldUpdateVersion() { + service.revokeStatusChange(command); + + verify(repository).patch(anyString(), eq(CommandTestFactory.RELATION_VERSION + 1), any()); + } + + @Test + void shouldUpdateStatus() { + service.revokeStatusChange(command); + + verify(repository).patch(anyString(), anyLong(), eq(Map.of(Vorgang.MONGODB_FIELDNAME_STATUS, Vorgang.Status.BESCHIEDEN.name()))); + } + + @Test + void shouldPublishEvent() { + service.revokeStatusChange(command); + + verify(publisher).publishEvent(any(CommandRevokedEvent.class)); + } + + @Test + void shouldPublishFailEventOnConcurrentModification() { + doThrow(ConcurrentModificationException.class).when(service).doUpdateStatus(any(), anyLong(), any()); + + service.revokeStatusChange(command); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + + @Test + void shouldThrowTechnicalExceptionOnWrongPrevState() { + doReturn(Optional.empty()).when(service).getPreviousStatus(any()); + + assertThatThrownBy(() -> service.revokeStatusChange(command)).isInstanceOf(TechnicalException.class); + } + + @Nested + class TestCheckPreviousStatus { + @Test + void shouldReturnStatus() { + var prevStatus = service.getPreviousStatus(command); + + assertThat(prevStatus).contains(PREVIOUS_STATUS); + } + + @Test + void shouldReturnEmptyOnMissingState() { + var prevStatus = service.getPreviousStatus(CommandTestFactory.createBuilder().previousState(null).build()); + + assertThat(prevStatus).isEmpty(); + } + + @Test + void shouldReturnEmptyOnEmptyState() { + var prevStatus = service.getPreviousStatus(CommandTestFactory.createBuilder().previousState(Map.of()).build()); + + assertThat(prevStatus).isEmpty(); + } + + @Test + void shouldReturnEmptyOnWrongStateField() { + var prevStatus = service.getPreviousStatus(CommandTestFactory.create()); + + assertThat(prevStatus).isEmpty(); + } + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/system/SystemStatusGrpcServiceTest.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/system/SystemStatusGrpcServiceTest.java index 5014e7a..8ff2ac1 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/system/SystemStatusGrpcServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/system/SystemStatusGrpcServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.system; +package de.ozgcloud.vorgang.system; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; -import de.itvsh.ozg.pluto.common.search.SearchService; -import io.grpc.stub.StreamObserver; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -36,8 +37,8 @@ import org.mockito.Mock; import org.springframework.boot.info.BuildProperties; import org.springframework.test.util.ReflectionTestUtils; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; +import de.ozgcloud.vorgang.common.search.SearchService; +import io.grpc.stub.StreamObserver; class SystemStatusGrpcServiceTest { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/DeleteUserSchedulerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/DeleteUserSchedulerTest.java new file mode 100644 index 0000000..1f58885 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/DeleteUserSchedulerTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.vorgang.command.CommandService; + +class DeleteUserSchedulerTest { + + @InjectMocks + private DeleteUserScheduler scheduler; + + @Mock + private UserService service; + @Mock + private CommandService commandService; + + @Test + void shouldCallFindInactiveUserIds() { + when(service.findInactiveUserIds()).thenReturn(Stream.empty()); + + scheduler.deleteUsers(); + + verify(service).findInactiveUserIds(); + } + + @Test + void shouldCallExistsCommandWithUserIds() { + var userId = "userId"; + when(service.findInactiveUserIds()).thenReturn(Stream.of(userId)); + + scheduler.deleteUsers(); + + verify(commandService).existsCommandWithUserId(userId); + } + + @Test + void shouldCallDeleteInactiveUser() { + var userId = "userId"; + when(service.findInactiveUserIds()).thenReturn(Stream.of(userId)); + + scheduler.deleteUsers(); + + verify(service).deleteInactiveUser(userId); + } + + @Nested + class TestCatchException { + + @Test + void shouldCatchFindUserIds() { + when(service.findInactiveUserIds()).thenThrow(new RuntimeException()); + + assertThatNoException().isThrownBy(scheduler::deleteUsers); + } + + @Test + void shouldCatchExistsCommandWithUserIds() { + when(service.findInactiveUserIds()).thenReturn(Stream.of("userId")); + when(commandService.existsCommandWithUserId(anyString())).thenThrow(new RuntimeException()); + + assertThatNoException().isThrownBy(scheduler::deleteUsers); + } + + @Test + void shouldCatchDeleteInactiveUsers() { + when(service.findInactiveUserIds()).thenReturn(Stream.of("userId")); + doThrow(new RuntimeException()).when(service).deleteInactiveUser(anyString()); + + assertThatNoException().isThrownBy(scheduler::deleteUsers); + } + + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserProfileRemoteServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserProfileRemoteServiceTest.java new file mode 100644 index 0000000..57a3729 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserProfileRemoteServiceTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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 de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub; +import de.ozgcloud.user.userprofile.GrpcDeleteInactiveUserRequest; +import de.ozgcloud.user.userprofile.GrpcFindInactiveUserIdsResponse; +import de.ozgcloud.user.userprofile.GrpcUserProfileId; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; + +class UserProfileRemoteServiceTest { + + @Spy + @InjectMocks + private UserProfileRemoteService service; + + @Mock + private UserProfileServiceBlockingStub userProfileServiceStub; + + private static final GrpcFindInactiveUserIdsResponse RESPONSE = GrpcFindInactiveUserIdsResponse.newBuilder() + .addUserProfileIds(GrpcUserProfileId.newBuilder().setId(UserTestFactory.ID)).build(); + + @Nested + class TestFindInactiveUserIds { + + @BeforeEach + void setup() { + doReturn(userProfileServiceStub).when(service).getUserServiceStub(); + when(userProfileServiceStub.findInactiveUserIds(any())).thenReturn(RESPONSE); + } + + @Test + void shouldCallUserServiceStub() { + service.findInactiveUserIds(); + + verify(userProfileServiceStub).findInactiveUserIds(any()); + } + + @Test + void shouldMapResponse() { + service.findInactiveUserIds(); + + verify(service).mapFindInactiveUserIdsResponse(RESPONSE); + } + } + + @Nested + class TestResponseMapping { + + @Test + void shouldReturnUserIds() { + var result = service.mapFindInactiveUserIdsResponse(RESPONSE); + + assertThat(result).containsExactly(UserTestFactory.ID); + } + } + + @Nested + class TestDeleteInactiveUser { + + @BeforeEach + void setup() { + doReturn(userProfileServiceStub).when(service).getUserServiceStub(); + } + + @Test + void shouldCallUserServiceStub() { + var deleteRequest = GrpcDeleteInactiveUserRequest.newBuilder().setUserId(UserTestFactory.ID).build(); + doReturn(deleteRequest).when(service).buildDeleteInactiveUsersRequest(any()); + + service.deleteInactiveUser(UserTestFactory.ID); + + verify(userProfileServiceStub).deleteInactiveUser(deleteRequest); + } + + @Test + void shouldCallBuildRequest() { + service.deleteInactiveUser(UserTestFactory.ID); + + verify(service).buildDeleteInactiveUsersRequest(UserTestFactory.ID); + } + } + + @Nested + class TestBuildDeleteInactiveUsersRequest { + + @Test + void shouldBuildRequest() { + var result = service.buildDeleteInactiveUsersRequest(UserTestFactory.ID); + + assertThat(result.getUserId()).isEqualTo(UserTestFactory.ID); + } + } + + @Nested + class TestGetInterceptor { + + @Test + void shouldCallSetInterceptor() { + service.getUserServiceStub(); + + verify(userProfileServiceStub).withInterceptors(any()); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserServiceTest.java new file mode 100644 index 0000000..05ed5a4 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/UserServiceTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.vorgang.callcontext.UserTestFactory; + +class UserServiceTest { + + @InjectMocks + private UserService service; + + @Mock + private UserProfileRemoteService userRemoteService; + + @Nested + class TestFindInactiveUserIds { + + @Test + void shouldCallUserRemoteService() { + service.findInactiveUserIds(); + + verify(userRemoteService).findInactiveUserIds(); + } + } + + @Nested + class TestDeleteInactiveUsers { + + @Test + void shouldCallUserRemoteService() { + service.deleteInactiveUser(UserTestFactory.ID); + + verify(userRemoteService).deleteInactiveUser(UserTestFactory.ID); + } + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptorTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptorTest.java new file mode 100644 index 0000000..0a20578 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/user/VorgangManagerCallContextAttachingInterceptorTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.user; + +import static de.ozgcloud.common.grpc.GrpcUtil.*; +import static de.ozgcloud.vorgang.user.VorgangManagerCallContextAttachingInterceptor.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +class VorgangManagerCallContextAttachingInterceptorTest { + + @InjectMocks + private VorgangManagerCallContextAttachingInterceptor interceptor; + + @Nested + class TestInterceptCall<A, B> { + + @Mock + private MethodDescriptor<A, B> method; + @Mock + private CallOptions callOptions; + @Mock + private Channel next; + @Mock + private ClientCall<Object, Object> nextCall; + + @Mock + private ClientCall.Listener<B> listener; + @Mock + private Metadata headers; + @Captor + private ArgumentCaptor<Metadata> metadataCaptor; + + @BeforeEach + void initMocks() { + when(next.newCall(any(), any())).thenReturn(nextCall); + } + + @Test + void shouldAddUserId() { + var addedMetadata = interceptCall(); + + assertThat(addedMetadata.get(createKeyOf(KEY_USER_ID))).isEqualTo(VORGANG_MANAGER_SENDER_USER_ID.getBytes()); + } + + @Test + void shouldAddClientName() { + var addedMetadata = interceptCall(); + + assertThat(addedMetadata.get(createKeyOf(KEY_CLIENT_NAME))).isEqualTo(VORGANG_MANAGER_CLIENT_NAME.getBytes()); + } + + @Test + void shouldAddRequestId() { + var addedMetadata = interceptCall(); + + assertThat(addedMetadata.get(createKeyOf(KEY_REQUEST_ID))).isNotNull(); + } + + private Metadata interceptCall() { + var call = interceptor.interceptCall(method, callOptions, next); + + call.start(listener, headers); + + verify(headers).merge(metadataCaptor.capture()); + return metadataCaptor.getValue(); + } + } + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEATest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEATest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEATest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEATest.java index 0e51d59..3c8665d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenProviderEATest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenProviderEATest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenServiceITCase.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenServiceITCase.java index e7af5a6..2a74ca5 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AktenzeichenServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AktenzeichenServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.itvsh.kop.common.test.ITCase; +import de.ozgcloud.common.test.ITCase; @ITCase class AktenzeichenServiceITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapperTest.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapperTest.java index e3331ea..3ded5e7 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -32,7 +32,7 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Spy; -import de.itvsh.kop.pluto.common.grpc.GrpcFormDataMapper; +import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper; class AntragstellerMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerTestFactory.java similarity index 96% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerTestFactory.java index 0cee8bd..6dffcc0 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/AntragstellerTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/AntragstellerTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Map; import java.util.UUID; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProviderTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProviderTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProviderTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProviderTest.java index 34fef93..eb97e3d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/DefaultAktenzeichenProviderTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/DefaultAktenzeichenProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapperTest.java new file mode 100644 index 0000000..8b2d32e --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderMapperTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.vorgang.servicekonto.GrpcServiceKontoTestFactory; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoMapper; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; + +@DisplayName("Eingang header mapper") +class EingangHeaderMapperTest { + + @InjectMocks + private final EingangHeaderMapper mapper = Mappers.getMapper(EingangHeaderMapper.class); + @Mock + private final ServiceKontoMapper serviceKontoMapper = Mappers.getMapper(ServiceKontoMapper.class); + + @DisplayName("map from grpc") + @Nested + class TestFromGrpc { + + @BeforeEach + void mockPostfachAddressMapper() { + when(serviceKontoMapper.fromServiceKonto(any())).thenReturn(ServiceKontoTestFactory.create()); + } + + @Test + void shouldCallPostfachAddressMapper() { + fromGrpc(); + + verify(serviceKontoMapper).fromServiceKonto(any()); + } + + @Test + void shouldMapDateStrToZonedDateTime() { + var eingangHeader = fromGrpc(); + + assertThat(eingangHeader.getCreatedAt()).isEqualTo(GrpcEingangHeaderTestFactory.CREATED_AT); + } + + @Test + void shouldMapAllFields() { + var eingangHeader = fromGrpc(); + + assertThat(eingangHeader).usingRecursiveComparison().ignoringFields("serviceKonto").isEqualTo(EingangHeaderTestFactory.create()); + } + + private EingangHeader fromGrpc() { + return mapper.fromGrpc(GrpcEingangHeaderTestFactory.create()); + } + } + + @DisplayName("map to grpc") + @Nested + class TestToGrpc { + + @BeforeEach + void mockPostfachAddressMapper() { + when(serviceKontoMapper.toServiceKonto(any())).thenReturn(GrpcServiceKontoTestFactory.create()); + } + + @Test + void shouldMapZonedDateTimeToDateStr() { + var eingangHeader = fromGrpc(EingangHeaderTestFactory.create()); + + assertThat(eingangHeader.getCreatedAt()).isEqualTo(EingangHeaderTestFactory.CREATED_AT_STR); + } + + @Test + void shouldProceedWithEmptyValues() { + var eingangHeader = fromGrpc(EingangHeaderTestFactory.createBuilder().createdAt(null).build()); + + assertThat(eingangHeader.getCreatedAt()).isEqualTo(StringUtils.EMPTY); + } + + private GrpcEingangHeader fromGrpc(EingangHeader eingangHeader) { + return mapper.toGrpc(eingangHeader); + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderTestFactory.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderTestFactory.java index d9e87ac..d64ca3c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangHeaderTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; import java.util.UUID; import com.thedeanda.lorem.LoremIpsum; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; + public class EingangHeaderTestFactory { public static final String CREATED_AT_STR = "2021-01-10T10:30:00Z"; @@ -39,6 +41,8 @@ public class EingangHeaderTestFactory { public static final String FORM_ID = UUID.randomUUID().toString(); public static final String SENDER = LoremIpsum.getInstance().getWords(2); + public static final String VORGANG_NUMMER = "1234"; + public static EingangHeader create() { return createBuilder().build(); } @@ -50,7 +54,9 @@ public class EingangHeaderTestFactory { .formId(FORM_ID) .formName(FORM_NAME) .formEngineName(VorgangTestFactory.FORM_ENGINE_NAME) - .sender(SENDER); + .vorgangNummer(VORGANG_NUMMER) + .sender(SENDER) + .serviceKonto(ServiceKontoTestFactory.create()); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangMapperTest.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangMapperTest.java index eb3bdcb..e343c9c 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static de.itvsh.kop.pluto.common.grpc.GrpcSubFormTestFactory.*; +import static de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory.*; +import static de.ozgcloud.vorgang.vorgang.LabelProcessor.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -42,9 +43,9 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.test.util.ReflectionTestUtils; -import de.itvsh.kop.pluto.common.grpc.GrpcFormDataMapper; -import de.itvsh.kop.pluto.common.grpc.GrpcSubFormTestFactory; -import de.itvsh.ozg.pluto.files.FileIdMapper; +import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper; +import de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory; +import de.ozgcloud.vorgang.files.FileIdMapper; class EingangMapperTest { @@ -149,22 +150,28 @@ class EingangMapperTest { @Test void fieldsInSubForm() { var eingang = mapper.fromGrpc(grpcEingang); - @SuppressWarnings("unchecked") - Map<String, Object> formData = (Map<String, Object>) eingang.getFormData().get(TITLE); - assertThat(formData).containsEntry(FIELD_NAME, FIELD_VALUE); + Map<String, Object> formData = getSubForm(eingang); + assertThat(formData).containsEntry(FIELD_NAME, FIELD); } @DisplayName("mapped FormData should contains subForm") @Test void shouldHaveMappedSubFormWithSubForm() { var eingang = mapper.fromGrpc(grpcEingang); - @SuppressWarnings("unchecked") - Map<String, Object> formData = (Map<String, Object>) eingang.getFormData().get(TITLE); - assertThat(formData).containsKey(GrpcSubFormTestFactory.SUBFORM_NAME); + Map<String, Object> formData = getSubForm(eingang); + assertThat(formData).containsKey(GrpcSubFormTestFactory.SUBFORM_TITLE); } + @SuppressWarnings("unchecked") + private Map<String, Object> getSubForm(Eingang eingang) { + Map<String, Object> formData = (Map<String, Object>) eingang.getFormData().get(TITLE); + formData = (Map<String, Object>) formData.get(VALUE_KEY); + return formData; + } + + @SuppressWarnings("unchecked") @DisplayName("mapped SubForm should contain List of SubForms") @Test void shouldHaveMappedListOfSubForms() { @@ -174,20 +181,23 @@ class EingangMapperTest { .build()).build(); var eingang = mapper.fromGrpc(grpcEingang); - @SuppressWarnings("unchecked") - var formData = (List<Map<String, Object>>) eingang.getFormData().get(TITLE); - assertThat(formData).contains(EingangTestFactory.FORM_DATA, EingangTestFactory.FORM_DATA); + var formData = (Map<String, Object>) eingang.getFormData().get(TITLE); + var formList = (List<Map<String, Object>>) formData.get(VALUE_KEY); + + assertThat(formList).contains(EingangTestFactory.FORM_DATA, EingangTestFactory.FORM_DATA); } + @SuppressWarnings("unchecked") @DisplayName("mapped SubForm should contain field") @Test void subFormShouldContainField() { var eingang = mapper.fromGrpc(grpcEingang); - @SuppressWarnings("unchecked") - Map<String, Object> subForm = (Map<String, Object>) ((Map<String, Object>) eingang.getFormData().get(TITLE)).get(SUBFORM_NAME); - assertThat(subForm).containsEntry(SUBFORM_FIELD_NAME, SUBFORM_FIELD_VALUE); + Map<String, Object> subForm = (Map<String, Object>) getSubForm(eingang).get(SUBFORM_TITLE); + subForm = (Map<String, Object>) subForm.get(VALUE_KEY); + + assertThat(subForm).containsEntry(SUBFORM_FIELD_NAME, SUBFORM_FIELD); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangTestFactory.java similarity index 69% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangTestFactory.java index 8fcfc19..2f159b6 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/EingangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,26 +21,33 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.Map; import java.util.UUID; -import de.itvsh.kop.pluto.common.grpc.GrpcSubFormTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory; public class EingangTestFactory { public static final String ID = UUID.randomUUID().toString(); + public static final String SINGLE_FIELD_LABEL = GrpcSubFormTestFactory.FIELD_LABEL; public static final String SINGLE_FIELD_NAME = GrpcSubFormTestFactory.FIELD_NAME; public static final String SINGLE_FIELD_VALUE = GrpcSubFormTestFactory.FIELD_VALUE; + public static final Map<String, Object> SINGLE_FIELD = GrpcSubFormTestFactory.FIELD; + public static final String SUBFORM_LABEL = GrpcSubFormTestFactory.SUBFORM_LABEL; + public static final String SUBFORM_NAME = GrpcSubFormTestFactory.SUBFORM_TITLE; + + public static final String SUBFORM_FIELD_LABEL = GrpcSubFormTestFactory.SUBFORM_FIELD_LABEL; public static final String SUBFORM_FIELD_NAME = GrpcSubFormTestFactory.SUBFORM_FIELD_NAME; public static final String SUBFORM_FIELD_VALUE = GrpcSubFormTestFactory.SUBFORM_FIELD_VALUE; - public static final String SUBFORM_NAME = GrpcSubFormTestFactory.SUBFORM_NAME; - public static final Map<String, Object> SUBFORM = Map.of(SUBFORM_FIELD_NAME, SUBFORM_FIELD_VALUE); + public static final Map<String, Object> SUBFORM_FIELD = GrpcSubFormTestFactory.SUBFORM_FIELD; - public static final Map<String, Object> FORM_DATA = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, SUBFORM_NAME, SUBFORM); + public static final Map<String, Object> SUBFORM = GrpcSubFormTestFactory.SUBFORM; + public static final Map<String, Object> SUBFORM_FLAT = Map.of(SUBFORM_FIELD_NAME, SUBFORM_FIELD); + public static final Map<String, Object> FORM_DATA = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD, SUBFORM_NAME, SUBFORM); public static Eingang create() { return createBuilder().build(); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterByMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterByMapperTest.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterByMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterByMapperTest.java index 0923b6a..e871d3d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterByMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterByMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.mockito.Mockito.*; @@ -38,9 +38,9 @@ import org.mockito.Mock; import static org.assertj.core.api.Assertions.*; -import de.itvsh.ozg.pluto.common.callcontext.CallContextUserTestFactory; -import de.itvsh.ozg.pluto.common.callcontext.CurrentUserService; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; class FilterByMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaTestFactory.java similarity index 77% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaTestFactory.java index bb5c681..869c303 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FilterCriteriaTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FilterCriteriaTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,16 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; public class FilterCriteriaTestFactory { public static final String ORGANISATIONSEINHEIT_ID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID; public static final boolean FILTER_BY_ORGANISATIONSEINHEITEN_ID = true; public static final Status STATUS = Status.NEU; + public static final boolean FILTER_BY_ASSIGNED_TO = true; + public static final boolean HAS_NEXT_WIEDERVORLAGE_FRIST = false; public static FilterCriteria createEmpty() { return FilterCriteria.builder().build(); @@ -45,6 +47,8 @@ public class FilterCriteriaTestFactory { .filterByOrganisationseinheitenId(FILTER_BY_ORGANISATIONSEINHEITEN_ID) .organisationseinheitId(ORGANISATIONSEINHEIT_ID) .singleStatus(STATUS) - .assignedTo(UserTestFactory.ID); + .filterByAssignedTo(FILTER_BY_ASSIGNED_TO) + .assignedTo(UserTestFactory.ID) + .hasNextWiedervorlageFrist(HAS_NEXT_WIEDERVORLAGE_FRIST); } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapperTest.java new file mode 100644 index 0000000..ba55b0a --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryMapperTest.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.operator.OperandFunctionParser; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.common.operator.OperatorTestFactory; + +class FindVorgangQueryMapperTest { + + @InjectMocks + private FindVorgangQueryMapper mapper = spy(Mappers.getMapper(FindVorgangQueryMapper.class)); + + @Mock + private OperandFunctionParser operandFunctionParser; + + @Nested + class TestFromFindVorgangQuery { + + @Test + void shouldSetLogicalOperator() { + var result = mapper.fromQuery(GrpcQueryTestFactory.create()); + + assertThat(result.getLogicalOperator()).isEqualTo(FindVorgangQueryTestFactory.LOGICAL_OPERATOR); + } + + @Test + void shouldCallBuildOperator() { + var grpcFindVorgangQuery = GrpcQueryTestFactory.create(); + var expectedExpression = grpcFindVorgangQuery.getExpressions(0); + + mapper.fromQuery(grpcFindVorgangQuery); + + verify(mapper).buildOperator(expectedExpression); + } + + @Test + void shouldSetOperator() { + var expectedOperator = OperatorTestFactory.createEqualOperator(); + doReturn(expectedOperator).when(mapper).buildOperator(any()); + + var result = mapper.fromQuery(GrpcQueryTestFactory.create()); + + assertThat(result.getOperators()).containsExactly(expectedOperator); + } + + @Test + void shouldSkipMappingNestedQuery() { + doReturn(false).when(mapper).hasSubQuery(any()); + + mapper.fromQuery(GrpcQueryTestFactory.create()); + + verify(mapper).fromQuery(any()); + } + + @Test + void shouldSetNestedQuery() { + var expectedNestedQuery = FindVorgangQueryTestFactory.createBuilder() + .logicalOperator(FindVorgangQuery.LogicalOperator.OR) + .clearOperators() + .operator(OperatorTestFactory.createLessThenOperator()) + .build(); + var nestedQuery = GrpcQueryTestFactory.createBuilder().setLogicalOperator(GrpcLogicalOperator.OR) + .clearExpressions() + .addExpressions(GrpcVorgangQueryExpressionTestFactory.createBuilder() + .setOperator(GrpcQueryOperator.LESS_THEN) + .setOperandIntValue(OperatorTestFactory.INT_VALUE)) + .build(); + + var result = mapper.fromQuery(GrpcQueryTestFactory.createBuilder().setNestedQuery(nestedQuery).build()); + + assertThat(result.getNestedQuery()).usingRecursiveComparison().isEqualTo(expectedNestedQuery); + } + + } + + @Nested + class TestHasSubForm { + + @Test + void shouldApproveSubQuery() { + var result = mapper.hasSubQuery(GrpcQueryTestFactory.createBuilder().setNestedQuery(GrpcQueryTestFactory.create()).build()); + + assertThat(result).isTrue(); + } + + @Test + void shouldRejectIfNoSubQuery() { + var result = mapper.hasSubQuery(GrpcQueryTestFactory.create()); + + assertThat(result).isFalse(); + } + } + + @Nested + class TestFromLogicalOperator { + + @Test + void shouldMapAnd() { + var result = mapper.fromLogicalOperator(GrpcLogicalOperator.AND); + + assertThat(result).isEqualTo(FindVorgangQuery.LogicalOperator.AND); + } + + @Test + void shouldMapOr() { + var result = mapper.fromLogicalOperator(GrpcLogicalOperator.OR); + + assertThat(result).isEqualTo(FindVorgangQuery.LogicalOperator.OR); + } + } + + @Nested + class TestBuildOperator { + + @Mock + private OperatorBuilder operatorBuilder; + + @Test + void shouldSetFieldPath() { + var operator = mapper.buildOperator(GrpcVorgangQueryExpressionTestFactory.create()); + + assertThat(operator).extracting("fieldPath").isEqualTo(OperatorTestFactory.PATH); + } + + @Test + void shouldCallGetValue() { + var queryExpression = GrpcVorgangQueryExpressionTestFactory.create(); + + mapper.buildOperator(queryExpression); + + verify(mapper).getValue(queryExpression); + } + + @Test + void shouldSetOperand() { + doReturn(OperatorTestFactory.STRING_VALUE).when(mapper).getValue(any()); + + var operator = mapper.buildOperator(GrpcVorgangQueryExpressionTestFactory.create()); + + assertThat(operator).extracting("operand").isEqualTo(OperatorTestFactory.STRING_VALUE); + } + + @Test + void shouldCallOperatorBuilder() { + try(var mockOperatorBuilder = Mockito.mockStatic(OperatorBuilder.class)) { + mockOperatorBuilder.when(() -> OperatorBuilder.from(any())).thenReturn(operatorBuilder); + mockOperatorBuilder.when(() -> operatorBuilder.fieldPath(any())).thenReturn(operatorBuilder); + mockOperatorBuilder.when(() -> operatorBuilder.operand(any())).thenReturn(operatorBuilder); + + mapper.buildOperator(GrpcVorgangQueryExpressionTestFactory.create()); + + mockOperatorBuilder.verify(() -> OperatorBuilder.from(GrpcVorgangQueryExpressionTestFactory.OPERATOR)); + } + } + + } + + @Nested + class TestGetValue { + + @Test + void shouldReturnNullWhenNotSet() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.createBuilder().clearOperandStringValue().build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isNull(); + } + + @Test + void shouldCallGetStringValue() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.create(); + + mapper.getValue(statisticQuery); + + verify(mapper).getStringValue(statisticQuery); + } + + @Test + void shouldReturnInteger() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.createBuilder().setOperandIntValue(1).build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isEqualTo(1); + } + + @Test + void shouldReturnBoolean() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.createBuilder().setOperandBoolValue(true).build(); + + var value = mapper.getValue(statisticQuery); + + assertThat(value).isEqualTo(true); + } + + @Nested + class TestGetStringValue { + + @Test + void shouldCallOperandFunctionParser() { + var functionValue = "function()"; + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.createBuilder().setOperandStringValue(functionValue).build(); + + mapper.getStringValue(statisticQuery); + + verify(operandFunctionParser).parse(functionValue); + } + + @Test + void shouldReturnNull() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.createBuilder().setOperandStringValue("null").build(); + + var value = mapper.getStringValue(statisticQuery); + + assertThat(value).isNull(); + } + + @Test + void shouldReturnStringValue() { + var statisticQuery = GrpcVorgangQueryExpressionTestFactory.create(); + + var value = mapper.getStringValue(statisticQuery); + + assertThat(value).isEqualTo(OperatorTestFactory.STRING_VALUE); + } + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryTestFactory.java new file mode 100644 index 0000000..ed24d87 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangQueryTestFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.vorgang.common.operator.OperatorTestFactory; +import de.ozgcloud.vorgang.vorgang.FindVorgangQuery.LogicalOperator; + +public class FindVorgangQueryTestFactory { + + public static final LogicalOperator LOGICAL_OPERATOR = LogicalOperator.AND; + + public static FindVorgangQuery create() { + return createBuilder().build(); + } + + public static FindVorgangQuery.FindVorgangQueryBuilder createBuilder() { + return FindVorgangQuery.builder() + .logicalOperator(LOGICAL_OPERATOR) + .operator(OperatorTestFactory.createEqualOperator()); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapperTest.java similarity index 83% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapperTest.java index cbeffe5..c20f7fd 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -42,6 +42,8 @@ class FindVorgangRequestMapperTest { private final FindVorgangRequestMapper mapper = Mappers.getMapper(FindVorgangRequestMapper.class); @Mock private FilterByMapper filterByMapper; + @Mock + private FindVorgangQueryMapper findVorgangQueryMapper; @DisplayName("Map from find vorgang request") @Nested @@ -72,5 +74,15 @@ class FindVorgangRequestMapperTest { verify(filterByMapper).fromFilterBy(GrpcFilterByTestFactory.create()); } + + @Test + void shouldMapQuery() { + var expectedQuery = GrpcQueryTestFactory.create(); + var findVorgangRequest = GrpcFindVorgangRequestTestFactory.createBuilder().setQuery(expectedQuery).build(); + + mapper.fromFindVorgangRequest(findVorgangRequest); + + verify(findVorgangQueryMapper).fromQuery(expectedQuery); + } } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestTestFactory.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestTestFactory.java index 5ec1ae9..ba6a6da 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/FindVorgangRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/FindVorgangRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import com.thedeanda.lorem.LoremIpsum; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequest.OrderCriteria; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest.OrderCriteria; public class FindVorgangRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcAntragstellerTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcAntragstellerTestFactory.java similarity index 96% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcAntragstellerTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcAntragstellerTestFactory.java index 3da6713..e843219 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcAntragstellerTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcAntragstellerTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class GrpcAntragstellerTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcCreateVorgangRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcCreateVorgangRequestTestFactory.java similarity index 81% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcCreateVorgangRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcCreateVorgangRequestTestFactory.java index e090c0f..e4afb5e 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcCreateVorgangRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcCreateVorgangRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class GrpcCreateVorgangRequestTestFactory { @@ -31,6 +31,10 @@ public class GrpcCreateVorgangRequestTestFactory { return createBuilder().build(); } + public static GrpcCreateVorgangRequest createWithFormData(GrpcFormData formData) { + return createBuilder().setEingang(GrpcEingangTestFactory.createBuilder().setFormData(formData)).build(); + } + public static GrpcCreateVorgangRequest.Builder createBuilder() { return GrpcCreateVorgangRequest.newBuilder() .setEingang(GRPC_EINGANG); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangHeaderTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangHeaderTestFactory.java similarity index 81% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangHeaderTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangHeaderTestFactory.java index 8d9a0c7..795f65f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangHeaderTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangHeaderTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; +import de.ozgcloud.vorgang.servicekonto.GrpcServiceKontoTestFactory; + public class GrpcEingangHeaderTestFactory { private final static String REQUEST_ID = EingangHeaderTestFactory.REQUEST_ID; private final static String CREATED_AT_STR = EingangHeaderTestFactory.CREATED_AT_STR; - public static ZonedDateTime CREATED_AT = EingangHeaderTestFactory.CREATED_AT; + public static final ZonedDateTime CREATED_AT = EingangHeaderTestFactory.CREATED_AT; private final static String FORM_ID = EingangHeaderTestFactory.FORM_ID; public final static String FORM_NAME = EingangHeaderTestFactory.FORM_NAME; @@ -46,6 +48,8 @@ public class GrpcEingangHeaderTestFactory { .setFormId(FORM_ID) .setFormName(FORM_NAME) .setFormEngineName(VorgangTestFactory.FORM_ENGINE_NAME) - .setSender(SENDER); + .setVorgangNummer(EingangHeaderTestFactory.VORGANG_NUMMER) + .setSender(SENDER) + .setServiceKonto(GrpcServiceKontoTestFactory.create()); } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangTestFactory.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangTestFactory.java index 4c375df..2c90bbf 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcEingangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcEingangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.UUID; -import de.itvsh.kop.pluto.common.grpc.GrpcSubFormTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory; public class GrpcEingangTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFilterByTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFilterByTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFilterByTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFilterByTestFactory.java index 015277b..5603968 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFilterByTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFilterByTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static de.itvsh.ozg.pluto.vorgang.FilterCriteriaTestFactory.*; +import static de.ozgcloud.vorgang.vorgang.FilterCriteriaTestFactory.*; -import de.itvsh.ozg.pluto.command.UserTestFactory; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; public class GrpcFilterByTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFindVorgangRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindVorgangRequestTestFactory.java similarity index 90% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFindVorgangRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindVorgangRequestTestFactory.java index 7cb9687..e337f97 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFindVorgangRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFindVorgangRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static de.itvsh.ozg.pluto.vorgang.FindVorgangRequestTestFactory.*; +import static de.ozgcloud.vorgang.vorgang.FindVorgangRequestTestFactory.*; public class GrpcFindVorgangRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFinishCreationRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFinishCreationRequestTestFactory.java similarity index 85% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFinishCreationRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFinishCreationRequestTestFactory.java index bff54f4..d7603e1 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcFinishCreationRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcFinishCreationRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.util.List; @@ -33,10 +33,13 @@ public class GrpcFinishCreationRequestTestFactory { private static List<GrpcIncomingFile> representations = List.of(representation); public static GrpcFinishCreationRequest create() { + return createBuilder().build(); + } + + public static GrpcFinishCreationRequest.Builder createBuilder() { return GrpcFinishCreationRequest.newBuilder() .setVorgangId(VorgangTestFactory.ID) .addAllAttachments(attachments) - .addAllRepresentations(representations) - .build(); + .addAllRepresentations(representations); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileGroupTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileGroupTestFactory.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileGroupTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileGroupTestFactory.java index ce0f94a..a8708aa 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileGroupTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileGroupTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class GrpcIncomingFileGroupTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileTestFactory.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileTestFactory.java index b4916ce..5ebe3c0 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcIncomingFileTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcIncomingFileTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import com.google.protobuf.ByteString; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcQueryTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcQueryTestFactory.java new file mode 100644 index 0000000..7a17c49 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcQueryTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +public class GrpcQueryTestFactory { + + public static final GrpcLogicalOperator LOGICAL_OPERATOR = GrpcLogicalOperator.AND; + + public static GrpcQuery create() { + return createBuilder().build(); + } + + public static GrpcQuery.Builder createBuilder() { + return GrpcQuery.newBuilder() + .setLogicalOperator(LOGICAL_OPERATOR) + .addExpressions(GrpcVorgangQueryExpressionTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangHeadTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangHeadTestFactory.java new file mode 100644 index 0000000..0469d89 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangHeadTestFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.vorgang.servicekonto.GrpcServiceKontoTestFactory; + +public class GrpcVorgangHeadTestFactory { + + public static GrpcVorgangHead create() { + return createBuilder().build(); + } + + public static GrpcVorgangHead.Builder createBuilder() { + return GrpcVorgangHead.newBuilder() + .setServiceKonto(GrpcServiceKontoTestFactory.create()); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangQueryExpressionTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangQueryExpressionTestFactory.java new file mode 100644 index 0000000..7da9b7c --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangQueryExpressionTestFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static de.ozgcloud.vorgang.common.operator.OperatorTestFactory.*; + +import de.ozgcloud.vorgang.common.GrpcQueryOperator; + +public class GrpcVorgangQueryExpressionTestFactory { + + public static final String PATH = "Vorgang.field"; + public static final GrpcQueryOperator OPERATOR = GrpcQueryOperator.EQUAL; + + public static GrpcVorgangQueryExpression create() { + return createBuilder().build(); + } + + public static GrpcVorgangQueryExpression.Builder createBuilder() { + return GrpcVorgangQueryExpression.newBuilder() + .setPath(PATH) + .setOperator(OPERATOR) + .setOperandStringValue(STRING_VALUE); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceFindQueryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceFindQueryITCase.java new file mode 100644 index 0000000..1ddc093 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceFindQueryITCase.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@SpringBootTest(properties = { + "grpc.server.inProcessName=test", + "grpc.server.port=-1", + "grpc.client.inProcess.address=in-process:test" +}) +@DirtiesContext +@DataITCase +class GrpcVorgangServiceFindQueryITCase { + + private static final String VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH = "ClientAttribute.OzgCloud_NachrichtenManager.hasNewPostfachNachricht"; + + @Autowired + private VorgangHeaderRepository repository; + @Autowired + private MongoOperations mongoOperations; + + @MockBean + private CurrentUserService currentUserService; + + @GrpcClient("inProcess") + private VorgangServiceGrpc.VorgangServiceBlockingStub vorgangServiceStub; + + private Vorgang vorgangWithNextFristMinus2Days; + private Vorgang vorgangNewCreatedAt; + + @BeforeEach + void init() { + when(currentUserService.findUser()).thenReturn(Optional.of(CallContextUserTestFactory.create())); + when(currentUserService.getUser()).thenReturn(CallContextUserTestFactory.create()); + + mongoOperations.dropCollection(Vorgang.class); + mongoOperations.save(VorgangTestFactory.createBuilder().id(null) + .createdAt(ZonedDateTime.now()) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now())).build()); + vorgangWithNextFristMinus2Days = mongoOperations.save(VorgangTestFactory.createBuilder().id(null) + .status(Vorgang.Status.BESCHIEDEN) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minusDays(2))).build()); + vorgangNewCreatedAt = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()); + } + + @Test + void shouldFindWhereExists() { + var request = GrpcFindVorgangRequestTestFactory.createBuilder().clearFilterBy().setQuery( + GrpcQuery.newBuilder() + .addExpressions(GrpcVorgangQueryExpression.newBuilder() + .setOperator(GrpcQueryOperator.EXISTS) + .setPath("ClientAttribute.%s.nextWiedervorlageFrist".formatted(CriteriaUtil.DEFAULT_CLIENT)))).build(); + + var result = vorgangServiceStub.findVorgang(request); + + assertThat(result.getVorgangList()).hasSize(2); + } + + @Test + void shouldFindWithCertainNextFrist() { + var request = GrpcFindVorgangRequestTestFactory.createBuilder() + .clearFilterBy() + .setOrderBy(GrpcFindVorgangRequest.GrpcOrderBy.CREATED_AT_DESC) + .setQuery(GrpcQuery.newBuilder().addExpressions( + GrpcVorgangQueryExpression.newBuilder() + .setOperator(GrpcQueryOperator.LESS_THEN) + .setPath("ClientAttribute.%s.nextWiedervorlageFrist".formatted(CriteriaUtil.DEFAULT_CLIENT)) + .setOperandStringValue(LocalDate.now().minusDays(1).toString()))) + .build(); + + var result = vorgangServiceStub.findVorgang(request); + + assertThat(result.getVorgangList()).hasSize(1).first().extracting(GrpcVorgangHeader::getId).isEqualTo(vorgangWithNextFristMinus2Days.getId()); + } + + @Test + void shouldFindByComplexCondition() { + var request = GrpcFindVorgangRequestTestFactory.createBuilder().clearFilterBy() + .setOrderBy(GrpcFindVorgangRequest.GrpcOrderBy.CREATED_AT_DESC) + .setQuery(GrpcQuery.newBuilder() + .addExpressions(GrpcVorgangQueryExpression.newBuilder() + .setOperator(GrpcQueryOperator.EQUAL) + .setPath("Vorgang." + Vorgang.MONGODB_FIELDNAME_STATUS) + .setOperandStringValue("NEU")) + .addExpressions(GrpcVorgangQueryExpression.newBuilder() + .setOperator(GrpcQueryOperator.LESS_THEN_OR_EQUAL_TO) + .setPath("Vorgang." + Vorgang.MONGODB_FIELDNAME_CREATED_AT) + .setOperandStringValue(VorgangTestFactory.CREATED_AT.toString())) + ) + .build(); + + var result = vorgangServiceStub.findVorgang(request); + + assertThat(result.getVorgangList()).hasSize(1).first().extracting(GrpcVorgangHeader::getId).isEqualTo(vorgangNewCreatedAt.getId()); + } + + @Test + void shouldFindVorgangWithNewPostfachNachricht() { + var vorgang = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).clientAttributes(createClientAttributesMap()).build()); + + var request = GrpcFindVorgangRequestTestFactory.createBuilder().clearFilterBy() + .setOrderBy(GrpcFindVorgangRequest.GrpcOrderBy.CREATED_AT_DESC) + .setQuery(GrpcQuery.newBuilder().addExpressions( + GrpcVorgangQueryExpression.newBuilder() + .setPath(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH) + .setOperator(GrpcQueryOperator.UNEQUAL))) + .build(); + + var result = vorgangServiceStub.findVorgang(request); + + assertThat(result.getVorgangList()).hasSize(1).first().extracting(GrpcVorgangHeader::getId).isEqualTo(vorgang.getId()); + } + + private ClientAttributesMap createClientAttributesMapWithWiedervorlageNextFrist(LocalDate nextFrist) { + return ClientAttributesMapTestFactory.createWithAttribute(buildWiedervorlageNextFristClientAttribute(nextFrist)); + } + + private ClientAttribute buildWiedervorlageNextFristClientAttribute(LocalDate nextFrist) { + return ClientAttributeTestFactory.createBuilder() + .clientName(CriteriaUtil.DEFAULT_CLIENT) + .attributeName(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST) + .stringValue(Optional.of(nextFrist.toString())).build(); + } + + private ClientAttributesMap createClientAttributesMap() { + return ClientAttributesMapTestFactory.createWithAttribute(buildClientAttribute()); + } + + private ClientAttribute buildClientAttribute() { + return ClientAttributeTestFactory.createBuilder() + .clientName("OzgCloud_NachrichtenManager") + .attributeName("hasNewPostfachNachricht") + .intValue(Optional.empty()) + .boolValue(Optional.of(true)) + .build(); + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceITCase.java new file mode 100644 index 0000000..fca3f0b --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceITCase.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +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.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.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.callcontext.CallContextUserTestFactory; +import de.ozgcloud.vorgang.callcontext.CurrentUserService; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import de.ozgcloud.vorgang.common.grpc.GrpcFormDataTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcFormFieldTestFactory; +import de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import io.grpc.stub.StreamObserver; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@ITCase +class GrpcVorgangServiceITCase { + + static final String VALUE_KEY = "value"; + static final String LABEL_KEY = "label"; + + private static final String NAME_FIELD_1 = "field1"; + private static final String VALUE_FIELD_1 = "value1"; + private static final String LABEL_FIELD_1 = "label1"; + private static final Map<String, Object> FIELD_1 = Map.of(LABEL_KEY, LABEL_FIELD_1, VALUE_KEY, VALUE_FIELD_1); + + private static final String NAME_FIELD_2 = "field2"; + private static final String VALUE_FIELD_2 = "value2"; + private static final String LABEL_FIELD_2 = "label2"; + private static final Map<String, Object> FIELD_2 = Map.of(LABEL_KEY, LABEL_FIELD_2, VALUE_KEY, VALUE_FIELD_2); + + private static final String NAME_FIELD_3 = "field3"; + private static final String VALUE_FIELD_3 = "value3"; + private static final String LABEL_FIELD_3 = "label3"; + private static final Map<String, Object> FIELD_3 = Map.of(LABEL_KEY, LABEL_FIELD_3, VALUE_KEY, VALUE_FIELD_3); + + private static final List<GrpcFormField> formFields = List.of( + createFormField(NAME_FIELD_1, VALUE_FIELD_1, LABEL_FIELD_1), + createFormField(NAME_FIELD_2, VALUE_FIELD_2, LABEL_FIELD_2), + createFormField(NAME_FIELD_3, VALUE_FIELD_3, LABEL_FIELD_3)); + + private static final String TITLE_SUBFORM_1 = "SUBFORM_1"; + private static final String TITLE_SUBFORM_2 = "SUBFORM_2"; + private static final String TITLE_SUBFORM_3 = "SUBFORM_3"; + + @Autowired + private GrpcVorgangService grpcVorgangService; + @MockBean + private VorgangService service; + + @Nested + class TestCreateVorgang { + @Mock + private StreamObserver<GrpcCreateVorgangResponse> responseObserver; + @Captor + private ArgumentCaptor<Eingang> eingangCaptor; + + @BeforeEach + void init() { + when(service.startCreation(any())).thenReturn(VorgangTestFactory.create()); + } + + @Test + void shouldKeepFieldsOrder() { + var grpcFormData = GrpcFormData.newBuilder().addAllField(formFields).build(); + + Map<String, Object> formData = startCreation(grpcFormData); + + assertThat(removeControlData(formData)).containsExactly( + entry(NAME_FIELD_1, FIELD_1), + entry(NAME_FIELD_2, FIELD_2), + entry(NAME_FIELD_3, FIELD_3)); + } + + @Test + void shouldKeepSubFormOrder() { + var grpcFormData = GrpcFormData.newBuilder().addForm(GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_1)) + .addForm(GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_2)) + .addForm(GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_3)).build(); + + Map<String, Object> formData = startCreation(grpcFormData); + + verifySubFormOrder(formData, TITLE_SUBFORM_1, TITLE_SUBFORM_2, TITLE_SUBFORM_3); + } + + @SuppressWarnings("unchecked") + @Test + void shouldKeepFieldsOrderInSubForm() { + var grpcFormData = GrpcFormDataTestFactory.createBuilder().addForm( + GrpcSubFormTestFactory.createBuilder().clearField().clearSubForm().setTitle(TITLE_SUBFORM_1).addAllField(formFields)) + .build(); + + var formData = (Map<String, Object>) startCreation(grpcFormData).get(TITLE_SUBFORM_1); + formData = (Map<String, Object>) formData.get(VALUE_KEY); + + assertThat(removeControlData(formData)).containsExactly( + entry(NAME_FIELD_1, FIELD_1), + entry(NAME_FIELD_2, FIELD_2), + entry(NAME_FIELD_3, FIELD_3)); + } + + private LinkedHashMap<String, Object> removeControlData(Map<String, Object> formData) { + var editable = new LinkedHashMap<>(formData); + editable.remove("_kopControlData"); + return editable; + } + + @SuppressWarnings("unchecked") + @Test + void shouldKeepOrderInSubForm() { + var grpcFormData = GrpcFormDataTestFactory.createBuilder().addForm( + GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_1).clearField().clearSubForm() + .addSubForm(GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_3)) + .addSubForm(GrpcSubFormTestFactory.createBuilder().setTitle(TITLE_SUBFORM_2))) + .build(); + + var formData = (Map<String, Object>) startCreation(grpcFormData).get(TITLE_SUBFORM_1); + formData = (Map<String, Object>) formData.get(VALUE_KEY); + + verifySubFormOrder(formData, TITLE_SUBFORM_3, TITLE_SUBFORM_2); + } + + private static void verifySubFormOrder(Map<String, Object> formData, String... subFormTitle) { + var entries = new ArrayList<>(formData.entrySet()); + for (int i = 0; i < subFormTitle.length; i++) { + var entry = entries.get(i); + assertThat(entry.getKey()).isEqualTo(subFormTitle[i]); + } + } + + private Map<String, Object> startCreation(GrpcFormData grpcFormData) { + grpcVorgangService.startCreation(GrpcCreateVorgangRequestTestFactory.createWithFormData(grpcFormData), responseObserver); + + verify(service).startCreation(eingangCaptor.capture()); + return eingangCaptor.getValue().getFormData(); + + } + } + + private static GrpcFormField createFormField(String fieldName, String fieldValue, String label) { + return GrpcFormFieldTestFactory.createBuilder().setName(fieldName).setValue(fieldValue).setLabel(label).build(); + } + + @Nested + class TestLoadVorgang { + + private static final String REQUEST_ID = "request_id"; + + @Mock + private StreamObserver<GrpcFindVorgangWithEingangResponse> streamObserver; + @Captor + private ArgumentCaptor<GrpcFindVorgangWithEingangResponse> findVorgangResponseCaptor; + + @BeforeEach + void initVorgang() { + var formData = createFormData(); + + var eingang = EingangTestFactory.createBuilder().formData(formData).build(); + var vorgang = VorgangTestFactory.createBuilder().clearEingangs().eingangs(List.of(eingang)).build(); + + when(service.getById(any(), any())).thenReturn(vorgang); + } + + @Test + @WithMockUser + void shouldKeepFieldOrder() { + var grpcFormData = requestFormData(); + + assertThat(grpcFormData).isEqualTo(expectedFormData()); + } + + private static Map<String, Object> createFormData() { + Map<String, Object> formData = new LinkedHashMap<>(); + formData.put(NAME_FIELD_1, FIELD_1); + formData.put(NAME_FIELD_2, FIELD_2); + formData.put(NAME_FIELD_3, FIELD_3); + for (String subFormName : List.of(TITLE_SUBFORM_1, TITLE_SUBFORM_2, TITLE_SUBFORM_3)) { + var subForm = new LinkedHashMap<>(); + formData.put(subFormName, subForm); + subForm.put(NAME_FIELD_1, FIELD_1); + subForm.put(NAME_FIELD_2, FIELD_2); + subForm.put(NAME_FIELD_3, FIELD_3); + } + return formData; + } + + private static GrpcFormData expectedFormData() { + var grpcFormData = GrpcFormDataTestFactory.createBuilder().clearField().addAllField(formFields); + for (String subFormName : List.of(TITLE_SUBFORM_1, TITLE_SUBFORM_2, TITLE_SUBFORM_3)) { + grpcFormData.addForm(GrpcSubForm.newBuilder() + .setTitle(subFormName) + .addAllField(formFields)); + } + return grpcFormData.build(); + } + + private GrpcFormData requestFormData() { + grpcVorgangService.findVorgangWithEingang(GrpcFindVorgangWithEingangRequest.newBuilder().setId(REQUEST_ID).build(), streamObserver); + verify(streamObserver).onNext(findVorgangResponseCaptor.capture()); + return findVorgangResponseCaptor.getValue().getVorgangWithEingang().getEingang().getFormData(); + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceTest.java similarity index 79% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceTest.java index 7f85cbc..2d4a2f9 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,8 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -40,8 +41,6 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.data.domain.Page; -import static org.assertj.core.api.Assertions.*; - import io.grpc.stub.StreamObserver; class GrpcVorgangServiceTest { @@ -50,7 +49,7 @@ class GrpcVorgangServiceTest { private static final int OFFSET = 0; private static final long TOTAL = 42L; - @Spy // NOSONAR + @Spy @InjectMocks private GrpcVorgangService service; @Mock @@ -58,15 +57,18 @@ class GrpcVorgangServiceTest { @Mock private VorgangHeaderService headerService; @Mock - private EingangMapper eingangMapper; - @Mock private VorgangHeaderMapper vorgangHeaderMapper; + + @Mock + private EingangMapper eingangMapper; @Mock private VorgangWithEingangMapper vorgangWithEingangMapper; @Mock private FindVorgangRequestMapper findVorgangRequestMapper; + @Mock private FilterByMapper filterByMapper; + @Mock private IncomingFileMapper incomingFileMapper; @Mock @@ -90,49 +92,6 @@ class GrpcVorgangServiceTest { when(eingangMapper.fromGrpc(any())).thenReturn(eingang); } - @Nested - class TestCreateVorgang { - - @BeforeEach - void mockVorgangService() { - when(vorgangService.createVorgang(any())).thenReturn(VorgangTestFactory.create()); - } - - @Test - void shouldCallEingangMapper() throws Exception { - callCreateVorgang(); - - verify(eingangMapper).fromGrpc(GrpcEingangTestFactory.create()); - } - - @Test - void shouldCallService() throws Exception { - callCreateVorgang(); - - verify(vorgangService).createVorgang(eingang); - } - - @Test - void shouldReturnMessage() throws Exception { - callCreateVorgang(); - - assertThat(responseCaptor.getValue().getMessage()).isEqualTo("ok"); - } - - @Test - void shouldReturnVorgangId() throws Exception { - callCreateVorgang(); - - assertThat(responseCaptor.getValue().getVorgangId()).isEqualTo(VorgangTestFactory.ID); - } - - private void callCreateVorgang() throws Exception { - service.createVorgang(request, responseObserver); - - verify(responseObserver).onNext(responseCaptor.capture()); - } - } - @Nested class TestStartCreation { @@ -142,34 +101,27 @@ class GrpcVorgangServiceTest { } @Test - void shouldCallEingangMapper() throws Exception { + void shouldCallEingangMapper() { callStartCreation(); verify(eingangMapper).fromGrpc(GrpcEingangTestFactory.create()); } @Test - void shouldCallService() throws Exception { - callStartCreation(); - - verify(vorgangService).startCreation(eingang); - } - - @Test - void shouldReturnMessage() throws Exception { + void shouldReturnMessage() { callStartCreation(); assertThat(responseCaptor.getValue().getMessage()).isEqualTo("ok"); } @Test - void shouldReturnVorgangId() throws Exception { + void shouldReturnVorgangId() { callStartCreation(); assertThat(responseCaptor.getValue().getVorgangId()).isEqualTo(VorgangTestFactory.ID); } - private void callStartCreation() throws Exception { + private void callStartCreation() { service.startCreation(request, responseObserver); verify(responseObserver).onNext(responseCaptor.capture()); @@ -253,36 +205,36 @@ class GrpcVorgangServiceTest { @Captor private ArgumentCaptor<FindVorgangRequest> findVorgangRequestCaptor; - private final GrpcVorgangHeader plutoVorgangHeader = GrpcVorgangHeader.newBuilder().build(); + private final GrpcVorgangHeader grpcVorgangHeader = GrpcVorgangHeader.newBuilder().build(); private final GrpcFindVorgangRequest request = GrpcFindVorgangRequest.newBuilder().setLimit(LIMIT).setOffset(OFFSET) .build(); @BeforeEach - void initMockReturnValues() throws Exception { + void initMockReturnValues() { when(page.getContent()).thenReturn(Collections.singletonList(VorgangHeaderTestFactory.create())); when(page.getTotalElements()).thenReturn(TOTAL); when(headerService.findAll(any(FindVorgangRequest.class))).thenReturn(page); - when(vorgangHeaderMapper.toGrpcVorgangHeader(any())).thenReturn(plutoVorgangHeader); + when(vorgangHeaderMapper.toGrpcVorgangHeader(any())).thenReturn(grpcVorgangHeader); when(findVorgangRequestMapper.fromFindVorgangRequest(any(GrpcFindVorgangRequest.class))) .thenReturn(FindVorgangRequestTestFactory.create()); } @Test - void shouldCallVorgangHeaderService() throws Exception { + void shouldCallVorgangHeaderService() { callFindVorgaenge(); verify(headerService).findAll(findVorgangRequestCaptor.capture()); } @Test - void shouldCallVorgangHeaderMapper() throws Exception { + void shouldCallVorgangHeaderMapper() { callFindVorgaenge(); verify(vorgangHeaderMapper).toGrpcVorgangHeader(any()); } @Test - void shouldContainVorgangData() throws Exception { + void shouldContainVorgangData() { callFindVorgaenge(); verify(vorgangHeaderMapper).toGrpcVorgangHeader(headerCaptor.capture()); @@ -291,7 +243,7 @@ class GrpcVorgangServiceTest { } @Test - void shouldSetTotal() throws Exception { + void shouldSetTotal() { callFindVorgaenge(); var response = responseCaptor.getValue(); @@ -299,7 +251,7 @@ class GrpcVorgangServiceTest { assertThat(response.getTotal()).isEqualTo(TOTAL); } - private void callFindVorgaenge() throws Exception { + private void callFindVorgaenge() { service.findVorgang(request, responseObserver); verify(responseObserver).onNext(responseCaptor.capture()); @@ -333,42 +285,46 @@ class GrpcVorgangServiceTest { @Nested class TestFindVorgangWithEingangService { + @Captor + private ArgumentCaptor<Vorgang> vorgangArgumentCaptor; + @BeforeEach void mock() { when(filterByMapper.fromFilterBy(any(GrpcFilterBy.class))).thenReturn(filterCriteria); } @Test - void shouldCallHeaderService() throws Exception { + void shouldCallHeaderService() { callFindVorgangWithEingang(); verify(vorgangService).getById(VorgangTestFactory.ID, filterCriteria); } @Test - void shouldCallFindVorgangRequestMapper() throws Exception { + void shouldCallFindVorgangRequestMapper() { callFindVorgangWithEingang(); verify(filterByMapper).fromFilterBy(GrpcFilterByTestFactory.create()); } @Test - void shouldCallVorgangWithEingangMapper() throws Exception { + void shouldCallVorgangWithEingangMapper() { callFindVorgangWithEingang(); verify(vorgangWithEingangMapper).toVorgangWithEingang(vorgang); } @Test - void shouldContainVorgangData() throws Exception { + void shouldContainVorgangData() { callFindVorgangWithEingang(); assertThat(responseCaptor.getValue().getVorgangWithEingang()).usingRecursiveComparison() .isEqualTo(GrpcVorgangWithEingangTestFactory.create()); } + } - private void callFindVorgangWithEingang() throws Exception { + private void callFindVorgangWithEingang() { service.findVorgangWithEingang(request, responseObserver); verify(responseObserver).onNext(responseCaptor.capture()); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangWithEingangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangWithEingangTestFactory.java similarity index 81% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangWithEingangTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangWithEingangTestFactory.java index 59412d8..cae8291 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcVorgangWithEingangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcVorgangWithEingangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import de.itvsh.ozg.pluto.clientattribute.GrpcClientAttributeTestFactory; -import de.itvsh.ozg.pluto.command.GrpcUserTestFactory; +import de.ozgcloud.vorgang.clientattribute.GrpcClientAttributeTestFactory; +import de.ozgcloud.vorgang.command.GrpcUserTestFactory; public class GrpcVorgangWithEingangTestFactory { @@ -32,10 +32,6 @@ public class GrpcVorgangWithEingangTestFactory { return createBuilder().build(); } - static GrpcVorgangWithEingang createWithEingang(GrpcEingang eingang) { - return createBuilder().setEingang(eingang).build(); - } - static GrpcVorgangWithEingang.Builder createBuilder() { return GrpcVorgangWithEingang.newBuilder() .setId(VorgangTestFactory.ID) @@ -44,6 +40,7 @@ public class GrpcVorgangWithEingangTestFactory { .setNummer(VorgangTestFactory.VORGANG_NUMMER) .setStatus(VorgangTestFactory.STATUS.name()) .setCreatedAt(VorgangTestFactory.INITIAL_DATE_STR) + .setHeader(GrpcVorgangHeadTestFactory.create()) .setEingang(GrpcEingangTestFactory.create()) .setVersion(VorgangTestFactory.VERSION) .setAssignedTo(GrpcUserTestFactory.ID) diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcZustaendigeStelleTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcZustaendigeStelleTestFactory.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcZustaendigeStelleTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcZustaendigeStelleTestFactory.java index da43cc4..97f32eb 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/GrpcZustaendigeStelleTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/GrpcZustaendigeStelleTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class GrpcZustaendigeStelleTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapperTest.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapperTest.java index 1d6cba1..989c551 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; @@ -32,7 +32,7 @@ import org.mockito.InjectMocks; import org.mockito.Spy; import org.springframework.test.util.ReflectionTestUtils; -import de.itvsh.ozg.pluto.files.FileIdMapper; +import de.ozgcloud.vorgang.files.FileIdMapper; class IncomingFileGroupMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupTestFactory.java similarity index 92% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupTestFactory.java index afb7f68..a878181 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileGroupTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileGroupTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class IncomingFileGroupTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapperTest.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapperTest.java index e5712d4..f2dbbc1 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; @@ -31,7 +31,7 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Spy; -import de.itvsh.ozg.pluto.files.FileIdMapper; +import de.ozgcloud.vorgang.files.FileIdMapper; class IncomingFileMapperTest { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileTestFactory.java similarity index 93% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileTestFactory.java index a2a8ae2..b6999ec 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/IncomingFileTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/IncomingFileTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -29,8 +29,8 @@ import java.io.InputStream; import java.util.Random; import java.util.UUID; -import de.itvsh.kop.common.test.TestUtils; -import de.itvsh.ozg.pluto.files.FileId; +import de.ozgcloud.common.test.TestUtils; +import de.ozgcloud.vorgang.files.FileId; import lombok.AccessLevel; import lombok.NoArgsConstructor; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/LabelProcessorTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/LabelProcessorTest.java new file mode 100644 index 0000000..8abdf16 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/LabelProcessorTest.java @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static de.ozgcloud.vorgang.vorgang.EingangTestFactory.*; +import static de.ozgcloud.vorgang.vorgang.LabelProcessor.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.Spy; + +class LabelProcessorTest { + + @Spy + @InjectMocks + private LabelProcessor mapper; + + private Map<String, String> singleFieldLabelMap = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_LABEL); + private Map<String, String> subFormLabelMap = Map.of(SUBFORM_NAME, SUBFORM_LABEL); + private Map<String, String> fullFormLabelMap = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_LABEL, SUBFORM_NAME, SUBFORM_LABEL); + + private Map<String, Object> singleFieldWithLabel = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, CONTROL_DATA_KEY, singleFieldLabelMap); + + @Nested + class TestMoveLabelsToControlData { + + private Map<String, Object> singleFieldMap = Map.of(VALUE_KEY, SINGLE_FIELD_VALUE, LABEL_KEY, SINGLE_FIELD_LABEL); + + @Nested + class MoveLabels { + @BeforeEach + void init() { + doReturn(Optional.of(SINGLE_FIELD_LABEL)).when(mapper).getLabelFromFieldValue(any()); + + } + + @Test + void shouldAddLabelToControlData() { + doReturn(SINGLE_FIELD_VALUE).when(mapper).getValueWithoutLabel(any()); + + var result = mapper.moveLabelsToControlData(Map.of(SINGLE_FIELD_NAME, singleFieldMap)); + + assertThat(result).contains(entry(CONTROL_DATA_KEY, Map.of(LABELS_KEY, singleFieldLabelMap))); + } + + @Test + void shouldRemoveLabelFormValue() { + doReturn(SINGLE_FIELD_VALUE).when(mapper).getValueWithoutLabel(any()); + + var result = mapper.moveLabelsToControlData(Map.of(SINGLE_FIELD_NAME, singleFieldMap)); + + assertThat(result).contains(entry(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE)); + } + + @Test + void shouldProcessSubForm() { + mapper.moveLabelsToControlData(Map.of(SUBFORM_NAME, SUBFORM)); + + verify(mapper).doRecursionIfSubForm(Pair.of(SUBFORM_NAME, SUBFORM_FLAT)); + verify(mapper).moveLabelsToControlData(SUBFORM_FLAT); + } + } + + @Nested + class GetLables { + @Test + void shouldNotCallGetLabelForControlData() { + mapper.getLabelsFromFormData(Map.of(CONTROL_DATA_KEY, "")); + + verify(mapper, never()).getLabelFromFieldValue(any()); + } + + @Test + void shouldReturnFieldLable() { + doReturn(Optional.of(SINGLE_FIELD_LABEL)).when(mapper).getLabelFromFieldValue(any()); + + var labels = mapper.getLabelsFromFormData(singleFieldWithLabel); + + assertThat(labels).containsExactly(entry(SINGLE_FIELD_NAME, SINGLE_FIELD_LABEL)); + verify(mapper).getLabelFromFieldValue(SINGLE_FIELD_VALUE); + } + + @Test + void shouldOmitMissingLabel() { + doReturn(Optional.empty()).when(mapper).getLabelFromFieldValue(any()); + + var labels = mapper.getLabelsFromFormData(singleFieldWithLabel); + + assertThat(labels).isEmpty(); + } + + @Nested + class FromFieldValue { + @Test + void shouldReturnLabel() { + var label = mapper.getLabelFromFieldValue(Map.of(VALUE_KEY, SINGLE_FIELD_VALUE, LABEL_KEY, SINGLE_FIELD_LABEL)); + + assertThat(label).contains(SINGLE_FIELD_LABEL); + } + + @Test + void shouldReturnEmptyForValue() { + var label = mapper.getLabelFromFieldValue(SINGLE_FIELD_VALUE); + + assertThat(label).isEmpty(); + } + + @Test + void shouldReturnLableForSubform() { + var label = mapper.getLabelFromFieldValue(Map.of(VALUE_KEY, SUBFORM, LABEL_KEY, SUBFORM_LABEL)); + + assertThat(label).contains(SUBFORM_LABEL); + } + } + } + + @Nested + class RemoveLabel { + @Test + void shouldReturnSingleValue() { + var result = mapper.getValueWithoutLabel(SINGLE_FIELD_VALUE); + + assertThat(result).isEqualTo(SINGLE_FIELD_VALUE); + } + + @Test + void shouldReturnSingleValueWithoutLabel() { + var result = mapper.getValueWithoutLabel(Map.of(VALUE_KEY, SINGLE_FIELD_VALUE, LABEL_KEY, SINGLE_FIELD_LABEL)); + + assertThat(result).isEqualTo(SINGLE_FIELD_VALUE); + } + + @Test + void shouldReturnSubForm() { + var result = mapper.getValueWithoutLabel(SUBFORM); + + assertThat(result).isEqualTo(Map.of(SUBFORM_FIELD_NAME, SUBFORM_FIELD)); + } + + @Test + void shouldReturnSubFormWithoutLabel() { + var result = mapper.getValueWithoutLabel(Map.of(VALUE_KEY, SUBFORM, LABEL_KEY, SUBFORM_LABEL)); + + assertThat(result).isEqualTo(SUBFORM); + } + } + + @Nested + class AddLabelsToControlData { + @Test + void shouldAddLables() { + doReturn(singleFieldLabelMap).when(mapper).getLabelsFromFormData(any()); + + var result = mapper.addLabelsToControlData(Map.of(SINGLE_FIELD_NAME, singleFieldMap)); + + assertThat(result).isEqualTo(Map.of(LABELS_KEY, Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_LABEL))); + } + + @Test + void shouldAddNothingIfNoLabel() { + doReturn(Collections.emptyMap()).when(mapper).getLabelsFromFormData(any()); + + var result = mapper.addLabelsToControlData(Map.of(SINGLE_FIELD_NAME, singleFieldMap)); + + assertThat(result).isEmpty(); + } + } + + @Nested + class ReplaceControlData { + @Test + void shouldReplaceControlData() { + Map<String, Object> newControlData = Map.of("test", "test"); + + var result = mapper.replaceControlData(Map.of(CONTROL_DATA_KEY, Map.of("old", "old")), newControlData); + + assertThat(result).containsOnly(entry(CONTROL_DATA_KEY, newControlData)); + } + + @Test + void shouldAddNothingIfEmpty() { + var result = mapper.replaceControlData(Collections.emptyMap(), Collections.emptyMap()); + + assertThat(result).isEmpty(); + } + } + + @Test + void shouldMapEmptyFormData() { + var eingang = EingangTestFactory.createBuilder().formData(Collections.emptyMap()).build(); + + var mapped = mapper.moveLabelsToControlData(eingang); + + assertThat(mapped.getFormData()).isEqualTo(Collections.emptyMap()); + } + } + + @Nested + class TestMapKopControlDataToLabels { + + @DisplayName("Mapping a single Field should call mapValue()") + @Test + void shouldCallMapValueForSingleField() { + addLabels(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE); + + verify(mapper).addLabel(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, Collections.emptyMap()); + } + + @DisplayName("Should not map kopControlData") + @Test + void shouldNOTCallMapValueForControlData() { + addLabels(LabelProcessor.CONTROL_DATA_KEY, ""); + + verify(mapper, never()).addLabel(any(), any(), any()); + } + + private void addLabels(String key, Object value) { + mapper.addLabels(Map.of(key, value)); + } + + @Nested + class AddLabel { + + @Test + void shouldCallAddToFieldValue() { + mapper.addLabel(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, singleFieldLabelMap); + + verify(mapper).addLabelToFieldValue(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, singleFieldLabelMap); + } + + @Test + void shouldJoinSingleFieldMappings() { + Map<String, List<Object>> mappingResult = Map.of(SINGLE_FIELD_NAME, Collections.emptyList()); + doReturn(mappingResult).when(mapper).addLabelToFieldValue(any(), any(), any()); + + var mapped = mapper.addLabel(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, singleFieldLabelMap); + + assertThat(mapped).containsAllEntriesOf(mappingResult); + } + + @Nested + class ToFieldValue { + @Test + void shouldAddLabel() { + var mapped = mapper.addLabelToFieldValue(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_LABEL)); + + assertThat(mapped).isEqualTo( + Map.of(LabelProcessor.LABEL_KEY, SINGLE_FIELD_LABEL, LabelProcessor.VALUE_KEY, SINGLE_FIELD_VALUE)); + } + + @Test + void shouldHandleMissingLabel() { + var mapped = mapper.addLabelToFieldValue(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, Collections.emptyMap()); + + assertThat(mapped).isEqualTo(Map.of(LabelProcessor.VALUE_KEY, SINGLE_FIELD_VALUE)); + } + } + + @Test + void shouldCallAddLabelToSubForm() { + mapper.addLabel(SUBFORM_NAME, SUBFORM, Map.of(SUBFORM_NAME, SUBFORM_LABEL)); + + verify(mapper).addLabelsToSubForm(SUBFORM, Optional.of(SUBFORM_LABEL)); + } + + @Test + void shouldHandleMissingLabel() { + mapper.addLabel(SUBFORM_NAME, SUBFORM, Collections.emptyMap()); + + verify(mapper).addLabelsToSubForm(SUBFORM, Optional.empty()); + } + + @Nested + class ToSubForm { + @Test + void shouldAddLabel() { + var mapped = mapper.addLabelsToSubForm(SUBFORM, Optional.of(SUBFORM_LABEL)); + + assertThat(mapped).containsEntry(LabelProcessor.LABEL_KEY, SUBFORM_LABEL); + } + + @Test + void shouldIgnoreMissingLable() { + var mapped = mapper.addLabelsToSubForm(SUBFORM, Optional.empty()); + + assertThat(mapped).doesNotContainKey(LabelProcessor.LABEL_KEY); + } + + @Test + void shouldMapSubForm() { + mapper.addLabelsToSubForm(SUBFORM, Optional.of(SUBFORM_LABEL)); + + verify(mapper).addLabels(SUBFORM); + } + + @Test + void shouldAddMappedValue() { + var mappedValue = Collections.emptyMap(); + doReturn(mappedValue).when(mapper).addLabels(Mockito.<Map<String, Object>>any()); + + var mapped = mapper.addLabelsToSubForm(SUBFORM, Optional.of(SUBFORM_LABEL)); + + assertThat(mapped).containsEntry(LabelProcessor.VALUE_KEY, mappedValue); + } + } + + @Nested + class MergedProcessedValues { + private Map<String, Object> singleFieldMap = Map.of(VALUE_KEY, SINGLE_FIELD_VALUE, LABEL_KEY, SINGLE_FIELD_LABEL); + + private Map<String, Object> subFormFieldMap = Map.of(VALUE_KEY, SUBFORM_FIELD_VALUE, LABEL_KEY, SUBFORM_FIELD_LABEL); + + private Map<String, Object> subFormMap = Map.of(LabelProcessor.VALUE_KEY, subFormFieldMap, LABEL_KEY, SUBFORM_LABEL); + + @Test + void shouldContainFieldValue() { + doReturn(singleFieldMap).when(mapper).addLabelToFieldValue(any(), any(), any()); + + var mapped = mapper.addLabels( + Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, CONTROL_DATA_KEY, singleFieldLabelMap)); + + assertThat(mapped).containsExactly(entry(SINGLE_FIELD_NAME, singleFieldMap)); + } + + @Test + void shouldContainSubFormValue() { + doReturn(subFormMap).when(mapper).addLabelsToSubForm(any(), any()); + + var mapped = mapper.addLabels( + Map.of(CONTROL_DATA_KEY, subFormLabelMap, SUBFORM_NAME, SUBFORM)); + + assertThat(mapped).containsExactly(entry(SUBFORM_NAME, subFormMap)); + } + + @Test + void shouldContainsAllLabels() { + doReturn(singleFieldMap).when(mapper).addLabelToFieldValue(any(), any(), any()); + doReturn(subFormMap).when(mapper).addLabelsToSubForm(any(), any()); + + var mapped = mapper.addLabels( + Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE, CONTROL_DATA_KEY, fullFormLabelMap, SUBFORM_NAME, SUBFORM)); + + assertThat(mapped).isEqualTo(buildFullFormMap()); + } + + private Map<String, Object> buildFullFormMap() { + var map = new LinkedHashMap<String, Object>(); + map.put(SINGLE_FIELD_NAME, singleFieldMap); + map.put(SUBFORM_NAME, subFormMap); + + return map; + } + } + } + + @Test + void shouldMapEmptyFormData() { + var eingang = EingangTestFactory.createBuilder().formData(Collections.emptyMap()).build(); + + var mapped = mapper.moveLabelsToControlData(eingang); + + assertThat(mapped.getFormData()).isEqualTo(Collections.emptyMap()); + } + } + + @Nested + class TestIsFieldValue { + + @Test + void shouldReturnTrueForSimpleValue() { + var field = SINGLE_FIELD_VALUE; + + assertThat(mapper.isFieldValue(field)).isTrue(); + } + + @Test + void shouldReturnTrueForValueWithLabel() { + var field = Map.of( + LabelProcessor.LABEL_KEY, SINGLE_FIELD_LABEL, + LabelProcessor.VALUE_KEY, SINGLE_FIELD_VALUE); + + assertThat(mapper.isFieldValue(field)).isTrue(); + } + + @Test + void shouldReturnFalseForSubFormValueWithoutLabel() { + var field = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE); + + assertThat(mapper.isFieldValue(field)).isFalse(); + } + + @Test + void shouldReturnFalseForSubFormValueWithLabel() { + var field = Map.of( + LabelProcessor.LABEL_KEY, SUBFORM_LABEL, + LabelProcessor.VALUE_KEY, Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE)); + + assertThat(mapper.isFieldValue(field)).isFalse(); + } + + @Test + void shouldReturnFalseForEmptySubFormValue() { + var field = Map.of( + LabelProcessor.LABEL_KEY, SUBFORM_LABEL, + LabelProcessor.VALUE_KEY, Collections.emptyMap()); + + assertThat(mapper.isFieldValue(field)).isFalse(); + } + } + + @Nested + class TestGetFieldValue { + + @Test + void shouldReturnValueForSimpleField() { + var fieldValue = SINGLE_FIELD_VALUE; + + assertThat(mapper.getFieldValue(fieldValue)).isEqualTo(fieldValue); + } + + @Test + void shouldReturnValueForFieldWithLabel() { + var fieldValue = Map.of( + LabelProcessor.LABEL_KEY, SINGLE_FIELD_LABEL, + LabelProcessor.VALUE_KEY, SINGLE_FIELD_VALUE); + + assertThat(mapper.getFieldValue(fieldValue)).isEqualTo(SINGLE_FIELD_VALUE); + } + + @Test + void shouldReturnValueForSubForm() { + var fieldValue = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD_VALUE); + + assertThat(mapper.getFieldValue(fieldValue)).isEqualTo(fieldValue); + } + + @Test + void shouldReturnValueForSubFormWithLabel() { + var fieldValue = Map.of( + LabelProcessor.LABEL_KEY, SUBFORM_LABEL, + LabelProcessor.VALUE_KEY, SUBFORM); + + assertThat(mapper.getFieldValue(fieldValue)).isEqualTo(SUBFORM); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilderTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilderTest.java new file mode 100644 index 0000000..b3f855b --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/QueryCriteriaBuilderTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.springframework.data.mongodb.core.query.Criteria; + +import de.ozgcloud.vorgang.common.operator.OperatorTestFactory; +import de.ozgcloud.vorgang.vorgang.FindVorgangQuery.LogicalOperator; + +class QueryCriteriaBuilderTest { + + @Spy + @InjectMocks + private QueryCriteriaBuilder queryCriteriaBuilder; + + private Criteria criteria = Criteria.where(OperatorTestFactory.PATH).is(OperatorTestFactory.STRING_VALUE); + + @Nested + class TestFrom { + + @Test + void shouldBuildCriteriaFromOperators() { + var result = queryCriteriaBuilder.from(FindVorgangQueryTestFactory.create()); + + assertThat(result).isEqualTo(criteria); + } + + @Test + void shouldBuildFromNestedQuery() { + var nestedQuery = FindVorgangQueryTestFactory.createBuilder().logicalOperator(LogicalOperator.OR).build(); + var query = FindVorgangQueryTestFactory.createBuilder().clearOperators().nestedQuery(nestedQuery).build(); + + var result = queryCriteriaBuilder.from(query); + + assertThat(result).isEqualTo(criteria); + } + + @Test + void shouldCallAddFromOperators() { + var query = FindVorgangQueryTestFactory.create(); + + queryCriteriaBuilder.from(query); + + verify(queryCriteriaBuilder).addFromOperators(any(), eq(query.getOperators())); + } + + @Test + void shouldCallConnect() { + var query = FindVorgangQueryTestFactory.create(); + + queryCriteriaBuilder.from(query); + + verify(queryCriteriaBuilder).connect(eq(query.getLogicalOperator()), any()); + } + } + + @Nested + class TestAddFromOperators { + + @Test + void shouldAddOperators() { + var resultList = new ArrayList<Criteria>(); + + queryCriteriaBuilder.addFromOperators(resultList, List.of(OperatorTestFactory.createEqualOperator())); + + assertThat(resultList).containsExactly(criteria); + } + + } + + @Nested + class TestConnect { + + private Criteria criteria1 = Criteria.where(OperatorTestFactory.PATH).is(OperatorTestFactory.STRING_VALUE); + + @Test + void shouldConnectWithAnd() { + var result = queryCriteriaBuilder.connect(LogicalOperator.AND, List.of(criteria, criteria1)); + + assertThat(result.getCriteriaObject()).containsKey("$and"); + } + + @Test + void shouldConnectWithOr() { + var result = queryCriteriaBuilder.connect(LogicalOperator.OR, List.of(criteria, criteria1)); + + assertThat(result.getCriteriaObject()).containsKey("$or"); + } + + @Test + void shouldReturnEmptyCriteria() { + var result = queryCriteriaBuilder.connect(LogicalOperator.AND, List.of()); + + assertThat(result.getCriteriaObject()).isEmpty(); + } + + @Test + void shouldReturnSingleCriteria() { + var result = queryCriteriaBuilder.connect(LogicalOperator.AND, List.of(criteria)); + + assertThat(result).isEqualTo(criteria); + } + } + +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationServiceTest.java similarity index 97% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationServiceTest.java index 293da70..0e935bb 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangAuthorizationServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangAuthorizationServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEventTestFactory.java new file mode 100644 index 0000000..ceb6005 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangDeletedEventTestFactory.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.vorgang.command.CommandTestFactory; + +public class VorgangDeletedEventTestFactory { + + public static VorgangDeletedEvent create() { + return new VorgangDeletedEvent(CommandTestFactory.createBuilder().order("VORGANG_LOESCHEN").build()); + } + +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerITCase.java new file mode 100644 index 0000000..72df1a0 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerITCase.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static de.ozgcloud.vorgang.vorgang.VorgangService.*; +import static org.mockito.ArgumentMatchers.*; +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.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.vorgang.OzgCloudVorgangService; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandCreatedEvent; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.notification.antragsteller.AntragstellerNotificationEventListener; +import de.ozgcloud.notification.user.UserNotificationEventListener; +import de.ozgcloud.processor.processor.ProcessorService; +import de.ozgcloud.processor.vorgang.ProcessorVorgangMapper; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.files.FileService; + +@ITCase +@SpringBootTest(properties = { + "ozgcloud.processors[0].address: http://test1", + "ozgcloud.processors[0].name: processor1", + "ozgcloud.processors[0].forms[0].formEngineName: formEngineTest1", + "ozgcloud.processors[0].forms[0].formId: ID1" +}) +class VorgangEventListenerITCase { + + @Autowired + private ApplicationEventPublisher publisher; + + @SpyBean + private VorgangEventListener listener; + @SpyBean + private AntragstellerNotificationEventListener antragstellerNotificationEventListener; + @SpyBean + private UserNotificationEventListener userNotificationEventListener; + + @MockBean + private VorgangService service; + @MockBean + private VorgangHeaderService vorgangHeaderService; + @MockBean + private FileService fileService; + @Autowired + private CommandService commandService; + + @MockBean + private ProcessorService vorgagnProcessorService; + @MockBean + private OzgCloudVorgangService ozgCloudVorgangService; + @MockBean + private ProcessorVorgangMapper processorVorgangMapper; + + @Nested + class TestOnVorgangLoeschen { + + @BeforeEach + void init() { + doNothing().when(listener).publishEvent(any()); + } + + @Test + void shouldCallService() { + publisher.publishEvent(CommandCreatedEventTestFactory.create(CommandTestFactory.createBuilder().order("VORGANG_LOESCHEN").build())); + + verify(service, timeout(500)).deleteVorgang(VorgangTestFactory.ID); + } + + } + + @Nested + class TestOnVorgangCreated { + + @BeforeEach + void init() { + doNothing().when(antragstellerNotificationEventListener).onVorgangCreated(any()); + doNothing().when(userNotificationEventListener).onVorgangCreated(any()); + + } + + @Test + void shouldCallProcessorService() { + publisher.publishEvent(new VorgangCreatedEvent("id")); + + verify(vorgagnProcessorService, timeout(500)).processVorgang(any()); + } + } + + @Nested + class TestOnSetAktenzeichen { + + private static final Command SET_AKTENZEICHEN_COMMAND = CommandTestFactory.createBuilder().order(Order.SET_AKTENZEICHEN.name()) + .bodyObject(Map.of(BODY_OBJECT_AKTENZEICHEN, VorgangTestFactory.AKTENZEICHEN)).build(); + private static final CommandCreatedEvent SET_AKTENZEICHEN_EVENT = CommandCreatedEventTestFactory.create(SET_AKTENZEICHEN_COMMAND); + + @BeforeEach + void init() { + doNothing().when(listener).onSetAktenzeichen(any()); + } + + @Test + void shouldCallOnSetAktenzeichen() { + publisher.publishEvent(SET_AKTENZEICHEN_EVENT); + + verify(listener, timeout(500)).onSetAktenzeichen(SET_AKTENZEICHEN_EVENT); + } + + @Test + void shouldNotCallOnSetAktenzeichen() { + publisher.publishEvent(CommandCreatedEventTestFactory.create(CommandTestFactory.createBuilder().order("NOT_SET_AKTENZEICHEN").build())); + + verify(listener, never()).onSetAktenzeichen(any()); + } + } +} diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerTest.java new file mode 100644 index 0000000..c1aaf77 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangEventListenerTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static de.ozgcloud.vorgang.vorgang.VorgangService.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.context.ApplicationEventPublisher; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.common.errorhandling.FunctionalException; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.status.StatusService; +import de.ozgcloud.vorgang.vorgang.redirect.VorgangForwardFailedEventTestFactory; +import de.ozgcloud.vorgang.vorgang.redirect.VorgangRedirectedEventTestFactory; + +class VorgangEventListenerTest { + + @InjectMocks + private VorgangEventListener listener; + + @Mock + private VorgangService service; + @Mock + private VorgangHeaderService vorgangHeaderService; + @Mock + private StatusService statusService; + @Mock + private FileService fileService; + @Mock + private CommandService commandService; + + @Mock + private ApplicationEventPublisher publisher; + + @Nested + class OnVorgangRedirectedEvent { + + @Test + void shouldSetStatus() { + listener.updateStatus(VorgangRedirectedEventTestFactory.create()); + + verify(statusService).setStatusToWeitergeleitet(VorgangRedirectedEventTestFactory.SOURCE.getVorgangId(), + VorgangRedirectedEventTestFactory.SOURCE.getCreatedByCommand()); + } + } + + @Nested + class TestUpdateStatusOnVorgangForwardFailedEvent { + + @Test + void shouldSetStatus() { + listener.updateStatus(VorgangForwardFailedEventTestFactory.create()); + + verify(statusService).setStatusToInBearbeitung(VorgangForwardFailedEventTestFactory.SOURCE.getVorgangId(), + VorgangForwardFailedEventTestFactory.SOURCE.getId()); + } + } + + @Nested + class TestDeleteVorgang { + + @Test + void shouldDeleteVorgang() { + listener.onVorgangLoeschen(CommandCreatedEventTestFactory.create()); + + verify(service).deleteVorgang(VorgangTestFactory.ID); + } + + @Test + void shouldPublishDoneEvent() { + listener.onVorgangLoeschen(CommandCreatedEventTestFactory.create()); + + verify(publisher).publishEvent(any(CommandExecutedEvent.class)); + } + + @Test + void shouldPublishFailedEvent() { + doThrow(new FunctionalException(() -> "test")).when(service).deleteVorgang(any()); + + listener.onVorgangLoeschen(CommandCreatedEventTestFactory.create()); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + + @Test + void shouldDeleteFiles() { + listener.onVorgangLoeschen(CommandCreatedEventTestFactory.create()); + + verify(fileService).deleteAllByVorgang(VorgangTestFactory.ID); + } + } + + @Nested + class TestSetAktenzeichen { + + private static final Command SET_AKTENZEICHEN_COMMAND = CommandTestFactory.createBuilder().order(Order.SET_AKTENZEICHEN.name()) + .bodyObject(Map.of(BODY_OBJECT_AKTENZEICHEN, VorgangTestFactory.AKTENZEICHEN)).build(); + private static final String PREVIOUS_AKTENZEICHEN = VorgangTestFactory.ID + "-prev"; + + @BeforeEach + void init() { + when(vorgangHeaderService.getById(VorgangTestFactory.ID)).thenReturn( + VorgangHeaderTestFactory.createBuilder().aktenzeichen(PREVIOUS_AKTENZEICHEN).build()); + } + + @Test + void shouldCallGetById() { + callListener(); + + verify(vorgangHeaderService).getById(VorgangTestFactory.ID); + } + + @Test + void shouldFailIfVorgangNotFound() { + when(vorgangHeaderService.getById(VorgangTestFactory.ID)).thenThrow(TechnicalException.class); + + callListener(); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + + @Test + void shouldSetPreviousAktenzeichen() { + callListener(); + + verify(commandService).setPreviousState(CommandTestFactory.ID, + Map.of(VorgangService.BODY_OBJECT_AKTENZEICHEN, PREVIOUS_AKTENZEICHEN)); + } + + @Test + @DisplayName("should store a null in previousState, if Aktenzeichen is null") + void shouldHandleNullAktenzeichen() { + when(vorgangHeaderService.getById(VorgangTestFactory.ID)).thenReturn(VorgangHeaderTestFactory.createBuilder().aktenzeichen(null).build()); + + callListener(); + + verify(commandService).setPreviousState(CommandTestFactory.ID, Collections.singletonMap(VorgangService.BODY_OBJECT_AKTENZEICHEN, null)); + } + + @Test + void shouldCallVorgangService() { + callListener(); + + verify(service).setAktenzeichen(SET_AKTENZEICHEN_COMMAND); + } + + @Test + void shouldPublishEvent() { + callListener(); + + verify(publisher).publishEvent(any(SetAktenzeichenCompletedEvent.class)); + } + + @Nested + class TestFailedEvent { + + private final String ERROR_MESSAGE = LoremIpsum.getInstance().getWords(3); + + @Captor + private ArgumentCaptor<CommandFailedEvent> event; + + @BeforeEach + void init() { + doThrow(new RuntimeException(ERROR_MESSAGE)).when(service).setAktenzeichen(any()); + } + + @Test + void shouldContainCommandId() { + callListener(); + + verify(publisher).publishEvent(event.capture()); + assertThat(event.getValue().getSource()).isEqualTo(CommandTestFactory.ID); + assertThat(event.getValue().getErrorMessage()).isEqualTo(ERROR_MESSAGE); + } + + @Test + void shouldContainMessage() { + callListener(); + + verify(publisher).publishEvent(event.capture()); + assertThat(event.getValue().getErrorMessage()).isEqualTo(ERROR_MESSAGE); + } + } + + private void callListener() { + listener.onSetAktenzeichen(CommandCreatedEventTestFactory.create(SET_AKTENZEICHEN_COMMAND)); + } + } + +} \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeadTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeadTestFactory.java new file mode 100644 index 0000000..4bc3eb8 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeadTestFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; + +public class VorgangHeadTestFactory { + + public static VorgangHead create() { + return createBuilder().build(); + } + + public static VorgangHead.VorgangHeadBuilder createBuilder() { + return VorgangHead.builder() + .serviceKonto(ServiceKontoTestFactory.create()); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryITCase.java similarity index 51% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryITCase.java index b411024..026a430 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; @@ -46,19 +46,22 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; -import de.itvsh.ozg.pluto.clientattribute.ClientAttribute; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeMap; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeTestFactory; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMap; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.FindVorgangRequest.OrderCriteria; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.callcontext.UserTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeMap; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.common.GrpcQueryOperator; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import de.ozgcloud.vorgang.common.operator.OperatorBuilder; +import de.ozgcloud.vorgang.vorgang.FindVorgangQuery.LogicalOperator; +import de.ozgcloud.vorgang.vorgang.FindVorgangRequest.OrderCriteria; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; @DataITCase class VorgangHeaderRepositoryITCase { - static final String CLIENT_ATTRIBUTE_NEXT_WIEDERVORLAGE_FRIST = "nextWiedervorlageFrist"; @Autowired private VorgangHeaderRepository repository; @@ -78,35 +81,62 @@ class VorgangHeaderRepositoryITCase { .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().build()) .searchBy(StringUtils.EMPTY).build(); + @Test + void shouldSortExpiredWiedervorlagenByFrist() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("2") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(2, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(3, ChronoUnit.DAYS))).build()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(2).extracting(VorgangHeader::getId).containsExactly("1", "2"); + } + + // based on OZG-1991 + @DisplayName("should sort vorgaenge with expired wiedervorlage by frist even if another wiedervorlage is done") + @Test + void shouldSortExpiredWiedervorlagenByFristWithDoneWidervorlage() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(3, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(2, ChronoUnit.DAYS))).build()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(3).extracting(VorgangHeader::getId).containsExactly("1", "3", "2"); + } + @ParameterizedTest - @EnumSource(mode = Mode.EXCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG", "BESCHIEDEN", "WEITERGELEITET" }) - void shouldContainRemainingStatus(Status status) { - mongoOperations.save(VorgangTestFactory.createBuilder().id(null).status(status).build()); + @EnumSource(mode = Mode.INCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG" }) + void shouldSortZuBearbeitenAfterExpiredWdvlg(Status status) { + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(status).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(2, ChronoUnit.DAYS))).build()); var vorgaenge = repository.findAll(request).getContent(); - assertThat(vorgaenge).hasSize(1); + assertThat(vorgaenge).hasSize(2).extracting(VorgangHeader::getId).containsExactly("1", "2"); } @Test - void shouldPageableResultByGivenLimit() { - mongoOperations.save(VorgangTestFactory.createBuilder().id(String.valueOf("1")).build()); - mongoOperations.save(VorgangTestFactory.createBuilder().id(String.valueOf("2")).build()); + void shouldSortOpenWdvlgAfterZuBearbeiten() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("3") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(3, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(2, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(Status.NEU).build()); - var request = FindVorgangRequestTestFactory.createBuilder() - .orderBy(OrderCriteria.PRIORITY) - .filterBy(null).searchBy(StringUtils.EMPTY) - .limit(1) - .offset(0) - .build(); var vorgaenge = repository.findAll(request).getContent(); - assertThat(vorgaenge).hasSize(1); + assertThat(vorgaenge).hasSize(3).extracting(VorgangHeader::getId).containsExactly("1", "2", "3"); } @Test void shouldSortZurBearbeitungByCreatedAt() { - mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(Status.NEU).createdAt(ZonedDateTime.now()).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(Status.NEU) + .createdAt(ZonedDateTime.now()).build()); mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(Status.IN_BEARBEITUNG) .createdAt(ZonedDateTime.now().minus(1, ChronoUnit.DAYS)).build()); @@ -115,6 +145,33 @@ class VorgangHeaderRepositoryITCase { assertThat(vorgaenge).hasSize(2).extracting(VorgangHeader::getId).containsExactly("1", "2"); } + @Test + void shouldSortOpendWdvlgIgnoringClosedWdvlg() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").createdAt(ZonedDateTime.now().minus(2, ChronoUnit.DAYS)) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(4, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3").createdAt(ZonedDateTime.now().minus(2, ChronoUnit.DAYS)).build()); + + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").createdAt(ZonedDateTime.now().minus(1, ChronoUnit.DAYS)) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(3, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("4").createdAt(ZonedDateTime.now().minus(1, ChronoUnit.DAYS)).build()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(4).extracting(VorgangHeader::getId).containsExactly("3", "4", "1", "2"); + } + + @ParameterizedTest + @EnumSource(mode = Mode.INCLUDE, names = { "BESCHIEDEN", "WEITERGELEITET" }) + void shouldSortBearbeitetAfterWdvlg(Status status) { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(2, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(status).build()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(2).extracting(VorgangHeader::getId).containsExactly("1", "2"); + } + @ParameterizedTest @EnumSource(mode = Mode.INCLUDE, names = { "BESCHIEDEN", "WEITERGELEITET" }) void shouldReturnBearbeitetOnlyOnce(Status status) { @@ -125,144 +182,187 @@ class VorgangHeaderRepositoryITCase { assertThat(vorgaenge).hasSize(1); } - @Nested - class sortOrder { - final FindVorgangRequest request = FindVorgangRequestTestFactory.createBuilder() - .orderBy(OrderCriteria.PRIORITY) - .filterBy(FilterCriteriaTestFactory.createBuilder().clearStatus().build()) - .searchBy(StringUtils.EMPTY).build(); + // Zeigt den Bug von OZG-3156 + @ParameterizedTest + @EnumSource + void shouldReturnWithWdvlgOnlyOnce(Status status) { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(status) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(2, ChronoUnit.DAYS))).build()); - @BeforeEach - void init() { - mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); - mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + var vorgaenge = repository.findAll(request).getContent(); - mongoOperations.save(VorgangTestFactory.createBuilder().id("4").status(Status.ABGESCHLOSSEN) - .createdAt(ZonedDateTime.now().minusDays(2)).build()); - mongoOperations.save(VorgangTestFactory.createBuilder().id("3").status(Status.NEU) - .createdAt(ZonedDateTime.now().minusDays(2)).build()); - mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(Status.IN_BEARBEITUNG) - .createdAt(ZonedDateTime.now().minusDays(3)).build()); - mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(Status.IN_BEARBEITUNG) - .createdAt(ZonedDateTime.now().minusDays(4)).build()); - mongoOperations.save(VorgangTestFactory.createBuilder().id("9").createdAt(ZonedDateTime.now().minusDays(1)) - .status(Status.BESCHIEDEN).build()); - - mongoOperations.save(VorgangTestFactory.createBuilder().id("5").createdAt(ZonedDateTime.now().minusDays(1)) - .clientAttributes(buildClientAttribute(30, false)).build()).getId(); - mongoOperations.save(VorgangTestFactory.createBuilder().id("6").createdAt(ZonedDateTime.now().minusDays(1)) - .clientAttributes(buildClientAttribute(300, true)).build()).getId(); - mongoOperations.save(VorgangTestFactory.createBuilder().id("7").createdAt(ZonedDateTime.now().minusDays(1)) - .clientAttributes(buildClientAttribute(5, false)).build()).getId(); - mongoOperations.save(VorgangTestFactory.createBuilder().id("8").createdAt(ZonedDateTime.now().minusDays(1)) - .clientAttributes(buildClientAttribute(10, true)).build()).getId(); + assertThat(vorgaenge).hasSize(1); + } - } + @ParameterizedTest + @EnumSource(mode = Mode.EXCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG", "BESCHIEDEN", "WEITERGELEITET" }) + void shouldContainRemainingStatus(Status status) { + mongoOperations.save(VorgangTestFactory.createBuilder().id(null).status(status).build()); - private ClientAttributesMap buildClientAttribute(int deltaDays, boolean isMinus) { - ClientAttribute attribute; - ClientAttribute.ClientAttributeBuilder builder = ClientAttributeTestFactory.createBuilder() - .clientName(VorgangHeaderRepositoryImpl.DEFAULT_CLIENT) - .attributeName(CLIENT_ATTRIBUTE_NEXT_WIEDERVORLAGE_FRIST); - if (isMinus) { - attribute = builder.stringValue(Optional.of(LocalDate.now().minusDays(deltaDays).toString())).build(); - } else { - attribute = builder.stringValue(Optional.of(LocalDate.now().plusDays(deltaDays).toString())).build(); - } + var vorgaenge = repository.findAll(request).getContent(); - var attributeMap = new ClientAttributeMap(); - List.of(attribute).stream().forEach(attrib -> attributeMap.put(attrib.getAttributeName(), attrib)); - ClientAttributesMap attributesMap = new ClientAttributesMap(); - attributesMap.put(attribute.getClientName(), attributeMap); + assertThat(vorgaenge).hasSize(1); + } - return attributesMap; - } + @Test + void shouldPageableResultByGivenLimit() { + mongoOperations.save(VorgangTestFactory.createBuilder().id(String.valueOf("1")).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id(String.valueOf("2")).build()); - @Nested - class rang1 { - @Test - @DisplayName("Position 0: Vorgang von vor 1 Tagen mit Status 'NEU' und offener Wiedervorlage mit Frist vor 300 Tagen") - void vorgangWithStatusNeuAndOpenWiedervorlageAtPostion0() { - var vorgaenge = repository.findAll(request).getContent(); + var request = FindVorgangRequestTestFactory.createBuilder() + .orderBy(OrderCriteria.PRIORITY) + .filterBy(null).searchBy(StringUtils.EMPTY) + .limit(1) + .offset(0) + .build(); + var vorgaenge = repository.findAll(request).getContent(); - assertThat(vorgaenge.get(0).getId()).isEqualTo("6"); - } + assertThat(vorgaenge).hasSize(1); + } - @Test - @DisplayName("Position 1: Vorgang von vor 1 Tagen mit Status 'NEU' und offener Wiedervorlage mit Frist vor 10 Tagen") - void vorgangWithStatusNeuAndOpenWiedervorlageAtPostion1() { - var vorgaenge = repository.findAll(request).getContent(); + @Test + void shouldConsiderWiedervorlageDone() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(2, ChronoUnit.DAYS))).build()); - assertThat(vorgaenge.get(1).getId()).isEqualTo("8"); - } - } + var vorgaenge = repository.findAll(request).getContent(); - @Nested - class rang2 { - @Test - @DisplayName("Position 2: Vorgang von vor 5 Tagen mit Status 'IN_BEARBEITUNG' und ohne Wiedervorlage") - void vorgangWithStatusInBearbeitungWithoutWiedervorlageAtPostion4() { - var vorgaenge = repository.findAll(request).getContent(); + assertThat(vorgaenge).hasSize(2); + assertThat(vorgaenge.get(0).getId()).isEqualTo("2"); + assertThat(vorgaenge.get(1).getId()).isEqualTo("1"); + } - assertThat(vorgaenge.get(2).getId()).isEqualTo("1"); - } + // based on OZG-1822 + @Test + void shouldShowVorgangWithDoneAndOpenWiedervorlage() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(1, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").build()); - @Test - @DisplayName("Position 3: Vorgang von vor 3 Tagen mit Status 'IN_BEARBEITUNG' und ohne Wiedervorlage") - void vorgangWithStatusInBearbeietungWithoutWiedervorlageAtPostion5() { - var vorgaenge = repository.findAll(request).getContent(); + var vorgaenge = repository.findAll(request).getContent(); - assertThat(vorgaenge.get(3).getId()).isEqualTo("2"); - } + assertThat(vorgaenge).hasSize(2).extracting(VorgangHeader::getId).containsExactly("2", "1"); + } - @Test - @DisplayName("Position 4: Vorgang von vor 2 Tagen mit Status 'NEU' und ohne Wiedervorlage") - void vorgangWithStatusNeuWithoutWiedervorlageAtPostion6() { - var vorgaenge = repository.findAll(request).getContent(); + // based on OZG-1826, OZG-1885 + @DisplayName("should show Vorgang with expired Wdvlg only once.") + @ParameterizedTest + @EnumSource + void shouldShowExpiredWdvlgOnlyOnce(Status status) { + mongoOperations.save(VorgangTestFactory.createBuilder().id(null).status(Status.NEU).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id(null).status(status) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(1, ChronoUnit.DAYS))) + .build()); - assertThat(vorgaenge.get(4).getId()).isEqualTo("3"); - } + var vorgaenge = repository.findAll(request).getContent(); - @Test - @DisplayName("Position 5: Vorgang von vor 1 Tagen mit Status 'NEU' und offener Wiedervorlage mit Frist in 5 Tagen") - void vorgangWithStatusNeuAndOpenWiedervorlageAtPostion3() { - var vorgaenge = repository.findAll(request).getContent(); + assertThat(vorgaenge).hasSize(2); + } + } - assertThat(vorgaenge.get(5).getId()).isEqualTo("7"); - } + @DisplayName("Sort createdAt desc") + @Nested + class TestSortCreatedAtDesc { - @Test - @DisplayName("Position 6: Vorgang von vor 1 Tagen mit Status 'NEU' und offener Wiedervorlage mit Frist in 30 Tagen") - void vorgangWithStatusNeuAndOpenWiedervorlageAtPostion2() { - var vorgaenge = repository.findAll(request).getContent(); + @DisplayName("with single status filter criteria") + @Nested + class TestWithSingleStatusCriteria { - assertThat(vorgaenge.get(6).getId()).isEqualTo("5"); - } + @BeforeEach + void prepareDatabase() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(2, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(3, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(4, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("4").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(5, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("5").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(6, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("6").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(7, ChronoUnit.DAYS)).build()); } - @Nested - class rang3 { - @Test - @DisplayName("Position 7: Vorgang von vor 1 Tagen mit Status 'BESCHIEDEN'") - void vorgangWithStatusBeschiedenAtPostion7() { - var vorgaenge = repository.findAll(request).getContent(); + @Test + void shouldReturnSortedVorgaenge() { + var request = buildRequestWithFilterCriteria(FilterCriteriaTestFactory.createBuilder().assignedTo(null).build()); - assertThat(vorgaenge.get(7).getId()).isEqualTo("9"); - } + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(6).extracting(VorgangHeader::getId).containsExactly("1", "2", "3", "4", "5", "6"); } + } - @Nested - class rang4 { - @Test - @DisplayName("Position 8: Vorgang von vor 2 Tagen mit Status 'ABGESCHLOSSEN' ohne Wiedervorlage") - void vorgangWithStatusAbgeschlossenWithoutWiedervorlageAtPostion8() { - var vorgaenge = repository.findAll(request).getContent(); + @DisplayName("with single status and assignedTo filter criteria") + @Nested + class TestWithSingleStatusAndAssignedToCriteria { - assertThat(vorgaenge.get(8).getId()).isEqualTo("4"); - } + @BeforeEach + void prepareDatabase() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(2, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(3, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(4, ChronoUnit.DAYS)) + .assignedTo(null) + .build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("4").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(5, ChronoUnit.DAYS)).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("5").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(6, ChronoUnit.DAYS)) + .assignedTo(null) + .build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("6").status(Status.NEU) + .createdAt(ZonedDateTime.now().minus(7, ChronoUnit.DAYS)).build()); } + + @Test + void shouldReturnSortedVorgaenge() { + var request = buildRequestWithFilterCriteria(FilterCriteriaTestFactory.create()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(4).extracting(VorgangHeader::getId).containsExactly("1", "2", "4", "6"); + } + } + + private FindVorgangRequest buildRequestWithFilterCriteria(FilterCriteria filterCriteria) { + return FindVorgangRequestTestFactory.createBuilder() + .orderBy(OrderCriteria.CREATED_AT_DESC) + .filterBy(filterCriteria) + .searchBy(StringUtils.EMPTY).build(); + } + } + + @DisplayName("Sort hasNextWiedervorlageFrist") + @Nested + class TestSortHasNextWiedervorlageFrist { + + @Test + void shouldReturnSortedVorgaenge() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("2") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now())).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(1, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(1, ChronoUnit.DAYS))).build()); + + var request = buildRequestWithFilterCriteria(FilterCriteria.builder().build()); + + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(3).extracting(VorgangHeader::getId).containsExactly("3", "2", "1"); } + private FindVorgangRequest buildRequestWithFilterCriteria(FilterCriteria filterCriteria) { + return FindVorgangRequestTestFactory.createBuilder() + .orderBy(OrderCriteria.NEXT_WIEDERVORLAGE_FRIST) + .filterBy(filterCriteria) + .searchBy(StringUtils.EMPTY).build(); + } } @Nested @@ -378,6 +478,24 @@ class VorgangHeaderRepositoryITCase { assertThat(vorgaenge).hasSize(1); assertThat(vorgaenge.get(0).getId()).isEqualTo("1"); } + + @Test + void shouldHaveVorgaengeIgnoringWdvl() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(3, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().minus(3, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("3").build()); + + var request = FindVorgangRequestTestFactory.createBuilder() + .orderBy(OrderCriteria.EA_PRIORITY) + .filterBy(null) + .searchBy(StringUtils.EMPTY) + .build(); + var vorgaenge = repository.findAll(request).getContent(); + + assertThat(vorgaenge).hasSize(3).extracting(VorgangHeader::getId).containsExactly("1", "2", "3"); + } } @Nested @@ -416,6 +534,47 @@ class VorgangHeaderRepositoryITCase { assertThat(vorgangHeaderPage.getTotalPages()).isEqualTo(1); } } + + @Nested + class TestVorgangWithWiedervorlagen { + + @BeforeEach + void prepareDatabase() { + mongoOperations.dropCollection(Vorgang.class); + + mongoOperations.save(buildWithOrganisationseinheitId(organisationseinheitenId)); + mongoOperations.save(VorgangTestFactory.createBuilder().id(null) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(2, ChronoUnit.DAYS))) + .build()); + } + + @Test + void shouldFilterByDefaultId() { + var vorgangHeaderPage = repository.findAll(request); + + assertThat(vorgangHeaderPage.getTotalElements()).isEqualTo(1); + } + + @Test + void shouldFilterByGivenId() { + var filterCriteria = FilterCriteriaTestFactory.createBuilder().clearOrganisationseinheitIds() + .organisationseinheitId(organisationseinheitenId).build(); + var vorgangHeaderPage = repository.findAll(createRequestWithFilterBy(filterCriteria)); + + assertThat(vorgangHeaderPage.getTotalElements()).isEqualTo(1); + } + + @Test + void shouldHaveJustOneVorgangStatusNeu() { + mongoOperations.dropCollection(Vorgang.class); + mongoOperations.save(VorgangTestFactory.createBuilder() + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(2, ChronoUnit.DAYS))).build()); + + var vorgangHeaderPage = repository.findAll(request); + + assertThat(vorgangHeaderPage.getTotalElements()).isEqualTo(1); + } + } } @Nested @@ -524,8 +683,10 @@ class VorgangHeaderRepositoryITCase { @Nested class TestAssignedTo { - private final FilterCriteria.FilterCriteriaBuilder filterCriteriaBuilder = FilterCriteria.builder() - .filterByOrganisationseinheitenId(false); + private final FilterCriteria.FilterCriteriaBuilder filterCriteriaBuilder = FilterCriteriaTestFactory.createBuilder() + .filterByOrganisationseinheitenId(false) + .clearStatus() + .clearOrganisationseinheitIds(); @BeforeEach void initVorgaenge() { @@ -556,7 +717,7 @@ class VorgangHeaderRepositoryITCase { @DisplayName("should return an unfiltered list if there is an empty assignedTo string") @Test void shouldReturnUnfilteredListOnEmpty() { - var emptyFilterCriteria = filterCriteriaBuilder.assignedTo(StringUtils.EMPTY).build(); + var emptyFilterCriteria = filterCriteriaBuilder.filterByAssignedTo(false).assignedTo(StringUtils.EMPTY).build(); var page = repository.findAll(createRequestWithFilterBy(emptyFilterCriteria)); @@ -572,6 +733,71 @@ class VorgangHeaderRepositoryITCase { assertThat(page.getTotalElements()).isEqualTo(2); } + + @Test + void shouldReturnUnassignedVorgang() { + var filterCriteria = filterCriteriaBuilder.assignedTo(StringUtils.EMPTY).build(); + + var page = repository.findAll(createRequestWithFilterBy(filterCriteria)); + + assertThat(page.getTotalElements()).isEqualTo(1); + } + } + + @DisplayName("Has next wiedervorlage frist") + @Nested + class TestHasNextWiedervorlageFrist { + + @Test + void shouldHaveTotalElements() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(1, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id("2").clientAttributes(null).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()); + + var vorgaenge = repository.findAll(createRequestWithFilterBy(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(true).build())); + + assertThat(vorgaenge.getTotalElements()).isEqualTo(1); + } + + @Test + void shouldReturnWhereNextWiedervorlageExistsOnly() { + mongoOperations.save(VorgangTestFactory.createBuilder().id(null) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now())).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().clientAttributes(null).id(null).build()); + + var vorgaenge = repository.findAll(createRequestWithFilterBy(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(true).build())); + + assertThat(vorgaenge.getContent()).hasSize(1); + } + + @Nested + class TestWithFindVorgangQuery { + + @Test + void shouldReturnWhereNextWiedervorlageExistsOnly() { + mongoOperations.save(VorgangTestFactory.createBuilder().id(null) + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now())).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().clientAttributes(null).id(null).build()); + + var vorgaenge = repository.findAll(createFindVorgangRequest()); + + assertThat(vorgaenge.getContent()).hasSize(1); + } + + private FindVorgangRequest createFindVorgangRequest() { + return FindVorgangRequestTestFactory.createBuilder() + .searchBy(StringUtils.EMPTY) + .findVorgangQuery(FindVorgangQuery.builder() + .logicalOperator(LogicalOperator.AND) + .operator(OperatorBuilder + .from(GrpcQueryOperator.EXISTS) + .fieldPath("ClientAttribute.Alfa.nextWiedervorlageFrist") + .build()) + .build()) + .build(); + } + } } private Page<VorgangHeader> callRepositoryFindAll(FindVorgangRequest request) { @@ -583,6 +809,17 @@ class VorgangHeaderRepositoryITCase { return FindVorgangRequestTestFactory.createBuilder().searchBy(StringUtils.EMPTY).filterBy(filterBy).build(); } + private ClientAttributesMap createClientAttributesMapWithWiedervorlageNextFrist(LocalDate nextFrist) { + return ClientAttributesMapTestFactory.createWithAttribute(buildWiedervorlageNextFristClientAttribute(nextFrist)); + } + + private ClientAttribute buildWiedervorlageNextFristClientAttribute(LocalDate nextFrist) { + return ClientAttributeTestFactory.createBuilder() + .clientName(CriteriaUtil.DEFAULT_CLIENT) + .attributeName(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST) + .stringValue(Optional.of(nextFrist.toString())).build(); + } + private Vorgang buildWithOrganisationseinheitId(String organisationseinheitenId) { var eingang = buildEingangWithOrganisationseinheitenId(organisationseinheitenId); return VorgangTestFactory.createBuilder().id(null).clearEingangs().eingang(eingang).build(); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplITCase.java similarity index 64% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplITCase.java index e49607b..53ade4a 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.Optional; import java.util.UUID; import org.apache.commons.lang3.StringUtils; @@ -36,8 +39,13 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Query; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.clientattribute.ClientAttribute; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeTestFactory; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMapTestFactory; +import de.ozgcloud.vorgang.common.db.CriteriaUtil; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; @DataITCase class VorgangHeaderRepositoryImplITCase { @@ -68,6 +76,15 @@ class VorgangHeaderRepositoryImplITCase { assertThat(countTotalVorgaenge(query)).isZero(); } + @Test + void shouldIgnoreDELETEDVorgang() { + mongoOperations.save(VorgangTestFactory.createBuilder().status(Status.DELETED).build()); + + var query = buildFilterQuery(FilterCriteriaTestFactory.createBuilder().clearStatus().build()); + + assertThat(countTotalVorgaenge(query)).isZero(); + } + @Nested class TestWithOrganisationseinheitenIdFilter { @@ -101,6 +118,9 @@ class VorgangHeaderRepositoryImplITCase { @Nested class TestWithAssignedToFilter { + private final FilterCriteria.FilterCriteriaBuilder filterCriteriaBuilder = FilterCriteriaTestFactory.createBuilder() + .clearStatus().clearOrganisationseinheitIds(); + @BeforeEach void initData() { mongoOperations.save(VorgangTestFactory.createBuilder().id(null).assignedTo(USER_ID).status(Status.NEU).build()); @@ -109,14 +129,14 @@ class VorgangHeaderRepositoryImplITCase { @Test void shouldReturnTotalOnAssignedTo() { - var query = buildFilterQuery(FilterCriteria.builder().assignedTo(USER_ID).build()); + var query = buildFilterQuery(filterCriteriaBuilder.assignedTo(USER_ID).build()); assertThat(countTotalVorgaenge(query)).isEqualTo(1); } @Test void shouldReturnUnfilteredList() { - var query = buildFilterQuery(FilterCriteria.builder().assignedTo(StringUtils.EMPTY).build()); + var query = buildFilterQuery(filterCriteriaBuilder.filterByAssignedTo(false).assignedTo(StringUtils.EMPTY).build()); assertThat(countTotalVorgaenge(query)).isEqualTo(2); } @@ -146,6 +166,42 @@ class VorgangHeaderRepositoryImplITCase { } } + @Nested + class TestWithHasNextWiedervorlageFristFilter { + + @BeforeEach + void initData() { + mongoOperations.save(VorgangTestFactory.createBuilder().id("1") + .clientAttributes(createClientAttributesMapWithWiedervorlageNextFrist(LocalDate.now().plus(1, ChronoUnit.DAYS))).build()); + mongoOperations.save(VorgangTestFactory.createBuilder().id(null).status(Status.NEU).build()); + } + + private ClientAttributesMap createClientAttributesMapWithWiedervorlageNextFrist(LocalDate nextFrist) { + return ClientAttributesMapTestFactory.createWithAttribute(buildWiedervorlageNextFristClientAttribute(nextFrist)); + } + + private ClientAttribute buildWiedervorlageNextFristClientAttribute(LocalDate nextFrist) { + return ClientAttributeTestFactory.createBuilder() + .clientName(CriteriaUtil.DEFAULT_CLIENT) + .attributeName(CriteriaUtil.CLIENT_ATTRIBUT_NEXT_WIEDERVORLAGE_FRIST) + .stringValue(Optional.of(nextFrist.toString())).build(); + } + + @Test + void shouldReturnTotalOnStatus() { + var query = buildFilterQuery(FilterCriteria.builder().hasNextWiedervorlageFrist(true).build()); + + assertThat(countTotalVorgaenge(query)).isEqualTo(1); + } + + @Test + void shouldReturnUnfilteredList() { + var query = buildFilterQuery(FilterCriteria.builder().clearStatus().build()); + + assertThat(countTotalVorgaenge(query)).isEqualTo(2); + } + } + private Query buildFilterQuery(FilterCriteria filterCriteria) { return repositoryImpl.buildFilterQuery(filterCriteria); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplTest.java similarity index 94% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplTest.java index 9e72f01..52775fb 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderRepositoryImplTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderRepositoryImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java similarity index 65% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java index da5477e..67068a4 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collections; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; @@ -38,12 +39,16 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import de.ozgcloud.common.errorhandling.TechnicalException; + class VorgangHeaderServiceTest { @InjectMocks + @Spy private VorgangHeaderService service; @Mock private VorgangHeaderRepository repository; @@ -113,4 +118,58 @@ class VorgangHeaderServiceTest { .build(); } } + + @Nested + class TestFindById { + + @Test + void shouldCallRepository() { + service.findById(VorgangTestFactory.ID); + + verify(repository).findById(VorgangTestFactory.ID); + } + + @Test + void shouldReturnRepositoryResult() { + var repositoryResult = Optional.of(VorgangHeaderTestFactory.create()); + when(repository.findById(VorgangTestFactory.ID)).thenReturn(repositoryResult); + + var serviceResult = service.findById(VorgangTestFactory.ID); + + assertThat(serviceResult).isEqualTo(repositoryResult); + } + } + + @Nested + class TestGEtById { + + @Test + void shouldCallFindById() { + doReturn(Optional.of(VorgangHeaderTestFactory.create())).when(service).findById(VorgangTestFactory.ID); + + service.getById(VorgangTestFactory.ID); + + verify(service).findById(VorgangTestFactory.ID); + } + + @Test + void shouldReturnVorgangHeader() { + var expectedVorgangHeader = VorgangHeaderTestFactory.create(); + doReturn(Optional.of(expectedVorgangHeader)).when(service).findById(VorgangTestFactory.ID); + + var vorgangHeader = service.getById(VorgangTestFactory.ID); + + assertThat(vorgangHeader).isEqualTo(expectedVorgangHeader); + } + + @Test + @DisplayName("should throw exception if VorgangHeader could not be found") + void shouldThrowException() { + doReturn(Optional.empty()).when(service).findById(VorgangTestFactory.ID); + + assertThatThrownBy(() -> service.getById(VorgangTestFactory.ID)) + .isInstanceOf(TechnicalException.class) + .hasMessageContaining(VorgangTestFactory.ID + " could not be found"); + } + } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderTestFactory.java similarity index 88% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderTestFactory.java index 94bb2b3..c394473 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangHeaderTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangHeaderTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; -import static de.itvsh.ozg.pluto.vorgang.VorgangTestFactory.*; +import static de.ozgcloud.vorgang.vorgang.VorgangTestFactory.*; public class VorgangHeaderTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangITCase.java similarity index 62% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangITCase.java index 76c21ca..299c396 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import java.util.List; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -43,12 +41,14 @@ import org.springframework.context.annotation.Primary; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.PlutoServerApplication; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.VorgangManagerServerApplication; +import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; import io.grpc.stub.StreamObserver; @DataITCase -@SpringBootTest(classes = { PlutoServerApplication.class, TestConfig.class }) +@SpringBootTest(classes = { VorgangManagerServerApplication.class, TestConfig.class }) class VorgangITCase { @Autowired @@ -56,108 +56,168 @@ class VorgangITCase { @Autowired private MongoOperations mongoOperations; + @DisplayName("Create vorgang") @Nested class TestCreateVorgang { - @Mock - private StreamObserver<GrpcCreateVorgangResponse> responseObserver; - @Captor - private ArgumentCaptor<GrpcCreateVorgangResponse> responseCaptor; + @DisplayName("start creation") + @Nested + class TestStartCreation { - private final GrpcCreateVorgangRequest request = GrpcCreateVorgangRequestTestFactory.create(); + @Mock + private StreamObserver<GrpcCreateVorgangResponse> responseObserver; + @Captor + private ArgumentCaptor<GrpcCreateVorgangResponse> responseCaptor; - @BeforeEach - void dropVorgangCollection() { - mongoOperations.dropCollection(Vorgang.class); - } + private final GrpcEingang eingangWithoutFiles = GrpcEingangTestFactory.createBuilder().clearAttachments().clearRepresentations().build(); + private final GrpcCreateVorgangRequest request = GrpcCreateVorgangRequestTestFactory.createBuilder().clearEingang() + .setEingang(eingangWithoutFiles).build(); - @Test - void verifyGrpcResponseMessage() { - var grpcResponse = doCreateVorgangServiceCall(); + @BeforeEach + void dropVorgangCollection() { + mongoOperations.dropCollection(Vorgang.class); + } - assertThat(grpcResponse.getMessage()).isEqualTo("ok"); - } + @Test + void verifyGrpcResponseMessage() { + var grpcResponse = doCreateVorgangServiceCall(); - @Test - void shouldHaveEingang() { - doCreateVorgangServiceCall(); + assertThat(grpcResponse.getMessage()).isEqualTo("ok"); + assertThat(grpcResponse.getVorgangId()).isNotNull(); + } - List<Vorgang> vorgangs = mongoOperations.findAll(Vorgang.class); + @Test + void shouldHaveEingang() { + doCreateVorgangServiceCall(); - assertThat(vorgangs).hasSize(1); - assertThat(vorgangs.get(0).getEingangs()).hasSize(1); - } + var vorgaenge = mongoOperations.findAll(Vorgang.class); - @Nested - class TestAttachments { + assertThat(vorgaenge).hasSize(1).extracting(Vorgang::getEingangs).hasSize(1); + } @Test - void numberOfAttachments() { + void shouldHaveNumberOfAttachments() { doCreateVorgangServiceCall(); - var eingang = getFirstEingang(); - assertThat(eingang.getNumberOfAttachments()).isEqualTo(4); + assertThat(getFirstEingang().getNumberOfAttachments()).isEqualTo(4); } @Test - void numberOfAttachmentGroups() { + void shouldHaveNumerOfRepresentations() { doCreateVorgangServiceCall(); - var eingang = getFirstEingang(); - assertThat(eingang.getAttachments()).hasSize(1); + assertThat(getFirstEingang().getNumberOfRepresentations()).isEqualTo(5); } - @Test - void validateFirstAttachmentOfFirstGroup() { - doCreateVorgangServiceCall(); - var eingang = getFirstEingang(); + @DisplayName("With service konto") + @Nested + class TestWithServiceKonto { + + @Test + void shouldHaveServiceKonto() { + doCreateVorgangServiceCall(); + + var serviceKonto = getVorgang().getHeader().getServiceKonto(); + assertThat(serviceKonto).isNotNull(); + assertThat(serviceKonto.getType()).isEqualTo(ServiceKontoTestFactory.TYPE); + assertThat(serviceKonto.getPostfachAddresses()).hasSize(1); + } + + } + + private GrpcCreateVorgangResponse doCreateVorgangServiceCall() { + service.startCreation(request, responseObserver); + verify(responseObserver).onNext(responseCaptor.capture()); - assertThat(eingang.getAttachments().get(0).getFiles().get(0)).usingRecursiveComparison().isEqualTo(IncomingFileTestFactory.create()); + return responseCaptor.getValue(); } } + @DisplayName("finish creation") @Nested - class TestRepresentations { + class TestFinishCreation { - private Eingang eingang; + @Mock + private StreamObserver<GrpcFinishCreationResponse> responseObserver; + @Captor + private ArgumentCaptor<GrpcFinishCreationResponse> responseCaptor; - @BeforeEach - void doCall() { - doCreateVorgangServiceCall(); - } + private GrpcFinishCreationRequest request; + + private String vorgangId; + + private final Eingang eingangWithoutFiles = EingangTestFactory.createBuilder().clearAttachments().clearRepresentations().build(); + private final Vorgang vorgang = VorgangTestFactory.createBuilder().clearEingangs().eingang(eingangWithoutFiles) + .clientAttributes(new ClientAttributesMap()).build(); @BeforeEach - void getEingang() { - eingang = getFirstEingang(); + void init() { + mongoOperations.dropCollection(Vorgang.class); + vorgangId = mongoOperations.save(vorgang).getId(); + request = GrpcFinishCreationRequestTestFactory.createBuilder().setVorgangId(vorgangId).build(); } @Test - void shouldHaveRepresentations() { - assertThat(eingang.getRepresentations()).hasSize(1); + void verifyGrpcResponseMessage() { + var grpcResponse = doCreateVorgangServiceCall(); + + assertThat(grpcResponse.getMessage()).isEqualTo("ok"); } - @Test - void shouldHaveNumerOfRepresentations() { - assertThat(eingang.getNumberOfRepresentations()).isEqualTo(5); + @DisplayName("attachments") + @Nested + class TestAttachments { + + @Test + void shouldExists() { + doCreateVorgangServiceCall(); + + assertThat(getFirstEingang().getAttachments()).hasSize(1); + } + + @Test + void shouldHaveFile() { + doCreateVorgangServiceCall(); + + var attachment = getFirstEingang().getAttachments().get(0).getFiles().get(0); + assertThat(attachment).usingRecursiveComparison().isEqualTo(IncomingFileTestFactory.create()); + } } - @Test - void shouldHaveIncomingFile() { - IncomingFile incomingFile = eingang.getRepresentations().get(0); + @DisplayName("representations") + @Nested + class TestRepresentations { + + @Test + void shouldExists() { + doCreateVorgangServiceCall(); - assertThat(incomingFile).usingRecursiveComparison().isEqualTo(IncomingFileTestFactory.create()); + assertThat(getFirstEingang().getRepresentations()).hasSize(1); + } + + @Test + void shouldHaveFile() { + doCreateVorgangServiceCall(); + + var representation = getFirstEingang().getRepresentations().get(0); + assertThat(representation).usingRecursiveComparison().isEqualTo(IncomingFileTestFactory.create()); + } + } + + private GrpcFinishCreationResponse doCreateVorgangServiceCall() { + service.finishCreation(request, responseObserver); + verify(responseObserver).onNext(responseCaptor.capture()); + + return responseCaptor.getValue(); } } private Eingang getFirstEingang() { - return mongoOperations.findAll(Vorgang.class).get(0).getEingangs().get(0); + return getVorgang().getEingangs().get(0); } - private GrpcCreateVorgangResponse doCreateVorgangServiceCall() { - service.createVorgang(request, responseObserver); - verify(responseObserver).onNext(responseCaptor.capture()); - - return responseCaptor.getValue(); + private Vorgang getVorgang() { + return mongoOperations.findAll(Vorgang.class).get(0); } } @@ -321,7 +381,7 @@ class VorgangITCase { class TestConfig { @Bean @Primary - public ApplicationEventPublisher mockEventPublisher() { + ApplicationEventPublisher mockEventPublisher() { return mock(ApplicationEventPublisher.class); } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java similarity index 62% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java index 860719b..f132237 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; +import java.util.ConcurrentModificationException; import java.util.List; import java.util.Map; import java.util.TimeZone; @@ -39,8 +41,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +import de.ozgcloud.common.test.DataITCase; @DataITCase class VorgangRepositoryITCase { @@ -109,7 +110,7 @@ class VorgangRepositoryITCase { } @Test - void shouldContainCorretTime() { + void shouldContainCorrectTime() { var persisted = repository .save(VorgangTestFactory.createBuilder().id(null).createdAt(ZonedDateTime.parse("2021-01-01T10:00:00+05:00")).build()); @@ -119,6 +120,13 @@ class VorgangRepositoryITCase { assertThat(loaded.getCreatedAt().format(DateTimeFormatter.ISO_DATE_TIME)).hasToString("2021-01-01T05:00:00Z"); } + @Test + void shouldNotLoadDeletedVorgang() { + mongoOperations.save(VorgangStubTestFactory.create()); + + assertThat(repository.findById(VorgangTestFactory.ID)).isEmpty(); + } + @Nested class TestLoadVorgangWithEingangSubForm { @@ -155,7 +163,7 @@ class VorgangRepositoryITCase { assertThat(loaded).isPresent(); var fieldValue = loaded.get().getEingangs().get(0).getFormData().get(EingangTestFactory.SINGLE_FIELD_NAME); - assertThat(fieldValue).isEqualTo(EingangTestFactory.SINGLE_FIELD_VALUE); + assertThat(fieldValue).isEqualTo(EingangTestFactory.SINGLE_FIELD); } @Test @@ -173,7 +181,6 @@ class VorgangRepositoryITCase { @BeforeEach void persistVorgang() { - mongoOperations.dropCollection(Vorgang.class); mongoOperations.save(VorgangTestFactory.create()); } @@ -191,8 +198,6 @@ class VorgangRepositoryITCase { @BeforeEach void init() { - mongoOperations.dropCollection(Vorgang.class); - repository.save(VorgangTestFactory.create()); } @@ -206,20 +211,33 @@ class VorgangRepositoryITCase { } @Nested - class TestUpdateStatus { - - @BeforeEach - void init() { - mongoOperations.dropCollection(Vorgang.class); + class TestFindAll { + @Test + void shouldFindVorgang() { mongoOperations.save(VorgangTestFactory.create()); + + var all = repository.findAll(); + + assertThat(all).hasSize(1); } @Test - void shouldLoadVorgang() { - repository.updateStatus(VorgangTestFactory.ID, VorgangTestFactory.VERSION, Status.IN_BEARBEITUNG); + void shouldNotFindVorgangInCreation() { + mongoOperations.save(VorgangTestFactory.createBuilder().inCreation(true).build()); + + var all = repository.findAll(); - assertThat(mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class).getStatus()).isEqualTo(Status.IN_BEARBEITUNG); + assertThat(all).isEmpty(); + } + + @Test + void shouldNotFindDELETEDVorgang() { + mongoOperations.save(VorgangStubTestFactory.create()); + + var all = repository.findAll(); + + assertThat(all).isEmpty(); } } @@ -235,29 +253,111 @@ class VorgangRepositoryITCase { mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()); } + @Test + void shouldNotExistsDELETEDVorgang() { + mongoOperations.save(VorgangTestFactory.createBuilder().status(Vorgang.Status.DELETED).build()); + + var exists = repository.exists(VorgangTestFactory.ID, Collections.singleton(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + + assertThat(exists).isFalse(); + } + @Nested class ByOrganisationEinheitenId { @Test void shouldReturnTrueOnMatch() { - var isPermitted = repository.exists(VorgangTestFactory.ID, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); + var exists = repository.exists(VorgangTestFactory.ID, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)); - assertThat(isPermitted).isTrue(); + assertThat(exists).isTrue(); } @Test void shouldReturnFalseOnNoMatch() { - var isPermitted = repository.exists(VorgangTestFactory.ID, List.of("quatsch")); + var exists = repository.exists(VorgangTestFactory.ID, List.of("quatsch")); - assertThat(isPermitted).isFalse(); + assertThat(exists).isFalse(); } @Test void shouldReturnFalseOnEmptyList() { - var isPermitted = repository.exists(VorgangTestFactory.ID, Collections.emptyList()); + var exists = repository.exists(VorgangTestFactory.ID, Collections.emptyList()); - assertThat(isPermitted).isFalse(); + assertThat(exists).isFalse(); } } } + + @Nested + class TestSaveStub { + @BeforeEach + void clearCollection() { + mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); + } + + @SuppressWarnings("unchecked") + @Test + void shouldOverwriteVorgang() { + mongoOperations.save(VorgangTestFactory.create()); + + repository.saveStub(VorgangStubTestFactory.create()); + + Map<String, Object> loaded = mongoOperations.findById(VorgangTestFactory.ID, Map.class, Vorgang.COLLECTION_NAME); + assertThat(loaded).hasSize(7); + } + + } + + @Nested + class TestSetAktenzeichen { + + @Test + void shouldSetAktenzeichen() { + mongoOperations.save(VorgangTestFactory.createBuilder().aktenzeichen(null).build()); + + repository.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.VERSION, VorgangTestFactory.AKTENZEICHEN); + + assertThat(getVorgang().getAktenzeichen()).isEqualTo(VorgangTestFactory.AKTENZEICHEN); + } + + @Test + void shouldUpdateAktenzeichen() { + mongoOperations.save(VorgangTestFactory.create()); + var newAktenzeichen = "newAktenzeichen"; + + repository.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.VERSION, newAktenzeichen); + + assertThat(getVorgang().getAktenzeichen()).isEqualTo(newAktenzeichen); + } + + @Test + void shouldResetAktenzeichen() { + mongoOperations.save(VorgangTestFactory.create()); + + repository.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.VERSION, null); + + assertThat(getVorgang().getAktenzeichen()).isNull(); + } + + @Test + void should() { + assertThat(mongoOperations.findAll(Vorgang.class)).isEmpty(); + + repository.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.VERSION, VorgangTestFactory.AKTENZEICHEN); + + assertThat(getVorgang()).isNull(); + } + + @Test + void shouldThrowExceptionByCollision() { + mongoOperations.save(VorgangTestFactory.createBuilder().aktenzeichen(null).build()); + + assertThrows(ConcurrentModificationException.class, + () -> repository.setAktenzeichen(VorgangTestFactory.ID, VorgangTestFactory.VERSION + 1, VorgangTestFactory.AKTENZEICHEN)); + } + + private Vorgang getVorgang() { + return mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); + } + } } \ No newline at end of file diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceITCase.java new file mode 100644 index 0000000..d99e591 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceITCase.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithMockUser; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.notification.antragsteller.AntragstellerNotificationEventListener; +import de.ozgcloud.notification.user.UserNotificationEventListener; +import de.ozgcloud.vorgang.command.CommandService; + +@DataITCase +@WithMockUser +class VorgangServiceITCase { + + @Autowired + private VorgangService vorgangService; + + @MockBean + private CommandService commandService; + + @MockBean + private AntragstellerNotificationEventListener antragstellerNotificationEventListener; + + @MockBean + private UserNotificationEventListener userNotificationEventListener; + + @DisplayName("Test creating a new Vorgang") + @Nested + class TestVorgangCreation { + @Test + void shouldStartCreateVorgang() { + var vorgang = vorgangService.startCreation(EingangTestFactory.create()); + + assertThat(vorgang.getId()).isNotNull(); + assertThat(vorgang.isInCreation()).isTrue(); + } + + @Test + void shouldFinishCreateVorgang() { + var vorgang = vorgangService.startCreation(EingangTestFactory.create()); + + vorgangService.finishCreation(vorgang.getId(), List.of(), List.of()); + + vorgang = vorgangService.getById(vorgang.getId()); + + assertThat(vorgang.isInCreation()).isFalse(); + verify(antragstellerNotificationEventListener).onVorgangCreated(any()); + verify(userNotificationEventListener).onVorgangCreated(any()); + } + } +} \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java similarity index 58% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java index 2e49d3d..f2e5e98 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -42,17 +42,15 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.security.access.AccessDeniedException; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeReadPermitted; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.VorgangCreatedEvent; -import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.redirect.ForwardingService; -import de.itvsh.ozg.pluto.vorgang.redirect.ForwardingTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeReadPermitted; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.common.errorhandling.NotFoundException; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; +import de.ozgcloud.vorgang.vorgang.redirect.ForwardingService; class VorgangServiceTest { @@ -64,129 +62,102 @@ class VorgangServiceTest { private VorgangRepository repository; @Mock private ForwardingService redirectService; - @Mock - private MongoOperations mongoOperations; + @Mock private ApplicationEventPublisher publisher; @Mock private AktenzeichenProvider aktenzeichenProvider; @Mock private VorgangAuthorizationService vorgangAuthorizationService; - @Mock private ClientAttributeReadPermitted readIsPermitted; @Captor private ArgumentCaptor<Vorgang> vorgangCaptor; - @Deprecated - @Nested - class TestCreateVorgang { + @Mock + private LabelProcessor kopControlDataMapper; - @Captor - private ArgumentCaptor<VorgangCreatedEvent> eventCaptor; + @Mock + private VorgangStubMapper stubMapper; + + @DisplayName("Start creation") + @Nested + class TestStartCreation { private final Eingang eingang = EingangTestFactory.create(); + private static final String VORGANG_NUMMER = "TEST_VN"; @BeforeEach - void init() { - when(repository.save(any())).thenReturn(VorgangTestFactory.create()); - } - - @Test - void shouldFillVorgangData() { - callCreateVorgang(); + void mockAktenzeichenProvider() { + when(aktenzeichenProvider.provideAktenzeichen(any())).thenReturn(VorgangTestFactory.AKTENZEICHEN); - verify(repository).save(vorgangCaptor.capture()); - assertThat(vorgangCaptor.getValue().getName()).isEqualTo(EingangHeaderTestFactory.FORM_NAME); - assertThat(vorgangCaptor.getValue().getStatus()).isEqualTo(Vorgang.Status.NEU); + when(kopControlDataMapper.moveLabelsToControlData(any(Eingang.class))).then(v -> v.getArgument(0)); } @Test - void shouldKeepEingangInVorgang() { - callCreateVorgang(); + void shouldSetName() { + var created = callStartCreation(); - verify(repository).save(vorgangCaptor.capture()); - assertThat(vorgangCaptor.getValue().getEingangs().get(0).getId()).isEqualTo(EingangTestFactory.ID); + assertThat(created.getName()).isEqualTo(EingangHeaderTestFactory.FORM_NAME); } @Test - void shouldCallAktenzeichenProvider() { - callCreateVorgang(); + void shouldSetStatus() { + var created = callStartCreation(); - verify(aktenzeichenProvider).provideAktenzeichen(eingang); + assertThat(created.getStatus()).isEqualTo(Vorgang.Status.NEU); } @Test void shouldSetVorgangNummer() { - callCreateVorgang(); + doReturn(VORGANG_NUMMER).when(service).getVorgangNummer(any()); - verify(repository).save(vorgangCaptor.capture()); - assertThat(vorgangCaptor.getValue().getNummer()).isEqualTo(EingangHeaderTestFactory.REQUEST_ID); - } - - @Test - void shouldSetInCreationFalse() { - callCreateVorgang(); + var created = callStartCreation(); - verify(repository).save(vorgangCaptor.capture()); - assertThat(vorgangCaptor.getValue().isInCreation()).isFalse(); + assertThat(created.getNummer()).isEqualTo(VORGANG_NUMMER); } + @DisplayName("eingang on vorgang") @Nested - class TestPublishVorgangCreateEvent { + class TestEingang { @Test - void shouldPublishOnInCreationFalse() { - callCreateVorgang(); + void shouldHaveFields() { + var created = callStartCreation(); - verify(publisher).publishEvent(eventCaptor.capture()); - assertThat(eventCaptor.getValue()).isInstanceOf(VorgangCreatedEvent.class) - .extracting(VorgangCreatedEvent::getSource).isEqualTo(VorgangTestFactory.ID); + assertThat(created.getEingangs().get(0)).usingRecursiveComparison().isEqualTo(eingang); } - } - - private void callCreateVorgang() { - service.createVorgang(eingang); - } - } - - @Nested - class TestStartCreation { - - private final Eingang eingang = EingangTestFactory.create(); - - @BeforeEach - void mockAktenzeichenProvider() { - when(aktenzeichenProvider.provideAktenzeichen(any())).thenReturn(VorgangTestFactory.AKTENZEICHEN); - } - @Test - void shouldSetName() { - var created = callStartCreation(); + @DisplayName("with existing serviceKonto") + @Nested + class TestWithExistingServiceKonto { - assertThat(created.getName()).isEqualTo(EingangHeaderTestFactory.FORM_NAME); - } + @Test + void shouldHaveServiceKonto() { + var vorgang = callStartCreation(); - @Test - void shouldSetStatus() { - var created = callStartCreation(); + assertThat(vorgang.getHeader().getServiceKonto()).usingRecursiveComparison().isEqualTo(ServiceKontoTestFactory.create()); + } + } - assertThat(created.getStatus()).isEqualTo(Vorgang.Status.NEU); - } + @DisplayName("without serviceKonto") + @Nested + class TestWithoutServiceKonto { - @Test - void shouldSetVorgangNummer() { - var created = callStartCreation(); + private static final EingangHeader EINGANG_HEADER_WITHOUT_SERVICE_KONTO = EingangHeaderTestFactory.createBuilder().serviceKonto(null) + .build(); + private static final Eingang EINGANG_WITHOUT_SERVICE_KONTO = EingangTestFactory.createBuilder() + .header(EINGANG_HEADER_WITHOUT_SERVICE_KONTO).build(); - assertThat(created.getNummer()).isEqualTo(EingangHeaderTestFactory.REQUEST_ID); - } + @Test + void shouldNotHaveServiceKonto() { + var vorgang = callStartCreation(EINGANG_WITHOUT_SERVICE_KONTO); - @Test - void shouldSaveEingangOnVorgang() { - var created = callStartCreation(); + assertThat(vorgang.getHeader().getServiceKonto()).isNull(); + } + } - assertThat(created.getEingangs().get(0)).usingRecursiveComparison().isEqualTo(eingang); } @Test @@ -218,6 +189,10 @@ class VorgangServiceTest { } private Vorgang callStartCreation() { + return callStartCreation(eingang); + } + + private Vorgang callStartCreation(Eingang eingang) { service.startCreation(eingang); verify(repository).save(vorgangCaptor.capture()); @@ -226,6 +201,26 @@ class VorgangServiceTest { } } + @Nested + class getVorgangNummer { + @Test + void shouldReturnGivenNummer() { + var result = service.getVorgangNummer(EingangHeaderTestFactory.create()); + + assertThat(result).isEqualTo(EingangHeaderTestFactory.VORGANG_NUMMER); + } + + @Test + void shouldReturnRequestId() { + var header = EingangHeaderTestFactory.createBuilder().vorgangNummer(null).build(); + + var result = service.getVorgangNummer(header); + + assertThat(result).isEqualTo(EingangHeaderTestFactory.REQUEST_ID); + } + } + + @DisplayName("Finish creation") @Nested class TestFinishCreation { @@ -289,6 +284,21 @@ class VorgangServiceTest { } } + @Nested + class TestVorgangNotFound { + @BeforeEach + void mockRepository() { + when(repository.findById(anyString())).thenReturn(Optional.of(VorgangTestFactory.create())); + } + + @Test + void shouldThrowException() { + when(repository.findById(anyString())).thenReturn(Optional.empty()); + + assertThrows(NotFoundException.class, () -> service.getById(VorgangTestFactory.ID)); + } + } + @Nested class TestGetById { @@ -300,11 +310,18 @@ class VorgangServiceTest { @BeforeEach void mockRepository() { when(repository.findById(anyString())).thenReturn(Optional.of(VorgangTestFactory.create())); + + when(kopControlDataMapper.addLabels(any(Eingang.class))).then(v -> v.getArgument(0)); } @Nested class AndOrganisationseinheitenIds { + @BeforeEach + void mockAttributeUtilService() { + when(readIsPermitted.test(any())).thenReturn(true); + } + @Test void shouldCallFindById() { service.getById(VorgangTestFactory.ID); @@ -341,14 +358,6 @@ class VorgangServiceTest { assertThat(vorgang).isNotNull().usingRecursiveComparison().isEqualTo(VorgangTestFactory.create()); } - @Test - void shouldThrowException() { - lenient().when(readIsPermitted.test(any())).thenReturn(true); - when(repository.findById(anyString())).thenReturn(Optional.empty()); - - assertThrows(NotFoundException.class, () -> service.getById(VorgangTestFactory.ID)); - } - @Test void shouldRemoveClientAttributesWithoutReadPermission() { when(readIsPermitted.test(any())).thenReturn(false); @@ -360,8 +369,6 @@ class VorgangServiceTest { @Test void shouldContainClientAttributesWithReadPermission() { - when(readIsPermitted.test(any())).thenReturn(true); - var loaded = service.getById(VorgangTestFactory.ID); assertThat(loaded.getClientAttributes()).isNotEmpty(); @@ -369,174 +376,93 @@ class VorgangServiceTest { } @Nested - class TestVorgangStatusChange { - - private Command command = CommandTestFactory.create(); - - @BeforeEach - void mockRepository() { - when(repository.findById(any())).thenReturn(Optional.of(VorgangTestFactory.create())); - } - - @Nested - class TestExecuteStatusChangeCommand { - - @Captor - private ArgumentCaptor<StatusChangedEvent> eventCaptor; - - @Test - void shouldUpdateStatus() { - doServiceCall(); - - verifyServiceCall(Status.ANGENOMMEN); - } - - @Test - void shouldCallRepository() { - doServiceCall(); - - verify(repository).findById(CommandTestFactory.RELATION_ID); - } - - @Test - void shouldPublishExecutedEvent() { - doServiceCall(); - - verify(publisher).publishEvent(eventCaptor.capture()); - assertThat(eventCaptor.getValue()).isInstanceOf(StatusChangedEvent.class) - .extracting(StatusChangedEvent::getSource).isSameAs(CommandTestFactory.ID); - } + class TestAssignToUser { - private void doServiceCall() { - service.executeStatusChangeCommand(command, Status.ANGENOMMEN); - } - } + private Command command = CommandTestFactory.createBuilder().body(Map.of("assignedTo", "Klaus")).build(); - @DisplayName("should update vorgang by the given status 'ANGENOMMEN") @Test - void shouldUpdateByStatusAngenommen() { - service.annehmen(command); + void shouldCallRepository() { + service.assignToUser(command); - verifyServiceCall(Status.ANGENOMMEN); + verify(repository).patch(CommandTestFactory.RELATION_ID, VorgangTestFactory.VERSION, Map.of("assignedTo", "Klaus")); } - @DisplayName("should update vorgang by the given status 'VERWORFEN") @Test - void shouldUpdateByStatusVerworfen() { - service.verwerfen(command); + void shouldPublishEvent() { + service.assignToUser(command); - verifyServiceCall(Status.VERWORFEN); + verify(publisher).publishEvent(any(VorgangAssignedEvent.class)); } + } - @DisplayName("should update vorgang by the given status 'IN_BEARBEITUNG") - @Test - void shouldUpdateByStatusBearbeiten() { - service.bearbeiten(command); + @DisplayName("Exists") + @Nested + class TestExists { - verifyServiceCall(Status.IN_BEARBEITUNG); - } + private final List<String> organisationseinheitenIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); - @DisplayName("should update vorgang by the given status 'BESCHIEDEN") @Test - void shouldUpdateByStatusBeschieden() { - service.bescheiden(command); + void shouldCallRepository() { + service.exists(VorgangTestFactory.ID, organisationseinheitenIds); - verifyServiceCall(Status.BESCHIEDEN); + verify(repository).exists(VorgangTestFactory.ID, organisationseinheitenIds); } + } - @DisplayName("should update vorgang by the given status 'ABGESCHLOSSEN") - @Test - void shouldUpdateByStatusAbgeschlossen() { - service.abschliessen(command); - - verifyServiceCall(Status.ABGESCHLOSSEN); - } + @Nested + class TestDeleteVorgang { - @DisplayName("should update status to 'WEITERGELEITET'") - @Test - void shouldUpdateToWeitergeleitet() { - service.setStatusToWeitergeleitet(ForwardingTestFactory.create()); + private Vorgang vorgang = VorgangTestFactory.create(); + private VorgangStub stub = VorgangStubTestFactory.create(); - verify(repository).updateStatusWithoutVersionCheck(VorgangTestFactory.ID, Status.WEITERGELEITET); + @BeforeEach + void init() { + when(repository.findById(any())).thenReturn(Optional.of(vorgang)); + when(stubMapper.fromVorgang(any())).thenReturn(stub); } - @Nested - class TestSetStatusToInBearbeitung { - - @Test - void shouldUpdateStatusWithoutVersionCheck() { - service.setStatusToInBearbeitung(CommandTestFactory.ID, VorgangTestFactory.ID); - - verify(repository).updateStatusWithoutVersionCheck(VorgangTestFactory.ID, Status.IN_BEARBEITUNG); - } - - @Test - void shouldPublishEvent() { - service.setStatusToInBearbeitung(CommandTestFactory.ID, VorgangTestFactory.ID); - - verify(publisher).publishEvent(any(StatusChangedEvent.class)); - } - - @Test - void shouldCallFindById() { - service.setStatusToInBearbeitung(CommandTestFactory.ID, VorgangTestFactory.ID); - - verify(repository).findById(VorgangTestFactory.ID); - } - } + @Test + void shouldLoadVorgang() { + service.deleteVorgang(VorgangTestFactory.ID); - private void verifyServiceCall(Status status) { - verify(service).executeStatusChangeCommand(command, status); + verify(service).loadById(VorgangTestFactory.ID); } - } - @Nested - class TestRevokeStatusChange { + @Test + void shouldMapToStub() { + service.deleteVorgang(VorgangTestFactory.ID); - @BeforeEach - void mockRepository() { - when(repository.findById(any())).thenReturn(Optional.of(VorgangTestFactory.create())); + verify(stubMapper).fromVorgang(vorgang); } @Test - void shouldRevindToOldStatus() { - service.revokeStatusChange(CommandTestFactory.create()); + void shouldPersistStub() { + service.deleteVorgang(VorgangTestFactory.ID); - verify(service).doUpdateStatus(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION + 1, CommandTestFactory.PREV_STATUS); + verify(repository).saveStub(stub); } } @Nested - class TestAssignToUser { - - private Command command = CommandTestFactory.createBuilder().body(Map.of("assignedTo", "Klaus")).build(); + class TestSetAktenzeichen { @Test void shouldCallRepository() { - service.assignToUser(command); + var command = CommandTestFactory.createBuilder() + .bodyObject(Map.of(VorgangService.BODY_OBJECT_AKTENZEICHEN, VorgangTestFactory.AKTENZEICHEN)).build(); - verify(repository).patch(CommandTestFactory.RELATION_ID, VorgangTestFactory.VERSION, Map.of("assignedTo", "Klaus")); - } - - @Test - void shouldPublishEvent() { - service.assignToUser(command); + service.setAktenzeichen(command); - verify(publisher).publishEvent(any(VorgangAssignedEvent.class)); + verify(repository).setAktenzeichen(VorgangTestFactory.ID, CommandTestFactory.RELATION_VERSION, VorgangTestFactory.AKTENZEICHEN); } - } - - @DisplayName("Exists") - @Nested - class TestExists { - - private final List<String> organisationseinheitenIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); @Test - void shouldCallRepository() { - service.exists(VorgangTestFactory.ID, organisationseinheitenIds); + void shouldTrimEmptyStringToNull() { + var command = CommandTestFactory.createBuilder().bodyObject(Map.of(VorgangService.BODY_OBJECT_AKTENZEICHEN, "")).build(); - verify(repository).exists(VorgangTestFactory.ID, organisationseinheitenIds); + service.setAktenzeichen(command); + + verify(repository).setAktenzeichen(VorgangTestFactory.ID, CommandTestFactory.RELATION_VERSION, null); } } } \ 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 new file mode 100644 index 0000000..bcc9e1f --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubMapperTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; + +class VorgangStubMapperTest { + + @InjectMocks + private VorgangStubMapper mapper = Mappers.getMapper(VorgangStubMapper.class); + + @Nested + class TestFormVorgang { + @Test + void shouldMapFields() { + var stub = mapper.fromVorgang(VorgangTestFactory.create()); + + assertThat(stub).usingRecursiveComparison() + .ignoringFields("deletedAt", "status") + .isEqualTo(VorgangStubTestFactory.create()); + } + + @Test + void shouldHaveStatusDELETED() { + var stub = mapper.fromVorgang(VorgangTestFactory.create()); + + assertThat(stub.getStatus()).isEqualTo(Vorgang.Status.DELETED); + } + + @Test + void shouldHaveDeletedAtOnNow() { + var stub = mapper.fromVorgang(VorgangTestFactory.create()); + + assertThat(stub.getDeletedAt()).isCloseTo(ZonedDateTime.now(), byLessThan(500, ChronoUnit.MILLIS)); + } + } + +} 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 new file mode 100644 index 0000000..41fe721 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangStubTestFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang; + +public class VorgangStubTestFactory { + + public static VorgangStub create() { + return createBuilder().build(); + } + + public static VorgangStub.VorgangStubBuilder createBuilder() { + return VorgangStub.builder() + .id(VorgangTestFactory.ID) + .name(VorgangTestFactory.NAME) + .createdAt(VorgangTestFactory.CREATED_AT) + .header(VorgangHeadStub.builder().organisationsEinheitId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID).build()) + .eingangs(EingangStub.builder().zustaendigeStelle(ZustaendigeStelleStub.builder() + .organisationseinheitenId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID).build()).build()); + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java similarity index 81% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java index 310917a..512d075 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import java.time.ZonedDateTime; @@ -29,10 +29,10 @@ import org.bson.types.ObjectId; import com.thedeanda.lorem.LoremIpsum; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMap; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributesMapTestFactory; -import de.itvsh.ozg.pluto.command.UserTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; +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; public class VorgangTestFactory { @@ -40,8 +40,12 @@ public class VorgangTestFactory { public static final String NAME = LoremIpsum.getInstance().getName(); public static final long VERSION = 42L; public static final Status STATUS = Status.NEU; - public static final String INITIAL_DATE_STR = "2021-01-10T10:30:00Z"; + + 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 VORGANG_NUMMER = "VOR-GANG-NUMMER-1"; public static final String AKTENZEICHEN = LoremIpsum.getInstance().getWords(1); public static final boolean IN_CREATION = false; @@ -71,6 +75,7 @@ public class VorgangTestFactory { .nummer(VORGANG_NUMMER) .status(STATUS) .createdAt(CREATED_AT) + .header(VorgangHeadTestFactory.create()) .eingang(EINGANG) .version(VERSION) .assignedTo(UserTestFactory.ID) diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapperTest.java similarity index 76% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapperTest.java index bbb3332..70de3f8 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/VorgangWithEingangMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangWithEingangMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -34,7 +34,9 @@ import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.clientattribute.ClientAttributeMapper; +import de.ozgcloud.vorgang.clientattribute.ClientAttributeMapper; +import de.ozgcloud.vorgang.servicekonto.GrpcServiceKontoTestFactory; +import de.ozgcloud.vorgang.servicekonto.ServiceKontoMapper; class VorgangWithEingangMapperTest { @@ -44,6 +46,8 @@ class VorgangWithEingangMapperTest { private EingangMapper eingangMapper; @Mock private ClientAttributeMapper clientAttributeMapper; + @Mock + private ServiceKontoMapper serviceKontoMapper; @Nested class TestToVorgangWithEingang { @@ -51,6 +55,7 @@ class VorgangWithEingangMapperTest { @BeforeEach void mockEingangMapper() { when(eingangMapper.toGrpc(any(Eingang.class))).thenReturn(GrpcEingangTestFactory.create()); + when(serviceKontoMapper.toServiceKonto(any())).thenReturn(GrpcServiceKontoTestFactory.create()); } @Test @@ -65,7 +70,7 @@ class VorgangWithEingangMapperTest { var vorgangWithEingang = callMapper(); assertThat(vorgangWithEingang).usingRecursiveComparison() - .ignoringFields("eingang_", "eingang", "clientAttributes_", "memoizedHashCode") + .ignoringFields("eingang_", "clientAttributes_", "memoizedHashCode", "header_") .isEqualTo(GrpcVorgangWithEingangTestFactory.create()); } @@ -76,6 +81,13 @@ class VorgangWithEingangMapperTest { assertThat(eingang).usingRecursiveComparison().isEqualTo(GrpcEingangTestFactory.create()); } + @Test + void shouldMapHeader() { + var header = callMapper().getHeader(); + + assertThat(header).usingRecursiveComparison().isEqualTo(GrpcVorgangHeadTestFactory.create()); + } + private GrpcVorgangWithEingang callMapper() { return mapper.toVorgangWithEingang(VorgangTestFactory.create()); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapperTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapperTest.java similarity index 95% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapperTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapperTest.java index bf2e0cf..3eac366 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleMapperTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; import static org.assertj.core.api.Assertions.*; diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleTestFactory.java similarity index 66% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleTestFactory.java index 3246c75..4a4cf2f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/ZustaendigeStelleTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/ZustaendigeStelleTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang; +package de.ozgcloud.vorgang.vorgang; public class ZustaendigeStelleTestFactory { public static final String ORGANISATIONSEINHEIT_ID = GrpcZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID; public static final String BEZEICHNUNG = "Amt für Kleintiere und Viehzeug"; public static final String EMAIL = GrpcZustaendigeStelleTestFactory.EMAIL; + public static final String GEMEINDE_SCHLUESSEL = "1029385858"; + public static final String AMTLICHER_REGIONAL_SCHLUESSEL = "09876512"; + public static final String HAUSANSCHRIFT_STRASSE = "Musterstraße 1"; + public static final String HAUSANSCHRIFT_PLZ = "12345"; + public static final String HAUSANSCHRIFT_ORT = "Musterhausen"; + public static final String TELEFON = "0894578199358"; public static ZustaendigeStelle create() { return createBuilder().build(); @@ -37,6 +43,12 @@ public class ZustaendigeStelleTestFactory { return ZustaendigeStelle.builder() // .organisationseinheitenId(ORGANISATIONSEINHEIT_ID) .bezeichnung(BEZEICHNUNG) - .email(EMAIL); + .email(EMAIL) + .gemeindeSchluessel(GEMEINDE_SCHLUESSEL) + .amtlicherRegionalSchluessel(AMTLICHER_REGIONAL_SCHLUESSEL) + .hausanschriftStrasse(HAUSANSCHRIFT_STRASSE) + .hausanschriftPlz(HAUSANSCHRIFT_PLZ) + .hausanschriftOrt(HAUSANSCHRIFT_ORT) + .telefon(TELEFON); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardVorgangITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardVorgangITCase.java similarity index 62% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardVorgangITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardVorgangITCase.java index bcb4e2c..0375f79 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardVorgangITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardVorgangITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.bson.types.ObjectId; @@ -44,29 +46,29 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.security.test.context.support.WithMockUser; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.mail.email.MailSendErrorEventTestFactory; -import de.itvsh.ozg.mail.email.MailSendRequest; -import de.itvsh.ozg.mail.email.MailSentEventTestFactory; -import de.itvsh.ozg.mail.email.MailService; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandStatus; -import de.itvsh.ozg.pluto.command.GrpcCommandService; -import de.itvsh.ozg.pluto.command.GrpcCreateCommandRequestTestFactory; -import de.itvsh.ozg.pluto.command.PersistedCommand; -import de.itvsh.ozg.pluto.files.FileId; -import de.itvsh.ozg.pluto.files.GridFsTestFactory; -import de.itvsh.ozg.pluto.files.OzgFileTestFactory; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.grpc.command.GrpcRedirectRequest; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileGroupTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.Vorgang.Status; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandStatus; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.nachrichten.email.MailSendErrorEventTestFactory; +import de.ozgcloud.nachrichten.email.MailSendRequest; +import de.ozgcloud.nachrichten.email.MailSentEventTestFactory; +import de.ozgcloud.nachrichten.email.MailService; +import de.ozgcloud.vorgang.command.GrpcCommandService; +import de.ozgcloud.vorgang.command.GrpcCreateCommandRequestTestFactory; +import de.ozgcloud.vorgang.command.PersistedCommand; +import de.ozgcloud.vorgang.files.FileId; +import de.ozgcloud.vorgang.files.GridFsTestFactory; +import de.ozgcloud.vorgang.files.OzgFileTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcOrder; +import de.ozgcloud.vorgang.grpc.command.GrpcRedirectRequest; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileGroupTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.Vorgang.Status; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; @DataITCase @@ -107,10 +109,13 @@ class ForwardVorgangITCase { var attachment = IncomingFileGroupTestFactory.createBuilder().clearFiles().file( IncomingFileTestFactory.createBuilder().id(storeNewFile()).build()).build(); var representation = IncomingFileTestFactory.createBuilder().id(storeNewFile()).build(); - var vorgang = VorgangTestFactory.createBuilder().clearEingangs().eingang(EingangTestFactory.createBuilder() - .clearAttachments().attachment(attachment) - .clearRepresentations().representation(representation) - .build()).build(); + var vorgang = VorgangTestFactory.createBuilder() + .status(Status.NEU) + .clearEingangs().eingang(EingangTestFactory.createBuilder() + .clearAttachments().attachment(attachment) + .clearRepresentations().representation(representation) + .build()) + .build(); mongoOperations.save(vorgang); } @@ -135,10 +140,10 @@ class ForwardVorgangITCase { void shouldHaveCommandWithFINISHEDState() { callServiceCreateCommand(); - var commands = mongoOperations.findAll(Command.class); - assertThat(commands).hasSize(1); - var redirectCommand = commands.get(0); - assertThat(redirectCommand.getStatus()).isEqualTo(CommandStatus.FINISHED); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var commands = mongoOperations.findAll(Command.class); + assertThat(commands).hasSize(1).first().extracting(Command::getStatus).isEqualTo(CommandStatus.FINISHED); + }); } // TODO Forwarding status @@ -159,28 +164,34 @@ class ForwardVorgangITCase { void forwardCommandShouldBeWithError() { callServiceCreateCommand(); - var commands = mongoOperations.findAll(PersistedCommand.class); - assertThat(commands).hasSize(1); - var redirectCommand = commands.get(0); - assertThat(redirectCommand.getStatus()).isEqualTo(CommandStatus.ERROR); - assertThat(redirectCommand.getErrorMessage()).isEqualTo(MailSendErrorEventTestFactory.ERROR_MSG); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var commands = mongoOperations.findAll(PersistedCommand.class); + assertThat(commands).hasSize(1).first().satisfies(redirectCommand -> { + assertThat(redirectCommand.getStatus()).isEqualTo(CommandStatus.ERROR); + assertThat(redirectCommand.getErrorMessage()).isEqualTo(MailSendErrorEventTestFactory.ERROR_MSG); + }); + }); } @Test void vorgangShouldHaveStatusIN_BEARBEITUNG() { callServiceCreateCommand(); - var loaded = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); - assertThat(loaded.getStatus()).isEqualTo(Status.IN_BEARBEITUNG); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var loaded = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); + assertThat(loaded.getStatus()).isEqualTo(Status.IN_BEARBEITUNG); + }); } @Test void forwardingShouldHaveStatusSEND_ERROR() { callServiceCreateCommand(); - var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); - assertThat(vorgang.getForwardings()).hasSize(1); - assertThat(vorgang.getForwardings().get(0).getStatus()).isEqualTo(Forwarding.Status.SEND_ERROR); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + var vorgang = mongoOperations.findById(VorgangTestFactory.ID, Vorgang.class); + assertThat(vorgang.getForwardings()).hasSize(1); + assertThat(vorgang.getForwardings().get(0).getStatus()).isEqualTo(Forwarding.Status.SEND_ERROR); + }); } } @@ -196,6 +207,7 @@ class ForwardVorgangITCase { .clearOrderString() .clearOrder().setOrder(GrpcOrder.REDIRECT_VORGANG) .clearRelationId().setRelationId(VorgangTestFactory.ID) + .setRelationVersion(VorgangTestFactory.VERSION) .setRedirectRequest(buildRedirectRequest()) .build(); } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerITCase.java similarity index 76% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerITCase.java index 3b0b678..818d433 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; +import static org.awaitility.Awaitility.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.concurrent.TimeUnit; + import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -36,13 +39,13 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationEventPublisher; import org.springframework.mail.javamail.JavaMailSender; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.mail.email.MailSentEventTestFactory; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEventTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.Order; -import de.itvsh.ozg.pluto.vorgang.VorgangService; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.nachrichten.email.MailSentEventTestFactory; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; +import de.ozgcloud.vorgang.vorgang.VorgangService; @ITCase class ForwardingEventListenerITCase { @@ -59,13 +62,14 @@ class ForwardingEventListenerITCase { @Nested class TestForwardVorgang { + @Test void shouldCallForwardingService() { var command = CommandTestFactory.createBuilder().order(Order.REDIRECT_VORGANG.name()).build(); publisher.publishEvent(CommandCreatedEventTestFactory.create(command)); - verify(service).forwardByCommand(command); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(service).forwardByCommand(command)); } } @@ -78,7 +82,7 @@ class ForwardingEventListenerITCase { publisher.publishEvent(MailSentEventTestFactory.create(forwarding)); - verify(service).onRedirectMailSent(forwarding); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(service).onRedirectMailSent(forwarding)); } @ParameterizedTest @@ -94,13 +98,14 @@ class ForwardingEventListenerITCase { @Nested class CommandCreatedEvent { + @Test void shouldCallForwardingService() { var command = CommandTestFactory.createBuilder().order(Order.FORWARD_SUCCESSFULL.name()).build(); publisher.publishEvent(CommandCreatedEventTestFactory.create(command)); - verify(service).markAsSuccessfull(command); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> verify(service).markAsSuccessfull(command)); } } diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerTest.java similarity index 60% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerTest.java index 99aa071..eb74766 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingEventListenerTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingEventListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,20 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.ConcurrentModificationException; + import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.springframework.context.ApplicationEventPublisher; -import de.itvsh.ozg.mail.email.MailSentEventTestFactory; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandCreatedEventTestFactory; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.command.Order; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.nachrichten.email.MailSentEventTestFactory; +import de.ozgcloud.vorgang.command.CommandCreatedEventTestFactory; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.command.Order; class ForwardingEventListenerTest { @@ -43,6 +48,28 @@ class ForwardingEventListenerTest { @Mock private ForwardingService forwardingService; + @Mock + private ApplicationEventPublisher publisher; + + @Nested + class onForwardOrderCommand { + + @Test + void shouldCallService() { + listener.onForwardOrder(CommandCreatedEventTestFactory.create()); + + verify(forwardingService).forwardByCommand(notNull()); + } + + @Test + void shouldPublishFailedEventOnError() { + when(forwardingService.forwardByCommand(any())).thenThrow(ConcurrentModificationException.class); + + listener.onForwardOrder(CommandCreatedEventTestFactory.create()); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + } @Nested class onMailSentEvent { @@ -55,6 +82,7 @@ class ForwardingEventListenerTest { verify(forwardingService).onRedirectMailSent(forwarding); } + } @Nested @@ -69,6 +97,15 @@ class ForwardingEventListenerTest { verify(forwardingService).markAsSuccessfull(command); } + @Test + void shouldPublishFailedEventOnError() { + doThrow(RuntimeException.class).when(forwardingService).markAsSuccessfull(any()); + + listener.markAsSuccessfull(CommandCreatedEventTestFactory.create()); + + verify(publisher).publishEvent(any(CommandFailedEvent.class)); + } + } @Nested diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcServiceTest.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcServiceTest.java index c8c1dc7..9bd78db 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingGrpcServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingGrpcServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -37,9 +37,9 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.ozg.pluto.forwarding.GrpcForwarding; -import de.itvsh.ozg.pluto.forwarding.GrpcForwardingsResponse; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.forwarding.GrpcForwarding; +import de.ozgcloud.vorgang.forwarding.GrpcForwardingsResponse; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import io.grpc.stub.StreamObserver; class ForwardingGrpcServiceTest { diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingITCase.java new file mode 100644 index 0000000..12a2ed3 --- /dev/null +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingITCase.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.vorgang.redirect; + +import static org.mockito.ArgumentMatchers.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.task.TaskExecutor; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.security.test.context.support.WithMockUser; + +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.nachrichten.email.MailSentEventTestFactory; +import de.ozgcloud.nachrichten.email.MailService; +import de.ozgcloud.vorgang.callcontext.CallContextTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; + +@DataITCase +public class ForwardingITCase { + + @Autowired + private ApplicationEventPublisher eventPublisher; + @Autowired + private MongoOperations mongoOperations; + @Autowired + private TaskExecutor taskExecutor; + @MockBean + private MailService mailService; + + @Nested + class TestAcknowledgeForwarding { + + private Vorgang vorgang; + + @BeforeEach + void setup() { + vorgang = VorgangTestFactory.create(); + mongoOperations.save(vorgang); + } + + @Test + @WithMockUser(username = CallContextTestFactory.CLIENT) + void shouldCallMailService() { + var forwarding = ForwardingTestFactory.createBuilder().vorgangId(vorgang.getId()).build(); + + publishEventInNewThread(MailSentEventTestFactory.create(forwarding)); + + Mockito.verify(mailService, Mockito.timeout(1000)).sendMail(any()); + } + + private void publishEventInNewThread(ApplicationEvent event) { + taskExecutor.execute(() -> eventPublisher.publishEvent(event)); + } + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepositoryITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepositoryITCase.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepositoryITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepositoryITCase.java index 0ebcbe1..79e287f 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingRepositoryITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingRepositoryITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.assertj.core.api.Assertions.*; @@ -33,10 +33,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -import de.itvsh.kop.common.test.DataITCase; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.redirect.Forwarding.Status; +import de.ozgcloud.common.test.DataITCase; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.redirect.Forwarding.Status; @DataITCase class ForwardingRepositoryITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceITCase.java similarity index 89% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceITCase.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceITCase.java index 86dfdb4..40a4cfb 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceITCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.assertj.core.api.Assertions.*; @@ -32,12 +32,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.util.ReflectionTestUtils; -import de.itvsh.kop.common.test.ITCase; -import de.itvsh.ozg.pluto.vorgang.AntragstellerTestFactory; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.vorgang.vorgang.AntragstellerTestFactory; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; @ITCase class ForwardingServiceITCase { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceTest.java similarity index 87% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceTest.java index e6583c6..3231326 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Map; import java.util.Optional; -import de.itvsh.ozg.mail.email.MailRecipient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -42,24 +42,24 @@ import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; import org.springframework.test.util.ReflectionTestUtils; -import static org.assertj.core.api.Assertions.*; - -import de.itvsh.ozg.mail.email.MailSendRequest; -import de.itvsh.ozg.mail.email.MailSendRequest.MailAttachment; -import de.itvsh.ozg.mail.email.MailService; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.vorgang.AntragstellerTestFactory; -import de.itvsh.ozg.pluto.vorgang.EingangHeaderTestFactory; -import de.itvsh.ozg.pluto.vorgang.EingangTestFactory; -import de.itvsh.ozg.pluto.vorgang.Vorgang; -import de.itvsh.ozg.pluto.vorgang.VorgangService; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.nachrichten.email.MailRecipient; +import de.ozgcloud.nachrichten.email.MailSendRequest; +import de.ozgcloud.nachrichten.email.MailSendRequest.MailAttachment; +import de.ozgcloud.nachrichten.email.MailService; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.status.StatusService; +import de.ozgcloud.vorgang.vorgang.AntragstellerTestFactory; +import de.ozgcloud.vorgang.vorgang.EingangHeaderTestFactory; +import de.ozgcloud.vorgang.vorgang.EingangTestFactory; +import de.ozgcloud.vorgang.vorgang.Vorgang; +import de.ozgcloud.vorgang.vorgang.VorgangService; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; class ForwardingServiceTest { - @Spy // NOSONAR + @Spy @InjectMocks private ForwardingService service; @Mock @@ -74,6 +74,9 @@ class ForwardingServiceTest { @Mock private VorgangService vorgangService; + @Mock + private StatusService statusService; + @Mock private ApplicationEventPublisher publisher; @@ -218,7 +221,7 @@ class ForwardingServiceTest { @Nested class TestOnRedirectMailSent { - @Captor // NOSONAR + @Captor private ArgumentCaptor<VorgangRedirectedEvent> eventCaptor; private Forwarding forwarding = ForwardingTestFactory.create(); @@ -551,32 +554,72 @@ class ForwardingServiceTest { private Command command = CommandTestFactory.create(); private Vorgang vorgang = VorgangTestFactory.create(); - @BeforeEach - void initTest() { + @Test + void shouldDoRedirect() { when(vorgangService.getById(any())).thenReturn(vorgang); - doNothing().when(service).redirectVorgang(any(), any()); - } + doNothing().when(service).doRedirect(any(), any()); - @DisplayName("should update vorgang by the given status 'IN_BEARBEITUNG") - @Test - void shouldCallService() { service.forwardByCommand(command); - verify(vorgangService).setStatusToInBearbeitung(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION); + verify(service).doRedirect(command, vorgang); } - @Test - void shouldForwardVorgang() { - service.forwardByCommand(command); + @DisplayName("on version missmatch") + @Nested + class VersionMissmatch { + + @BeforeEach + void initTest() { + when(vorgangService.getById(any())).thenReturn(vorgang); + } + + @Test + void shouldDoNothing() { + service.forwardByCommand(CommandTestFactory.createBuilder().relationVersion(5L).build()); + + verify(service, never()).doRedirect(any(), any()); + } - verify(service).redirectVorgang(vorgang, command); + @Test + void shouldMarkAsFailed() { + var command = CommandTestFactory.createBuilder().relationVersion(5L).build(); + + service.forwardByCommand(command); + + verify(service).markAsFailed(command); + } } - @Test - void shouldNOTDispatchEvent() { - service.forwardByCommand(command); + @Nested + class doRedirect { + + @BeforeEach + void initTest() { + doNothing().when(service).redirectVorgang(any(), any()); + } + + @DisplayName("should update vorgang by the given status 'IN_BEARBEITUNG") + @Test + void shouldCallService() { + service.doRedirect(command, vorgang); + + verify(statusService).setStatusToInBearbeitung(CommandTestFactory.RELATION_ID, CommandTestFactory.RELATION_VERSION); + } - verifyNoInteractions(publisher); + @Test + void shouldForwardVorgang() { + service.doRedirect(command, vorgang); + + verify(service).redirectVorgang(vorgang, command); + } + + @Test + void shouldNOTDispatchEvent() { + service.doRedirect(command, vorgang); + + verifyNoInteractions(publisher); + } } + } } \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingTestFactory.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingTestFactory.java index 86f589c..d64043d 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ForwardingTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ForwardingTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import java.util.UUID; -import de.itvsh.ozg.pluto.command.CommandTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.redirect.Forwarding.Status; +import de.ozgcloud.vorgang.command.CommandTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.redirect.Forwarding.Status; public class ForwardingTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java similarity index 79% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java index 4099964..a938c69 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/GrpcFindForwardingsRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; -import de.itvsh.ozg.pluto.command.GrpcCallContextTestFactory; -import de.itvsh.ozg.pluto.forwarding.GrpcFindForwardingsRequest; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.command.GrpcCallContextTestFactory; +import de.ozgcloud.vorgang.forwarding.GrpcFindForwardingsRequest; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; public class GrpcFindForwardingsRequestTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestTestFactory.java similarity index 88% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestTestFactory.java index b85ea78..f1f1fda 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/RedirectRequestTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; class RedirectRequestTestFactory { static final String EMAIL = "test@ozg-sh.de"; - static final String PASSWORD = "geheim"; + static final String PASSWORD = ""; public static RedirectRequest create() { return createBuilder().build(); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEventTestFactory.java similarity index 84% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEventTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEventTestFactory.java index 5733755..649ee08 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangForwardFailedEventTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangForwardFailedEventTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; -import de.itvsh.ozg.pluto.command.Command; -import de.itvsh.ozg.pluto.command.CommandTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.vorgang.command.CommandTestFactory; public class VorgangForwardFailedEventTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEventTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEventTestFactory.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEventTestFactory.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEventTestFactory.java index fb0e7a8..26e1b85 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/VorgangRedirectedEventTestFactory.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/VorgangRedirectedEventTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; public class VorgangRedirectedEventTestFactory { diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderServiceTest.java similarity index 91% rename from pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderServiceTest.java rename to vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderServiceTest.java index 9e14177..91e9cc3 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/ZipBuilderServiceTest.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/redirect/ZipBuilderServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.ozg.pluto.vorgang.redirect; +package de.ozgcloud.vorgang.vorgang.redirect; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -44,12 +44,12 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.test.util.ReflectionTestUtils; -import de.itvsh.ozg.pluto.files.FileId; -import de.itvsh.ozg.pluto.files.FileService; -import de.itvsh.ozg.pluto.vorgang.IncomingFileGroupTestFactory; -import de.itvsh.ozg.pluto.vorgang.IncomingFileTestFactory; -import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; -import de.itvsh.ozg.pluto.vorgang.redirect.ZipBuilderService.ZipBuilder; +import de.ozgcloud.vorgang.files.FileId; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.vorgang.IncomingFileGroupTestFactory; +import de.ozgcloud.vorgang.vorgang.IncomingFileTestFactory; +import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; +import de.ozgcloud.vorgang.vorgang.redirect.ZipBuilderService.ZipBuilder; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.io.outputstream.ZipOutputStream; import net.lingala.zip4j.model.ZipParameters; @@ -89,7 +89,7 @@ class ZipBuilderServiceTest { builder.addFile("", IncomingFileTestFactory.create()); verify(zipOut).putNextEntry(parametersCaptor.capture()); - assertThat(parametersCaptor.getValue().getFileNameInZip()).isEqualTo("/" + IncomingFileTestFactory.NAME); + assertThat(parametersCaptor.getValue().getFileNameInZip()).isEqualTo(IncomingFileTestFactory.NAME); } @Test diff --git a/vorgang-manager-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/vorgang-manager-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 0000000..79b126e --- /dev/null +++ b/vorgang-manager-server/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1 @@ +org.mockito.junit.jupiter.MockitoExtension \ No newline at end of file diff --git a/pluto-server/src/test/resources/TestDoc.docx b/vorgang-manager-server/src/test/resources/TestDoc.docx similarity index 100% rename from pluto-server/src/test/resources/TestDoc.docx rename to vorgang-manager-server/src/test/resources/TestDoc.docx diff --git a/vorgang-manager-server/src/test/resources/application-itcase.yml b/vorgang-manager-server/src/test/resources/application-itcase.yml new file mode 100644 index 0000000..96b714f --- /dev/null +++ b/vorgang-manager-server/src/test/resources/application-itcase.yml @@ -0,0 +1,17 @@ +logging: + level: + ROOT: ERROR, + '[org.springframework]': ERROR + '[org.springframework.data.mongodb.core]': WARN + '[de.ozgcloud]': WARN + config: classpath:log4j2-local.xml + +grpc: + server: + port: -1 + +ozgcloud: + aktenzeichen: de.ozgcloud.vorgang.vorgang.AktenzeichenProviderEA + +mongock: + enabled: false diff --git a/pluto-server/src/test/resources/application-with_db.yml b/vorgang-manager-server/src/test/resources/application-with_db.yml similarity index 81% rename from pluto-server/src/test/resources/application-with_db.yml rename to vorgang-manager-server/src/test/resources/application-with_db.yml index fa1211c..9f1bcf2 100644 --- a/pluto-server/src/test/resources/application-with_db.yml +++ b/vorgang-manager-server/src/test/resources/application-with_db.yml @@ -6,4 +6,4 @@ spring: data: mongodb: host: localhost - database: embeded_db \ No newline at end of file + database: embeded_db diff --git a/vorgang-manager-server/src/test/resources/bayernid.p12 b/vorgang-manager-server/src/test/resources/bayernid.p12 new file mode 100644 index 0000000000000000000000000000000000000000..fa82ce9007cc50831496073cdb03d8b6a92b5ee4 GIT binary patch literal 6349 zcmXqLk~qo4$ZXIg(Zt57)#lOmotKfFaY2(rF-wy~zCn{jwm}o?bQCGp4wfd?7K0|% z27@Nn8a8gIE*>sMrUgwbzYUsLz8h$=alwQcnGK{_M3!p?sR<gE^S*x5W)*a{xogRa zPoJ5X8BQ>;G_jmeShiixahKAKj)Ft)e?79=_3qXt3D&RLZ@=oaCCvRb`x(psV&U~w zFB8wGgx_|`cD(d+-5VWa>zbX$NxpL>R@_P8mWU6%FmqF7Xw9{jyQ@=@o~EBtNnBGq zp>L<qEl=sWbq(j<DOmC|M?Tq=m=%9TXtLs@#5=!S7;B`h9)?W5d8GJ~?D;mSw5GxZ zDbfAuE8agn?`3=M#z%|Q*YZCaCR}D{J7MtUfJUBYGh69I+m$XWkG;26o_d?JYw<4m zV+SvtKM=((|5WjYlKiFO=VISI-q>l1iiW-qwQc`zmA;|Q(d^8;xdr#46;8H2^GOx% zQdOvRR=RLu{turiGqxY*P>yU>w+@K-)ArFg>aECpt%Yu>iW|6_?o4sGvva+j^_u2h z-P+x6R+yPTnO2tneCm9Yq`Sp}t&5k&s_vTn>So%TQ`Oq(QJ?2<2`c1#n7eO7{>Ovg zimrXTayH0(HS?c9S9#3@Hs@)AOT=9Qd~P+F_ZiG=eLpwug6fx3wXv0lR$2L#_moW3 ziR9h5aN)Po-hUV073bSkFXG$bUtsR%G2yF-y#0#6;CVNne4O5Y>!$bYuiw{k+}UFL zP=CU)-UPm{t4ca!-%QGCE;0A0{k162Ddp>~U#6dUCyK1x6mgPg($?i2M|lgXirLz% z5Bb|S-{w9P`~D?Yf%lbYo2S+*3)j2y3hDZDs?XmOAC#lFCiIq*?xd%c=CV^Z_;_z< zNW04CAFRA<`}}r>%G)RH_uaLh&hhx)O`R3XB(KloQhcW*IJx_z3UhL5$*0mSC6Nbn z_Q(B--2Zer2jjp0d0TJsu=cmrFK+x5uMjdf``c=*Q_Wr64<<9e3JhUAAXdV^^q2Dg z>lUAORwmlNR=y|oTCbJM;kR$a?puwl>O$V19yT3de|GuIk^a&Lk9M+bd-p)7^7p)} z+gfhk{5^f2c(47LrR^uCeSGaAlD9b`E$ZgJfGUB>fh(Cg7aQ=Gtm)E!#?nzR<^0C9 zW&c-iXL;P2#_)K~S%qZ>D_?rM6wBUmxuMlFLm>O)CynQpr<Mhmc5Vz@<$GX9Y|B-( zf{O57S1su?WzQ}z(LN@8`N*OZw|`BoTH+*JW1#10bw{l-OY{%RC9ShrtJu`$9%)Lh z>Zotxoam5#{pX$9#uGkQ`#paOu^ra0-muz7eT{`%?k|gtH?OXX-1@B2%RXvecIQHc zLtmvGv>skxlTpmHCwN-y9Jy+%byhu5ahHB)X<agYpf^j(Gtq3G&!l>njETl`oO?Fp zRymf~Jj>WE+2Ys}BlJ^-FPM9QeciUzdp;J`9NRhZ;r;Mwm6whk)^IrCdpP>EeZ%H} zZ*ouW9bR`@V|8>`VRO){X3g)}D{X@pYM6;mifKRS!Y{S;jOH)q7x@bxhT9&GGA+BP zHqEB&Ku?p1){niMExXsrE}bAHF_ZIV1nX3eFD55{IQr+$-u5+IE<8JZ)$~Ps>t6q1 z=$p9zxae;!%WzJ!^s4&6U7Hv8a=fkb_;l-`XhiD11YQo+4-e+8^J0n66pmW^_~pTW zxvjJLzGNt@icxpJFf*_vzDR#ld(j&)wi(y%9XNZYTX%Zt$u0MD8;?58aJ(^LO7fI@ z)4nHuE}nA!#-)m*53T$i_V*Ol-7K(R@X?fR|DAop;M7)S_PMXNE}pTJ{rvTIvHW0L zN%<_pJOgETQOPN4D8?d^mXZ{6)?QWkq*<0hWbmGE=3?8*4crlmL=3IuEEwDwf*1lA ztQZs+Tp0ow92p`RbQwYzTp5BHLKqYnd>Pysd>P^y{28Jc+!^8-oEdT$@)=4QQVg1e z&cKagXIs!DwAY|XXeSdRgF%zfCWH(lN_or%Dvwtmmd>iniA(X>VZ7vH@WB?Dqy5t0 z^0=W%sABoK+(j-&c&a)?UWLxuvOAztC!)Cg^wEa}H_ug1C@-Amx`K6$++X?KSBr)3 zDZbN<=F^c?xcm6P)vb%Zf4)}Czjvy7nb}5VsmI!kbLAfzybb9t52}{_P%PYMe{5~k z{M;ms8@7&J+;^{klTP-zB&Dq(*8kexd)cjnlWLAQO#R0G{M6xptJj{@(3v#vdyt~X z;{%LaTlFp-y7{Cx=n3P`gAu2Wy|38jb=g;_#N|oJO=jhYBVm*F>=a?x#kTi(;hWI# zEFZ~$v&;1NMT<7)_bB`n;PY!`oq6_`ebR+XXSQ#;I>$NipjCo?i^TO=K5yrK+oZkQ z)x|SZ<;SJX?Sb`C6V4{azAoR$Gu_eEY7hI1ipif2uM9kXJHvpn>|X9FX34nXLzX|y z_}-fcxf&?fmYm%`>C0+vgFx%W!J$|4Y&?C>mYAl5)V>amkI=2#w0_Q(OLfK9dFDz@ zNo?_WA0K98%W`qUr_b@Z(-ys%Q+)o(gn~0G+m`6p@hwl={^aY*oRC*pmzJHkIW2OK zap#Ady>W*vTI)7%`tW)F?tt}&H(XEO`t`tsC09D7dBk<JEqsjGA4JIg*s;HKms`5M z)0Ii4K^$s3&QA@W`LOv`deWP=kSQf*EKh5icCbE^V%f%fM?7ze6?32@oAmM*sl1<l zKl#Sk^vpYQ|Mj~0%*!TbrMHFEl-N%?`}W_7<{rkgtHLKfS9Y4_XBj3oKc-UZO1gcc zd&HVOiwr`HID9NqBo8xHIzEY$OlrOIH(<`ZKY?3UPPO;0RSh=r+id+?-6+_2v#E-j zNrV4}Y_FFUd23u)lAo$(uy_ZCPDwa%B)Rv@Wu5}3``P#9O|%>Ke!JY(vvb3>Rnu*J zKkQch7p<mzq-J|lZ}LY=MP<v3#5cPRD1;p<FgyNs3+o2krYW7ATMo9q5k4Pm*teqM zsoh@1kFn(kS{B`3!mn5RvGCgkA9o$`<~7;tJ#4IhbUi+qzu}(i!T4Oi2P`>X1w}VK z7v8mcjb8l4cMpvk8h7*MNluL7vR^vi-@U*h^wd@t=X-pTJH#DkEuNox+V<%Su?zE* zU)`ymA#J(-i1_!JOQu~oU3D)kooU5dEtSP)oG({o&n~vP#aSP{+vS*7$8(FRdqNJp zd4KvBQ(L&d@T|Vzm4%k7e79~c?sPTkYdiAsW$a^*Yd*&`5*RA?+-Zw)+q(F=0q5J- zs%-zRsI+8F{k}au<IBy@$0Vg!%vSna@H8U*)3IoYzn=x}3QuQ?+dijHU9(Z@q;J|y z9*-~Ge-~KmYdv}B7RT%Jsd~XxkpnAEUHiG-@6U~Iz4I1ioH%#NEdGPQi=<`xE56;{ zr|?>ESx(<_jaPLywm7UP{Ov2T<9^&K_vcP;eH3PX5MI{!>!!q$Ltp<~y?P|!FW=%~ zJ=W+jowetp+b>oA;tvSSdSSZKLzpckv_UuI%8bIm%_<Fnp1ZSab03%;yDJ;w<h^12 zy+a)_rc=_m_$-@d|6a~2SMHEL|De+ISGz-76BCyQu>R-eK9w=`;G@fTe~4@OYM*Nq zkl`q>m{#zs=T5lM|Ic#K&%Uf)W7lbXOXS?UJ#E~Z?PjlHsCa5u+7{<qYxeHu1)(J~ z-j(QnTF;#4?Xly{x(g5b3Kh9#c>cL?@tJJ=YPHRi{h#jQUtKKd!6Xp<rsTBI*QjHM zR_19${JVYJaK_CiyL;tt8~$C)+4irwhQDXAs7asvE|qkV2Rb|UMJ!G<lQs;S_q5#D zTvm5Vm}kzX{gb8^n1oss2B)WQUGgqq!P3<_?<N)`UVL^j^Gtz#y{Zde>(&L#cV(u$ zTDsuCkB*kAotb%tWq0lGrigP#SLLxSbGRv5K4F^K`AyP?z7|w(n_^e+-CNam>7w|6 z)dh1d@>u3*E>KQc5nnUc@iN=Q@7JDP(n{o3^fgfAest66Sm~wCNwZIh>TESBsb60D z;=Wvn@B@Bs#gh+jO`CheFSq^Dgv!JRtXI>wK3&LtKVQ!62JfCCgM*v1Yi7IH$lEOq z)Xw>^W8sn`doC_i{B&otc}c{ttcE|w-5xF0YiV|FQ4#OFQ+&aRGi{^Uan(Zt-(ufM za5MO%W!6h<a^to+Z+6&9<NurxzvX5&`~M3Tf9~mM&x~;TvqVSANAe_Z_5NS)INP!= zzcbqMJHY%;LGSJD1|c=kw#;JE36}m*ks{XnrDmV{vdv)8wtcPa9+MWG&z-x6Csyd( ziO9acA!@u;t8e+|z6d<=x9a_Jlg@{Rn`eIiY^zor{renqKvLEAhEKJXDQu5_sEe_` zww|)8N@YrMw<Sw&+y$%aOCleg2;Z)>@z%aro7+V-l}neoITkMqndr;@`k0%4uFO0p zJ^lHAxa`svUOc7g-W0^UEbR&hTjVXj>5?D0i_{Jnu9mb_vM#FZy}`tL>!;2+0r$8+ z+YLYb46NDbt-OE9i$w=7p7r^?!$@!InrAt2;mjKv|0upZUuO5-$i%Xn;eXxKf{k__ zo934M%1gQT^6f?=pIxcB5`SecWNuHs9=>qfOWtP_%wu+Xrbu$<?QRfeR#=p@!pHc~ zfnPQ2kNcedbztst(_;yzPkDQNNr|%eEcmIpEK_?^&!S0x3NAj%w5xaJ-?#nQx?GFr z0TQ$BZD18(N|wp-pJ#FA?%Uges@m6iZfdg6tWRn@V0Ghyd~5Fl<qt<M+)EcfnKoxj zv_jBHL+;h0i`g&!R;)fB9(QW#%G{ELsc|8*KXdS;%A0*rmF0UVQa0aOGqiK(fdaO( z+pX(m&ez6lDW0apxg?>u=XA@o%R!O4C7+okXTN6kW9{NpztT3<!OeBDUZC%ztvLew z|FwEv?y8tHVKH~dUV(|fYyRuJR55jvk?RtVVEeL+ot5p@6~RTTw~9Rv)%wcQG&8sR zK>NX0SN^LxNo!rMZOr($t5WvUqB;5t4@p=ptNL#4)6ce*H8jFu%`?M2>u%&UPEuJM zeP&w63&uH&*Yf{x9C^B>!#aum#>^>Sk9tPCm@m4c)_#w-V7VU0_9>GjzPHpTnJF<W z`@3LSW3KUMTb}YOh2^^?fBXq;kovTj^X_RiOWw3t-FH1lO}3dtPZB?MyY*ELhZDmy z*)|Iv;mff}{TIr<b!9xX3Ve8=WrfHyiR1lDUp6-wztY~Uo2RQRx9=6tp&8m6r*Yl$ z-8<vz;_FY}S?1};JhX6D{yuHHPtx%ifk|PfXK3s@roV4WXMu6q3ZZu|Ju~ud9(@#_ z=%TATr=-#%-tMNrV~g{5Z29>9a$K1a^?Od_rQ0cy_iJC?x0ekG+4q~TaT9~YC5_!% znS}c`F4*XpASzX8CRALO5E3kDWcun!@ZX!^$*cTt#xDJHU+cW8OYI8_y-&F_H1iD; zeBNu^SP=Q*Q}2xHzSA{o9C+G_iZypE-0>|lzT^AbzpJ|yZp|wA%d|gDC-u;~D+W~y zl79b7a4-L4&3EqcVW*-irA&POPi-%pySUM!Qab76lCbdo&o4`>3S4vEk}h-bLS=c< z@{Rj9N2dlSoozWc=Xi6i>G>As-fven-|AtOGQSfc`9>ym=bXbbKQu!m3v*dgtj>OU zmhEG6Hu4YCp}&8-H!S>PU*z$xjnA>}cJ!&8JyCUEJYyGVomu*K|BI~qag&!fs+9-r zta8wJTbQutUisv{Blkjn%D>b;Hk);I-s;;NCps?*+%4j;usH8_tLf^cIXBpTC^D^_ ztF+3?y8fQI(rl*Bc6?dW{nvXu>C@`dI2PV<?4-z6^|-RV(|*|HTe++?4>wA?{_2_g zhbM>bzD&AsYo6HTwKJ_I|1xa3bV$?g|I0Ii%=5QY@0==jiMve8WWnsfPX=Guw6{cu z>$o3gTPppE!NLF0h1;?J&t!hQ-I*|<^Zf&TGw&CX%1o6rJw2tYyjTBt{qcgWXRX6p zFQH4P|6l7|nQDGxLU;$)Y@3UQB_Ais|I@tS9eh7%^<|-IrG0-NIVN2{-?Cp`wdhS} z?agc@Yi*%jk;_vp4$s^6@WZK#4-d>#J}B|L=jE}(mpI#1&w9l?U}f0)_yAMY*8ffG zf2_YJdN0<xyU9T6s)p-?klzy(Y(=<)xYy6~jCr+w<CC2M-&d=vneA=rQeb&8EyE_` z*2D>`r3$UOr4wg%PCfqBLGih__36^8Id?gqUXLs<6AGHqp?`Oh!>znizkj*xz9hP| ztZ{~NmEpP@$8rl3-X7hPeN5NPaZSIcS^J_K$;T2ZKPGhXuf1QUy8GlVW?8+<MM}2r z0*_bzS)Ja=SLAmmPu$t->kO^)FD=(<3#xW<99*KC`QG&UQ=RD2e{<rGa}=Knd?a!? z+fyKg|6rlkncaeCHnDBkxc86#Wnq5p^d$$?-8X*oD3w1fr+Zvn<feyH#Wn}A&q3Et z*1N9U{JU8&gm-;Gt^G6Cdq1u!HUx@!o+@7_ep4-`a6;gkL&fTU3JMSR2>v~@_e)a5 zp~cpFHd;7MJiPDvY;&u~NfI5c2W{VdoW1GroF4}Nywr1L{_Hk=^<+tRU=s7D*I^oY zIoFk^`P~&@x$~eZF}TO}{>4X`oGaE^=aw&$f9lJ%X_MRGzQ1R#ZvPY@Q1JOtz2w_j zkIqc95@F_;dnj`L{7?K#PDrcRxTl;pnUnOUT~+mMBkRe>*A5!Be2M+O(NQ(v^rzGh zHlgebjE#28|9*6(+Rg=z0tR9UACK)?V^n{*d4jy{tLqWx=32yRT&gv=!nNYqu9c51 zSq1sGvuB<V4XwHRv#BO=*YZF0(vjXr4XgJ)W;d-3Zam8TTh;33=^xpF2g|I!-Trbb zeEB7{ohj4#;>;puuGM6}8un0Sj!A;Z-`#9MNlGP_|0Sz9;(4X&)twK^BuqYcV#QOv zkf}%HHMjVmec^aRg7dSPa8BvPXKIt$xqP<Ogew)O>G-ZMC@|8<JhXlJ`Ig2QK^exh zMJvx%U4L8gIn`|P+3@)?7e5L7zj*ofia*_RxBt9ev6Zdr`x&)K&ZQ>WLg}?8TK|tN zuQ|=~Ch5h3%Elj2ev86IcCf7#v1y;+_b}Jw_vv<3sjWVoC%<0O*n0e&^t$+YVq9F? zJ7?@nUfHIae&~s+?{SaqI<=L4MM@ks%SsovcPCe#nJc}f_d^0>s*kw=_oU)y9||x2 zx!P_}=D9D7_3*kw>ttIa4+_s*b8zd~uQwNSf4y9mwDQL49Y<PAw&j~A-kPYo&E2_? z$JFHB490#ImWP2ejv6f!zkH_hlZwzu`*Z0YGq3MdElSxavXC?U-{t9DtJ-hReSXW< zJbzu}Y?DLp8eR&r{@X4vzxDc82e*5kMU!%B)C-SkoBi3pTH?*UON)gsU5N=zzjim! z-SCJ@_8P@09=AK@#Yk|?czsMHPjIP(o9&|7+QLI^k6T{|UFmncm@846aIS88u+PQC z*=$#gj3+OOJYewW$iaL=!!7~I5{o8{wcpihr50`wo3T6k(c8Yba0Z5lv*w)JceR0E zS~a|V=L!F|bMba_ymp;ld|#&jtD4!S8S^gJy=3D%!tv&#wAr~mSB>vab601VV6MN+ z#Nqsy`+e`VqlOGC^=rG=mi|>_KYT%c@sALdlXg-Hm#hB<PJOrXjIoY5%hJ+vY1_R0 zVecc3sqyCpTy&W({9(tgEdJs}3$Aq3`&>NsTj%7o<aM9lTiMUr&#uIfmEE^3!JGA) zsg1{XyY*lACLecM>$cm?p0jtZ_*{*qdalHe<xAe1nx&WCSLB-LrgmpfK`rOq?GfMP z{8I1nPq4chp`v(asn65)1->3lOo@IryeAg$u{8aAGU<Lneg6~#K90MMHsLxC&-7hL znm*s;X}8rWqXn9a6fV7uIxb$8JxO<}grzK_+!lc&u5T@8Ds*S8nIyr>qI7*{-`OWg zeX^-c8PAt_>MRa=x#0Hy^&eDO8+oG~*R?sxKb3!ZrS*Epu?6?MISQP`+SZ?t(E0JF zBk9(WH-`6wio%P6{2h*e_i;aet2rXc&CK#~%lb26D+SpWOlLARD`%X^xkP?_#P7EK zkM<UNt@t12{O`oowK1uSr2N+2O^H_xS2#Ake{byeEnCm++Om6ot_Y*&x=pKs#cSW1 zSM5KXX8f)5;?c7CQ@9^8Pit|A*Di0buXo(CRb%qZJO5{HwLX}~7*KJP<B#c$`+-pr zC4Zt+Cx$xp<}BQ>D|1mom!j2gRZ*KSN3Za2>HM)&-}CXOxFz~$OO{<SY7DArTCrm7 zq2QHnyUYG<7U=l&P>NqeSx%}@KXqcEpi$Rt`}ybM*q!(6wVb1{&+d#J({-c7it8u0 zaH>2go++54a4nc4I*Enh*#omU$ql;u(}nKO>74Fxo2T#F+kA$O25$Kxr(V(Xr!H}s zrHLGK|9@lhdg~O^$!`_J(*M*QnJfBx_iD3V*$K}|%+e-n%v-f=Yh3y=iBE1k3)^Qs z(XTz~d0vf4zroUTwvTT6%89%I=e9^$b1cobQ*!z-^)&BH?ebk#Yi>Wz{vi?An&_7z zWMF5YXu!$Fs?EpDB*n_WBC_|=0)w=*Udx@*zi=q&e4pVM_P~!t#D|Ml<;OLVKJ|B3 Tvzv}ZT5L>J)@Nd7oWKA8<KO^t literal 0 HcmV?d00001 diff --git a/vorgang-manager-server/src/test/resources/bayernid/bsp-nachricht b/vorgang-manager-server/src/test/resources/bayernid/bsp-nachricht new file mode 100644 index 0000000..531b80b --- /dev/null +++ b/vorgang-manager-server/src/test/resources/bayernid/bsp-nachricht @@ -0,0 +1 @@ +<ns4:sendBspNachrichtNative xmlns:ns3="http://www.akdb.de/egov/bsp/nachrichten" xmlns:ns4="urn:akdb:bsp:postkorb:komm:webservice"><bspNachricht><?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:BspNachricht xmlns:ns2="http://www.akdb.de/egov/bsp/nachrichten" xmlns:ns3="urn:akdb:bsp:postkorb:komm:webservice"><ns2:NachrichtenKopf><ns2:Identifikation.Nachricht><ns2:Erstellungszeitpunkt>2020-04-01T10:30:10.000Z</ns2:Erstellungszeitpunkt><ns2:NachrichtenId>1</ns2:NachrichtenId></ns2:Identifikation.Nachricht><ns2:Absender><ns2:Dienst>Stadtverwaltung</ns2:Dienst><ns2:Mandant>Fürth</ns2:Mandant><ns2:Gemeindeschluessel><ns2:Tabelle>36</ns2:Tabelle><ns2:Schluessel>09563000</ns2:Schluessel></ns2:Gemeindeschluessel></ns2:Absender><ns2:Empfaenger><ns2:PostkorbId>1</ns2:PostkorbId></ns2:Empfaenger></ns2:NachrichtenKopf><ns2:NachrichtenInhalt><ns2:Betreff>Test Subject</ns2:Betreff><ns2:StorkQaaLevel>LEVEL_1</ns2:StorkQaaLevel><ns2:ZuVorgang><ns2:VorgangsId>1</ns2:VorgangsId></ns2:ZuVorgang><ns2:FreiText><ns2:Encoding><ns2:Tabelle>9004</ns2:Tabelle><ns2:Schluessel>text/plain</ns2:Schluessel></ns2:Encoding><ns2:Text>BodyString</ns2:Text></ns2:FreiText></ns2:NachrichtenInhalt></ns2:BspNachricht></bspNachricht></ns4:sendBspNachrichtNative> \ No newline at end of file diff --git a/vorgang-manager-server/src/test/resources/bayernid/test.txt b/vorgang-manager-server/src/test/resources/bayernid/test.txt new file mode 100644 index 0000000..814be41 --- /dev/null +++ b/vorgang-manager-server/src/test/resources/bayernid/test.txt @@ -0,0 +1 @@ +some simple text \ No newline at end of file diff --git a/vorgang-manager-server/src/test/resources/junit-platform.properties b/vorgang-manager-server/src/test/resources/junit-platform.properties new file mode 100644 index 0000000..1cebb76 --- /dev/null +++ b/vorgang-manager-server/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled = true \ No newline at end of file diff --git a/pluto-utils/pom.xml b/vorgang-manager-utils/pom.xml similarity index 66% rename from pluto-utils/pom.xml rename to vorgang-manager-utils/pom.xml index 95d1f76..e5c4435 100644 --- a/pluto-utils/pom.xml +++ b/vorgang-manager-utils/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + 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 @@ -24,43 +24,40 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-dependencies</artifactId> - <version>1.2.1</version> - <relativePath /> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-dependencies</artifactId> + <version>3.0.1</version> + <relativePath/> </parent> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-utils</artifactId> - <name>Pluto Util Project</name> - <version>1.0.0</version> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-utils</artifactId> + <name>OZG-Cloud Vorgang Manager Utils</name> + <version>2.4.0</version> <properties> - <pluto.version>1.0.0</pluto.version> - <maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version> <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version> - - <maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version> - <maven-failsafe-plugin.version>3.0.0-M7</maven-failsafe-plugin.version> - <jacoco.plugin.version>0.8.8</jacoco.plugin.version> - - <lombok.version>1.18.24</lombok.version> + + <maven-surefire-plugin.version>3.2.2</maven-surefire-plugin.version> + <maven-failsafe-plugin.version>3.2.2</maven-failsafe-plugin.version> + <lombok.version>1.18.28</lombok.version> + </properties> <dependencies> <dependency> - <groupId>de.itvsh.kop.common</groupId> - <artifactId>kop-common-lib</artifactId> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-lib</artifactId> </dependency> <dependency> - <groupId>de.itvsh.ozg.pluto</groupId> - <artifactId>pluto-interface</artifactId> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> + <version>${project.version}</version> </dependency> <dependency> @@ -99,6 +96,18 @@ <artifactId>assertj-core</artifactId> <scope>test</scope> </dependency> + + <!-- commons --> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + <exclusions> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> + </dependency> </dependencies> <build> @@ -120,8 +129,6 @@ <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> - <source>${java.version}</source> - <target>${java.version}</target> <fork>true</fork> <annotationProcessorPaths> <path> @@ -138,14 +145,18 @@ <showWarnings>true</showWarnings> <compilerArgs> - <compilerArg> -Amapstruct.defaultComponentModel=spring + <compilerArg> + -Amapstruct.defaultComponentModel=spring </compilerArg> - <compilerArg> -Amapstruct.unmappedTargetPolicy=WARN + <compilerArg> + -Amapstruct.unmappedTargetPolicy=WARN </compilerArg> - <compilerArg> -Amapstruct.unmappedSourcePolicy=WARN + <compilerArg> + -Amapstruct.unmappedSourcePolicy=WARN </compilerArg> </compilerArgs> <generatedSourcesDirectory>target/generated-sources</generatedSourcesDirectory> + <release>${java.version}</release> </configuration> </plugin> @@ -155,7 +166,7 @@ <version>${maven-surefire-plugin.version}</version> <configuration> <argLine> - ${surefire.jacoco.args} + ${surefire.jacoco.args} </argLine> </configuration> </plugin> @@ -165,7 +176,7 @@ <version>${maven-failsafe-plugin.version}</version> <configuration> <argLine> - ${surefire.jacoco.args} + ${surefire.jacoco.args} </argLine> <classesDirectory>${project.build.outputDirectory}</classesDirectory> </configuration> @@ -181,7 +192,6 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>${jacoco.plugin.version}</version> <executions> <execution> <id>start-agent</id> @@ -201,6 +211,32 @@ </execution> </executions> </plugin> + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <mapping> + <config>SCRIPT_STYLE</config> + </mapping> + <licenseSets> + <licenseSet> + <header>license/eupl_v1_2_de/header.txt</header> + <excludes> + <exclude>**/README</exclude> + <exclude>src/test/resources/**</exclude> + <exclude>src/main/resources/**</exclude> + </excludes> + </licenseSet> + </licenseSets> + </configuration> + <dependencies> + <dependency> + <groupId>de.ozgcloud.common</groupId> + <artifactId>ozgcloud-common-license</artifactId> + <version>${ozgcloud.license.version}</version> + </dependency> + </dependencies> + </plugin> </plugins> </build> -</project> \ No newline at end of file +</project> diff --git a/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtils.java b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtils.java new file mode 100644 index 0000000..9e21907 --- /dev/null +++ b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtils.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static java.util.Objects.*; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.tuple.Pair; + +import de.ozgcloud.vorgang.vorgang.GrpcFormField; + +class FormDataMappingUtils { + + static final String VALUE_KEY = "value"; + static final String LABEL_KEY = "label"; + static final String CONTROL_DATA_KEY = "controlData"; + + static final String META_DATA_KEY = "metadata"; + + private FormDataMappingUtils() { + } + + static GrpcFormField buildFormField(String name, String value) { + return buildFormField(name, value, null); + } + + static GrpcFormField buildFormField(String name, String value, String label) { + var formFieldBuilder = GrpcFormField.newBuilder().setName(name).setValue(value); + if (nonNull(label)) { + formFieldBuilder.setLabel(label); + } + return formFieldBuilder.build(); + } + + static Map<String, Object> pairAccumulator(Map<String, Object> map, Pair<String, Map<String, Object>> pair) { + return addToMap(map, pair.getLeft(), pair.getRight()); + } + + static Map<String, Object> combiner(Map<String, Object> map, Map<String, Object> toAddMap) { + toAddMap.forEach((key, value) -> addToMap(map, key, value)); + return map; + } + + static Map<String, Object> addToMap(Map<String, Object> map, String name, Object value) { + map.compute(name, (k, v) -> isNull(v) ? value : merge(v, value)); + return map; + } + + static Object merge(Object currentValue, Object newValue) { + var result = buildListFrom(currentValue); + result.addAll(buildListFrom(newValue)); + return Collections.unmodifiableList(result); + } + + private static List<Object> buildListFrom(Object value) { + if (value instanceof Collection<?> values) { + return new LinkedList<>(values); + } else { + return new LinkedList<>(List.of(value)); + } + } + + static boolean isSubForm(Object value) { + return (!isValue(value) && getValueObject(value) instanceof Map); + } + + static boolean isValue(Object value) { + if (value instanceof Map<?, ?> valueMap) { + return valueMap.containsKey(VALUE_KEY) && + (valueMap.get(VALUE_KEY) instanceof String + || valueMap.get(VALUE_KEY) instanceof Number + || valueMap.get(VALUE_KEY) instanceof LocalDate + || valueMap.get(VALUE_KEY) instanceof Boolean); + } else { + return value instanceof String; + } + } + + static Object getValueObject(Object valueContainer) { + if (valueContainer instanceof Map<?, ?> valueMap) { + if (valueMap.containsKey(VALUE_KEY)) { + return valueMap.get(VALUE_KEY); + } + return valueContainer; + } else { + return valueContainer; + } + } + + static String getValue(Object valueContainer) { + return getValueObject(valueContainer).toString(); + } + + @SuppressWarnings("unchecked") + static Map<String, Object> getValueMap(Map<String, Object> valueContainer) { + if (valueContainer.containsKey(VALUE_KEY)) { + return (Map<String, Object>) valueContainer.get(VALUE_KEY); + } + return valueContainer; + } + + static Optional<String> getLabel(Object valueContainer) { + if (valueContainer instanceof Map<?, ?> valueMap) { + return Optional.ofNullable((String) valueMap.get(LABEL_KEY)); + } + return Optional.empty(); + } + + static boolean isMapWithLabel(Map<?, ?> map) { + return nonNull(map) && map.size() == 2 + && map.containsKey(LABEL_KEY) && map.containsKey(VALUE_KEY); + } + + @SuppressWarnings("unchecked") + public static <A, B> Map<A, B> getMap(Map<String, Object> map, String key, Map<A, B> defaultMap) { + return MapUtils.getMap(map, key, defaultMap); + } +} diff --git a/pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapper.java b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapper.java similarity index 53% rename from pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapper.java rename to vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapper.java index 18c8ead..d08694a 100644 --- a/pluto-utils/src/main/java/de/itvsh/kop/pluto/common/grpc/GrpcFormDataMapper.java +++ b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,26 +21,28 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.pluto.common.grpc; +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.FormDataMappingUtils.*; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.StringUtils; import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ReportingPolicy; -import de.itvsh.ozg.pluto.vorgang.GrpcFormData; -import de.itvsh.ozg.pluto.vorgang.GrpcFormField; -import de.itvsh.ozg.pluto.vorgang.GrpcSubForm; +import de.ozgcloud.vorgang.vorgang.GrpcFormData; +import de.ozgcloud.vorgang.vorgang.GrpcFormField; +import de.ozgcloud.vorgang.vorgang.GrpcSubForm; @Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, // unmappedSourcePolicy = ReportingPolicy.WARN, // @@ -58,14 +60,15 @@ public interface GrpcFormDataMapper { } default List<GrpcFormField> mapToAllFields(Map<String, Object> formData) { - return formData.entrySet().stream().filter(entry -> entry.getValue() instanceof String)// - .map(entry -> mapToField(entry.getKey(), entry.getValue().toString()))// + return formData.entrySet().stream() + .filter(entry -> isValue(entry.getValue())) + .map(entry -> mapToField(entry.getKey(), entry.getValue())) .toList(); } default List<GrpcFormField> mapStringListsToFields(Map<String, Object> formData) { return formData.entrySet().stream() - .filter(entry -> entry.getValue() instanceof List) + .filter(entry -> getValueObject(entry.getValue()) instanceof List) .map(this::mapListStringElementsToFormFields) .flatMap(List::stream) .toList(); @@ -73,108 +76,132 @@ public interface GrpcFormDataMapper { @SuppressWarnings("unchecked") private List<GrpcFormField> mapListStringElementsToFormFields(Entry<String, Object> entry) { - return ((List<Object>) entry.getValue()).stream() - .filter(String.class::isInstance) - .map(String.class::cast) - .map(e -> mapToField(entry.getKey(), e)) + return ((List<Object>) getValueObject(entry.getValue())).stream() + .filter(FormDataMappingUtils::isValue) + .map(valueContainer -> mapToField(entry.getKey(), valueContainer)) + .map(field -> getLabel(entry.getValue()).map(label -> field.toBuilder().setLabel(label).build()).orElse(field)) .toList(); } default List<GrpcSubForm> mapObjectListsToFields(Map<String, Object> formData) { return formData.entrySet().stream() - .filter(entry -> entry.getValue() instanceof List) + .filter(entry -> getValueObject(entry.getValue()) instanceof List) .map(this::mapListObjectElementsToFormFields) .flatMap(List::stream) .toList(); } @SuppressWarnings("unchecked") - private List<GrpcSubForm> mapListObjectElementsToFormFields(Entry<String, Object> entry) { - return ((List<Object>) entry.getValue()).stream() - .filter(Map.class::isInstance) + default List<GrpcSubForm> mapListObjectElementsToFormFields(Entry<String, Object> entry) { + return ((List<Object>) getValueObject(entry.getValue())).stream() + .filter(FormDataMappingUtils::isSubForm) .map(Map.class::cast) - .map(e -> buildSubForm(entry.getKey(), e)) + .map(valueMap -> buildSubForm(entry.getKey(), valueMap)) .toList(); } @SuppressWarnings("unchecked") default List<GrpcSubForm> mapToSubForms(Map<String, Object> formData) { return formData.entrySet().stream() - .filter(entry -> entry.getValue() instanceof Map) + .filter(entry -> isSubForm(entry.getValue())) .map(entry -> buildSubForm(entry.getKey(), (Map<String, Object>) entry.getValue())) .toList(); } default GrpcSubForm buildSubForm(String name, Map<String, Object> map) { + Map<String, Object> formMap = getValueMap(map); + return GrpcSubForm.newBuilder().setTitle(name) - .addAllField(mapToAllFields(map)) - .addAllSubForm(mapToSubForms(map)) - .addAllField(mapStringListsToFields(map)) - .addAllSubForm(mapObjectListsToFields(map)).build(); + .setLabel(getLabel(map).orElse(StringUtils.EMPTY)) + .addAllField(mapToAllFields(formMap)) + .addAllSubForm(mapToSubForms(formMap)) + .addAllField(mapStringListsToFields(formMap)) + .addAllSubForm(mapObjectListsToFields(formMap)).build(); } - default GrpcFormField mapToField(String name, String value) { - return GrpcFormField.newBuilder().setName(name).setValue(value).build(); + default GrpcFormField mapToField(String name, Object valueContainer) { + var fieldBuilder = GrpcFormField.newBuilder().setName(name).setValue(getValue(valueContainer)); + getLabel(valueContainer).ifPresent(fieldBuilder::setLabel); + return fieldBuilder.build(); } default Map<String, Object> mapFromFormData(GrpcFormData formData) { - Map<String, Object> result = new HashMap<>(); + Map<String, Object> result = new LinkedHashMap<>(); result.putAll(mapSubFormFields(formData.getFieldList())); result.putAll(mapFormData(formData.getFormList())); return result; } default Map<String, Object> mapFormData(List<GrpcSubForm> subForms) { - return subForms.stream().map(subForm -> Pair.of(subForm.getTitle(), mapSubForm(subForm))) - .collect(HashMap<String, Object>::new, this::pairAccumulator, this::combiner); + var subFormMap = subForms.stream() + .map(subForm -> new FormDataContainer(subForm.getTitle(), subForm.getLabel(), mapSubForm(subForm))) + .collect(LinkedHashMap::new, this::formDataAccumulator, this::combiner); + + return removeLeadingValueKey(subFormMap); } - private Map<String, Object> pairAccumulator(Map<String, Object> map, Pair<String, Map<String, Object>> pair) { - return addToMap(map, pair.getLeft(), pair.getRight()); + private Map<String, Object> formDataAccumulator(Map<String, Object> map, FormDataContainer container) { + return addToMap(map, container.name, container.formData, container.label); } default Map<String, Object> mapSubForm(GrpcSubForm subForm) { - Map<String, Object> result = new HashMap<>(); + Map<String, Object> result = new LinkedHashMap<>(); result.putAll(mapSubFormFields(subForm.getFieldList())); result.putAll(mapFormData(subForm.getSubFormList())); + return result; } default Map<String, Object> mapSubFormFields(List<GrpcFormField> fields) { - return fields.stream().collect(HashMap<String, Object>::new, this::accumulator, this::combiner); + var fieldMap = fields.stream().collect(LinkedHashMap::new, this::accumulator, this::combiner); + + return removeLeadingValueKey(fieldMap); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> removeLeadingValueKey(Map<String, Object> formMap) { + if (formMap.containsKey(VALUE_KEY)) { + return (Map<String, Object>) formMap.get(VALUE_KEY); + } + return formMap; } private Map<String, Object> accumulator(Map<String, Object> map, GrpcFormField field) { - return addToMap(map, field.getName(), field.getValue()); + return addToMap(map, field.getName(), field.getValue(), field.getLabel()); } default Map<String, Object> combiner(Map<String, Object> map1, Map<String, Object> map2) { for (Entry<String, Object> entry : map2.entrySet()) { - addToMap(map1, entry.getKey(), entry.getValue()); + addToMap(map1, entry.getKey(), entry.getValue(), null); } return map1; } @SuppressWarnings("unchecked") - private Map<String, Object> addToMap(Map<String, Object> map, String name, Object value) { + private Map<String, Object> addToMap(Map<String, Object> map, String name, Object value, String label) { var valueInMap = map.get(name); if (Objects.isNull(valueInMap)) { - map.put(name, value); + map.put(name, buildFieldMap(value, label)); + } else if (value instanceof Collection) { + addCollectionValue(map, name, (Collection<Object>) value, label); } else { - if (value instanceof Collection) { - addCollectionValue(map, name, (Collection<Object>) value); - } else { - addNonCollectionValue(map, name, value); - } + addNonCollectionValue(map, name, value, label); } return map; } + private Map<String, Object> buildFieldMap(Object value, String label) { + if (StringUtils.isNotBlank(label)) { + return Map.of(LABEL_KEY, label, VALUE_KEY, value); + } + return Map.of(VALUE_KEY, value); + } + @SuppressWarnings("unchecked") - private Map<String, Object> addCollectionValue(Map<String, Object> map, String name, Collection<Object> value) { - var valueInMap = map.get(name); + private Map<String, Object> addCollectionValue(Map<String, Object> map, String name, Collection<Object> value, String label) { + var valueInMap = getValueObject(map.get(name)); var newList = new LinkedList<Object>(); if (valueInMap instanceof Collection) { @@ -184,22 +211,33 @@ public interface GrpcFormDataMapper { newList.add(valueInMap); newList.addAll(value); } - map.put(name, newList); + map.put(name, buildWithLabel(newList, label)); return map; } @SuppressWarnings("unchecked") - private Map<String, Object> addNonCollectionValue(Map<String, Object> map, String name, Object value) { - var valueInMap = map.get(name); + private Map<String, Object> addNonCollectionValue(Map<String, Object> map, String name, Object value, String label) { + var valueInMap = getValueObject(map.get(name)); if (valueInMap instanceof Collection) { var newList = new LinkedList<>((Collection<Object>) valueInMap); newList.add(value); - map.put(name, newList); + map.put(name, buildWithLabel(newList, label)); } else { - map.put(name, new LinkedList<>(List.of(valueInMap, value))); + map.put(name, buildWithLabel(List.of(valueInMap, value), label)); } return map; } + + private Map<String, Object> buildWithLabel(Object value, String label) { + if (StringUtils.isBlank(label)) { + return Map.of(VALUE_KEY, value); + } + return Map.of(LABEL_KEY, label, VALUE_KEY, value); + } + + record FormDataContainer(String name, String label, Map<String, Object> formData) { + + } } diff --git a/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapper.java b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapper.java new file mode 100644 index 0000000..fd15c22 --- /dev/null +++ b/vorgang-manager-utils/src/main/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapper.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.mapstruct.Mapper; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.common.GrpcSubObject; + +@Mapper +public interface GrpcObjectMapper { + + Predicate<Entry<String, Object>> IS_VALUE_INSTANCEOF_MAP = entry -> entry.getValue() instanceof Map; + + default GrpcObject fromMap(Map<String, Object> map) { + return GrpcObject.newBuilder() + .addAllProperty(mapToAllProperties(map)) + .addAllSubObject(mapToSubObjects(map)) + .build(); + } + + @SuppressWarnings("unchecked") + default List<GrpcSubObject> mapToSubObjects(Map<String, Object> propertyMap) { + return propertyMap.entrySet().stream() + .filter(IS_VALUE_INSTANCEOF_MAP) + .map(entry -> buildSubObject(entry.getKey(), (Map<String, Object>) entry.getValue())) + .toList(); + } + + default GrpcSubObject buildSubObject(String name, Map<String, Object> map) { + return GrpcSubObject.newBuilder().setName(name) + .addAllProperty(mapToAllProperties(map)) + .addAllSubObject(mapToSubObjects(map)) + .build(); + } + + default List<GrpcProperty> mapToAllProperties(Map<String, Object> propertyMap) { + return propertyMap.entrySet().stream() + .filter(IS_VALUE_INSTANCEOF_MAP.negate()) + .map(entry -> mapToProperty(entry.getKey(), entry.getValue())) + .toList(); + } + + default GrpcProperty mapToProperty(String name, Object value) { + if (value instanceof Collection<?> valueList) { + return buildPropertyForValueList(name, valueList); + } + return buildPropertyForValueObject(name, value); + } + + private GrpcProperty buildPropertyForValueList(String name, Collection<?> valueList) { + return GrpcProperty.newBuilder().setName(name).addAllValue(valueList.stream().map(this::getStringValue).toList()).build(); + } + + private GrpcProperty buildPropertyForValueObject(String name, Object value) { + return GrpcProperty.newBuilder().setName(name).addValue(getStringValue(value)).build(); + } + + // TODO do null value handling externally configurable + private String getStringValue(Object value) { + return Optional.ofNullable(value).map(Object::toString).orElse(StringUtils.EMPTY); + } + + default Map<String, Object> mapFromGrpc(GrpcObject bodyObject) { + var map = new HashMap<String, Object>(); + bodyObject.getPropertyList().stream().map(this::mapProperty).forEach(entry -> map.put(entry.getKey(), entry.getValue())); + bodyObject.getSubObjectList().forEach(subObject -> map.put(subObject.getName(), mapSubObject(subObject))); + + return map; + } + + default Map<String, Object> mapSubObject(GrpcSubObject object) { + var map = new HashMap<String, Object>(); + object.getPropertyList().stream().map(this::mapProperty).forEach(entry -> map.put(entry.getKey(), entry.getValue())); + object.getSubObjectList().forEach(subObject -> map.put(subObject.getName(), mapSubObject(subObject))); + + return map; + } + + default Pair<String, Object> mapProperty(GrpcProperty property) { + return switch (property.getValueCount()) { + case 0 -> Pair.of(property.getName(), null); + case 1 -> Pair.of(property.getName(), property.getValue(0)); + default -> Pair.of(property.getName(), property.getValueList().stream().map(StringUtils::trimToNull).toList()); + }; + } +} \ No newline at end of file diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtilsTest.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtilsTest.java new file mode 100644 index 0000000..77db24b --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/FormDataMappingUtilsTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.FormDataMappingUtils.*; +import static de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import de.ozgcloud.vorgang.vorgang.GrpcFormField; + +class FormDataMappingUtilsTest { + + @Nested + class TestCombiner { + + @Test + void missingInMap2ShouldContainValue() { + Map<String, Object> map1 = Map.of("TEST", "VALUE1"); + Map<String, Object> map2 = Map.of(); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", "VALUE1"); + } + + @Test + void missingInMap1ShouldContainValue() { + Map<String, Object> map1 = new HashMap<>(); + Map<String, Object> map2 = Map.of("TEST", "VALUE1"); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", "VALUE1"); + } + + @Test + void inBothMapShouldCombineToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); + Map<String, Object> map2 = Map.of("TEST", "VALUE2"); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); + } + + @Test + void listInMap2ShouldStayAList() { + Map<String, Object> map1 = Map.of("TEST", List.of("VALUE1", "VALUE2")); + Map<String, Object> map2 = Map.of(); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); + } + + @Test + void valueInMap1ShouldBeAddedToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE2", "VALUE3")); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3")); + } + + @Test + void valueInMap2ShouldBeAddedToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); + Map<String, Object> map2 = Map.of("TEST", "VALUE3"); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3")); + } + + @Test + void listInMap1ShouldStayAList() { + Map<String, Object> map1 = new HashMap<>(); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE1", "VALUE2")); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); + } + + @Test + void listInBothMapsShouldByCombined() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE3", "VALUE4")); + + var combined = FormDataMappingUtils.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2", "VALUE3", "VALUE4")); + } + } + + @Nested + @DisplayName("Add value to map") + class TestAddValueToMap { + + private static final String KEY = "key"; + + private Map<String, Object> map = new HashMap<>(); + + @Test + void shouldAddValue() { + FormDataMappingUtils.addToMap(map, KEY, "value"); + + assertThat(map).containsEntry("key", "value"); + } + + @Test + void shouldAddCollection() { + FormDataMappingUtils.addToMap(map, KEY, List.of("value1", "value2")); + + assertThat(map).containsEntry("key", List.of("value1", "value2")); + } + + @Test + void shouldAddCollection2() { + map.put(KEY, "value"); + + FormDataMappingUtils.addToMap(map, KEY, List.of("value1", "value2")); + + assertThat(map).containsEntry("key", List.of("value", "value1", "value2")); + } + + @Test + void shouldAddCollection3() { + map.put(KEY, List.of("value")); + + FormDataMappingUtils.addToMap(map, KEY, List.of("value1", "value2")); + + assertThat(map).containsEntry("key", List.of("value", "value1", "value2")); + } + + @Test + void shouldAddToCollection() { + map.put(KEY, List.of("value")); + + FormDataMappingUtils.addToMap(map, KEY, "value1"); + + assertThat(map).containsEntry("key", List.of("value", "value1")); + } + + @Test + void shouldAddMap() { + var map2 = Map.of("key2", "value2"); + + FormDataMappingUtils.addToMap(map, KEY, map2); + + assertThat(map).containsEntry("key", map2); + } + } + + @Nested + @DisplayName("Build GrpcFormField") + class TestToGrpcFormField { + + private static String NAME = "name"; + private static String LABEL = "label value"; + private static String VALUE = "value"; + + @Test + void shouldSetValue() { + var field = buildFormField(); + + assertThat(field.getValue()).isEqualTo(GrpcFormFieldTestFactory.VALUE); + } + + @Test + void shouldMapName() { + var field = buildFormField(); + + assertThat(field.getName()).isEqualTo(GrpcFormFieldTestFactory.NAME); + } + + @Test + void shouldMapLabel() { + var field = buildFormField(); + + assertThat(field.getLabel()).isEqualTo(LABEL); + } + + @Test + void shouldMapWithoutLabel() { + var field = FormDataMappingUtils.buildFormField(NAME, VALUE); + + assertThat(field).isEqualTo(GrpcFormFieldTestFactory.createBuilder().clearLabel().build()); + } + + private GrpcFormField buildFormField() { + return FormDataMappingUtils.buildFormField(NAME, VALUE, LABEL); + } + + } + + @Nested + class TestGetLabel { + + @Test + void shouldReturnLabel() { + var label = FormDataMappingUtils.getLabel(Map.of(LABEL_KEY, FIELD_LABEL)); + + assertThat(label).contains(FIELD_LABEL); + } + + @Test + void shouldHandleAtomicValue() { + var label = FormDataMappingUtils.getLabel(FIELD_VALUE); + + assertThat(label).isEmpty(); + } + + @Test + void shouldHandleMissingLabel() { + var label = FormDataMappingUtils.getLabel(Map.of(VALUE_KEY, FIELD_VALUE)); + + assertThat(label).isEmpty(); + } + } +} \ No newline at end of file diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapperTest.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapperTest.java new file mode 100644 index 0000000..ced869a --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataMapperTest.java @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.FormDataMappingUtils.*; +import static de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Spy; + +import de.ozgcloud.vorgang.vorgang.GrpcFormData; +import de.ozgcloud.vorgang.vorgang.GrpcFormField; +import de.ozgcloud.vorgang.vorgang.GrpcSubForm; + +class GrpcFormDataMapperTest { + + @Spy + @InjectMocks + private GrpcFormDataMapper mapper = Mappers.getMapper(GrpcFormDataMapper.class); + + @Nested + class TestMapToAllFields { + @Test + void shouldMapFieldForStringValue() { + mapper.mapToAllFields(Map.of(FIELD_NAME, FIELD_VALUE)); + + verify(mapper).mapToField(FIELD_NAME, FIELD_VALUE); + } + + @Test + void shouldMapFieldForValueMap() { + Map<String, Object> valueMap = Map.of(VALUE_KEY, FIELD_VALUE); + + mapper.mapToAllFields(Map.of(FIELD_NAME, valueMap)); + + verify(mapper).mapToField(FIELD_NAME, valueMap); + } + + @Test + void shouldNOTMapFieldForSubForm() { + Map<String, Object> subForm = Map.of(SUBFORM_TITLE, Map.of(FIELD_NAME, FIELD_VALUE)); + + mapper.mapToAllFields(Map.of(FIELD_NAME, subForm)); + + verify(mapper, never()).mapToField(any(), any()); + } + + @Test + void souldNOTMapFieldForSubFormValue() { + Map<String, Object> subForm = Map.of(SUBFORM_TITLE, Map.of(FIELD_NAME, FIELD_VALUE)); + + mapper.mapToAllFields(Map.of(FIELD_NAME, Map.of(VALUE_KEY, subForm))); + + verify(mapper, never()).mapToField(any(), any()); + } + + @Nested + class MapToField { + + private Map<String, Object> valueContainer = Map.of(VALUE_KEY, FIELD_VALUE, LABEL_KEY, FIELD_LABEL); + + @Test + void shouldHaveName() { + var grpcField = mapper.mapToField(FIELD_NAME, valueContainer); + + assertThat(grpcField.getName()).isEqualTo(FIELD_NAME); + } + + @Test + void shouldHaveValue() { + var grpcField = mapper.mapToField(FIELD_NAME, valueContainer); + + assertThat(grpcField.getValue()).isEqualTo(FIELD_VALUE); + } + + @Test + void shouldHaveLabel() { + var grpcField = mapper.mapToField(FIELD_NAME, valueContainer); + + assertThat(grpcField.getLabel()).isEqualTo(FIELD_LABEL); + } + } + } + + @Nested + class TestSimpleValueMapping { + + @Test + void shouldHaveField() { + GrpcFormData formData = mapper.mapToFormData(Map.of("key", "value")); + + assertThat(formData.getFieldList()).hasSize(1); + } + + @Test + void shouldNotHaveSubForms() { + + GrpcFormData formData = mapper.mapToFormData(Map.of("key", "value")); + + assertThat(formData.getFormList()).isEmpty(); + } + + @Test + void shouldHaveNameField() { + + GrpcFormData formData = mapper.mapToFormData(Map.of("key", "value")); + + assertThat(formData.getField(0).getName()).isEqualTo("key"); + assertThat(formData.getField(0).getValue()).isEqualTo("value"); + } + } + + @Nested + class TestSubFormMapping { + + @Test + void shouldHaveSubForm() { + + GrpcFormData formData = mapper.mapToFormData(Map.of("key", Map.of("subKey", "value"))); + + assertThat(formData.getFormList()).hasSize(1); + } + + @Test + void shouldNotHaveFields() { + + GrpcFormData formData = mapper.mapToFormData(Map.of("key", Map.of("subKey", "value"))); + + assertThat(formData.getFieldList()).isEmpty(); + } + + @Test + void shouldHaveSubFormField() { + + GrpcFormData formData = mapper.mapToFormData(Map.of("key", Map.of("subKey", "value"))); + + assertThat(formData.getForm(0).getFieldList()).hasSize(1); + assertThat(formData.getForm(0).getTitle()).isEqualTo("key"); + assertThat(formData.getForm(0).getField(0).getName()).isEqualTo("subKey"); + assertThat(formData.getForm(0).getField(0).getValue()).isEqualTo("value"); + } + } + + @DisplayName("Mapped SubFormField") + @Nested + class TestSubFormFieldMapping { + + private final GrpcSubForm subForm = GrpcSubFormTestFactory.create(); + + @Test + void shouldContainField() { + var mapped = mapper.mapSubFormFields(subForm.getFieldList()); + + assertThat(mapped).containsKey(GrpcSubFormTestFactory.FIELD_NAME); + } + + @Test + void shouldContainValue() { + var mapped = mapper.mapSubFormFields(subForm.getFieldList()); + + assertThat(mapped).containsEntry(GrpcSubFormTestFactory.FIELD_NAME, GrpcSubFormTestFactory.FIELD); + } + + @Nested + class TestCombiner { + @Test + void missingInMap2ShouldContainValue() { + Map<String, Object> map1 = Map.of("TEST", "VALUE1"); + Map<String, Object> map2 = Map.of(); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", "VALUE1"); + } + + @Test + void missingInMap1ShouldContainValue() { + Map<String, Object> map1 = new HashMap<>(); + Map<String, Object> map2 = Map.of("TEST", "VALUE1"); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, "VALUE1")); + } + + @Test + void inBothMapShouldCombineToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); + Map<String, Object> map2 = Map.of("TEST", "VALUE2"); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, List.of("VALUE1", "VALUE2"))); + } + + @Test + void listInMap2ShouldStayAList() { + Map<String, Object> map1 = Map.of("TEST", List.of("VALUE1", "VALUE2")); + Map<String, Object> map2 = Map.of(); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", List.of("VALUE1", "VALUE2")); + } + + @Test + void valueInMap1ShouldBeAddedToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", "VALUE1")); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE2", "VALUE3")); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, List.of("VALUE1", "VALUE2", "VALUE3"))); + } + + @Test + void valueInMap2ShouldBeAddedToList() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); + Map<String, Object> map2 = Map.of("TEST", "VALUE3"); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, List.of("VALUE1", "VALUE2", "VALUE3"))); + } + + @Test + void listInMap1ShouldStayAList() { + Map<String, Object> map1 = new HashMap<>(); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE1", "VALUE2")); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, List.of("VALUE1", "VALUE2"))); + } + + @Test + void listInBothMapsShouldByCombined() { + Map<String, Object> map1 = new HashMap<>(Map.of("TEST", List.of("VALUE1", "VALUE2"))); + Map<String, Object> map2 = Map.of("TEST", List.of("VALUE3", "VALUE4")); + + var combined = mapper.combiner(map1, map2); + + assertThat(combined).containsEntry("TEST", Map.of(VALUE_KEY, List.of("VALUE1", "VALUE2", "VALUE3", "VALUE4"))); + } + } + } + + @Nested + class TestMapFormData { + + @Test + void shouldHaveTitleAsKey() { + var mapped = mapper.mapFormData(List.of(GrpcSubFormTestFactory.create())); + + assertThat(mapped).containsKey(TITLE); + } + + @SuppressWarnings("unchecked") + @Test + void shouldHaveLabel() { + var mapped = mapper.mapFormData(List.of(GrpcSubFormTestFactory.create())); + + assertThat((Map<String, Object>) mapped.get(TITLE)).containsEntry(LABEL_KEY, LABEL); + } + + @Test + void shouldHaveSubFormField() { + var mapped = mapKontaktSubForm(); + + assertThat(mapped).containsKey(FIELD_NAME); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> mapKontaktSubForm() { + var mapped = mapper.mapFormData(List.of(GrpcSubFormTestFactory.create())); + + var formMap = (Map<String, Object>) mapped.get(TITLE); + return (Map<String, Object>) formMap.get(VALUE_KEY); + } + + @SuppressWarnings("unchecked") + @Test + void shouldJoinIntoListInValue() { + var mapped = mapper.mapFormData(List.of(GrpcSubFormTestFactory.create(), GrpcSubFormTestFactory.create())); + + var formList = (Map<String, Object>) mapped.get(TITLE); + + assertThat(formList).containsKey(VALUE_KEY); + var value = (List<Map<String, Object>>) formList.get(VALUE_KEY); + assertThat(value).hasSize(2); + } + } + + @Nested + class TestMapStringListsToFields { + + @Test + void emptyMapShouldNotBeMapped() { + List<GrpcFormField> fields = mapper.mapStringListsToFields(Collections.emptyMap()); + + assertThat(fields).isEmpty(); + } + + @Test + void simpleValueShouldNotBeMapped() { + List<GrpcFormField> fields = mapper.mapStringListsToFields(Map.of("a", "b")); + + assertThat(fields).isEmpty(); + } + + @Test + void listObjectValuesShouldBeMapped() { + List<GrpcFormField> fields = mapper.mapStringListsToFields(Map.of("key", List.of("value1", "value2"))); + + assertThat(fields).hasSize(2); + assertThat(fields.get(0).getName()).isEqualTo("key"); + assertThat(fields.get(0).getValue()).isEqualTo("value1"); + + assertThat(fields.get(1).getName()).isEqualTo("key"); + assertThat(fields.get(1).getValue()).isEqualTo("value2"); + } + + @Test + void shouldMapValueList() { + var fields = mapper.mapStringListsToFields(Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(FIELD_VALUE)))); + + assertThat(fields).hasSize(1).first().extracting(GrpcFormField::getValue).isEqualTo(FIELD_VALUE); + } + + @Test + void shouldAddLabel() { + var fields = mapper.mapStringListsToFields(Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(FIELD_VALUE)))); + + assertThat(fields).hasSize(1).first().extracting(GrpcFormField::getLabel).isEqualTo(FIELD_LABEL); + } + } + + @Nested + class TestMapObjectListsToFields { + + @Captor + private ArgumentCaptor<Entry<String, Object>> entryCaptor; + + @Test + void simpleValueShouldNotBeMapped() { + List<GrpcSubForm> fields = mapper.mapObjectListsToFields(Map.of("a", "b")); + + assertThat(fields).isEmpty(); + } + + @Test + void listOfSimpleValueShouldNotBeMapped() { + List<GrpcSubForm> fields = mapper.mapObjectListsToFields(Map.of("a", List.of("l1", "l2"))); + + assertThat(fields).isEmpty(); + } + + @Test + void listOfObjectsShouldBeMappedToSubForms() { + List<GrpcSubForm> fields = mapper + .mapObjectListsToFields(Map.of("key", List.of(Collections.emptyMap(), Collections.emptyMap()))); + + assertThat(fields).hasSize(2); + } + + @Test + void listOfObjectsShouldMappedToSubFormTitle() { + List<GrpcSubForm> fields = mapper.mapObjectListsToFields(Map.of("key", List.of(Collections.emptyMap(), Collections.emptyMap()))); + + assertThat(fields.get(0).getTitle()).isEqualTo("key"); + assertThat(fields.get(1).getTitle()).isEqualTo("key"); + } + + @Test + void listOfObjectsShouldBeMapped() { + List<GrpcSubForm> fields = mapper.mapObjectListsToFields(Map.of("key", List.of(Map.of("a1", "a2")))); + + assertThat(fields.get(0).getFieldCount()).isEqualTo(1); + assertThat(fields.get(0).getField(0).getName()).isEqualTo("a1"); + assertThat(fields.get(0).getField(0).getValue()).isEqualTo("a2"); + } + + @Test + void shouldMapSubForm() { + List<GrpcSubForm> subForms = mapper.mapObjectListsToFields(Map.of(SUBFORM_TITLE, List.of(SUBFORM))); + + assertThat(subForms).hasSize(1); + + assertThat(subForms.get(0).getField(0).getName()).isEqualTo(SUBFORM_FIELD_NAME); + assertThat(subForms.get(0).getField(0).getValue()).isEqualTo(SUBFORM_FIELD_VALUE); + } + + @Test + void shouldMapListOfObjectsWithLabel() { + List<GrpcSubForm> subForms = mapper.mapObjectListsToFields(Map.of(SUBFORM_TITLE, List.of(SUBFORM))); + + assertThat(subForms).hasSize(1); + var subForm = subForms.get(0); + + assertThat(subForm.getLabel()).isEqualTo(SUBFORM_LABEL); + assertThat(subForm.getField(0).getLabel()).isEqualTo(SUBFORM_FIELD_LABEL); + } + + @Test + void doubleNestedListObjectValuesShouldBeMapped() { + GrpcFormData formData = mapper.mapToFormData(Map.of("key1", Map.of("key2", List.of("value1", "value2")))); + + assertThat(formData.getForm(0).getFieldCount()).isEqualTo(2); + } + + @Test + void multipleNestedListObjectValuesShouldBeMapped() { + GrpcFormData formData = mapper.mapToFormData(Map.of("key1", Map.of("key2", Map.of("key3", List.of("value1", "value2"))))); + + assertThat(formData.getForm(0).getSubForm(0).getFieldCount()).isEqualTo(2); + } + + @Test + void shouldCallMappingMethodForValueList() { + mapper.mapObjectListsToFields(Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(SUBFORM)))); + + verify(mapper).mapListObjectElementsToFormFields(entryCaptor.capture()); + assertThat(entryCaptor.getValue().getKey()).isEqualTo(FIELD_NAME); + assertThat(entryCaptor.getValue().getValue()).isInstanceOf(Map.class); + } + + @Test + void shouldAddLabel() { + var subForms = mapper.mapObjectListsToFields(Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(SUBFORM)))); + + assertThat(subForms).hasSize(1).first().extracting(GrpcSubForm::getLabel).isEqualTo(SUBFORM_LABEL); + } + } + + @Nested + class TestMapListOfMixedValuesInFormData { + + @Test + void shouldMapListOfStrings() { + GrpcFormData formData = mapper + .mapToFormData(Map.of("key", List.of("value1", "value2", Map.of("internKey1", "internValue1")))); + + assertThat(formData.getFieldCount()).isEqualTo(2); + assertThat(formData.getFormCount()).isEqualTo(1); + } + } + + @Nested + class TestMapListObjectElementsToFormFields { + @Test + void shouldMapValueMap() { + Map<String, Object> formData = Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(SUBFORM))); + + var result = mapper.mapListObjectElementsToFormFields(formData.entrySet().iterator().next()); + + assertThat(result).hasSize(1).first().extracting(GrpcSubForm::getTitle).isEqualTo(FIELD_NAME); + } + + @Test + void shouldAddLabel() { + Map<String, Object> formData = Map.of(FIELD_NAME, Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, List.of(SUBFORM))); + + var result = mapper.mapListObjectElementsToFormFields(formData.entrySet().iterator().next()); + + assertThat(result).hasSize(1).first().extracting(GrpcSubForm::getLabel).isEqualTo(SUBFORM_LABEL); + } + } + + @Nested + class TestBuildSubForm { + + @Test + void shouldHaveLabel() { + var grpc = mapper.buildSubForm(SUBFORM_TITLE, SUBFORM); + + assertThat(grpc.getLabel()).isEqualTo(SUBFORM_LABEL); + } + + } +} diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataTestFactory.java new file mode 100644 index 0000000..08e7509 --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormDataTestFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import de.ozgcloud.vorgang.vorgang.GrpcFormData; +import de.ozgcloud.vorgang.vorgang.GrpcFormData.Builder; + +public class GrpcFormDataTestFactory { + + public static GrpcFormData create() { + return createBuilder().build(); + } + + public static Builder createBuilder() { + return GrpcFormData.newBuilder() + .addField(GrpcFormFieldTestFactory.create()); + } +} diff --git a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormFieldTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormFieldTestFactory.java similarity index 72% rename from pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormFieldTestFactory.java rename to vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormFieldTestFactory.java index 7388b00..a5e53a8 100644 --- a/pluto-utils/src/test/java/de/itvsh/kop/pluto/common/grpc/GrpcFormFieldTestFactory.java +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcFormFieldTestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * 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 @@ -21,22 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.itvsh.kop.pluto.common.grpc; +package de.ozgcloud.vorgang.common.grpc; -import de.itvsh.ozg.pluto.vorgang.GrpcFormField; +import de.ozgcloud.vorgang.vorgang.GrpcFormField; public class GrpcFormFieldTestFactory { - public static final String TEST_NAME = "name"; - public static final String TEST_VALUE = "value"; + public static final String NAME = "name"; + public static final String VALUE = "value"; + public static final String LABEL = "label"; public static GrpcFormField create() { return createBuilder().build(); } - private static GrpcFormField.Builder createBuilder() { + public static GrpcFormField.Builder createBuilder() { return GrpcFormField.newBuilder() - .setName(TEST_NAME) - .setValue(TEST_VALUE); + .setName(NAME) + .setValue(VALUE) + .setLabel(LABEL); } } diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapperTest.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapperTest.java new file mode 100644 index 0000000..b891576 --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectMapperTest.java @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.GrpcObjectTestFactory.createAsMap; +import static de.ozgcloud.vorgang.common.grpc.GrpcPropertyTestFactory.*; +import static de.ozgcloud.vorgang.common.grpc.GrpcSubObjectTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.Spy; + +import de.ozgcloud.common.binaryfile.FileId; +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.common.GrpcSubObject; + +class GrpcObjectMapperTest { + + @Spy + private final GrpcObjectMapper mapper = Mappers.getMapper(GrpcObjectMapper.class); + + @DisplayName("From map") + @Nested + class TestFromMap { + + @Test + void shouldCallMapToAllProperties() { + var sourceMap = createAsMap(); + + mapper.fromMap(sourceMap); + + verify(mapper).mapToAllProperties(sourceMap); + } + + @Test + void shouldCallMapToSubObjects() { + var sourceMap = createAsMap(); + + mapper.fromMap(sourceMap); + + verify(mapper).mapToSubObjects(sourceMap); + } + + @Test + void shouldMapToGrpcObject() { + var sourceMap = createAsMap(); + + var grpcObject = mapper.fromMap(sourceMap); + + assertThat(grpcObject).isEqualTo(GrpcObjectTestFactory.create()); + } + + @DisplayName("should map type") + @Nested + class TestByType { + + @DisplayName("Long") + @Test + void shouldMapLongMapToGrpc() { + var value = 42L; + var expectedProperty = GrpcPropertyTestFactory.createWithValue(value); + + var grpcObject = mapFromMap(value); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + @DisplayName("Integer") + @Test + void shouldMapIntegerMapToGrpc() { + var expectedProperty = GrpcPropertyTestFactory.createWithValue(Integer.MAX_VALUE); + + var grpcObject = mapFromMap(Integer.MAX_VALUE); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + @DisplayName("Boolean") + @Test + void shouldMapBooleanMapToGrpc() { + var expectedProperty = GrpcPropertyTestFactory.createWithValue(Boolean.TRUE); + + var grpcObject = mapFromMap(Boolean.TRUE); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + @DisplayName("LocalDate") + @Test + void shouldMapLocalDateMapToGrpc() { + var date = "2022-12-11"; + var expectedProperty = GrpcPropertyTestFactory.createWithValue(date); + + var grpcObject = mapFromMap(LocalDate.parse(date)); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + @DisplayName("ZonedDateTime") + @Test + void shouldMapZonedDateTimeMapToGrpc() { + var zonedDateTime = "2007-12-03T10:15:30+01:00"; + var expectedProperty = GrpcPropertyTestFactory.createWithValue(zonedDateTime); + + var grpcObject = mapFromMap(ZonedDateTime.parse(zonedDateTime)); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + @DisplayName("FileId") + @Test + void shouldMapFileIdMapToGrpc() { + var fileId = FileId.createNew(); + var expectedProperty = GrpcPropertyTestFactory.createWithValue(fileId); + + var grpcObject = mapFromMap(fileId); + + assertThat(grpcObject.getPropertyList()).hasSize(1).first().isEqualTo(expectedProperty); + } + + private GrpcObject mapFromMap(Object value) { + return mapper.fromMap(Map.of(PROPERTY_NAME, value)); + } + + } + } + + @DisplayName("Map all properties") + @Nested + class TestMapAllProperties { + + private Map<String, Object> propertyMap = Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE); + + @Test + void shouldCallMapToProperty() { + mapper.mapToAllProperties(propertyMap); + + verify(mapper, times(1)).mapToProperty(PROPERTY_NAME, PROPERTY_NAME_VALUE); + } + + @Test + void shouldMapToProperty() { + var grpcProperties = mapper.mapToAllProperties(propertyMap); + + assertThat(grpcProperties).isEqualTo(List.of(GrpcPropertyTestFactory.create())); + } + + @Test + void shouldNotCallMapToPropertyOnMap() { + mapper.mapToAllProperties(Map.of(PROPERTY_NAME, propertyMap)); + + verify(mapper, never()).mapToProperty(any(), any()); + } + } + + @DisplayName("Map property") + @Nested + class TestMapProperty { + + @DisplayName("should map null value of property to an empty string") + @Test + void shouldMapNullValueToEmptyString() { + var grpcProperty = mapper.mapToProperty(PROPERTY_NAME, null); + + assertThat(grpcProperty.getValueList()).containsExactly(StringUtils.EMPTY); + } + + @DisplayName("should map if value is a collection") + @Test + void shouldMapValueAsCollection() { + var grpcProperty = mapper.mapToProperty(PROPERTY_NAME, Set.of(PROPERTY_NAME_VALUE, "another_value")); + + assertThat(grpcProperty.getValueList()).containsExactlyInAnyOrder(PROPERTY_NAME_VALUE, "another_value"); + } + + @DisplayName("should map if value is a collection containing null") + @Test + void shouldMapValueAsCollectionContainsNull() { + var listContainsNull = Collections.singletonList(null); + + var grpcProperty = mapper.mapToProperty(PROPERTY_NAME, listContainsNull); + + assertThat(grpcProperty.getValueList()).containsExactly(StringUtils.EMPTY); + } + + @DisplayName("should map if value is a list considering the order of the values") + @Test + void shouldMapValueAsListConsideringOrder() { + var list = List.of("firstProperty", "secondProperty"); + + var grpcProperty = mapper.mapToProperty(PROPERTY_NAME, list); + + assertThat(grpcProperty.getValueList()).containsExactly("firstProperty", "secondProperty"); + } + + } + + @DisplayName("Map subObject") + @Nested + class TestMapSubObject { + + @Test + void shouldCallBuildSubObject() { + var propertyValueAsMap = Map.<String, Object>of("additionalPropertName", "additionalPropertyNameValue"); + mapper.mapToSubObjects(Map.of(PROPERTY_NAME, propertyValueAsMap)); + + verify(mapper).buildSubObject(PROPERTY_NAME, propertyValueAsMap); + } + + @Test + void shouldNotCallBuildSubObjectOnNonMapValue() { + mapper.mapToSubObjects(Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE)); + + verify(mapper, never()).buildSubObject(any(), any()); + } + } + + @DisplayName("Build subObject") + @Nested + class TestBuildSubObject { + + @Test + void shouldCallMapAllProperties() { + mapper.buildSubObject(PROPERTY_NAME, GrpcPropertyTestFactory.createAsMap()); + + verify(mapper).mapToAllProperties(GrpcPropertyTestFactory.createAsMap()); + } + + @Test + void shouldCallMapSubObject() { + mapper.buildSubObject(PROPERTY_NAME, GrpcPropertyTestFactory.createAsMap()); + + verify(mapper).mapToSubObjects(GrpcPropertyTestFactory.createAsMap()); + } + + @Test + void shouldAddPropertiesToSubObject() { + var wantedProperty = GrpcPropertyTestFactory.create(); + + var grpcSubObject = mapper.buildSubObject(GrpcSubObjectTestFactory.SUB_OBJECT_NAME, Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE)); + + assertThat(grpcSubObject.getPropertyList()).hasSize(1).first().isEqualTo(wantedProperty); + } + } + + @Nested + class TestMapFromGrpcProperty { + + @Test + @DisplayName("should map grpc property into map") + void shouldMapProperty() { + var targetMap = mapper.mapProperty(GrpcPropertyTestFactory.create()); + + assertThat(targetMap).isEqualTo(Pair.of(PROPERTY_NAME, PROPERTY_NAME_VALUE)); + } + + @Test + @DisplayName("should map property with collection as value to map") + void shouldMapAllPropertyValues() { + var anotherValue = "anotherPropertyValue"; + var grpcProperty = GrpcPropertyTestFactory.createBuilder().addValue(anotherValue).build(); + + var targetMap = mapper.mapProperty(grpcProperty); + + assertThat(targetMap).isEqualTo(Pair.of(PROPERTY_NAME, List.of(PROPERTY_NAME_VALUE, anotherValue))); + } + + @Test + @DisplayName("should map property without value to map") + void shouldMapEmptyProperty() { + var targetMap = mapper.mapProperty(GrpcPropertyTestFactory.createWithoutValue()); + + assertThat(targetMap).isEqualTo(Pair.of(PROPERTY_NAME, null)); + } + + @Test + void shouldTrimToNull() { + GrpcProperty grpcProperty = GrpcPropertyTestFactory.createBuilder().addValue(StringUtils.EMPTY).build(); + + var resultEntry = mapper.mapProperty(grpcProperty); + + assertThat(resultEntry).isEqualTo(Pair.of(PROPERTY_NAME, Arrays.asList(PROPERTY_NAME_VALUE, null))); + } + + } + + @Nested + class TestMapFromGrpcObject { + + @Test + void shouldMapFromGrpcObject() { + Map<String, Object> wantedMap = Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE, SUB_OBJECT_NAME, createSubObjectMap()); + var map = mapper.mapFromGrpc(GrpcObjectTestFactory.create()); + + assertThat(map).containsAllEntriesOf(wantedMap); + } + } + + @Nested + class TestMapFromSubObject { + + @Test + @DisplayName("should map subObject into a map") + void shouldMapSubObject() { + var resultMap = mapper.mapSubObject(GrpcSubObjectTestFactory.create()); + + assertThat(resultMap).containsAllEntriesOf(createSubObjectMap()); + } + + @Test + @DisplayName("should map empty property values of subObject to nulls") + void shouldMapSubObjectEmptyValues() { + var grpcSubObject = GrpcSubObject.newBuilder().setName(SUB_OBJECT_NAME).addProperty(createWithoutValue()).build(); + + var resultMap = mapper.mapSubObject(grpcSubObject); + + assertThat(resultMap).containsEntry(PROPERTY_NAME, null); + } + + } + + private static Map<String, Object> createSubObjectMap() { + return Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE, SUB_SUB_OBJECT_NAME, Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE)); + } +} diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectTestFactory.java new file mode 100644 index 0000000..47502cb --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcObjectTestFactory.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.GrpcPropertyTestFactory.*; +import static de.ozgcloud.vorgang.common.grpc.GrpcSubObjectTestFactory.*; + +import java.util.Map; + +import de.ozgcloud.vorgang.common.GrpcObject; + +public class GrpcObjectTestFactory { + + public static GrpcObject create() { + return createBuilder().build(); + } + + public static GrpcObject.Builder createBuilder() { + return GrpcObject.newBuilder() + .addProperty(GrpcPropertyTestFactory.create()) + .addSubObject(GrpcSubObjectTestFactory.create()); + } + + public static Map<String, Object> createAsMap() { + var subSubMap = Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE); + var subMap = Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE, SUB_SUB_OBJECT_NAME, subSubMap); + return Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE, SUB_OBJECT_NAME, subMap); + } +} \ No newline at end of file diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcPropertyTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcPropertyTestFactory.java new file mode 100644 index 0000000..f81643b --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcPropertyTestFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import java.util.Map; + +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.common.GrpcProperty.Builder; + +public class GrpcPropertyTestFactory { + + public static final String PROPERTY_NAME = "propertyName"; + public static final String PROPERTY_NAME_VALUE = "propertyNameValue"; + + public static GrpcProperty create() { + return createBuilder().build(); + } + + public static GrpcProperty createWithoutValue() { + return createBuilder().clearValue().build(); + } + public static GrpcProperty createWithValue(Object value) { + return createBuilder().clearValue().addValue(String.valueOf(value)).build(); + } + + public static Builder createBuilder() { + return GrpcProperty.newBuilder() + .setName(PROPERTY_NAME) + .addValue(PROPERTY_NAME_VALUE); + } + + public static Map<String, Object> createAsMap() { + return Map.of(PROPERTY_NAME, PROPERTY_NAME_VALUE); + } +} diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubFormTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubFormTestFactory.java new file mode 100644 index 0000000..875c6d2 --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubFormTestFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.vorgang.common.grpc; + +import static de.ozgcloud.vorgang.common.grpc.FormDataMappingUtils.*; + +import java.util.Map; + +import de.ozgcloud.vorgang.vorgang.GrpcFormField; +import de.ozgcloud.vorgang.vorgang.GrpcSubForm; + +public class GrpcSubFormTestFactory { + + public static final String TITLE = "kontakt"; + public static final String LABEL = "Alternative kontakt Label"; + + public static final String FIELD_NAME = "vorname"; + public static final String FIELD_VALUE = "Thea"; + public static final String FIELD_LABEL = "Alternative name Label"; + public static final Map<String, Object> FIELD = Map.of(LABEL_KEY, FIELD_LABEL, VALUE_KEY, FIELD_VALUE); + + public static final String SUBFORM_TITLE = "otherData"; + public static final String SUBFORM_LABEL = "Alternative otherData label"; + + public static final String SUBFORM_FIELD_NAME = "E-Mail"; + public static final String SUBFORM_FIELD_VALUE = "thea@mailinator.de"; + public static final String SUBFORM_FIELD_LABEL = "Alternative E-mail label"; + public static final Map<String, Object> SUBFORM_FIELD = Map.of(VALUE_KEY, SUBFORM_FIELD_VALUE, LABEL_KEY, SUBFORM_FIELD_LABEL); + + public static final Map<String, Object> SUBFORM = Map.of(VALUE_KEY, Map.of(SUBFORM_FIELD_NAME, SUBFORM_FIELD), LABEL_KEY, SUBFORM_LABEL); + + public static GrpcSubForm create() { + return createBuilder().build(); + } + + public static GrpcSubForm.Builder createBuilder() { + return GrpcSubForm.newBuilder() + .setTitle(TITLE).setLabel(LABEL) + .addField(GrpcFormField.newBuilder().setName(FIELD_NAME).setValue(FIELD_VALUE).setLabel(FIELD_LABEL).build()) + .addSubForm(GrpcSubForm.newBuilder().setTitle(SUBFORM_TITLE).setLabel(SUBFORM_LABEL) + .addField(GrpcFormField.newBuilder() + .setName(SUBFORM_FIELD_NAME) + .setLabel(SUBFORM_FIELD_LABEL) + .setValue(SUBFORM_FIELD_VALUE) + .build())); + } + + public static GrpcSubForm createWithLabels() { + return createWithLabelsBuilder().build(); + } + + public static GrpcSubForm.Builder createWithLabelsBuilder() { + return GrpcSubForm.newBuilder() + .setTitle(TITLE) + .addField(GrpcFormField.newBuilder().setName(FIELD_NAME).setValue(FIELD_VALUE).setLabel(FIELD_LABEL)) + .addSubForm(GrpcSubForm.newBuilder().setTitle(SUBFORM_TITLE).setLabel(SUBFORM_LABEL) + .addField(GrpcFormField.newBuilder() + .setName(SUBFORM_FIELD_NAME) + .setValue(SUBFORM_FIELD_VALUE) + .setLabel(SUBFORM_FIELD_LABEL) + .build())) + .setLabel(LABEL); + } +} \ No newline at end of file diff --git a/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubObjectTestFactory.java b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubObjectTestFactory.java new file mode 100644 index 0000000..ec9751b --- /dev/null +++ b/vorgang-manager-utils/src/test/java/de/ozgcloud/vorgang/common/grpc/GrpcSubObjectTestFactory.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.vorgang.common.grpc; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.vorgang.common.GrpcSubObject; +import de.ozgcloud.vorgang.common.GrpcSubObject.Builder; + +public class GrpcSubObjectTestFactory { + + public static final String SUB_OBJECT_NAME = LoremIpsum.getInstance().getWords(1); + public static final String SUB_SUB_OBJECT_NAME = LoremIpsum.getInstance().getWords(1); + + public static GrpcSubObject create() { + return createBuilder().build(); + } + + public static Builder createBuilder() { + return GrpcSubObject.newBuilder() + .setName(SUB_OBJECT_NAME) + .addProperty(GrpcPropertyTestFactory.create()) + .addSubObject(GrpcSubObject.newBuilder() + .setName(SUB_SUB_OBJECT_NAME) + .addProperty(GrpcPropertyTestFactory.create())); + } +} diff --git a/vorgang-manager-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/vorgang-manager-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 0000000..79b126e --- /dev/null +++ b/vorgang-manager-utils/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1 @@ +org.mockito.junit.jupiter.MockitoExtension \ No newline at end of file diff --git a/vorgang-manager-utils/src/test/resources/junit-platform.properties b/vorgang-manager-utils/src/test/resources/junit-platform.properties new file mode 100644 index 0000000..1cebb76 --- /dev/null +++ b/vorgang-manager-utils/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled = true \ No newline at end of file -- GitLab