diff --git a/archive-manager-server/pom.xml b/archive-manager-server/pom.xml index e227c8c5824f7dafe3c82935cdd23efb486ab370..1fb65a9297a092b47a988edd515d797f37d77a0e 100644 --- a/archive-manager-server/pom.xml +++ b/archive-manager-server/pom.xml @@ -95,6 +95,10 @@ <groupId>de.ozgcloud.document</groupId> <artifactId>document-manager-interface</artifactId> </dependency> + <dependency> + <groupId>de.ozgcloud.xta</groupId> + <artifactId>xta-client-lib</artifactId> + </dependency> <!-- Spring --> <dependency> diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java index cae0d47eb139ac4eb1733ee9802a8276dccf5b29..90f158d548309ca8961473fb78cafec16219e6d4 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java @@ -81,7 +81,6 @@ public class ArchiveManagerConfiguration { public static final String CALL_CONTEXT_PROVIDER_NAME = "archive_CallContextProvider"; public static final String CALL_CONTEXT_MAPPER_NAME = "archive_CallContextMapper"; - public static final String CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_ClientAttributeService"; public static final String OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_OzgCloudClientAttributeService"; public static final String KOMMENTAR_SERVICE_NAME = "archive_KommentarService"; diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java similarity index 63% rename from archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java rename to archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java index 83e74246a033293f93b5790a2c74d50f982043ae..1525b91fcbe26e08c3b1464869a5e23b8f380f41 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.archive.vorgang; +package de.ozgcloud.archive.archivierung; import java.util.function.Consumer; import java.util.function.Predicate; @@ -34,48 +34,81 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.stereotype.Component; import de.ozgcloud.archive.ArchiveManagerConfiguration; -import de.ozgcloud.archive.attributes.ClientAttributeService; +import de.ozgcloud.archive.common.callcontext.CallContextUser; import de.ozgcloud.archive.common.callcontext.CurrentUserService; +import de.ozgcloud.archive.common.command.CommandService; +import de.ozgcloud.archive.common.errorhandling.TimeoutException; +import de.ozgcloud.archive.vorgang.VorgangService; import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandCreatedEvent; import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.command.VorgangLockedEvent; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; -@Component() +@Component @RequiredArgsConstructor @Log4j2 -class ArchiveEventListener { +public class ArchiveEventListener { + static final int MAXIMUM_CHECKS_FOR_PENDING_COMMANDS = 3; + static final int WAIT_INTERVAL = 30 * 1000; private static final String LOG_MESSAGE_TEMPLATE = "{}. Command failed."; private static final String ERROR_MESSAGE_TEMPLATE = "Error on executing %s Command (id: %s)."; static final String ARCHIVE_VORGANG_ORDER = "ARCHIVE_VORGANG"; - private static final String IS_ARCHIVE_VORGANG_EVENT = - "{T(de.ozgcloud.archive.vorgang.ArchiveEventListener).IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}"; + private static final String IS_ARCHIVE_VORGANG_EVENT = "{T(de.ozgcloud.archive.archivierung.ArchiveEventListener).IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}"; public static final Predicate<Command> IS_ARCHIVE_VORGANG_COMMAND = command -> ARCHIVE_VORGANG_ORDER.equals(command.getOrder()); + private static final String IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT = "{T(de.ozgcloud.archive.archivierung.ArchiveEventListener)." + + "IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND.test(event.getCommand())}"; + public static final Predicate<Command> IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND = command -> CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME + .equals(command.getCreatedByClientName()); + @Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR private final CurrentUserService currentUserService; - @Qualifier(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR - private final ClientAttributeService clientAttributeService; - @Qualifier(ArchiveManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR private final VorgangService vorgangService; private final ApplicationEventPublisher eventPublisher; + @Qualifier(ArchiveManagerConfiguration.COMMAND_SERVICE_NAME) // NOSONAR + private final CommandService commandService; + private final ArchiveService archiveService; + @EventListener(condition = IS_ARCHIVE_VORGANG_EVENT) void onArchiveVorgangEvent(CommandCreatedEvent event) { runWithSecurityContext(event.getSource(), this::doLockVorgang); } void doLockVorgang(Command command) { - clientAttributeService.setVorgangArchiving(command.getVorgangId()); + archiveService.setVorgangArchiving(command.getVorgangId()); vorgangService.lockVorgang(command); } + @EventListener(condition = IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT) + public void onVorgangLockedEvent(VorgangLockedEvent event) { + waitForPendingCommandsToFinish(event.getCommand().getVorgangId(), WAIT_INTERVAL); + runWithSecurityContext(event.getCommand(), archiveService::archiveVorgang); + } + + void waitForPendingCommandsToFinish(String vorgangId, long waitIntervalInMillis) { + var numberOfAttempts = 0; + while (commandService.hasPendingCommandsExceptWithOrder(vorgangId, ARCHIVE_VORGANG_ORDER)) { + numberOfAttempts++; + if (numberOfAttempts >= MAXIMUM_CHECKS_FOR_PENDING_COMMANDS) { + throw new TimeoutException("Waiting for pending commands"); + } + try { + Thread.sleep(waitIntervalInMillis); + } catch (InterruptedException e) { + LOG.error("Error while waiting for commands to finish.", e); + Thread.currentThread().interrupt(); + } + } + } + void runWithSecurityContext(Command command, Consumer<Command> commandExecutor) { SecurityContext prevContext = null; try { diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java similarity index 59% rename from archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java rename to archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java index 21d24f804eb7d430b399243e9af5baaa8affecb8..dc45d255352044fa6b333ff08bc590851cb88274 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java @@ -21,7 +21,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.archive.attributes; +package de.ozgcloud.archive.archivierung; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +import jakarta.activation.DataHandler; +import jakarta.activation.FileDataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -32,17 +39,22 @@ import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; import de.ozgcloud.archive.ArchiveManagerConfiguration; import de.ozgcloud.archive.common.callcontext.CallContextUser; +import de.ozgcloud.archive.common.xta.XtaService; +import de.ozgcloud.archive.export.ExportService; +import de.ozgcloud.command.Command; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.model.XtaFile; import lombok.RequiredArgsConstructor; -@Service(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR +@Service @RequiredArgsConstructor -public class ClientAttributeService { +class ArchiveService { public static final String ATTRIBUTE_NAME_ANTRAG_ARCHIVING = "ARCHIVING"; - + private final XtaService xtaService; + private final ExportService exportService; @Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR private final OzgCloudClientAttributeService ozgCloudAttributesService; - private final OzgCloudVorgangIdMapper vorgangIdMapper; public void setVorgangArchiving(String vorgangId) { @@ -58,4 +70,37 @@ public class ClientAttributeService { .build(); } + public void archiveVorgang(Command command) { + xtaService.sendXdomeaFile(buildXdomeaXtaFile(command.getVorgangId())); + } + + XtaFile buildXdomeaXtaFile(String vorgangId) { + var fileNameId = createFileNameId(); + return XtaFile.builder() + .name(exportService.buildXdomeaFileName(fileNameId)) + .content(createFileContent(vorgangId, fileNameId)) + .contentType("application/zip") + .build(); + } + + String createFileNameId() { + return UUID.randomUUID().toString(); + } + + DataHandler createFileContent(String vorgangId, String fileNameId) { + try { + var tempFile = createTempFile(fileNameId); + var fileDataSource = new FileDataSource(tempFile); + exportService.writeXdomeaFileContent(vorgangId, fileNameId, fileDataSource.getOutputStream()); + return new DataHandler(fileDataSource); + } catch (IOException e) { + throw new TechnicalException("Error on creating file content for xDomea file!", e); + } + } + + File createTempFile(String fileNameId) throws IOException { + var tempFile = File.createTempFile(fileNameId, ".zip"); + tempFile.deleteOnExit(); + return tempFile; + } } diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java index cceb21c3920a447cd89382196b08de1ca99d9e7f..58344ce3e7a567afcb01183f18c351480c6cc973 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java @@ -33,6 +33,7 @@ import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterce import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; import de.ozgcloud.archive.ArchiveManagerConfiguration; import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest; import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest; import lombok.RequiredArgsConstructor; import net.devh.boot.grpc.client.inject.GrpcClient; @@ -64,6 +65,15 @@ class CommandRemoteService { return builder.build(); } + public boolean hasPendingCommands(String vorgangId) { + var response = getGrpcServiceWithInterceptor().existsPendingCommands(buildHasPendingCommandRequest(vorgangId)); + return response.getExistsPendingCommands(); + } + + GrpcExistsPendingCommandsRequest buildHasPendingCommandRequest(String vorgangId) { + return GrpcExistsPendingCommandsRequest.newBuilder().setVorgangId(vorgangId).build(); + } + CommandServiceBlockingStub getGrpcServiceWithInterceptor() { return grpcService.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider)); } diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java index 2a0f5d9fe635f48335405f1f8a040a54721eb82d..a1f4e512ba5723b7c28c322812a0784bf56473e6 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java @@ -24,11 +24,16 @@ package de.ozgcloud.archive.common.command; import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.archive.ArchiveManagerConfiguration; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -39,9 +44,20 @@ public class CommandService { @Qualifier(ArchiveManagerConfiguration.COMMAND_REMOTE_SERVICE_NAME) // NOSONAR private final CommandRemoteService remoteService; + @Qualifier(ArchiveManagerConfiguration.OZGCLOUD_COMMAND_SERVICE_NAME) // NOSONAR + private final OzgCloudCommandService ozgCloudCommandService; public Stream<ArchiveManagerCommand> findFinishedCommands(@NonNull String vorgangId) { return remoteService.findCommands(vorgangId, Optional.of("FINISHED"), Optional.empty()); } + public boolean hasPendingCommandsExceptWithOrder(String vorgangId, String order) { + var pendingCommands = ozgCloudCommandService.getPendingCommands(OzgCloudVorgangId.from(vorgangId)); + return pendingCommands.stream().anyMatch(hasNotOrder(order)); + } + + private Predicate<? super OzgCloudCommand> hasNotOrder(String order) { + return command -> !StringUtils.equals(command.getOrder(), order); + } + } diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java new file mode 100644 index 0000000000000000000000000000000000000000..1de21d85e04f3c422d4de01560a7798f28aa2393 --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java @@ -0,0 +1,17 @@ +package de.ozgcloud.archive.common.errorhandling; + +import de.ozgcloud.common.errorhandling.TechnicalException; + +public class TimeoutException extends TechnicalException { + + private static final String MESSAGE_TEMPLATE = "%s exceeded its time limit."; + + public TimeoutException(String request) { + super(MESSAGE_TEMPLATE.formatted(request)); + } + + public TimeoutException(String request, Throwable cause) { + super(MESSAGE_TEMPLATE.formatted(request), cause); + } + +} diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..d112b2c26dbfe68d4d97b819afd6a9b667e20549 --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java @@ -0,0 +1,34 @@ +package de.ozgcloud.archive.common.xta; + +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.model.XtaIdentifier; +import lombok.RequiredArgsConstructor; + +@Component +@ConfigurationPropertiesBinding +@RequiredArgsConstructor +public class JsonToXtaIdentifierListConverter implements Converter<String, List<XtaIdentifier>> { + + private final ObjectMapper objectMapper; + + @Override + public List<XtaIdentifier> convert(String source) { + try { + return objectMapper.readValue(source, new TypeReference<List<XtaIdentifier>>() { + }); + } catch (JsonProcessingException e) { + throw new TechnicalException("Error on converting XtaIdentifier!", e); + } + } + +} diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..174f5862deb05402b3200b9aedd221f5cdd5e96b --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java @@ -0,0 +1,61 @@ +package de.ozgcloud.archive.common.xta; + +import java.io.IOException; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import de.ozgcloud.archive.common.xta.XtaProperties.XtaClientKeyStore; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.config.XtaClientConfig; +import de.ozgcloud.xta.client.config.XtaClientConfig.KeyStore; +import de.ozgcloud.xta.client.exception.XtaClientInitializationException; + +@Configuration +class XtaConfiguration { + + @Bean + @ConditionalOnProperty(prefix = XtaProperties.XTA_PROPERTIES_PREFIX, name = "enabled") + XtaClient xtaClient(XtaProperties xtaProperties) { + try { + return XtaClient.from(buildXtaClientConfig(xtaProperties)); + } catch (XtaClientInitializationException e) { + throw new TechnicalException("Error on initializing Xta client.", e); + } + } + + XtaClientConfig buildXtaClientConfig(XtaProperties xtaProperties) { + return XtaClientConfig.builder() + .sendServiceUrl(xtaProperties.getSendServiceUrl()) + .managementServiceUrl(xtaProperties.getManagementServiceUrl()) + .msgBoxServiceUrl(xtaProperties.getMsgBoxServiceUrl()) + .clientCertKeystore(buildKeystore(xtaProperties.getKeyStore())) + .trustStore(buildKeystore(xtaProperties.getTrustStore())) + .maxListItems(xtaProperties.getMaxLoadedMessages()) + .clientIdentifiers(xtaProperties.getClientIdentifiers()) + .build(); + } + + private KeyStore buildKeystore(XtaClientKeyStore clientCert) { + try { + return XtaClientConfig.KeyStore.builder() + .content(clientCert.getFile().getContentAsByteArray()) + .type(clientCert.getType()) + .password(clientCert.getPassword()) + .build(); + } catch (IOException e) { + throw new TechnicalException("Error on reading Xta client certificate.", e); + } + } + + @Bean + @Lazy + ObjectMapper objectMapper() { + return new ObjectMapper(); + } +} diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..d5409da8ffaf6e8b7d7ecb408f631007a45f9a6d --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java @@ -0,0 +1,70 @@ +package de.ozgcloud.archive.common.xta; + +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; + +import de.ozgcloud.xta.client.model.XtaIdentifier; +import lombok.Getter; +import lombok.Setter; + +@Configuration +@ConfigurationProperties(prefix = XtaProperties.XTA_PROPERTIES_PREFIX) +@Getter +@Setter +public class XtaProperties { + + static final String XTA_PROPERTIES_PREFIX = "ozgcloud.xta"; + + /* + * Flag to enable/disable XTA adapter usage. + */ + private boolean enabled = false; + /* + * XTA endpoint messages are sent to. + */ + private String sendServiceUrl; + /* + * XTA endpoint to message box. + */ + private String msgBoxServiceUrl; + /* + * XTA endpoint to management information + */ + private String managementServiceUrl; + /* + * Maximum number of messages loaded from message box. + */ + private int maxLoadedMessages = 50; + /* + * Reference to client certification key store. + */ + private XtaClientKeyStore keyStore; + /* + * Reference to trust store. + */ + private XtaClientKeyStore trustStore; + /* + * Client identifiers used to identify client at XTA adapter. + */ + private List<XtaIdentifier> clientIdentifiers; + + @Getter + @Setter + public static class XtaClientKeyStore { + /* + * Reference to key store reference. + */ + private Resource file; + /* + * Type of the referenced key store. + */ + private String type; + /* + * Password to access key store. + */ + private char[] password; + } +} diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java new file mode 100644 index 0000000000000000000000000000000000000000..9aac41082bcaaa23dbb2b1acbadaf85411791ef5 --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java @@ -0,0 +1,41 @@ +package de.ozgcloud.archive.common.xta; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.exception.XtaClientException; +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; +import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class XtaService { + private static final String XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE = "XtaClient is not configured! Cannot send message to DMS."; + + private final Optional<XtaClient> xtaClient; + + public void sendXdomeaFile(XtaFile xdomeaFile) { + try { + getXtaClient().sendMessage(createMessage(xdomeaFile)); + } catch (XtaClientException e) { + throw new TechnicalException("Error on sending xDomea message!", e); + } + } + + XtaMessage createMessage(XtaFile xdomeaFile) { + try { + return XdomeaXtaMessageCreator.createInstance().createMessage(xdomeaFile); + } catch (XtaClientException e) { + throw new TechnicalException("Error on creating xDomea message!", e); + } + } + + XtaClient getXtaClient() { + return xtaClient.orElseThrow(() -> new TechnicalException(XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE)); + } +} diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java index 6aee7b10575fc54a6b42a132a3b93eba83059148..65893226e8a3cf0cf17e40914a0eaa7241eb7e6b 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java @@ -44,8 +44,6 @@ import net.devh.boot.grpc.server.service.GrpcService; @RequiredArgsConstructor class ExportGrpcService extends ExportServiceImplBase { - private static final String EXPORT_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea"; - static final int CHUNK_SIZE = 256 * 1024; private final ExportService exportService; @@ -64,14 +62,10 @@ class ExportGrpcService extends ExportServiceImplBase { void sendFileName(StreamObserver<GrpcExportVorgangResponse> responseObserver, String fileNameId) { responseObserver.onNext(GrpcExportVorgangResponse.newBuilder() - .setVorgangFile(GrpcFile.newBuilder().setFileName(buildXdomeaFileName(fileNameId)).build()) + .setVorgangFile(GrpcFile.newBuilder().setFileName(exportService.buildXdomeaFileName(fileNameId)).build()) .build()); } - String buildXdomeaFileName(String fileNameId) { - return String.format(EXPORT_FILENAME_TEMPLATE, fileNameId); - } - GrpcBinaryFileServerDownloader<GrpcExportVorgangResponse> buildExportDownloader(String vorgangId, String fileNameId, StreamObserver<GrpcExportVorgangResponse> responseObserver) { return GrpcBinaryFileServerDownloader.<GrpcExportVorgangResponse>builder() diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java index 6f1c42f2869ada9c9b5c7db8f86acee7101ee481..555dd08ff192966cb4f0a90396053f8cec20be61 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java @@ -56,10 +56,11 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Service -class ExportService { +public class ExportService { static final String EXPORT_FILENAME_SUFFIX = "_Abgabe.Abgabe.0401.xml"; private static final String EXPORT_FILENAME_TEMPLATE = "%s" + EXPORT_FILENAME_SUFFIX; + private static final String EXPORT_XDOMEA_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea"; private final XdomeaXmlMarshaller xDomeaXmlMarshaller; @@ -72,6 +73,10 @@ class ExportService { private final ExportNachrichtService exportNachrichtService; private final ExportBescheidService exportBescheidService; + public String buildXdomeaFileName(String fileNameId) { + return String.format(EXPORT_XDOMEA_FILENAME_TEMPLATE, fileNameId); + } + public void writeXdomeaFileContent(String vorgangId, String filenameId, OutputStream outputStream) { var exportData = collectExportData(vorgangId, filenameId); writeZipFile(exportData, outputStream); diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java index 6fb11b68a9d9edc41668d66a302f3a07c7dabfb3..44c5f661718557c8c10b7f625e06b965cc4f2cd3 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java @@ -98,8 +98,8 @@ public class VorgangService { return allgemeineMetadatenType; } - public void lockVorgang(Command command) { - ozgCloudCommandService.addSubCommands(buildCreateSubCommandsRequest(command.getId(), buildLockVorgangSubCommand(command))); + public void lockVorgang(Command parentCommand) { + ozgCloudCommandService.addSubCommands(buildCreateSubCommandsRequest(parentCommand.getId(), buildLockVorgangSubCommand(parentCommand))); } OzgCloudCommand buildLockVorgangSubCommand(Command command) { @@ -129,5 +129,4 @@ public class VorgangService { .executionMode(SUB_COMMAND_EXECUTION_MODE) .build(); } - } diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java similarity index 72% rename from archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java rename to archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java index e72c6347f66a6c5e27cf33583a37198bcb84a71a..121c50c0f22613bce9ecb97ce1ab1b2a560076c9 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java @@ -21,8 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.archive.vorgang; +package de.ozgcloud.archive.archivierung; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import org.junit.jupiter.api.Nested; @@ -31,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.ApplicationEventPublisher; +import de.ozgcloud.archive.common.callcontext.CallContextUser; import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandCreatedEventTestFactory; import de.ozgcloud.command.CommandTestFactory; @@ -68,4 +70,30 @@ class ArchiveEventListenerITCase { verifyNoInteractions(eventListener); } } + + @Nested + class TestOnVorgangLockedEvent { + + private static final Command COMMAND = CommandTestFactory.createBuilder() + .createdByClientName(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME) + .build(); + + @Test + void shouldReactOnOrder() { + var event = VorgangLockedEventTestFactory.withCommand(COMMAND); + doNothing().when(eventListener).onVorgangLockedEvent(any()); + + publisher.publishEvent(event); + + verify(eventListener).onVorgangLockedEvent(event); + } + + @Test + void shouldNotReactOnOtherOrder() { + publisher + .publishEvent(VorgangLockedEventTestFactory.withCommand(CommandTestFactory.createBuilder().createdByClientName("OTHER").build())); + + verifyNoInteractions(eventListener); + } + } } \ No newline at end of file diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java similarity index 58% rename from archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java rename to archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java index 0a2f444469ebf75b153eeeb3c64d5bd68f29ed5a..2e8379ee8653f773140c170fa5e453d706b0c9b0 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.archive.vorgang; +package de.ozgcloud.archive.archivierung; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -40,12 +40,16 @@ import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.core.context.SecurityContext; -import de.ozgcloud.archive.attributes.ClientAttributeService; import de.ozgcloud.archive.common.callcontext.CurrentUserService; +import de.ozgcloud.archive.common.command.CommandService; +import de.ozgcloud.archive.common.errorhandling.TimeoutException; +import de.ozgcloud.archive.vorgang.VorgangService; +import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandCreatedEventTestFactory; import de.ozgcloud.command.CommandFailedEvent; import de.ozgcloud.command.CommandTestFactory; +import de.ozgcloud.command.VorgangLockedEvent; class ArchiveEventListenerTest { @@ -58,11 +62,13 @@ class ArchiveEventListenerTest { @Mock private CurrentUserService currentUserService; @Mock - private ClientAttributeService clientAttributeService; - @Mock private VorgangService vorgangService; @Mock private ApplicationEventPublisher eventPublisher; + @Mock + private CommandService commandService; + @Mock + private ArchiveService archiveService; @Captor private ArgumentCaptor<Consumer<Command>> commandExecutorCapture; @@ -94,7 +100,7 @@ class ArchiveEventListenerTest { void shouldCallSetVorgangArchiving() { doLockVorgang(); - verify(clientAttributeService).setVorgangArchiving(CommandTestFactory.VORGANG_ID); + verify(archiveService).setVorgangArchiving(CommandTestFactory.VORGANG_ID); } @Test @@ -165,4 +171,103 @@ class ArchiveEventListenerTest { assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isNotEmpty(); } } + + @Nested + class TestOnVorgangLockedEvent { + + private final Command command = CommandTestFactory.create(); + private final VorgangLockedEvent event = new VorgangLockedEvent(command); + + @BeforeEach + void mock() { + doNothing().when(eventListener).waitForPendingCommandsToFinish(any(), anyLong()); + } + + @Test + void shouldCallWaitForPendingCommandsToFinish() { + onVorgangLockedEvent(); + + verify(eventListener).waitForPendingCommandsToFinish(CommandTestFactory.VORGANG_ID, ArchiveEventListener.WAIT_INTERVAL); + } + + @Test + void shouldCallRunWithSecurityContext() { + onVorgangLockedEvent(); + + verify(eventListener).runWithSecurityContext(eq(command), any()); + } + + @Nested + class TestCommandExecuter { + + @BeforeEach + void mock() { + doNothing().when(eventListener).runWithSecurityContext(any(), any()); + } + + @Test + void shouldCallRunWithSecurityContext() { + onVorgangLockedEvent(); + + verify(eventListener).runWithSecurityContext(eq(command), commandExecutorCapture.capture()); + commandExecutorCapture.getValue().accept(command); + + verify(archiveService).archiveVorgang(command); + + } + } + + private void onVorgangLockedEvent() { + eventListener.onVorgangLockedEvent(event); + } + } + + @Nested + class TestWaitForPendingCommandsToFinish { + + @Test + void shouldCallCommandServiceForPendingCommandsOnce() { + when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(false); + + waitForPendingCommandsToFinish(); + + verify(commandService).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER); + } + + @Test + void shouldCallCommandServiceForPendingCommandsTwice() { + when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true) + .thenReturn(false); + + waitForPendingCommandsToFinish(); + + verify(commandService, times(2)).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, + ArchiveEventListener.ARCHIVE_VORGANG_ORDER); + } + + @Test + void shouldCallAbortWaitingAfterMaxAttempts() { + when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true); + + var timeoutExceptionThrown = waitForPendingCommandsToFinishAndCatchException(); + + verify(commandService, times(ArchiveEventListener.MAXIMUM_CHECKS_FOR_PENDING_COMMANDS)) + .hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER); + assertThat(timeoutExceptionThrown).isTrue(); + } + + private boolean waitForPendingCommandsToFinishAndCatchException() { + try { + waitForPendingCommandsToFinish(); + } catch (TimeoutException e) { + return true; + } + return false; + } + + private void waitForPendingCommandsToFinish() { + eventListener.waitForPendingCommandsToFinish(VorgangWithEingangTestFactory.ID, 1); + } + } + } \ No newline at end of file diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4e1213a6c62b4966f2d1299ef6fa42b02dff2db5 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java @@ -0,0 +1,333 @@ +package de.ozgcloud.archive.archivierung; + +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.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.UUID; + +import jakarta.activation.DataHandler; +import jakarta.activation.FileDataSource; + +import org.junit.jupiter.api.AfterEach; +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.MockedConstruction; +import org.mockito.Spy; + +import de.ozgcloud.apilib.client_attribute.OzgCloudAccessPermission; +import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; +import de.ozgcloud.archive.common.callcontext.CallContextUser; +import de.ozgcloud.archive.common.xta.XtaService; +import de.ozgcloud.archive.export.ExportService; +import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandTestFactory; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.model.XtaFile; +import lombok.SneakyThrows; + +class ArchiveServiceTest { + + @Spy + @InjectMocks + private ArchiveService service; + + @Mock + private ExportService exportService; + @Mock + private XtaService xtaService; + @Mock + private OzgCloudClientAttributeService ozgCloudAttributesService; + @Mock + private OzgCloudVorgangIdMapper vorgangIdMapper; + + @Nested + class TestSetVorgangArchiving { + + @Test + void shouldBuildBooleanClientAttribute() { + setVorgangArchiving(); + + verify(service).buildBooleanClientAttribute(true); + } + + @Test + void shouldCallVorgangIdMapper() { + setVorgangArchiving(); + + verify(vorgangIdMapper).fromString(VorgangWithEingangTestFactory.ID); + } + + @Test + void shouldSetClientAttribute() { + var attribute = OzgCloudBooleanClientAttributeTestFactory.create(); + doReturn(attribute).when(service).buildBooleanClientAttribute(true); + when(vorgangIdMapper.fromString(VorgangWithEingangTestFactory.ID)).thenReturn(OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID)); + + setVorgangArchiving(); + + verify(ozgCloudAttributesService).setClientAttribute(attribute, OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID)); + } + + private void setVorgangArchiving() { + service.setVorgangArchiving(VorgangWithEingangTestFactory.ID); + } + } + + @Nested + class TestBuildBooleanClientAttribute { + + @Test + void shouldSetClientName() { + var attribute = service.buildBooleanClientAttribute(false); + + assertThat(attribute.getClientName()).isEqualTo(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME); + } + + @Test + void shouldSetAccess() { + var attribute = service.buildBooleanClientAttribute(false); + + assertThat(attribute.getAccess()).isEqualTo(OzgCloudAccessPermission.READ_ONLY); + } + + @Test + void shouldSetAttributeName() { + var attribute = service.buildBooleanClientAttribute(false); + + assertThat(attribute.getAttributeName()).isEqualTo(ArchiveService.ATTRIBUTE_NAME_ANTRAG_ARCHIVING); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldSetValue(boolean isArchiving) { + var attribute = service.buildBooleanClientAttribute(isArchiving); + + assertThat(attribute.getValue()).isEqualTo(isArchiving); + } + } + + @Nested + class TestArchiveVorgang { + + private final Command command = CommandTestFactory.create(); + private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create(); + + @BeforeEach + void mock() { + doReturn(xdomeaFile).when(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID); + } + + @Test + void shouldCallBuildXdomeaXtaFile() { + archiveVorgang(); + + verify(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID); + } + + @Test + void shouldCallSendXdomeaFile() { + archiveVorgang(); + + verify(xtaService).sendXdomeaFile(xdomeaFile); + } + + private void archiveVorgang() { + service.archiveVorgang(command); + } + } + + @Nested + class TestBuildXdomeaXtaFile { + + private final String fileNameId = UUID.randomUUID().toString(); + + @BeforeEach + void mock() { + doReturn(fileNameId).when(service).createFileNameId(); + when(exportService.buildXdomeaFileName(any())).thenReturn(XdomeaXtaFileTestFactory.FILE_NAME); + doReturn(XdomeaXtaFileTestFactory.DATA_HANDLER).when(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId); + } + + @Test + void shouldCallCreateFileNameId() { + buildXdomeaXtaFile(); + + verify(service).createFileNameId(); + } + + @Test + void shouldCallBuildXdomeaFileName() { + buildXdomeaXtaFile(); + + verify(exportService).buildXdomeaFileName(fileNameId); + } + + @Test + void shouldCallCreateFileContent() { + buildXdomeaXtaFile(); + + verify(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId); + } + + @Test + void shouldReturnXdomeaFile() { + var xdomeaFile = buildXdomeaXtaFile(); + + assertThat(xdomeaFile).usingRecursiveComparison().isEqualTo(XdomeaXtaFileTestFactory.create()); + } + + private XtaFile buildXdomeaXtaFile() { + return service.buildXdomeaXtaFile(VorgangWithEingangTestFactory.ID); + } + } + + @Nested + class TestCreateFileNameId { + + private final UUID uuid = UUID.randomUUID(); + + @Test + void shouldReturnRandomUUID() { + try (var mockedStaticUUID = mockStatic(UUID.class)) { + mockedStaticUUID.when(UUID::randomUUID).thenReturn(uuid); + + var returnedFileNameId = service.createFileNameId(); + + assertThat(returnedFileNameId).isEqualTo(uuid.toString()); + } + } + } + + @Nested + class TestCreateFileContent { + + private final String fileNameId = UUID.randomUUID().toString(); + + @Nested + class TestOnNoExceptionThrown { + private MockedConstruction<FileDataSource> fileDataSourceConstruction; + private FileDataSource fileDataSource; + private File dataSourceFile; + + private MockedConstruction<DataHandler> dataHandlerConstruction; + private DataHandler dataHandler; + private FileDataSource dataHandlerSource; + + @Mock + private File tempFile; + @Mock + private OutputStream outputStream; + + @BeforeEach + @SneakyThrows + void setUpMock() { + doReturn(tempFile).when(service).createTempFile(fileNameId); + fileDataSourceConstruction = mockConstruction(FileDataSource.class, + (fileDataSource, context) -> { + dataSourceFile = (File) context.arguments().get(0); + this.fileDataSource = fileDataSource; + when(fileDataSource.getOutputStream()).thenReturn(outputStream); + }); + dataHandlerConstruction = mockConstruction(DataHandler.class, (dataHandler, context) -> { + this.dataHandler = dataHandler; + dataHandlerSource = (FileDataSource) context.arguments().get(0); + }); + } + + @AfterEach + void cleanUp() { + fileDataSourceConstruction.close(); + dataHandlerConstruction.close(); + } + + @Test + @SneakyThrows + void shouldCallCreateTempFile() { + createFileContent(); + + verify(service).createTempFile(fileNameId); + } + + @Test + void shouldCreateFileDataSourceWithTempFile() { + createFileContent(); + + assertThat(dataSourceFile).isEqualTo(tempFile); + } + + @Test + @SneakyThrows + void shouldGetOutputStreamOfFileDataSource() { + createFileContent(); + + verify(fileDataSource).getOutputStream(); + } + + @Test + void shouldWriteXdomeaContentToOutputStream() { + createFileContent(); + + verify(exportService).writeXdomeaFileContent(VorgangWithEingangTestFactory.ID, fileNameId, outputStream); + } + + @Test + void shouldConstructDataHandlerFromFileDataSource() { + createFileContent(); + + assertThat(dataHandlerConstruction.constructed()).hasSize(1); + assertThat(dataHandlerSource).isEqualTo(fileDataSource); + } + + @Test + void shouldReturnDataHandler() { + var resultDataHandler = createFileContent(); + + assertThat(resultDataHandler).isEqualTo(dataHandler); + } + } + + @Nested + class TestOnIOExceptionThrown { + @Test + @SneakyThrows + void shouldThrowTechnicalExcpetion() { + doThrow(IOException.class).when(service).createTempFile(any()); + + assertThrows(TechnicalException.class, () -> createFileContent()); + } + } + + private DataHandler createFileContent() { + return service.createFileContent(VorgangWithEingangTestFactory.ID, fileNameId); + } + } + + @Nested + class TestCreateTempFile { + + private final String fileNameId = UUID.randomUUID().toString(); + + @Test + @SneakyThrows + void shouldReturnFile() { + var file = service.createTempFile(fileNameId); + + assertThat(file).isNotNull().isInstanceOf(File.class); + } + } + +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..954b23b8ace8a76a6951b1e091d090c8c233fee9 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java @@ -0,0 +1,29 @@ +package de.ozgcloud.archive.archivierung; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.apilib.client_attribute.OzgCloudAccessPermission; +import de.ozgcloud.apilib.client_attribute.OzgCloudBooleanClientAttribute; +import de.ozgcloud.apilib.client_attribute.OzgCloudBooleanClientAttribute.OzgCloudBooleanClientAttributeBuilder; +import de.ozgcloud.archive.common.callcontext.CallContextUserTestFactory; + +public class OzgCloudBooleanClientAttributeTestFactory { + + private static final boolean VALUE = true; + private static final String ATTRIBUTE_NAME = LoremIpsum.getInstance().getWords(1); + private static final OzgCloudAccessPermission ACCESS = OzgCloudAccessPermission.READ_ONLY; + private static final String CLIENT_NAME = CallContextUserTestFactory.CLIENT_NAME; + + public static OzgCloudBooleanClientAttribute create() { + return createBuilder().build(); + } + + private static OzgCloudBooleanClientAttributeBuilder<?, ?> createBuilder() { + return OzgCloudBooleanClientAttribute.builder() + .clientName(CLIENT_NAME) + .access(ACCESS) + .attributeName(ATTRIBUTE_NAME) + .value(VALUE); + } + +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..7fb4dc2005d62f7699d1d6c26ca2e41800df4afc --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java @@ -0,0 +1,12 @@ +package de.ozgcloud.archive.archivierung; + +import de.ozgcloud.command.Command; +import de.ozgcloud.command.VorgangLockedEvent; + +public class VorgangLockedEventTestFactory { + + public static VorgangLockedEvent withCommand(Command command) { + return new VorgangLockedEvent(command); + } + +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java index 517fbd26e956a7ba10fdb503a6dfbf6e1c0ecfc4..27f26a2fdebd76cb97a6fd81379f40d5314e2ed7 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java @@ -34,6 +34,8 @@ import org.junit.jupiter.api.AfterEach; 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.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; @@ -48,6 +50,8 @@ import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; import de.ozgcloud.vorgang.grpc.command.GrpcCommand; import de.ozgcloud.vorgang.grpc.command.GrpcCommandsResponse; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsResponse; import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest; class CommandRemoteServiceTest { @@ -187,4 +191,67 @@ class CommandRemoteServiceTest { } } + @Nested + class TestHasPendingCommands { + + private final GrpcExistsPendingCommandsRequest request = GrpcExistsPendingCommandsRequestTestFactory.create(); + + @Mock + private CommandServiceBlockingStub serviceStubWithInterceptor; + + @BeforeEach + void mock() { + doReturn(serviceStubWithInterceptor).when(service).getGrpcServiceWithInterceptor(); + doReturn(request).when(service).buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID); + var response = GrpcExistsPendingCommandsResponse.newBuilder().setExistsPendingCommands(true).build(); + when(serviceStubWithInterceptor.existsPendingCommands(any())).thenReturn(response); + } + + @Test + void shouldCallBuildHasPendingCommandRequest() { + hasPendingCommands(); + + verify(service).buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID); + } + + @Test + void shouldCallGetCommandServiceStub() { + hasPendingCommands(); + + verify(service).getGrpcServiceWithInterceptor(); + } + + @Test + void shouldCallServiceStubWithInterceptor() { + hasPendingCommands(); + + verify(serviceStubWithInterceptor).existsPendingCommands(request); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldReturnIfCommandsArePending(boolean hasPendingCommands) { + var response = GrpcExistsPendingCommandsResponse.newBuilder().setExistsPendingCommands(hasPendingCommands).build(); + when(serviceStubWithInterceptor.existsPendingCommands(any())).thenReturn(response); + + var result = hasPendingCommands(); + + assertThat(result).isEqualTo(hasPendingCommands); + } + + private boolean hasPendingCommands() { + return service.hasPendingCommands(VorgangWithEingangTestFactory.ID); + } + } + + @Nested + class TestBuildHasPendingCommandRequest { + + @Test + void shouldReturnRequest() { + var request = service.buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID); + + assertThat(request).isEqualTo(GrpcExistsPendingCommandsRequestTestFactory.create()); + } + } } diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java index 493b639403a05b9e953f66b63ecf2c085fe41dc3..b4a09e172312f7e956b92cd758c662649ba69e7e 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java @@ -23,8 +23,12 @@ */ package de.ozgcloud.archive.common.command; +import static org.assertj.core.api.Assertions.*; +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.Nested; @@ -33,6 +37,11 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; class CommandServiceTest { @@ -41,6 +50,8 @@ class CommandServiceTest { private CommandService service; @Mock private CommandRemoteService remoteService; + @Mock + private OzgCloudCommandService ozgCloudCommandService; @Nested class TestFindFinishedCommands { @@ -54,4 +65,50 @@ class CommandServiceTest { verify(remoteService).findCommands(VorgangWithEingangTestFactory.ID, Optional.of(VORGANG_STATUS_FINISHED), Optional.empty()); } } + + @Nested + class TestHasPendingCommandsExceptArchive { + + private final String order = LoremIpsum.getInstance().getWords(1); + + @Test + void shouldCallOzgCloudCommandService() { + hasPendingCommandsExceptWithOrder(); + + verify(ozgCloudCommandService).getPendingCommands(OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID)); + } + + @Test + void shouldReturnFalseOnNoPendingCommands() { + when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(Collections.emptyList()); + + var result = hasPendingCommandsExceptWithOrder(); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnTrueOnPendingCommands() { + when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.create())); + + var result = hasPendingCommandsExceptWithOrder(); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnFalseOnCommandWithExcpetionOrder() { + when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.createBuilder() + .order(order) + .build())); + + var result = hasPendingCommandsExceptWithOrder(); + + assertThat(result).isFalse(); + } + + private boolean hasPendingCommandsExceptWithOrder() { + return service.hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, order); + } + } } diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..8a5780c56ebb1bf57a717f87f704f0cb4da390ff --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java @@ -0,0 +1,18 @@ +package de.ozgcloud.archive.common.command; + +import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest.Builder; + +public class GrpcExistsPendingCommandsRequestTestFactory { + public static final String VORGAND_ID = VorgangWithEingangTestFactory.ID.toString(); + + public static GrpcExistsPendingCommandsRequest create() { + return createBuilder().build(); + } + + public static Builder createBuilder() { + return GrpcExistsPendingCommandsRequest.newBuilder() + .setVorgangId(VORGAND_ID); + } +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..be5d9a974e360c0fdea92a0261e52a7c150553f1 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java @@ -0,0 +1,48 @@ +package de.ozgcloud.archive.common.xta; + +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 org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.SneakyThrows; + +class JsonToXtaIdentifierListConverterTest { + + @InjectMocks + private JsonToXtaIdentifierListConverter converter; + + @Spy + private ObjectMapper objectMapper; + + @Nested + class TestConvert { + + @Test + void shouldReturnListOfXtaIdentifier() { + var jsonInput = XtaIdentifierTestFactory.createAsJson(); + + var identifiers = converter.convert(jsonInput); + + assertThat(identifiers).usingRecursiveFieldByFieldElementComparator().containsExactly(XtaIdentifierTestFactory.create()); + } + + @Test + @SneakyThrows + void shouldThrowTechnicalException() { + doThrow(JsonProcessingException.class).when(objectMapper).readValue(anyString(), any(TypeReference.class)); + + assertThrows(TechnicalException.class, () -> converter.convert("invalid input")); + } + } +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..35f2f02f7a09728f1293a89fa4c808c44aecdf91 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java @@ -0,0 +1,30 @@ +package de.ozgcloud.archive.common.xta; + +import java.util.UUID; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.xta.client.model.XtaIdentifier; +import de.ozgcloud.xta.client.model.XtaIdentifier.XtaIdentifierBuilder; + +public class XtaIdentifierTestFactory { + + public static final String CATEGORY = LoremIpsum.getInstance().getWords(1); + public static final String VALUE = UUID.randomUUID().toString(); + public static final String NAME = LoremIpsum.getInstance().getName(); + + public static XtaIdentifier create() { + return createBuilder().build(); + } + + public static XtaIdentifierBuilder createBuilder() { + return XtaIdentifier.builder() + .name(NAME) + .value(VALUE) + .category(CATEGORY); + } + + public static String createAsJson() { + return "[{\"category\":\"%s\",\"name\":\"%s\",\"value\":\"%s\"}]".formatted(CATEGORY, NAME, VALUE); + } +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..536adb305f6e1acdac5731ff29f1c78eca0fec9a --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java @@ -0,0 +1,186 @@ +package de.ozgcloud.archive.common.xta; + +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.Optional; + +import org.junit.jupiter.api.AfterEach; +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.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.exception.XtaClientException; +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; +import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator; +import lombok.SneakyThrows; + +class XtaServiceTest { + + @Spy + @InjectMocks + private XtaService service; + + @Mock + private XtaClient xtaClient; + + @Nested + class TestSendXdomeaFile { + + private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create(); + @Mock + private XtaMessage xtaMessage; + + @BeforeEach + void mock() { + doReturn(xtaMessage).when(service).createMessage(xdomeaFile); + doReturn(xtaClient).when(service).getXtaClient(); + } + + @Test + void shouldGetXtaClient() { + sendXdomeaFile(); + + verify(service).getXtaClient(); + } + + @Test + @SneakyThrows + void shouldCallCreateMessage() { + sendXdomeaFile(); + + verify(service).createMessage(xdomeaFile); + } + + @Test + @SneakyThrows + void shouldSendMessage() { + sendXdomeaFile(); + + verify(xtaClient).sendMessage(xtaMessage); + } + + @Test + @SneakyThrows + void shouldThrowTechnicalException() { + when(xtaClient.sendMessage(any())).thenThrow(XtaClientException.class); + + assertThrows(TechnicalException.class, () -> sendXdomeaFile()); + } + + private void sendXdomeaFile() { + service.sendXdomeaFile(xdomeaFile); + } + } + + @Nested + class TestCreateMessage { + private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create(); + + private MockedStatic<XdomeaXtaMessageCreator> mockedStaticXdomeaXtaMessageCreator; + + @Mock + private XdomeaXtaMessageCreator xdomeaXtaMessageCreator; + @Mock + private XtaMessage xtaMessage; + + @BeforeEach + void setUpMock() { + mockedStaticXdomeaXtaMessageCreator = mockStatic(XdomeaXtaMessageCreator.class); + mockedStaticXdomeaXtaMessageCreator.when(XdomeaXtaMessageCreator::createInstance).thenReturn(xdomeaXtaMessageCreator); + } + + @AfterEach + void cleanUp() { + mockedStaticXdomeaXtaMessageCreator.close(); + } + + @Test + void shouldCreateXdomeaXtaMessageCreator() { + createMessage(); + + mockedStaticXdomeaXtaMessageCreator.verify(XdomeaXtaMessageCreator::createInstance); + } + + @Test + @SneakyThrows + void shouldCallCreateMessage() { + createMessage(); + + verify(xdomeaXtaMessageCreator).createMessage(xdomeaFile); + } + + @Test + @SneakyThrows + void shouldReturnMessage() { + when(xdomeaXtaMessageCreator.createMessage(any())).thenReturn(xtaMessage); + + var message = createMessage(); + + assertThat(message).isEqualTo(xtaMessage); + } + + @Test + @SneakyThrows + void shouldThrowTechnicalException() { + when(xdomeaXtaMessageCreator.createMessage(any())).thenThrow(XtaClientException.class); + + assertThrows(TechnicalException.class, () -> createMessage()); + } + + private XtaMessage createMessage() { + return service.createMessage(xdomeaFile); + } + } + + @Nested + class TestGetXtaClient { + + private XtaService xtaService; + + @Nested + class TestOnConfiguredXtaClient { + + @BeforeEach + void givenXtaClientConfigured() { + xtaService = spy(new XtaService(Optional.of(xtaClient))); + } + + @Test + void shouldReturnXtaClient() { + var returnedXtaClient = getXtaClient(); + + assertThat(returnedXtaClient).isSameAs(xtaClient); + } + + } + + @Nested + class TestOnUnconfiguredXtaClient { + + @BeforeEach + void givenXtaClientNotConfigured() { + xtaService = spy(new XtaService(Optional.empty())); + } + + @Test + void shouldThrowTechnicalException() { + assertThrows(TechnicalException.class, () -> getXtaClient()); + } + } + + private XtaClient getXtaClient() { + return xtaService.getXtaClient(); + } + } +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java index 42c3ceed2734357237282b51f6c101a99a5c2680..a783e3294b091987560488060a093cca416a806f 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java @@ -122,7 +122,7 @@ class ExportGrpcServiceITCase { } @Nested - class OnMinimalVorgang { + class TestOnMinimalVorgang { @BeforeEach void setUpMock() { @@ -159,7 +159,7 @@ class ExportGrpcServiceITCase { } @Nested - class OnVorgangWithKommentarAndAttachment { + class TestOnVorgangWithKommentarAndAttachment { private final String attachmentContent = LoremIpsum.getInstance().getWords(5); @BeforeEach diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java index 68c2d08c0c8c667cdb647936c8023e2998c8c8cc..52694de1c9a693475348ab5174472e74be5de8f3 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java @@ -78,37 +78,38 @@ class ExportGrpcServiceTest { void setUpMocks() { doReturn(fileNameId).when(service).createFileNameId(); doReturn(downloader).when(service).buildExportDownloader(VorgangWithEingangTestFactory.ID, fileNameId, responseObserver); + doNothing().when(service).sendFileName(any(), any()); } @Test void shouldCreateFileNameId() { - callService(); + exportVorgang(); verify(service).createFileNameId(); } @Test void shouldSendFileName() { - callService(); + exportVorgang(); verify(service).sendFileName(responseObserver, fileNameId); } @Test void shouldBuildExportDownloader() { - callService(); + exportVorgang(); verify(service).buildExportDownloader(VorgangWithEingangTestFactory.ID, fileNameId, responseObserver); } @Test void shouldStartDownloader() { - callService(); + exportVorgang(); verify(downloader).start(); } - private void callService() { + private void exportVorgang() { service.exportVorgang(request, responseObserver); } } @@ -141,17 +142,20 @@ class ExportGrpcServiceTest { private final String fileNameId = UUID.randomUUID().toString(); private final String fileName = LoremIpsum.getInstance().getName(); + @BeforeEach + void mock() { + when(exportService.buildXdomeaFileName(fileNameId)).thenReturn(fileName); + } + @Test void shouldCallBuildXdomeaFileName() { sendFileName(); - verify(service).buildXdomeaFileName(fileNameId); + verify(exportService).buildXdomeaFileName(fileNameId); } @Test void shouldSendFileName() { - doReturn(fileName).when(service).buildXdomeaFileName(fileNameId); - sendFileName(); verify(responseObserver).onNext(argThat((response) -> response.getVorgangFile().getFileName().equals(fileName))); @@ -259,17 +263,4 @@ class ExportGrpcServiceTest { } } - - @Nested - class TestBuildXdomeaFileName { - - private final String id = UUID.randomUUID().toString(); - - @Test - void shouldReturnFileName() { - var fileName = service.buildXdomeaFileName(id); - - assertThat(fileName).isEqualTo(id + "_Abgabe.Abgabe.0401.xdomea"); - } - } } diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java index 4e596932b22ff474e755f1b1369d429835cb6c52..08221c17a7dff76148d00a4dc20c13cc8886560a 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java @@ -54,6 +54,7 @@ import de.ozgcloud.archive.bescheid.ExportBescheidService; import de.ozgcloud.archive.common.ExportFilenameGenerator; import de.ozgcloud.archive.common.HistorienProtokollInformationTypeTestFactory; import de.ozgcloud.archive.common.XDomeaTestUtils; +import de.ozgcloud.archive.common.xta.XtaService; import de.ozgcloud.archive.file.ExportFileService; import de.ozgcloud.archive.file.OzgFile; import de.ozgcloud.archive.file.OzgFileTestFactory; @@ -100,6 +101,8 @@ class ExportServiceTest { private ExportNachrichtService exportNachrichtService; @Mock private ExportBescheidService exportBescheidService; + @Mock + private XtaService xtaService; @DisplayName("Write Xdomea File") @Nested @@ -665,4 +668,18 @@ class ExportServiceTest { assertThat(formEngineName).isEqualTo(EingangHeaderTestFactory.FORM_ENGINE_NAME); } } + + @Nested + class TestBuildXdomeaFileName { + + private final String id = UUID.randomUUID().toString(); + + @Test + void shouldReturnFileName() { + var fileName = service.buildXdomeaFileName(id); + + assertThat(fileName).isEqualTo(id + "_Abgabe.Abgabe.0401.xdomea"); + } + } + } \ No newline at end of file diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java index cb8c7167208f4591816aa16b83f1ffab7e9eeeed..265be54c9f8fcaa4ebd1d17c2b256fb07442f357 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java @@ -39,5 +39,4 @@ import net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguratio }) @ComponentScan({ "de.ozgcloud.*" }) public class GrpcIntegrationTestConfiguration { - } \ No newline at end of file diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java index d6c0b70d93b3fad5af0772dac927581a48c19edd..e5c9b728a196f3c6331de4f6f4e9a3e5d4c4e261 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java @@ -71,7 +71,7 @@ class XdomeaPropertiesValidatorTest { } @Nested - class OnUriNotSet { + class TestOnUriNotSet { private static final String PROPERTY_NAME = "behoerdenschluesselUri"; public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME; @@ -113,7 +113,7 @@ class XdomeaPropertiesValidatorTest { } @Nested - class OnVersionNotSet { + class TestOnVersionNotSet { public static final String PROPERTY_NAME = "behoerdenschluesselVersion"; public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME; diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java index a81cf33e3e421c9f43546aa8891c9f1006aaf625..cdb972dc4e6495e1b71d7ce3e7588f26fd0a0084 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java @@ -216,7 +216,7 @@ class KopfCreatorTest { class TestCreateKontaktType { @Nested - class OnBehoerdenschluesselNotSet { + class TestOnBehoerdenschluesselNotSet { @ParameterizedTest @NullAndEmptySource @@ -240,7 +240,7 @@ class KopfCreatorTest { } @Nested - class OnBehoerdenschluesselSet { + class TestOnBehoerdenschluesselSet { private static final BehoerdenkennungType expectedValue = new BehoerdenkennungType(); diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java index e5e23a8c0935db70042829ef6da1662496b636bc..3d5fc793a3dbdbd9cfe70a2f13a32f7fef8b3dff 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java @@ -24,6 +24,7 @@ package de.ozgcloud.archive.vorgang; import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Map; diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..3743f9d26eec05088a3935348f31aa5cc4821e45 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java @@ -0,0 +1,34 @@ +package de.ozgcloud.archive.vorgang; + +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; + +import org.mockito.Mock; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaFile.XtaFileBuilder; +import lombok.SneakyThrows; + +public class XdomeaXtaFileTestFactory { + + public static final String FILE_NAME = LoremIpsum.getInstance().getWords(1); + + @Mock + public static DataSource DATA_SOURCE; + + public static final DataHandler DATA_HANDLER = new DataHandler(DATA_SOURCE); + + public static XtaFile create() { + return createBuilder().build(); + } + + @SneakyThrows + public static XtaFileBuilder createBuilder() { + return XtaFile.builder() + .content(DATA_HANDLER) + .name(FILE_NAME) + .contentType("application/zip"); + } +} diff --git a/archive-manager-server/src/test/resources/application-itcase.yaml b/archive-manager-server/src/test/resources/application-itcase.yaml index 04ca541b6f2396d09a347684021e152ce0812abe..9bd1a3bb14e6dac750aca9251cb49cad90684702 100644 --- a/archive-manager-server/src/test/resources/application-itcase.yaml +++ b/archive-manager-server/src/test/resources/application-itcase.yaml @@ -3,6 +3,15 @@ ozgcloud: behoerdenschluessel: ABC behoerdenschluesselUri: http://meine.behoer.de behoerdenschluesselVersion: 1.0.15b + xta: + sendServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210sendPort.svc + msgBoxServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210msgBoxPort.svc + managementServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210managementPort.svc + maxListItems: 5 + keystore: + file: classpath:xtaTestStore.p12 + password: changeit + clientIdentifiers: '[{"category":"Generischer Antragsempfänger","name":"ozg-cloud dev","value":"gae:dev-environment@ozg-cloud.de"}]' grpc: server: diff --git a/archive-manager-server/src/test/resources/xtaTestStore.p12 b/archive-manager-server/src/test/resources/xtaTestStore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a0cc212c49745a428186d0d4f2f73dd6ac7f24ff Binary files /dev/null and b/archive-manager-server/src/test/resources/xtaTestStore.p12 differ diff --git a/pom.xml b/pom.xml index 8a2a1c0d314c0660bb33dff0b13bb51f233776bc..2f8e05ec7188ed7f0f76945c904d73eb489ab225 100644 --- a/pom.xml +++ b/pom.xml @@ -53,11 +53,12 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <vorgang-manager.version>2.18.0</vorgang-manager.version> <nachrichten-manager.version>2.15.0</nachrichten-manager.version> - <api-lib.version>0.14.0</api-lib.version> + <api-lib.version>0.16.0-SNAPSHOT</api-lib.version> <find-and-replace-maven-plugin.version>1.2.0</find-and-replace-maven-plugin.version> <protoc-jar-plugin.version>3.11.4</protoc-jar-plugin.version> <ozgcloud-common.version>4.7.0</ozgcloud-common.version> <document-manager.version>1.1.0</document-manager.version> + <xta-client-lib.version>0.1.0</xta-client-lib.version> </properties> <dependencyManagement> <dependencies> @@ -107,6 +108,11 @@ <artifactId>document-manager-interface</artifactId> <version>${document-manager.version}</version> </dependency> + <dependency> + <groupId>de.ozgcloud.xta</groupId> + <artifactId>xta-client-lib</artifactId> + <version>${xta-client-lib.version}</version> + </dependency> <!-- test --> <dependency>