diff --git a/pom.xml b/pom.xml index 674ac3156eb759db2655a30947402f0efb64847e..74d7b28f7820817de6226e1d3a412f32bdb06892 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,7 @@ <eingang-manager.version>2.17.0</eingang-manager.version> <intelliform-semantik.version>2.17.0</intelliform-semantik.version> <dfoerdermittel-semantik.version>2.17.0</dfoerdermittel-semantik.version> + <xta-client-lib.version>0.1.0</xta-client-lib.version> <xmlschema.version>2.3.0</xmlschema.version> @@ -86,6 +87,11 @@ <artifactId>dfoerdermittel-semantik</artifactId> <version>${dfoerdermittel-semantik.version}</version> </dependency> + <dependency> + <groupId>de.ozgcloud.xta</groupId> + <artifactId>xta-client-lib</artifactId> + <version>${xta-client-lib.version}</version> + </dependency> <!-- Spring --> <dependency> diff --git a/src/main/java/de/ozgcloud/eingang/xta/WsHeaderAddingInterceptor.java b/src/main/java/de/ozgcloud/eingang/xta/WsHeaderAddingInterceptor.java deleted file mode 100644 index 5437c339a17f47c38bac8834e0380a00e9d99fb4..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/WsHeaderAddingInterceptor.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.util.Objects; - -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBElement; -import jakarta.xml.bind.JAXBException; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.ws.client.WebServiceClientException; -import org.springframework.ws.client.support.interceptor.ClientInterceptor; -import org.springframework.ws.context.MessageContext; -import org.springframework.ws.soap.SoapMessage; - -import de.ozgcloud.eingang.common.errorhandling.TechnicalException; -import eu.osci.ws._2014._10.transport.OriginatorsType; -import eu.osci.ws._2014._10.transport.PartyIdentifierType; -import eu.osci.ws._2014._10.transport.PartyType; - -@Component -class WsHeaderAddingInterceptor implements ClientInterceptor { - - @Autowired - private XtaCurrentIdentifierService xtaCurrentIdentifierService; - - @Override - public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { - var soapMessage = (SoapMessage) messageContext.getRequest(); - var header = soapMessage.getSoapHeader(); - - try { - JAXBContext context = JAXBContext.newInstance(PartyType.class); - var marshaller = context.createMarshaller(); - marshaller.marshal(createAuthor(), header.getResult()); - } catch (JAXBException e) { - throw new TechnicalException("Error on handling Request for adding Header.", e); - } - - return true; - } - - JAXBElement<PartyType> createAuthor() { - eu.osci.ws._2014._10.transport.ObjectFactory objectFactory = new eu.osci.ws._2014._10.transport.ObjectFactory(); - - PartyType partyType = new PartyType(); - PartyIdentifierType identifier = new PartyIdentifierType(); - identifier.setValue(Objects.requireNonNull( - xtaCurrentIdentifierService.getCurrentIdentifier(), - "Expect current identifier to be set!") - ); - partyType.setIdentifier(identifier); - - var origin = new OriginatorsType(); - origin.setAuthor(partyType); - - return objectFactory.createAuthor(partyType); - } - - @Override - public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException { - return true; - } - - @Override - public boolean handleFault(MessageContext messageContext) throws WebServiceClientException { - return true; - } - - @Override - public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException { - // nothing to do here - } - -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierService.java b/src/main/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierService.java deleted file mode 100644 index cbf1532cd379f255669fde42b348fa8666b5bde8..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierService.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.util.List; - -import jakarta.validation.Valid; - -import org.springframework.stereotype.Service; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -@Service -@RequiredArgsConstructor -public class XtaCurrentIdentifierService { - - @Setter - @Getter - private String currentIdentifier; - - @Valid - private final XtaProperties properties; - - public List<String> getIdentifiers() { - return properties.getIdentifiers(); - } - -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaFile.java b/src/main/java/de/ozgcloud/eingang/xta/XtaFile.java deleted file mode 100644 index f0ce8da50afab52e21b09a5f1ffacbbc20041a26..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaFile.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.io.File; -import java.math.BigInteger; - -import lombok.Builder; - -@Builder -public record XtaFile(File file, - String contentType, - String name, - BigInteger size) { - -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java b/src/main/java/de/ozgcloud/eingang/xta/XtaFormMetaData.java similarity index 97% rename from src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java rename to src/main/java/de/ozgcloud/eingang/xta/XtaFormMetaData.java index 5e87118df9c026285e855f7ecfa07d771f5d7b31..214e65529bd4a9ea4e7550481c89cfd55cf3f33a 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaFormMetaData.java @@ -34,7 +34,7 @@ import lombok.ToString; @Builder @Getter @ToString -class XtaMessageMetaData implements FormMetaData { +class XtaFormMetaData implements FormMetaData { static final String SERVICE = "service"; static final String MESSAGE_TYPE_ENTRY_NAME = "messageType"; static final String MESSAGE_TYPE_LIST_VERSION = "messageTypeListVersion"; diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java index eda89334f08e94db75903cb62d0e6a43beb08be4..01fb3175cf3c39651efd03ad6bfe5a229775cd2a 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java @@ -22,15 +22,22 @@ */ package de.ozgcloud.eingang.xta; -import java.util.Collection; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.stream.Stream; +import de.ozgcloud.eingang.common.errorhandling.TechnicalException; +import jakarta.activation.DataHandler; +import lombok.SneakyThrows; import org.springframework.stereotype.Component; import de.ozgcloud.eingang.common.formdata.IncomingFile; import de.ozgcloud.eingang.xta.zip.ZipFileExtractor; +import de.ozgcloud.xta.client.model.XtaFile; + import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @@ -41,9 +48,9 @@ class XtaIncomingFilesMapper { private final ZipFileExtractor zipFileExtractor; - public List<IncomingFile> toIncomingFiles(Collection<XtaFile> messageFiles) { - if (Objects.nonNull(messageFiles)) { - return messageFiles.stream() + public List<IncomingFile> toIncomingFiles(XtaFile messageFile) { + if (Objects.nonNull(messageFile)) { + return Stream.of(messageFile) .map(this::toIncomingFile) .flatMap(this::tryToExtractZip) .toList(); @@ -51,15 +58,31 @@ class XtaIncomingFilesMapper { return List.of(); } + @SneakyThrows IncomingFile toIncomingFile(XtaFile messageFile) { + File tmpFile = persistToFile(messageFile.content()); return IncomingFile.builder() .name(messageFile.name()) .contentType(messageFile.contentType()) - .file(messageFile.file()) - .size(messageFile.file().length()) + .file(tmpFile) + .size(tmpFile.length()) .build(); } + private File persistToFile(DataHandler data) { + try { + var file = File.createTempFile("xta", ".data"); + file.deleteOnExit(); + var out = new FileOutputStream(file); + data.writeTo(out); + out.flush(); + out.close(); + return file; + } catch (IOException e) { + throw new TechnicalException("Error writing Attachment to temp file", e); + } + } + Stream<IncomingFile> tryToExtractZip(IncomingFile incomingFile) { try { List<IncomingFile> extractedZips = zipFileExtractor.extractIncomingFilesSafely(incomingFile); diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMapperHelper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMapperHelper.java index 6cda79d8b075f52a31b5f5e6e2444583b7e8285d..b3a0adb50f69c6afbbd92e36f2a0ffc5f2c874ce 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMapperHelper.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaMapperHelper.java @@ -32,7 +32,19 @@ import java.time.ZonedDateTime; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class XtaMapperHelper { - public static String getFormEngineName(XtaMessageMetaData metaData) { + public static String getFormEngineName(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData) { + if (StringUtils.equals(metaData.messageTypeCode(), XtaService.XDOMEA_0201_MESSAGE_TYPE)) { + // TODO OZG-5778 verify the correct engine name + return "XDOMEA"; + } + + if (StringUtils.startsWith(metaData.messageTypeCode(), XtaService.FIM_MESSAGE_TYPE_PREFIX)) { + return "FIM"; + } + return null; + } + + public static String getFormEngineName(XtaFormMetaData metaData) { if (StringUtils.equals(metaData.getMessageType(), XtaService.XDOMEA_0201_MESSAGE_TYPE)) { // TODO OZG-5778 verify the correct engine name return "XDOMEA"; @@ -45,7 +57,16 @@ public class XtaMapperHelper { } // TODO OZG-6176 Check if the problem can be fixed elsewhere - public static ZonedDateTime getCreatedAt(XtaMessageMetaData metaData) { + public static ZonedDateTime getCreatedAt(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData) { + // TODO add deliveryOrigin in xta-client-lib + /*if (metaData.deliveryOrigin() != null) { + return metaData.deliveryOrigin(); + }*/ + return ZonedDateTime.now(); + } + + // TODO OZG-6176 Check if the problem can be fixed elsewhere + public static ZonedDateTime getCreatedAt(XtaFormMetaData metaData) { if (metaData.getOrigin() != null) { return metaData.getOrigin(); } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java deleted file mode 100644 index 0170b14e0a504c11272c2af123a68d39359e1976..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.util.Collection; - -import lombok.Builder; -import lombok.Getter; -import lombok.Singular; - -@Builder(toBuilder = true) -@Getter -public class XtaMessage { - private String primaryFormDataMessage; - - private XtaMessageMetaData metaData; - @Singular - private Collection<XtaFile> messageFiles; - @Singular - private Collection<XtaFile> attachments; -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java index a87a88d302b9639aea173bf05d2913698f0fe31a..7b12d480c746af9f51ac1cdc638164758562dc3b 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java @@ -43,16 +43,17 @@ interface XtaMessageMapper { @Mapping(target = "formData", ignore = true) @Mapping(target = "id", ignore = true) @Mapping(target = "zustaendigeStelle", ignore = true) + @Mapping(target = "zustaendigeStelles", ignore = true) @Mapping(target = "header", source = "metaData") @Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(representationsAttachmentsPair.attachments()))") @Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(representationsAttachmentsPair.representations().size())") @Mapping(target = "representation", ignore = true) @Mapping(target = "attachment", ignore = true) @Mapping(target = "control.metaData", source = "metaData") - FormData toFormData(RepresentationsAttachmentsPair representationsAttachmentsPair, XtaMessageMetaData metaData, + FormData toFormData(RepresentationsAttachmentsPair representationsAttachmentsPair, de.ozgcloud.xta.client.model.XtaMessageMetaData metaData, @Context VorgangNummerSupplier vorgangNummerSupplier); - @Mapping(target = "formId", source = "messageType") + @Mapping(target = "formId", source = "messageTypeCode") @Mapping(target = "requestId", source = "messageId") @Mapping(target = "vorgangNummer", expression = "java(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH))") @Mapping(target = "serviceKonto", ignore = true) @@ -61,13 +62,32 @@ interface XtaMessageMapper { @Mapping(target = "channel", constant = "XTA") @Mapping(target = "formName", ignore = true) @Mapping(target = "formEngineName", expression = "java(XtaMapperHelper.getFormEngineName(metaData))") - FormHeader formHeaderFromMetaData(XtaMessageMetaData metaData, @Context VorgangNummerSupplier vorgangNummerSupplier); + FormHeader formHeaderFromMetaData(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData, @Context VorgangNummerSupplier vorgangNummerSupplier); + + @Mapping(target = "messageTypeListVersion", ignore = true) + @Mapping(target = "metaDataFile", ignore = true) + @Mapping(target = "service", source = "service") + // todo add origin and delivery in xta-client-lib + @Mapping(target = "origin", ignore = true) + @Mapping(target = "delivery", ignore = true) + @Mapping(target = "messageId", source = "messageId") + @Mapping(target = "messageType", source = "messageTypeCode") + @Mapping(target = "xtaIdentifier", source = "readerIdentifier.value") + XtaFormMetaData formMetaDataFromMetaData(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData); + + default XtaMessageId fromString(String id) { + return XtaMessageId.from(id); + } default String fromId(XtaMessageId id) { return id.toString(); } - default Optional<FormMetaData> mapMetaData(XtaMessageMetaData value) { + default Optional<FormMetaData> mapMetaData(de.ozgcloud.xta.client.model.XtaMessageMetaData value) { + return Optional.ofNullable(formMetaDataFromMetaData(value)); + } + + default Optional<FormMetaData> mapMetaData(XtaFormMetaData value) { return Optional.ofNullable(value); } } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java index 82b51e5b43bf15d4e3277c94630213088b958fcf..7727fa8526f696a13328a28ca08eb654c72948bb 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java @@ -44,7 +44,7 @@ interface XtaMessageMetaDataMapper { @Mapping(target = "messageId", source = "msgIdentification.messageID.value") @Mapping(target = "messageType", source = "qualifier.messageType.code") @Mapping(target = "xtaIdentifier", source = "destinations.reader.identifier.value") - XtaMessageMetaData fromSoap(MessageMetaData metaData); + XtaFormMetaData fromSoap(MessageMetaData metaData); default XtaMessageId fromString(String id) { return XtaMessageId.from(id); @@ -53,7 +53,7 @@ interface XtaMessageMetaDataMapper { @Mapping(target = "moreMessagesAvailable", constant = "false") XtaMessageMetaDatasAndHeader msgStatusListFromSoap(MsgStatusListTypeAndHeaderResponse statusList); - default Stream<XtaMessageMetaData> map(JAXBElement<MsgStatusListType> msgStatusListResponse) { + default Stream<XtaFormMetaData> map(JAXBElement<MsgStatusListType> msgStatusListResponse) { return msgStatusListResponse.getValue().getMessageMetaData().stream().map(this::fromSoap); } } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java index 9b1ed87cde79cdd72cb9ce69ce23f3da9b29c306..9538f1e08e6146af0520fcbbd1c84bd164b39737 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java @@ -34,5 +34,5 @@ class XtaMessageMetaDatasAndHeader { private String msgBoxRequestID; private boolean moreMessagesAvailable; - private Stream<XtaMessageMetaData> messages; + private Stream<XtaFormMetaData> messages; } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java deleted file mode 100644 index b12ce91b9ca05f1db26f5ab8b3f8f85fd982ab28..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.util.Iterator; - -public class XtaMessageMetadataRemoteIterator implements Iterator<XtaMessageMetaData> { - - private final XtaRemoteService xtaRemoteService; - private XtaMessageMetaDatasAndHeader messagesMetadata; - private Iterator<XtaMessageMetaData> remoteMessageIterator; - - public XtaMessageMetadataRemoteIterator(XtaRemoteService xtaRemoteService) { - this.xtaRemoteService = xtaRemoteService; - messagesMetadata = this.xtaRemoteService.getMessagesMetadata(); - remoteMessageIterator = getRemoteMessageIterator(messagesMetadata); - } - - @Override - public boolean hasNext() { - if (remoteMessageIterator.hasNext()) { - return true; - } - if (messagesMetadata.isMoreMessagesAvailable()) { - loadNextMessages(); - return remoteMessageIterator.hasNext(); - } - return false; - } - - void loadNextMessages() { - messagesMetadata = xtaRemoteService.getNextMessagesMetadata(messagesMetadata.getMsgBoxRequestID()); - remoteMessageIterator = getRemoteMessageIterator(messagesMetadata); - } - - Iterator<XtaMessageMetaData> getRemoteMessageIterator(XtaMessageMetaDatasAndHeader messagesMetadata) { - return messagesMetadata.getMessages().iterator(); - } - - @Override - public XtaMessageMetaData next() { - return remoteMessageIterator.next(); - } -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java b/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java deleted file mode 100644 index 76b4135d2eb477e356ff8a9be7574f8ac2032418..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.Iterator; -import java.util.stream.Stream; - -import javax.xml.namespace.QName; -import javax.xml.transform.TransformerException; - -import jakarta.validation.Valid; -import jakarta.xml.bind.JAXBElement; - -import org.apache.commons.io.IOUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.webservices.client.WebServiceTemplateBuilder; -import org.springframework.oxm.jaxb.Jaxb2Marshaller; -import org.springframework.stereotype.Service; -import org.springframework.ws.WebServiceMessage; -import org.springframework.ws.client.core.WebServiceMessageCallback; -import org.springframework.ws.client.core.WebServiceMessageExtractor; -import org.springframework.ws.soap.SoapFaultDetailElement; -import org.springframework.ws.soap.SoapHeader; -import org.springframework.ws.soap.SoapHeaderElement; -import org.springframework.ws.soap.SoapMessage; -import org.springframework.ws.soap.addressing.client.ActionCallback; -import org.springframework.ws.soap.addressing.version.Addressing10; -import org.springframework.ws.soap.client.SoapFaultClientException; -import org.springframework.ws.support.MarshallingUtils; -import org.w3._2005._08.addressing.AttributedURIType; - -import de.ozgcloud.eingang.common.errorhandling.TechnicalException; -import de.xoev.transport.xta._211.ContentType; -import de.xoev.transport.xta._211.ExceptionType; -import de.xoev.transport.xta._211.GenericContentContainer; -import eu.osci.ws._2008._05.transport.MsgBoxCloseRequestType; -import eu.osci.ws._2008._05.transport.MsgBoxFetchRequest; -import eu.osci.ws._2008._05.transport.MsgBoxGetNextRequestType; -import eu.osci.ws._2008._05.transport.MsgBoxResponseType; -import eu.osci.ws._2008._05.transport.MsgBoxStatusListRequestType; -import eu.osci.ws._2008._05.transport.MsgSelector; -import eu.osci.ws._2008._05.transport.MsgStatusListType; -import eu.osci.ws._2008._05.transport.ObjectFactory; -import eu.osci.ws._2014._10.transport.MessageMetaData; -import lombok.NonNull; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@Service -class XtaRemoteService { - - private static final String ERROR_ON_CLOSE_LOG_TEMPLATE = "Error result on close request.\nReason: %s"; - private static final String DETAIL_LOG_TEMPLATE = "Code: %s, Message: %s"; - - @Autowired - @Valid - private XtaProperties properties; - - @Autowired - private XtaMessageMetaDataMapper mapper; - - @Autowired - private WebServiceTemplateBuilder webServiceTemplateBuilder; - - @Autowired - @Qualifier("osciTransportMarshaller") - private Jaxb2Marshaller osciMarshaller; - - @Autowired - @Qualifier("xoevTransportMarshaller") - private Jaxb2Marshaller xoevMarshaller; - - public XtaMessageMetaDatasAndHeader getMessagesMetadata() { - return mapper.msgStatusListFromSoap(getStatusList()); - } - - public XtaMessageMetaDatasAndHeader getNextMessagesMetadata(String msgBoxRequestId) { - return mapper.msgStatusListFromSoap(getNextStatusList(msgBoxRequestId)); - } - - MsgStatusListTypeAndHeaderResponse getStatusList() { - var request = buildListRequest(); - return getGenericStatusList(request); - } - - MsgStatusListTypeAndHeaderResponse getNextStatusList(String msgBoxRequestId) { - var request = buildNextListRequest(msgBoxRequestId); - return getGenericStatusList(request); - } - - MsgStatusListTypeAndHeaderResponse getGenericStatusList(Object request) { - var template = webServiceTemplateBuilder.setMarshaller(osciMarshaller).setUnmarshaller(osciMarshaller).build(); - - return template.sendAndReceive(buildMarshalCallBack(request, buildActionCallback()), buildHeaderExtractor()); - } - - private ActionCallback buildActionCallback() { - return new ActionCallback(properties.getActions().getStatusList(), new Addressing10(), getTargetUri()); - } - - WebServiceMessageCallback buildMarshalCallBack(Object jaxbElement, ActionCallback callback) { - return new WebServiceMessageCallback() { - @Override - public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException { - MarshallingUtils.marshal(osciMarshaller, jaxbElement, message); - callback.doWithMessage(message); - } - }; - } - - WebServiceMessageExtractor<MsgStatusListTypeAndHeaderResponse> buildHeaderExtractor() { - return new WebServiceMessageExtractor<MsgStatusListTypeAndHeaderResponse>() { - @Override - public MsgStatusListTypeAndHeaderResponse extractData(WebServiceMessage message) throws IOException, TransformerException { - - MsgBoxResponseType header = extractHeader(message); - - return MsgStatusListTypeAndHeaderResponse.builder() - .msgBoxRequestID(header.getMsgBoxRequestID()) - .noMessageAvailable(header.getNoMessageAvailable() != null) - .messageItemsPending(header.getItemsPending()) - .messages(extractMessages(message)) - .build(); - } - - @SuppressWarnings("unchecked") - private MsgBoxResponseType extractHeader(WebServiceMessage message) { - SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader(); - Iterator<SoapHeaderElement> it = soapHeader - .examineHeaderElements(new QName("http://www.osci.eu/ws/2008/05/transport", "MsgBoxResponse")); - validateHasHeader(it); - return ((JAXBElement<MsgBoxResponseType>) osciMarshaller.unmarshal(it.next().getSource())).getValue(); - } - - private void validateHasHeader(Iterator<SoapHeaderElement> it) { - if (!it.hasNext()) { - throw new TechnicalException("Response from XTA GetStatusList has no header"); - } - } - - @SuppressWarnings("unchecked") - private Stream<MessageMetaData> extractMessages(WebServiceMessage message) throws IOException { - return ((JAXBElement<MsgStatusListType>) MarshallingUtils.unmarshal(osciMarshaller, message)).getValue().getMessageMetaData() - .stream(); - } - }; - } - - private JAXBElement<MsgBoxStatusListRequestType> buildListRequest() { - ObjectFactory objectFactory = new ObjectFactory(); - - MsgBoxStatusListRequestType msg = new MsgBoxStatusListRequestType(); - msg.setMaxListItems(properties.getMaxListElements()); - return objectFactory.createMsgBoxStatusListRequest(msg); - } - - private JAXBElement<MsgBoxGetNextRequestType> buildNextListRequest(String msgBoxRequestId) { - ObjectFactory objectFactory = new ObjectFactory(); - - MsgBoxGetNextRequestType msg = new MsgBoxGetNextRequestType(); - msg.setMsgBoxRequestID(msgBoxRequestId); - return objectFactory.createMsgBoxGetNextRequest(msg); - } - - private URI getTargetUri() { - try { - return new URI(buildServerAddressUri()); - } catch (URISyntaxException e) { - throw new TechnicalException("Error building target url: " + e); - } - } - - String buildServerAddressUri() { - return XtaRemoteServiceConfiguration.URI_TEMPLATE.formatted(properties.getServer().getProtocol(), - properties.getServer().getName()); - } - - public XtaMessage getMessage(XtaMessageId messageId) { - var contentContainer = loadContentContainer(messageId.toString()); - XtaFile formDataFile = getMessage(contentContainer); - - return XtaMessage.builder() - .metaData(null) - .primaryFormDataMessage(formDataFile.name()) - .messageFiles(Collections.singleton(formDataFile)) - .attachments(getAttachments(contentContainer).toList()) - .build(); - } - - GenericContentContainer loadContentContainer(String messageId) { - var callback = new ActionCallback(properties.getActions().getFetchRequest(), new Addressing10(), getTargetUri()); - var template = webServiceTemplateBuilder.setMarshaller(osciMarshaller).setUnmarshaller(xoevMarshaller).build(); - - return (GenericContentContainer) template.marshalSendAndReceive(buildFetchRequest(messageId), callback); - } - - XtaFile getMessage(GenericContentContainer container) { - return toXtaFile(container.getContentContainer().getMessage()); - } - - Stream<XtaFile> getAttachments(GenericContentContainer container) { - return container.getContentContainer().getAttachment().stream().map(this::toXtaFile); - } - - private XtaFile toXtaFile(ContentType type) { - return XtaFile.builder() - .file(persistToFile(type.getValue())) - .name(type.getFilename()) - .contentType(type.getContentType()) - .size(type.getSize()) - .build(); - } - - private File persistToFile(byte[] data) { - try { - var file = File.createTempFile("xta", ".data"); - file.deleteOnExit(); - var out = new FileOutputStream(file); - IOUtils.write(data, out); - out.flush(); - out.close(); - return file; - } catch (IOException e) { - throw new TechnicalException("Error writing Attachment to temp file", e); - } - } - - private JAXBElement<MsgBoxFetchRequest> buildFetchRequest(String msgId) { - MsgSelector msgSelector = new MsgSelector(); - AttributedURIType attribute = new AttributedURIType(); - attribute.setValue(msgId); - msgSelector.getMessageID().add(attribute); - - var request = new MsgBoxFetchRequest(); - request.setMsgSelector(msgSelector); - - return wrapAsJaxBElemement(request); - } - - private JAXBElement<MsgBoxFetchRequest> wrapAsJaxBElemement(MsgBoxFetchRequest request) { - QName qname = new QName("http://www.osci.eu/ws/2008/05/transport", "MsgBoxFetchRequest"); - - return new JAXBElement<>(qname, MsgBoxFetchRequest.class, request); - } - - public void close(@NonNull XtaMessageId messageId) { - var callback = new ActionCallback(properties.getActions().getCloseRequest(), new Addressing10(), getTargetUri()); - var template = webServiceTemplateBuilder.setMarshaller(osciMarshaller).setUnmarshaller(xoevMarshaller).build(); - - try { - template.marshalSendAndReceive(buildCloseRequest(messageId.toString()), callback); - } catch (SoapFaultClientException e) { - logErrorOnClose(e); - } - } - - private JAXBElement<MsgBoxCloseRequestType> buildCloseRequest(String msgId) { - MsgBoxCloseRequestType request = new MsgBoxCloseRequestType(); - var lastMsgReceived = request.getLastMsgReceived(); - - AttributedURIType attribute = new AttributedURIType(); - attribute.setValue(msgId); - lastMsgReceived.add(attribute); - - return new ObjectFactory().createMsgBoxCloseRequest(request); - } - - private void logErrorOnClose(SoapFaultClientException e) { - try { - var fault = e.getSoapFault(); - StringBuilder logBuilder = new StringBuilder(ERROR_ON_CLOSE_LOG_TEMPLATE.formatted(e.getSoapFault().getFaultStringOrReason())); - - var entries = fault.getFaultDetail().getDetailEntries(); - entries.forEachRemaining(entry -> logBuilder.append("\n").append(formatFaultEntry(entry))); - - LOG.error(logBuilder.toString(), e); - } catch (Exception e1) { - LOG.error("Error on loggging close error", e1); - LOG.error("origin error was", e); - } - } - - private String formatFaultEntry(SoapFaultDetailElement soapfaultdetailelement1) { - @SuppressWarnings("unchecked") - ExceptionType exceptionType = ((JAXBElement<ExceptionType>) xoevMarshaller.unmarshal(soapfaultdetailelement1.getSource())).getValue(); - - return DETAIL_LOG_TEMPLATE.formatted(exceptionType.getErrorCode().getCode(), exceptionType.getErrorCode().getName().toString()); - - } - -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfiguration.java b/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfiguration.java deleted file mode 100644 index 3f7036f4c1358bec4119da91e64ae0abd3cb24bd..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfiguration.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; - -import javax.net.ssl.KeyManagerFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webservices.client.WebServiceTemplateCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.oxm.jaxb.Jaxb2Marshaller; -import org.springframework.ws.client.support.destination.DestinationProvider; -import org.springframework.ws.client.support.interceptor.ClientInterceptor; -import org.springframework.ws.soap.SoapVersion; -import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; -import org.springframework.ws.transport.WebServiceMessageSender; -import org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender; - -import de.ozgcloud.eingang.common.errorhandling.TechnicalException; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@Configuration -public class XtaRemoteServiceConfiguration { - - static final String URI_TEMPLATE = "%s://%s/MB_XTA-WS/XTA210msgBoxPort.svc"; - - @Autowired - private XtaProperties properties; - - @Bean - Jaxb2Marshaller osciTransportMarshaller() { - Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); - marshaller.setContextPath("eu.osci.ws._2008._05.transport"); - marshaller.setMtomEnabled(true); - return marshaller; - } - - @Bean - Jaxb2Marshaller xoevTransportMarshaller() { - Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller(); - unmarshaller.setContextPath("de.xoev.transport.xta._211"); - unmarshaller.setMtomEnabled(true); - return unmarshaller; - } - - @Bean - WebServiceTemplateCustomizer webServiceTemplateCustomizer() { - return template -> template.setMessageSender(messageSender()); - } - - @Bean - WebServiceTemplateCustomizer setMessageFactoryCustomizer() { - return template -> template.setMessageFactory(messageFactory()); - } - - @Bean - WebServiceTemplateCustomizer addingInterceptorCustomizer(WsHeaderAddingInterceptor interceptor) { - return template -> template.setInterceptors(new ClientInterceptor[] { interceptor }); - } - - @Bean - WebServiceTemplateCustomizer setDestionationProvider() { - return template -> template.setDestinationProvider(destinationProvider()); - } - - @Bean - DestinationProvider destinationProvider() { - return () -> { - try { - String serverUri = buildServerAddressUri(properties.getServer()); - LOG.trace("Xta Service remote URI: {}", serverUri); - return new URI(serverUri); - } catch (URISyntaxException e) { - throw new TechnicalException("Error building URI", e); - } - }; - } - - String buildServerAddressUri(Server server) { - return URI_TEMPLATE.formatted(server.getProtocol(), server.getAddress()); - } - - @Bean - SaajSoapMessageFactory messageFactory() { - SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(); - messageFactory.setSoapVersion(SoapVersion.SOAP_12); - return messageFactory; - } - - @Bean - WebServiceMessageSender messageSender() { - try { - var keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(xtaKeyStore(), properties.getKeyStore().getPassword()); - - var messageSender1 = new HttpsUrlConnectionMessageSender(); - messageSender1.setKeyManagers(keyManagerFactory.getKeyManagers()); - messageSender1.setHostnameVerifier((hostname, session) -> true); // NOSONAR hostname verification is senseless due missing DNS for - // Dataport XTA Server - - return messageSender1; - } catch (Exception e) { - throw new TechnicalException("Error initializating message sender.", e); - } - } - - @Bean - KeyStore xtaKeyStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { - var keyStoreResource = properties.getKeyStore().getFile(); - var keyStore = KeyStore.getInstance(properties.getKeyStore().getType()); - try (InputStream keyStoreStream = keyStoreResource.getInputStream()) { - keyStore.load(keyStoreStream, properties.getKeyStore().getPassword()); - } - - return keyStore; - } - -} diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java b/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java index 6503ef32ade1c8ec5d1f19e185b74e003b0eedf9..6bd9ec46dcccb7e8a5ffd822f5de4d7a423746ef 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java @@ -28,9 +28,6 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; -import de.ozgcloud.eingang.common.formdata.FormData; -import de.ozgcloud.eingang.semantik.SemantikAdapter; -import lombok.NonNull; import lombok.extern.log4j.Log4j2; @Log4j2 @@ -39,8 +36,6 @@ class XtaRunner implements ApplicationListener<ContextRefreshedEvent> { @Autowired private XtaService service; - @Autowired - private SemantikAdapter semantikAdapter; @Override public void onApplicationEvent(ContextRefreshedEvent event) { @@ -50,20 +45,10 @@ class XtaRunner implements ApplicationListener<ContextRefreshedEvent> { void runGetXtaMessages() { try { - service.getMessages().forEach(this::processAndAcknowledge); + service.fetchMessages(); } catch (RuntimeException e) { LOG.error("Error fetch XTA Message List.", e); } } - private void processAndAcknowledge(@NonNull FormData formData) { - try { - LOG.info("Process XTA-Message '{}'.", formData.getHeader().getRequestId()); - semantikAdapter.processFormData(formData); - service.acknowledgeReceive(XtaMessageId.from(formData.getHeader().getRequestId())); - } catch (RuntimeException e) { - LOG.error("Error on processing XTA-Message. Continue with next message.", e); - } - } - } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/src/main/java/de/ozgcloud/eingang/xta/XtaService.java index 0dbd0950ec895d98597c769295c1da0966e365a1..f639661e38ef93c351ea3bbbb6907dcdbbe0f613 100644 --- a/src/main/java/de/ozgcloud/eingang/xta/XtaService.java +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaService.java @@ -25,13 +25,12 @@ package de.ozgcloud.eingang.xta; import static java.util.Collections.*; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.Spliterators; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; +import java.util.*; +import de.ozgcloud.eingang.semantik.SemantikAdapter; +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.model.XtaMessageStatus; +import lombok.SneakyThrows; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -56,7 +55,10 @@ class XtaService { static final String FIM_MESSAGE_TYPE_PREFIX = "fim."; @Autowired - private XtaRemoteService remoteService; + private XtaClient xtaClient; + @Autowired + private SemantikAdapter semantikAdapter; + @Autowired private XtaMessageMapper mapper; @Autowired @@ -65,71 +67,71 @@ class XtaService { private XdomeaMessageDataMapper xdomeaMessageDataMapper; @Autowired private XtaIncomingFilesMapper xtaIncomingFilesMapper; - @Autowired - private XtaCurrentIdentifierService service; - public Stream<FormData> getMessages() { - return createXtaMessageStream() - .filter(this::isSupportedMessageType) - .map(this::getFormDataIfNoRuntimeException) - .flatMap(Optional::stream); - } - Stream<XtaMessageMetaData> createXtaMessageStream() { - return service.getIdentifiers().stream() - .flatMap(this::createXtaMessageStreamForIdentifier); + @SneakyThrows + public void fetchMessages() { + var transportReports = xtaClient.fetchMessages(this::processMessage); + for (var transportReport : transportReports) { + if (transportReport.status() == XtaMessageStatus.GREEN) { + LOG.info("Fetched XTA message: {}", transportReport.metaData().messageId()); + } else { + LOG.warn( + "Failed to fetch XTA message with XTA transport report status {}: {}", + transportReport.status(), + transportReport.metaData().messageId() + ); + } + } } - private Stream<XtaMessageMetaData> createXtaMessageStreamForIdentifier(String identifier) { - service.setCurrentIdentifier(identifier); - var iterator = new XtaMessageMetadataRemoteIterator(remoteService); - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); + void processMessage(de.ozgcloud.xta.client.model.XtaMessage xtaMessage) { + Optional<FormData> formData = getFormDataIfNoRuntimeException(xtaMessage); + formData.ifPresent(this::processSemantik); } - boolean isSupportedMessageType(XtaMessageMetaData metaData) { - if (isXDomeaMessageType(metaData.getMessageType()) || isFimMessageType(metaData.getMessageType())) { - return true; + Optional<FormData> getFormDataIfNoRuntimeException(@NonNull de.ozgcloud.xta.client.model.XtaMessage xtaMessage) { + try { + return Optional.of(getFormData(xtaMessage)); + } catch (RuntimeException exception) { + LOG.error("Failed to process xta message (id: %s)".formatted(xtaMessage.metaData().messageId()), exception); + return Optional.empty(); } - LOG.warn("Ignoring XTA-Message of type '{}'.", metaData.getMessageType()); - return false; } - Optional<FormData> getFormDataIfNoRuntimeException(@NonNull XtaMessageMetaData metaData) { + void processSemantik(@NonNull FormData formData) { try { - return Optional.of(getFormData(metaData)); - } catch (RuntimeException exception) { - LOG.error("Failed to process xta message (id: %s)".formatted(metaData.getMessageId()), exception); - return Optional.empty(); + LOG.info("Semantic processing XTA-Message '{}'.", formData.getHeader().getRequestId()); + semantikAdapter.processFormData(formData); + } catch (RuntimeException e) { + LOG.error("Error on semantic processing XTA-Message. Continue with next message.", e); } } - FormData getFormData(@NonNull XtaMessageMetaData metaData) { - var msg = remoteService.getMessage(metaData.getMessageId()); - var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(msg.getMessageFiles()); + FormData getFormData(de.ozgcloud.xta.client.model.XtaMessage xtaMessage) { + var metaData = xtaMessage.metaData(); + var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(xtaMessage.messageFile()); var representationsAttachmentsPair = getRepresentationsAttachmentsPair(metaData, incomingFiles); var formData = mapper.toFormData(representationsAttachmentsPair, metaData, vorgangNummerSupplier); - formData = addAttachments(msg, formData); + formData = addAttachments(xtaMessage, formData); - return addRepresentations(formData, msg); + return addRepresentations(formData, xtaMessage.messageFile().name()); } - FormData addRepresentations(FormData formData, XtaMessage msg) { - return formData.toBuilder().control( - formData.getControl().toBuilder() - .representations(Optional.of(buildRepresentations(formData.getControl().getRepresentations(), msg))) - .build()) - .build(); - } + RepresentationsAttachmentsPair getRepresentationsAttachmentsPair(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData, List<IncomingFile> incomingFiles) { + if (isXDomeaMessageType(metaData.messageTypeCode())) { + return xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles); + } + if (isFimMessageType(metaData.messageTypeCode())) { + return mapIncomingFilesToRepresentations(incomingFiles); + } - private Representations buildRepresentations(Optional<Representations> base, XtaMessage msg) { - return base.map(Representations::toBuilder).orElseGet(Representations::builder) - .primaryFormDataRepresentation(msg.getPrimaryFormDataMessage()) - .build(); + throw new TechnicalException("Unexpected XTA message type: %s".formatted(metaData.messageTypeCode())); } - FormData addAttachments(XtaMessage msg, FormData inFormData) { - var attachments = buildAttachmentsInFiles(msg.getAttachments()); + FormData addAttachments(de.ozgcloud.xta.client.model.XtaMessage msg, FormData inFormData) { + var attachments = buildAttachmentsInFiles(msg.attachmentFiles()); if (CollectionUtils.isNotEmpty(attachments)) { return inFormData.toBuilder() .attachment(IncomingFileGroup.builder().name("sonstige").files(attachments).build()) @@ -139,19 +141,22 @@ class XtaService { return inFormData; } - private List<IncomingFile> buildAttachmentsInFiles(Collection<XtaFile> attachmentFiles) { + private List<IncomingFile> buildAttachmentsInFiles(Collection<de.ozgcloud.xta.client.model.XtaFile> attachmentFiles) { return attachmentFiles.stream().map(xtaIncomingFilesMapper::toIncomingFile).toList(); } - RepresentationsAttachmentsPair getRepresentationsAttachmentsPair(XtaMessageMetaData metaData, List<IncomingFile> incomingFiles) { - if (isXDomeaMessageType(metaData.getMessageType())) { - return xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles); - } - if (isFimMessageType(metaData.getMessageType())) { - return mapIncomingFilesToRepresentations(incomingFiles); - } + FormData addRepresentations(FormData formData, String primaryFormDataMessage) { + return formData.toBuilder().control( + formData.getControl().toBuilder() + .representations(Optional.of(buildRepresentations(formData.getControl().getRepresentations(), primaryFormDataMessage))) + .build()) + .build(); + } - throw new TechnicalException("Unexpected XTA message type: %s".formatted(metaData.getMessageType())); + private Representations buildRepresentations(Optional<Representations> base, String primaryFormDataMessage) { + return base.map(Representations::toBuilder).orElseGet(Representations::builder) + .primaryFormDataRepresentation(primaryFormDataMessage) + .build(); } private boolean isXDomeaMessageType(String messageType) { @@ -168,8 +173,4 @@ class XtaService { .attachments(emptyList()) .build(); } - - public void acknowledgeReceive(@NonNull XtaMessageId messageId) { - remoteService.close(messageId); - } } diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaServiceConfiguration.java b/src/main/java/de/ozgcloud/eingang/xta/XtaServiceConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..0719b32f4defbfe4ae0c27021628aa1a2f218d0f --- /dev/null +++ b/src/main/java/de/ozgcloud/eingang/xta/XtaServiceConfiguration.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.eingang.xta; + +import java.util.List; + +import lombok.SneakyThrows; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.XtaClientFactory; +import de.ozgcloud.xta.client.config.XtaClientConfig; +import de.ozgcloud.xta.client.model.XtaIdentifier; + +@Log4j2 +@Configuration +public class XtaServiceConfiguration { + + static final String URI_TEMPLATE = "https://%s/MB_XTA-WS/XTA210"; + + static final String XDOMEA_0201_MESSAGE_TYPE = "Geschaeftsgang.Geschaeftsgang.0201"; + + static final String FIM_MESSAGE_TYPE_PREFIX = "fim."; + + @Autowired + private XtaProperties properties; + + @Bean + @SneakyThrows + XtaClient xtaClient() { + XtaClientConfig xtaClientConfig = createClientConfig(); + XtaClientFactory clientFactory = XtaClientFactory.from(xtaClientConfig); + return clientFactory.create(); + } + + @SneakyThrows + XtaClientConfig createClientConfig() { + + var clientCertKeyStore = XtaClientConfig.KeyStore.builder() + .content(properties.getKeyStore().getFile().getContentAsByteArray()) + .type(properties.getKeyStore().getType()) + .password(properties.getKeyStore().getPassword()) + .build(); + + return XtaClientConfig.builder() + .clientIdentifiers(mapIdentifiers(properties.getIdentifiers())) + .managementServiceUrl(getManagementPortUrl()) + .sendServiceUrl(getSendPortUrl()) + .msgBoxServiceUrl(getMsgBoxPortUrl()) + .clientCertKeystore(clientCertKeyStore) + .isMessageSupported(this::isSupportedMessageType) + .build(); + } + + private List<XtaIdentifier> mapIdentifiers(List<String> identifiers) { + return identifiers.stream() + .map(identifier -> XtaIdentifier.builder().value(identifier).build()) + .toList(); + } + + String getBaseUrl() { + return URI_TEMPLATE.formatted(properties.getServer().getAddress()); + } + + private String getMsgBoxPortUrl() { + return getBaseUrl() + "msgBoxPort.svc"; + } + + private String getManagementPortUrl() { + return getBaseUrl() + "managementPort.svc"; + } + + private String getSendPortUrl() { + return getBaseUrl() + "sendPort.svc"; + } + + boolean isSupportedMessageType(de.ozgcloud.xta.client.model.XtaMessageMetaData metaData) { + if (isXDomeaMessageType(metaData.messageTypeCode()) || isFimMessageType(metaData.messageTypeCode())) { + return true; + } + LOG.warn("Ignoring XTA-Message of type '{}'.", metaData.messageTypeCode()); + return false; + } + + private boolean isXDomeaMessageType(String messageType) { + return StringUtils.equals(messageType, XDOMEA_0201_MESSAGE_TYPE); + } + + private boolean isFimMessageType(String messageType) { + return StringUtils.startsWith(messageType, FIM_MESSAGE_TYPE_PREFIX); + } + +} diff --git a/src/test/java/de/ozgcloud/eingang/xta/FormHeaderTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/FormHeaderTestFactory.java index e9bf27e47736d6988a70b82cdd70e4cc9e589be7..6d68f57a9dea4fd8f8c48b8454285e0dd8cea866 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/FormHeaderTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/FormHeaderTestFactory.java @@ -44,7 +44,7 @@ public class FormHeaderTestFactory { .requestId(XtaMessageTestFactory.MESSAGE_ID.toString()) .vorgangNummer(VORGANGNUMMER) .formName(FORM_NAME) - .formId(XtaMessageMetaDataTestFactory.MESSAGE_TYPE) - .createdAt(XtaMessageMetaDataTestFactory.ORIGIN); + .formId(XtaFormMetaDataTestFactory.MESSAGE_TYPE) + .createdAt(XtaFormMetaDataTestFactory.ORIGIN); } } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierServiceTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierServiceTest.java deleted file mode 100644 index f96f8fa006d7eaed3b2f5e7a580d66b3cc789d3e..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaCurrentIdentifierServiceTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -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; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; - -class XtaCurrentIdentifierServiceTest { - - private static final String IDENTIFIER1 = "identifier1"; - private static final String IDENTIFIER2 = "identifier2"; - private static final List<String> IDENTIFIERS = List.of(IDENTIFIER1, IDENTIFIER2); - - @Spy - @InjectMocks - private XtaCurrentIdentifierService service; - - @Mock - private XtaProperties properties; - - @DisplayName("get identifiers") - @Nested - class TestGetIdentifiers { - @BeforeEach - void mock() { - when(properties.getIdentifiers()).thenReturn(IDENTIFIERS); - } - - @DisplayName("should return") - @Test - void shouldReturn() { - assertThat(service.getIdentifiers()).isEqualTo(IDENTIFIERS); - } - } - -} diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java index 4221fec655e7aa48b29625d02cfec1b56232839c..b98ea399ed2d4a5a02719c2d80c16e8f7e0fba7d 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java @@ -28,9 +28,13 @@ import java.io.InputStream; import java.math.BigInteger; import java.nio.charset.StandardCharsets; +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; +import lombok.SneakyThrows; import org.apache.commons.io.FileUtils; -import lombok.SneakyThrows; +import de.ozgcloud.xta.client.model.XtaFile; class XtaFileTestFactory { @@ -46,25 +50,29 @@ class XtaFileTestFactory { return XtaFile.builder() .name(NAME) .contentType(ZIP_CONTENT_TYPE) - .file(createFile()); + .content(createData()); } @SneakyThrows - private static File createFile() { + private static DataHandler createData() { File tFile = File.createTempFile("test", ".zip"); tFile.deleteOnExit(); - FileUtils.write(tFile, CONTENT, StandardCharsets.UTF_8); - - return tFile; + DataSource fds = new FileDataSource(tFile); + return new DataHandler(fds); } @SneakyThrows static XtaFile withFileContent(InputStream stream, String fileName) { File tFile = File.createTempFile(fileName, ".zip"); tFile.deleteOnExit(); - FileUtils.copyInputStreamToFile(stream, tFile); - return createBuilder().name(fileName).size(BigInteger.valueOf(tFile.length())).file(tFile).build(); + DataSource fds = new FileDataSource(tFile); + DataHandler data = new DataHandler(fds); + return createBuilder() + .name(fileName) + .size(BigInteger.valueOf(tFile.length())) + .content(data) + .build(); } } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaFormMetaDataTestFactory.java similarity index 86% rename from src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java rename to src/test/java/de/ozgcloud/eingang/xta/XtaFormMetaDataTestFactory.java index 14c3a0e1b6f9a2e3838b1148b3b6d289a778a52e..cd1ec0b16e56084b315f4d510a9ca9d443e42326 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaFormMetaDataTestFactory.java @@ -29,7 +29,7 @@ import java.time.ZonedDateTime; import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory; -class XtaMessageMetaDataTestFactory { +class XtaFormMetaDataTestFactory { static final String MESSAGE_TYPE = "Geschaeftsgang.Geschaeftsgang.0201"; static final String FIM_MESSAGE_TYPE = "fim.S17000652.17000652001004"; @@ -37,12 +37,12 @@ class XtaMessageMetaDataTestFactory { static final String SERVICE = "urn:fim:Versammlungsanzeige:1.4"; static final String MESSAGE_TYPE_LIST_VERSION = "1.0"; - static XtaMessageMetaData create() { + static XtaFormMetaData create() { return createBuilder().build(); } - static XtaMessageMetaData.XtaMessageMetaDataBuilder createBuilder() { - return XtaMessageMetaData.builder() + static XtaFormMetaData.XtaFormMetaDataBuilder createBuilder() { + return XtaFormMetaData.builder() .messageId(MESSAGE_ID) .messageType(MESSAGE_TYPE) .messageTypeListVersion(MESSAGE_TYPE_LIST_VERSION) @@ -51,11 +51,11 @@ class XtaMessageMetaDataTestFactory { .service(SERVICE); } - static XtaMessageMetaData createFim() { + static XtaFormMetaData createFim() { return createFimBuilder().build(); } - static XtaMessageMetaData.XtaMessageMetaDataBuilder createFimBuilder() { + static XtaFormMetaData.XtaFormMetaDataBuilder createFimBuilder() { return createBuilder() .messageType(FIM_MESSAGE_TYPE); } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java b/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java index 92b71131a29054468da0621fce5aeb5a5bae22da..fd0e48cd02d4037ab5f4ea17b5195c8fce44c979 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java @@ -31,8 +31,8 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.List; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -55,6 +55,8 @@ import de.ozgcloud.eingang.router.VorgangRemoteService; import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; import de.ozgcloud.vorgang.vorgang.GrpcEingang; import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import de.ozgcloud.xta.client.XtaClient; + import io.grpc.Channel; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; @@ -84,7 +86,7 @@ class XtaITCase { private Channel channel; @MockitoBean - private XtaRemoteService xtaRemoteService; + private XtaClient xtaClient; @Captor private ArgumentCaptor<FormData> formDataArgumentCaptor; @@ -250,13 +252,9 @@ class XtaITCase { } } + @SneakyThrows private void mockNachrichtenBroker(String zipFileName) { - when(xtaRemoteService.getMessage(any(XtaMessageId.class))).thenReturn( - XtaResponseTestFactory.createGetMessageResponse(zipFileName)); - when(xtaRemoteService.getMessagesMetadata()) - .thenReturn(XtaResponseTestFactory.createGetStatusListResponse(List.of(zipFileName))); - when(xtaRemoteService.getNextMessagesMetadata(any())) - .thenReturn(XtaResponseTestFactory.createEmptyGetStatusListResponse()); + // TODO } @Target({ ElementType.METHOD }) diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java index 9bcc0e1544d329697aaa050b3849ee6451359864..b2c837e73036e840146cfc5453591a9a5d24063a 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java @@ -56,10 +56,10 @@ class XtaIncomingFilesMapperTest { when(mapper.toIncomingFile(xtaFile)).thenReturn(incomingFile); when(mapper.tryToExtractZip(incomingFile)).thenAnswer(x -> Stream.of(incomingFile)); - mapper.toIncomingFiles(List.of(xtaFile, xtaFile)); + mapper.toIncomingFiles(xtaFile); - inOrder(mapper).verify(mapper, calls(2)).toIncomingFile(xtaFile); - inOrder(mapper).verify(mapper, calls(2)).tryToExtractZip(incomingFile); + inOrder(mapper).verify(mapper, calls(1)).toIncomingFile(xtaFile); + inOrder(mapper).verify(mapper, calls(1)).tryToExtractZip(incomingFile); } @Test diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java index 87ca9255687db498b49e5f0bae6e41ff7679e8ee..672b68c75048f156999ebca098497afa9f9921f0 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java @@ -38,6 +38,7 @@ import org.mockito.Spy; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory; import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier; +import de.ozgcloud.xta.client.model.XtaMessageMetaData; class XtaMessageMapperTest { @@ -115,7 +116,7 @@ class XtaMessageMapperTest { var formData = doMapping(); assertThat(formData.getControl().getMetaData()).isPresent().get() - .extracting(metaData -> metaData.getEntry(XtaMessageMetaData.XTA_IDENTIFIER_ENTRY_NAME)) + .extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME)) .isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER); } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..3238362540d6697cad3bbbe8516c99a5beed572f --- /dev/null +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataFactory.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.eingang.xta; + +import static de.ozgcloud.eingang.xta.XtaMessageTestFactory.*; + +import java.time.ZonedDateTime; + +import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory; +import de.ozgcloud.xta.client.model.XtaIdentifier; +import de.ozgcloud.xta.client.model.XtaMessageMetaData; + +class XtaMessageMetaDataTestFactory { + + static final String MESSAGE_TYPE = "Geschaeftsgang.Geschaeftsgang.0201"; + static final String FIM_MESSAGE_TYPE = "fim.S17000652.17000652001004"; + static final ZonedDateTime ORIGIN = ZonedDateTime.parse("2022-10-29T15:45:52.4942149+02:00"); + static final String SERVICE = "urn:fim:Versammlungsanzeige:1.4"; + static final String MESSAGE_TYPE_LIST_VERSION = "1.0"; + static final XtaIdentifier READER_IDENTIFIER = XtaIdentifier.builder() + .value("vbe:010550120100").build(); + + static XtaMessageMetaData create() { + return createBuilder().build(); + } + + static XtaMessageMetaData.XtaMessageMetaDataBuilder createBuilder() { + return XtaMessageMetaData.builder() + .messageId(MESSAGE_ID.toString()) + .messageTypeCode(MESSAGE_TYPE) + // .origin(ORIGIN) TODO add in xta-client-lib + .readerIdentifier(READER_IDENTIFIER) + .service(SERVICE); + } + + static XtaMessageMetaData createFim() { + return createFimBuilder().build(); + } + + static XtaMessageMetaData.XtaMessageMetaDataBuilder createFimBuilder() { + return createBuilder() + .messageTypeCode(FIM_MESSAGE_TYPE); + } +} diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java index 68a479c0892adf926408984872ffdaca4d972f43..2e97f03bd035ad396bb7c1b13e8f5c7fc6ad5c10 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java @@ -30,7 +30,7 @@ class XtaMessageMetaDatasAndHeaderTestFactory { public static final String MSG_BOX_REQUEST_ID = UUID.randomUUID().toString(); - public static final XtaMessageMetaData MESSAGE1 = XtaMessageMetaDataTestFactory.create(); + public static final XtaFormMetaData MESSAGE1 = XtaFormMetaDataTestFactory.create(); public static XtaMessageMetaDatasAndHeader create() { return createBuilder().build(); diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java deleted file mode 100644 index 456518d4ab482b631dffb3304cd2d9795369c877..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import static org.assertj.core.api.Assertions.*; -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; -import org.mockito.Mock; - -class XtaMessageMetadataRemoteIteratorTest { - - private XtaMessageMetaDatasAndHeader messageMetaDatasAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.create(); - - @Mock - private XtaRemoteService remoteService; - - @BeforeEach - void setup() { - when(remoteService.getMessagesMetadata()).thenReturn(messageMetaDatasAndHeader); - } - - @Nested - class TestIteratorInitialization { - - @Test - void shouldCallGetMessagesMetadata() { - new XtaMessageMetadataRemoteIterator(remoteService); - - verify(remoteService).getMessagesMetadata(); - } - - @Test - void shouldCallRemoteMessageIterator() { - when(remoteService.getMessagesMetadata()).thenReturn(messageMetaDatasAndHeader); - - Object remoteIterator = spy(new XtaMessageMetadataRemoteIterator(remoteService)); - - assertThat(remoteIterator).extracting("remoteMessageIterator").isNotNull(); - } - } - - @Nested - class TestHasNext { - - @Test - void shouldReturnTrueAfterInitialization() { - var remoteIterator = new XtaMessageMetadataRemoteIterator(remoteService); - - assertThat(remoteIterator.hasNext()).isTrue(); - } - - @Test - void shouldReturnTrueWhenMoreMessagesAvailable() { - var messageMetadataAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.createBuilder().moreMessagesAvailable(true).build(); - when(remoteService.getMessagesMetadata()).thenReturn(messageMetadataAndHeader); - - var remoteIterator = new XtaMessageMetadataRemoteIterator(remoteService); - - assertThat(remoteIterator.hasNext()).isTrue(); - } - - @Test - void shouldCallLoadNextMessages() { - initTest(); - var remoteIterator = spy(new XtaMessageMetadataRemoteIterator(remoteService)); - - remoteIterator.hasNext(); - - verify(remoteIterator).loadNextMessages(); - } - - private void initTest() { - var messageMetadataAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.createBuilder() - .messages(Stream.empty()).moreMessagesAvailable(true).build(); - when(remoteService.getMessagesMetadata()).thenReturn(messageMetadataAndHeader); - var nextMessageMetadataAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.createBuilder().msgBoxRequestID("id").build(); - when(remoteService.getNextMessagesMetadata(any())).thenReturn(nextMessageMetadataAndHeader); - } - - @Test - void shouldReturnFalseWhenNoMoreMessagesAvailable() { - var messageMetadataAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.createBuilder().messages(Stream.empty()).build(); - when(remoteService.getMessagesMetadata()).thenReturn(messageMetadataAndHeader); - - var remoteIterator = new XtaMessageMetadataRemoteIterator(remoteService); - - assertThat(remoteIterator.hasNext()).isFalse(); - } - } - - @Nested - class TestLoadNextMessages { - - private XtaMessageMetaDatasAndHeader nextMessageMetadataAndHeader = XtaMessageMetaDatasAndHeaderTestFactory.createBuilder().msgBoxRequestID("id").build(); - - @BeforeEach - void setup() { - when(remoteService.getNextMessagesMetadata(any())).thenReturn(nextMessageMetadataAndHeader); - } - - @Test - void shouldCallGetMessages() { - new XtaMessageMetadataRemoteIterator(remoteService).loadNextMessages(); - - verify(remoteService).getNextMessagesMetadata(messageMetaDatasAndHeader.getMsgBoxRequestID()); - } - - @Test - void shouldCallGetRemoteMessageIterator() { - var remoteIterator = spy(new XtaMessageMetadataRemoteIterator(remoteService)); - - remoteIterator.loadNextMessages(); - - verify(remoteIterator).getRemoteMessageIterator(nextMessageMetadataAndHeader); - } - } -} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java index f29f0477c255e7e200620e934cc5a70dd91cb8cd..77712b7a2823da8a8a9fc2126f780370cba1d1cb 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java @@ -23,6 +23,11 @@ */ package de.ozgcloud.eingang.xta; +import java.util.List; + +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; + class XtaMessageTestFactory { static final XtaMessageId MESSAGE_ID = XtaMessageId.from("urn:de:xta:messageid:dataport_xta_210:81e40808-91c6-4765-aaf4-1aa62fec8be9"); @@ -38,7 +43,6 @@ class XtaMessageTestFactory { return XtaMessage.builder() .metaData(XtaMessageMetaDataTestFactory.create()) .messageFile(XtaFileTestFactory.create()) - .primaryFormDataMessage(XtaFileTestFactory.NAME) - .attachment(attachment); + .attachmentFiles(List.of(attachment)); } } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfigurationTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfigurationTest.java deleted file mode 100644 index 066dddde93f18da473f046e994b7d132ef5ed8a1..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceConfigurationTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Spy; - -class XtaRemoteServiceConfigurationTest { - - @Spy - @InjectMocks - XtaRemoteServiceConfiguration configuration; - - @Test - void testBuildServerAddressUri() { - - String serverUrl = configuration.buildServerAddressUri(XtaPropertiesTestFactory.create().getServer()); - - assertThat(serverUrl).isEqualTo("https://xta-adapter-port-forward-service.ssh-port-forward.svc.cluster.local/MB_XTA-WS/XTA210msgBoxPort.svc"); - } -} diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceFunctionalCase.java b/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceFunctionalCase.java deleted file mode 100644 index d8f92dcd6b7b563f55360dae166bcea558990a5d..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceFunctionalCase.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -import static org.assertj.core.api.Assertions.*; - -import jakarta.validation.Valid; - -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.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; - -import de.ozgcloud.eingang.Application; - -@Disabled("real live test - do only activate for manual testing") -@ActiveProfiles({ "itcase", "local" }) -@SpringBootTest(classes = Application.class, // - properties = { "ozgcloud.xta.server.name=LI33-0005", - "ozgcloud.xta.server.address=LI33-0005:3000", - "ozgcloud.xta.server.protocol=https", - "ozgcloud.xta.keystore.file=file:./KOP_SH_KIEL_DEV.p12", - "ozgcloud.xta.keystore.password=<geheim>" // replace this with real password - }) -class XtaRemoteServiceITCase { - - @Autowired - private XtaRemoteService remoteService; - @Autowired - @Valid - private XtaProperties xtaProperties; - - @Nested - class TestProperties { - @Test - void shouldHaveStatusListAction() { - assertThat(xtaProperties.getActions().getStatusList()).isNotNull(); - } - } - - @Nested - class TestGetStatusList { - - @Test - void shouldSendRequest() { - - var result = remoteService.getStatusList(); - - assertThat(result).isNotNull(); - - } - } - - @Nested - class TestGetMessage { - @Test - void shouldSendRequest() { - var result = remoteService.loadContentContainer("urn:de:xta:messageid:dataport_xta_210:20eb297a-e224-45a0-9376-5ebd4d9bcc9a"); - - assertThat(result).isNotNull(); - } - } - - @Nested - class TestClose { - @Test - void shouldThrowNoException() { - assertThatNoException().isThrownBy(() -> remoteService.close(XtaMessageTestFactory.MESSAGE_ID)); - } - } -} diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java deleted file mode 100644 index 0ac8a04d0c6b1fb62f9f78b1b3a24aa2f1317c6c..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.eingang.xta; - -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; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.springframework.boot.webservices.client.WebServiceTemplateBuilder; - -import de.xoev.transport.xta._211.GenericContentContainer; - -class XtaRemoteServiceTest { - - @Spy - @InjectMocks - private XtaRemoteService service; - - @Mock - private WebServiceTemplateBuilder templateBuilder; - @Mock - private XtaMessageMetaDataMapper mapper; - @Spy - private XtaProperties properties = XtaPropertiesTestFactory.create(); - - @Nested - class TestGetMessagesMetadata { - - @BeforeEach - void init() { - doReturn(MsgStatusListTypeAndHeaderResponseTestFactory.create()).when(service).getStatusList(); - when(mapper.msgStatusListFromSoap(any(MsgStatusListTypeAndHeaderResponse.class))) - .thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()); - } - - @Test - void shouldCallGetStatusList() { - service.getMessagesMetadata().getMessages().toList(); - - verify(service).getStatusList(); - } - - @Test - void shouldCallMapper() { - service.getMessagesMetadata(); - - verify(mapper).msgStatusListFromSoap(notNull()); - } - - @Test - void shouldReturnMessageId() { - var metaData = service.getMessagesMetadata().getMessages().toList(); - - assertThat(metaData).hasSize(1).first().usingRecursiveComparison().isEqualTo(XtaMessageMetaDataTestFactory.create()); - } - } - - @Nested - class TestGetNextMessagesMetadata { - - @BeforeEach - void init() { - doReturn(MsgStatusListTypeAndHeaderResponseTestFactory.create()).when(service).getStatusList(); - when(mapper.msgStatusListFromSoap(any(MsgStatusListTypeAndHeaderResponse.class))) - .thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()); - } - - @Test - void shouldCallGetNextStatusList() { - service.getMessagesMetadata().getMessages().toList(); - - verify(service).getStatusList(); - } - - @Test - void shouldCallMapper() { - service.getMessagesMetadata(); - - verify(mapper).msgStatusListFromSoap(notNull()); - } - - @Test - void shouldReturnMessageId() { - var metaData = service.getMessagesMetadata().getMessages().toList(); - - assertThat(metaData).hasSize(1).first().usingRecursiveComparison().isEqualTo(XtaMessageMetaDataTestFactory.create()); - } - } - - @Nested - class TestGetMessage { - - private XtaFile file = XtaFileTestFactory.create(); - @Mock - private GenericContentContainer contentContainerMock; - - @BeforeEach - void init() { - doReturn(file).when(service).getMessage(Mockito.<GenericContentContainer>any()); - doReturn(contentContainerMock).when(service).loadContentContainer(anyString()); - doReturn(Stream.of(file)).when(service).getAttachments(any()); - } - - @Test - void shouldCallLoadContentContainer() { - service.getMessage(XtaMessageTestFactory.MESSAGE_ID); - - verify(service).loadContentContainer(XtaMessageTestFactory.MESSAGE_ID.toString()); - } - - @Test - void shouldCallGetMessage() { - service.getMessage(XtaMessageTestFactory.MESSAGE_ID); - - verify(service).getMessage(contentContainerMock); - } - - @Test - void sohludCallGetAttachments() { - service.getMessage(XtaMessageTestFactory.MESSAGE_ID); - - verify(service).getAttachments(contentContainerMock); - } - - @Test - void shouldReturnMessageWithoutMetaData() { - var message = service.getMessage(XtaMessageTestFactory.MESSAGE_ID); - - assertThat(message.getMetaData()).isNull(); - } - - @Test - void shouldReturnMessageWithFile() { - var message = service.getMessage(XtaMessageTestFactory.MESSAGE_ID); - - assertThat(message.getMessageFiles()).hasSize(1).contains(file); - } - } -} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaResponseTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaResponseTestFactory.java index b7596f8e56caa131e6d0fe68bf43dbc9e85ba505..beee8d00f464ae5683413f45756559b3fdd4a440 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaResponseTestFactory.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaResponseTestFactory.java @@ -41,10 +41,15 @@ import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; import org.apache.commons.codec.Resources; import org.apache.commons.io.IOUtils; import de.ozgcloud.common.binaryfile.TempFileUtils; +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; public class XtaResponseTestFactory { @@ -78,7 +83,7 @@ public class XtaResponseTestFactory { public static XtaMessageMetaDatasAndHeader createGetStatusListResponse(List<String> xtaAttachmentFileNames) { var messageMetaDataItems = xtaAttachmentFileNames.stream() .map(name -> - XtaMessageMetaData.builder() + XtaFormMetaData.builder() .messageId(new XtaMessageId(MESSAGE_ID_BY_ATTACHMENT_FILENAME.get(name))) .messageType(MESSAGE_TYPE_BY_ATTACHMENT_FILENAME.get(name)) .origin(ZonedDateTime.now()) @@ -102,12 +107,15 @@ public class XtaResponseTestFactory { throw new RuntimeException(e); } + DataSource dataSource = new FileDataSource(file); + DataHandler dataHandler = new DataHandler(dataSource); + return XtaMessage.builder() .messageFile(XtaFile.builder() .contentType("application/zip") .name(xtaAttachmentFileName) .size(BigInteger.valueOf(file.length())) - .file(file) + .content(dataHandler) .build()) .build(); } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java index f5c6500cb292dee93954e02c3a3e9e5a8b95889d..19a0bf427e082d4d4d23430ac6c394e3ee37ee39 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java @@ -25,9 +25,6 @@ package de.ozgcloud.eingang.xta; 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; import org.mockito.InjectMocks; @@ -49,32 +46,12 @@ class XtaRunnerTest { @Nested class TestRunGetXtaMessages { - public static final FormData MESSAGE = FormDataTestFactory.create(); - - @BeforeEach - void init() { - when(service.getMessages()).thenReturn(Stream.of(MESSAGE)); - } - @Test - void shouldCallXtaServiceGetNextMessages() { + void shouldCallXtaServiceFetchMessages() { scheduler.runGetXtaMessages(); - verify(service).getMessages(); + verify(service).fetchMessages(); } - @Test - void shouldHandOverFormDataToSemantikAdapter() { - scheduler.runGetXtaMessages(); - - verify(semantikAdapter).processFormData(MESSAGE); - } - - @Test - void shouldAcknowledgeReceive() { - scheduler.runGetXtaMessages(); - - verify(service).acknowledgeReceive(XtaMessageTestFactory.MESSAGE_ID); - } } } diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaServiceConfigurationTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..012411dd3537a346029c552762521fc625b32e66 --- /dev/null +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceConfigurationTest.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.eingang.xta; + +import static de.ozgcloud.eingang.xta.XtaService.FIM_MESSAGE_TYPE_PREFIX; +import static org.assertj.core.api.Assertions.*; + +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 XtaServiceConfigurationTest { + + @Spy + @InjectMocks + XtaServiceConfiguration configuration; + + @Mock + XtaProperties properties = XtaPropertiesTestFactory.create(); + + @Test + void testBuildServerAddressUri() { + + String serverBaseUrl = configuration.getBaseUrl(); + + assertThat(serverBaseUrl).isEqualTo("https://xta-adapter-port-forward-service.ssh-port-forward.svc.cluster.local/MB_XTA-WS/XTA210"); + } + + @Nested + class TestIsSupportedMessageType { + + private static final String MESSAGE_TYPE_OTHER = "MESSAGE_TYPE_OTHER"; + + @Test + void shouldAcceptGeschaeftsgang() { + var geschaeftsgangMetaData = XtaMessageMetaDataTestFactory.create(); + + assertThat(configuration.isSupportedMessageType(geschaeftsgangMetaData)).isTrue(); + } + + @Test + void shouldAcceptFIM() { + var fimMetaData = XtaMessageMetaDataTestFactory.createBuilder() + .messageTypeCode(FIM_MESSAGE_TYPE_PREFIX + "34355") + .build(); + + assertThat(configuration.isSupportedMessageType(fimMetaData)).isTrue(); + } + + @Test + void shouldNotAcceptOtherMessageType() { + var metaDataDFoerder = XtaMessageMetaDataTestFactory.createBuilder() + .messageTypeCode(MESSAGE_TYPE_OTHER).build(); + + assertThat(configuration.isSupportedMessageType(metaDataDFoerder)).isFalse(); + } + } +} diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java index 5891d8140d1c0d4911a21a9f45512577db13b879..929fe6fd545477f77bf1ca03f2876deb27ebf24b 100644 --- a/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java @@ -28,10 +28,12 @@ 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 java.util.stream.Stream; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -50,17 +52,19 @@ import de.ozgcloud.eingang.common.formdata.IncomingFile; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier; import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper; +import de.ozgcloud.xta.client.XtaClient; +import de.ozgcloud.xta.client.model.XtaMessage; +import de.ozgcloud.xta.client.model.XtaMessageMetaData; +import de.ozgcloud.xta.client.model.XtaTransportReport; class XtaServiceTest { - private static final String MESSAGE_TYPE_OTHER = "MESSAGE_TYPE_OTHER"; - @Spy @InjectMocks private XtaService service; @Mock - private XtaRemoteService remoteService; + private XtaClient xtaClient; @Mock private XtaMessageMapper mapper; @Mock @@ -72,136 +76,68 @@ class XtaServiceTest { @Mock private XdomeaMessageDataMapper xdomeaMessageDataMapper; - @Mock - private XtaCurrentIdentifierService currentIdentifierService; - @Mock private FormData formData; @Mock private FormData formData2; + // TODO write missing tests + @Nested class TestGetMessagesAsFormData { - private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create(); - private final XtaMessage message = XtaMessageTestFactory.create(); + private final XtaTransportReport transportReport = XtaTransportReportFactory.create(); @DisplayName("with one message") @Nested class TestWithOneMessage { @BeforeEach + @SneakyThrows void setup() { - doReturn(Stream.of(messageMetaData)).when(service).createXtaMessageStream(); - } - - @Test - void shouldCallCreateStream() { - service.getMessages(); - - verify(service).createXtaMessageStream(); - } - - @Test - void shouldCallFilterByMessageType() { - setupMocks(); - - service.getMessages().toList(); - - verify(service).isSupportedMessageType(messageMetaData); - } - - @Test - void shouldCallGetFormDataIfNoRuntimeException() { - setupMocks(); - doReturn(true).when(service).isSupportedMessageType(messageMetaData); - - service.getMessages().toList(); - - verify(service).getFormData(messageMetaData); + doReturn(Stream.of(transportReport)).when(xtaClient).fetchMessages(any()); } @Test - void shouldNotCallGetFormDataIfNoRuntimeException() { - doReturn(false).when(service).isSupportedMessageType(messageMetaData); - - service.getMessages().toList(); + @SneakyThrows + void shouldCallXtaClient() { + service.fetchMessages(); - verify(service, never()).getFormDataIfNoRuntimeException(any()); + verify(xtaClient).fetchMessages(service::processMessage); } } @DisplayName("with multiple messages") @Nested class TestWithMultipleMessages { - private final XtaMessageMetaData messageMetaData2 = XtaMessageMetaDataTestFactory.createBuilder() - .messageId(XtaMessageId.from("messageId2")) - .build(); - private final XtaMessageMetaData messageMetaData3 = XtaMessageMetaDataTestFactory.createBuilder() - .messageId(XtaMessageId.from("messageId3")) - .build(); + private final XtaTransportReport transportReport2 = XtaTransportReportFactory.create(); + private final XtaTransportReport transportReport3 = XtaTransportReportFactory.create(); @BeforeEach + @SneakyThrows void setup() { - doReturn(Stream.of(messageMetaData, messageMetaData2, messageMetaData3)).when(service).createXtaMessageStream(); + doReturn(Stream.of(transportReport, transportReport2, transportReport3)).when(xtaClient).fetchMessages(any()); } @DisplayName("should return stream of messages") @Test + @SneakyThrows void shouldReturnStreamOfMessages() { - doReturn(true).when(service).isSupportedMessageType(messageMetaData); - doReturn(false).when(service).isSupportedMessageType(messageMetaData3); - doReturn(true).when(service).isSupportedMessageType(messageMetaData2); - doReturn(Optional.of(formData)).when(service).getFormDataIfNoRuntimeException(messageMetaData); - doReturn(Optional.of(formData2)).when(service).getFormDataIfNoRuntimeException(messageMetaData2); - - var result = service.getMessages().toList(); + service.fetchMessages(); - assertThat(result).containsExactly(formData, formData2); + verify(xtaClient, calls(3)).fetchMessages(service::processMessage); } } - - private void setupMocks() { - var testFormData = FormDataTestFactory.create(); - when(mapper.toFormData(any(), any(), eq(vorgangNummerSupplier))).thenReturn(testFormData); - when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn(message); - } - } - - @Nested - class TestIsSupportedMessageType { - - @Test - void shouldAcceptGeschaeftsgang() { - var geschaeftsgangMetaData = XtaMessageMetaDataTestFactory.create(); - - assertThat(service.isSupportedMessageType(geschaeftsgangMetaData)).isTrue(); - } - - @Test - void shouldAcceptFIM() { - var fimMetaData = XtaMessageMetaDataTestFactory.createBuilder() - .messageType(FIM_MESSAGE_TYPE_PREFIX + "34355") - .build(); - - assertThat(service.isSupportedMessageType(fimMetaData)).isTrue(); - } - - @Test - void shouldNotAcceptOtherMessageType() { - var metaDataDFoerder = XtaMessageMetaDataTestFactory.createBuilder().messageType(MESSAGE_TYPE_OTHER).build(); - - assertThat(service.isSupportedMessageType(metaDataDFoerder)).isFalse(); - } } @DisplayName("get form data if no runtime exception") @Nested class TestGetFormDataIfNoRuntimeException { + // BeforeEach from factory instead of Mock @Mock - XtaMessageMetaData messageMetaData; + XtaMessage message; @Mock FormData formData; @@ -209,9 +145,9 @@ class XtaServiceTest { @DisplayName("should call get formdata") @Test void shouldCallGetFormdata() { - service.getFormDataIfNoRuntimeException(messageMetaData); + service.getFormDataIfNoRuntimeException(message); - verify(service).getFormData(messageMetaData); + verify(service).getFormData(message); } @DisplayName("with exception") @@ -222,7 +158,7 @@ class XtaServiceTest { void shouldReturnEmpty() { doThrow(new RuntimeException("test-error")).when(service).getFormData(any()); - var result = service.getFormDataIfNoRuntimeException(messageMetaData); + var result = service.getFormDataIfNoRuntimeException(message); assertThat(result).isEmpty(); } @@ -236,7 +172,7 @@ class XtaServiceTest { void shouldReturn() { doReturn(formData).when(service).getFormData(any()); - var result = service.getFormDataIfNoRuntimeException(messageMetaData); + var result = service.getFormDataIfNoRuntimeException(message); assertThat(result).contains(formData); } @@ -264,33 +200,25 @@ class XtaServiceTest { void init() { classification = RepresentationsAttachmentsPairTestFactory.create(); var incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create()); - when(incomingFilesMapper.toIncomingFiles(message.getMessageFiles())).thenReturn(incomingFiles); + when(incomingFilesMapper.toIncomingFiles(message.messageFile())).thenReturn(incomingFiles); doReturn(classification).when(service).getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); } @BeforeEach void mockMessageMapping() { - when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn(message); when(mapper.toFormData(any(), any(), any())).thenReturn(mappedFormData); } - @Test - void shouldCallRemoteService() { - service.getFormData(messageMetaData); - - verify(remoteService).getMessage(XtaMessageTestFactory.MESSAGE_ID); - } - @Test void shouldCallMapper() { - service.getFormData(messageMetaData); + service.getFormData(message); verify(mapper).toFormData(classification, messageMetaData, vorgangNummerSupplier); } @Test void shouldCallMapperToFormData() { - service.getFormData(messageMetaData); + service.getFormData(message); verify(mapper).toFormData(classificationCaptor.capture(), messageMetaDataCaptor.capture(), eq(vorgangNummerSupplier)); assertThat(messageMetaDataCaptor.getValue()).isEqualTo(messageMetaData); @@ -299,7 +227,7 @@ class XtaServiceTest { @Test void shouldCallAddAttachments() { - service.getFormData(messageMetaData); + service.getFormData(message); verify(service).addAttachments(message, mappedFormData); } @@ -308,7 +236,7 @@ class XtaServiceTest { void shouldReturnMappedResult() { doReturn(mappedFormData).when(service).addRepresentations(any(), any()); - var result = service.getFormData(messageMetaData); + var result = service.getFormData(message); assertThat(result).isEqualTo(mappedFormData); } @@ -329,7 +257,7 @@ class XtaServiceTest { @Test void shouldWorkWithoutAnyAttachment() { - var result = service.addAttachments(XtaMessageTestFactory.createBuilder().clearAttachments().build(), inFormData); + var result = service.addAttachments(XtaMessageTestFactory.createBuilder().attachmentFiles(Collections.emptyList()).build(), inFormData); assertThat(result.getAttachments()).isEmpty(); assertThat(result.getNumberOfAttachments()).isZero(); @@ -339,7 +267,7 @@ class XtaServiceTest { @DisplayName("get representations attachments pair") @Nested class TestGetRepresentationsAttachmentsPair { - + // TODO use TestFactory instead of Mock @Mock private XtaMessageMetaData messageMetaData; @@ -356,7 +284,7 @@ class XtaServiceTest { @DisplayName("should use correct mapper xdomea message type") @Test void shouldUseCorrectMapperXdomeaMessageType() { - when(messageMetaData.getMessageType()).thenReturn(XtaService.XDOMEA_0201_MESSAGE_TYPE); + when(messageMetaData.messageTypeCode()).thenReturn(XtaService.XDOMEA_0201_MESSAGE_TYPE); when(xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles)) .thenReturn(classification); @@ -368,7 +296,7 @@ class XtaServiceTest { @DisplayName("should use correct mapping for FIM message") @Test void shouldUseCorrectMappingForFimMessage() { - when(messageMetaData.getMessageType()).thenReturn(FIM_MESSAGE_TYPE_PREFIX + "836487"); + when(messageMetaData.messageTypeCode()).thenReturn(FIM_MESSAGE_TYPE_PREFIX + "836487"); doReturn(classification).when(service).mapIncomingFilesToRepresentations(incomingFiles); var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); @@ -379,7 +307,7 @@ class XtaServiceTest { @DisplayName("should throw exception for unexpected message type") @Test void shouldThrowExceptionForUnexpectedMessageType() { - when(messageMetaData.getMessageType()).thenReturn("unexpected"); + when(messageMetaData.messageTypeCode()).thenReturn("unexpected"); assertThatThrownBy(() -> service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles)) .isInstanceOf(TechnicalException.class); @@ -415,63 +343,11 @@ class XtaServiceTest { } } - @Nested - class TestAcknowledgeReceive { - - @Test - void shouldCallRemoteService() { - service.acknowledgeReceive(XtaMessageTestFactory.MESSAGE_ID); - - verify(remoteService).close(XtaMessageTestFactory.MESSAGE_ID); - } - } - - @DisplayName("create XTA message stream") - @Nested - class TestCreateXtaMessageStream { - private static final List<String> XTA_IDENTIFIERS = List.of("XTA_IDENTIFIER", "XTA_IDENTIFIER2"); - - @Captor - private ArgumentCaptor<String> identifierCaptor; - - @BeforeEach - void mock() { - when(remoteService.getMessagesMetadata()) - .thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()) - .thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()); - when(currentIdentifierService.getIdentifiers()).thenReturn(XTA_IDENTIFIERS); - } - - @DisplayName("should return") - @Test - void shouldReturn() { - var result = service.createXtaMessageStream().toList(); - - assertThat(result).isEqualTo(getExpectedMessages()); - } - - private List<XtaMessageMetaData> getExpectedMessages() { - return Stream.concat( - XtaMessageMetaDatasAndHeaderTestFactory.create().getMessages(), - XtaMessageMetaDatasAndHeaderTestFactory.create().getMessages()).toList(); - } - - @DisplayName("should call set current identifier") - @Test - void shouldCallSetCurrentIdentifier() { - service.createXtaMessageStream().toList(); - - verify(currentIdentifierService, times(2)) - .setCurrentIdentifier(identifierCaptor.capture()); - assertThat(identifierCaptor.getAllValues()).isEqualTo(XTA_IDENTIFIERS); - } - } - @Nested class TestAddRepresentations { @Test void shouldAddPrimaryRepresentation() { - var result = service.addRepresentations(FormDataTestFactory.create(), XtaMessageTestFactory.create()); + var result = service.addRepresentations(FormDataTestFactory.create(), XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE); assertThat(result.getControl().getRepresentations()).isPresent().get() .extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE); @@ -484,7 +360,7 @@ class XtaServiceTest { Representations.builder().primaryFormDataPdfRepresentation("PDF_FILE").build())) .build()).build(); - var result = service.addRepresentations(formData, XtaMessageTestFactory.create()); + var result = service.addRepresentations(formData, XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE); var baseAssert = assertThat(result.getControl().getRepresentations()).isPresent().get(); baseAssert.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE); diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaTransportReportFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaTransportReportFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..38d236537ea352871b19a8432959dc6f8f10121c --- /dev/null +++ b/src/test/java/de/ozgcloud/eingang/xta/XtaTransportReportFactory.java @@ -0,0 +1,22 @@ +package de.ozgcloud.eingang.xta; + +import java.time.ZonedDateTime; + +import de.ozgcloud.xta.client.model.XtaMessageStatus; +import de.ozgcloud.xta.client.model.XtaTransportReport; + +public class XtaTransportReportFactory { + + + public static XtaTransportReport create() { + return createBuilder() + .build(); + } + + public static XtaTransportReport.XtaTransportReportBuilder createBuilder() { + return XtaTransportReport.builder() + .metaData(XtaMessageMetaDataTestFactory.create()) + .reportTime(ZonedDateTime.now()) + .status(XtaMessageStatus.GREEN); + } +}