diff --git a/xta-adapter/doc/example-response-getmessages-items-pending.xml b/xta-adapter/doc/example-response-getmessages-items-pending.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdc87bdc1989d52151d8bff1700546b5c60adac2 --- /dev/null +++ b/xta-adapter/doc/example-response-getmessages-items-pending.xml @@ -0,0 +1,51 @@ +<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> + <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> + <tran:MsgBoxResponse xmlns:tran="http://www.osci.eu/ws/2008/05/transport"> + <tran:MsgBoxResponse MsgBoxRequestID="urn:de:xta:requestid:xta-tester:e8959968-a8c3-4ba4-aad1-5928ad6030dc"> + <tran:ItemsPending>1</tran:ItemsPending> + </tran:MsgBoxResponse> + </tran:MsgBoxResponse> + <wsa:Action>http://www.osci.eu/ws/2008/05/transport/urn/messageTypes/MsgBoxStatusListRequest</wsa:Action> + <wsa:RelatesTo>uuid:d30e3dbd-4724-4a08-84b9-55e61ce1b404</wsa:RelatesTo> + </soapenv:Header> + <soapenv:Body> + <tran:MsgStatusList xmlns:tran="http://www.osci.eu/ws/2008/05/transport" xmlns:tran1="http://www.osci.eu/ws/2014/10/transport" xmlns:add="http://www.w3.org/2005/08/addressing"> + <tran1:MessageMetaData> + <tran1:DeliveryAttributes> + <tran1:Origin>2022-02-25T14:13:57.613+01:00</tran1:Origin> + <tran1:InitialSend>2022-02-25T14:13:57.613+01:00</tran1:InitialSend> + <tran1:Delivery>2022-02-25T14:13:57.613+01:00</tran1:Delivery> + <tran1:InitialFetch>2022-02-25T14:13:57.613+01:00</tran1:InitialFetch> + </tran1:DeliveryAttributes> + <tran1:Originators> + <tran1:Author> + <tran1:Identifier category="category" type="type"/> + </tran1:Author> + <tran1:Sender> + <tran1:Identifier category="category" type="type"/> + </tran1:Sender> + </tran1:Originators> + <tran1:Destinations> + <tran1:Reader> + <tran1:Identifier category="category" type="type"/> + </tran1:Reader> + </tran1:Destinations> + <tran1:MsgIdentification> + <add:MessageID>urn:de:xta:messageid:xta-tester:0149cd17-a905-4b4b-83c6-10b5ca04a96b</add:MessageID> + </tran1:MsgIdentification> + <tran1:Qualifier> + <tran1:Service>urn:service</tran1:Service> + <tran1:BusinessScenario> + <tran1:Defined> + <name>test</name> + </tran1:Defined> + </tran1:BusinessScenario> + <tran1:MessageType> + <name>mytype</name> + </tran1:MessageType> + </tran1:Qualifier> + <tran1:MsgSize>10</tran1:MsgSize> + </tran1:MessageMetaData> + </tran:MsgStatusList> + </soapenv:Body> +</soapenv:Envelope> \ No newline at end of file diff --git a/xta-adapter/doc/example-response-getmessages-no-messages-available.xml b/xta-adapter/doc/example-response-getmessages-no-messages-available.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f56105d0dc5bf57ffccff6b47c85e7088891741 --- /dev/null +++ b/xta-adapter/doc/example-response-getmessages-no-messages-available.xml @@ -0,0 +1,11 @@ +<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> + <s:Header> + <a:Action s:mustUnderstand="1">http://www.osci.eu/ws/2008/05/transport/urn/messageTypes/MsgBoxStatusListRequest</a:Action> + <h:MsgBoxResponse MsgBoxRequestID="1" xmlns:h="http://www.osci.eu/ws/2008/05/transport" xmlns="http://www.osci.eu/ws/2008/05/transport" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <NoMessageAvailable reason="Keine Nachrichten gefunden."/> + </h:MsgBoxResponse> + </s:Header> + <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <MsgStatusList xmlns="http://www.osci.eu/ws/2008/05/transport"/> + </s:Body> +</s:Envelope> \ No newline at end of file diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponse.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..aead2074638fccd8336b8c52c9e98fda734fc5f3 --- /dev/null +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponse.java @@ -0,0 +1,19 @@ +package de.ozgcloud.eingang.xta; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import eu.osci.ws._2014._10.transport.MessageMetaData; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@AllArgsConstructor +@Getter +@Builder +class MsgStatusListTypeAndHeaderResponse { + private String msgBoxRequestID; + private boolean noMessageAvailable; + private BigInteger messageItemsPending; + private Stream<MessageMetaData> messages; +} \ No newline at end of file diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java index 6208c760c8e7567575c912d0810b8f9a6303b9f6..f2e05fc7684fe33d1db3dd42ae46f1f044f23ef8 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java @@ -1,15 +1,10 @@ package de.ozgcloud.eingang.xta; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.util.Objects; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import de.ozgcloud.eingang.common.errorhandling.TechnicalException; -import de.ozgcloud.eingang.common.formdata.DeleteOnCloseInputStream; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormHeader; import de.ozgcloud.eingang.common.formdata.IncomingFile; @@ -44,7 +39,6 @@ interface XtaMessageMapper { return IncomingFile.builder() .name(messageFile.name()) .contentType("application/zip") -// .contentStream(openFile(messageFile.file())) .file(messageFile.file()) .size(messageFile.file().length()) .build(); @@ -52,14 +46,6 @@ interface XtaMessageMapper { return null; } - default InputStream openFile(File file) { - try { - return new DeleteOnCloseInputStream(file); - } catch (IOException e) { - throw new TechnicalException("Error opening xta message file."); - } - } - default String fromId(XtaMessageId id) { return id.toString(); } diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java index 71c7db468e50ae50af7d0746595f06ff17206a88..f81184fc20eb49e375f9d24dd9f5ce68021644c6 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java @@ -1,8 +1,16 @@ package de.ozgcloud.eingang.xta; +import java.math.BigInteger; +import java.util.Optional; +import java.util.stream.Stream; + +import jakarta.xml.bind.JAXBElement; + import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.Named; +import eu.osci.ws._2008._05.transport.MsgStatusListType; import eu.osci.ws._2014._10.transport.MessageMetaData; @Mapper @@ -17,4 +25,21 @@ interface XtaMessageMetaDataMapper { default XtaMessageId fromString(String id) { return XtaMessageId.from(id); } + + @Mapping(target = "moreMessagesAvailable", source = ".", qualifiedByName = "moreMessagesAvailable") + XtaMessageMetaDatasAndHeader msgStatusListFromSoap(MsgStatusListTypeAndHeaderResponse statusList); + + @Named("moreMessagesAvailable") + default boolean moreMessagesAvailable(MsgStatusListTypeAndHeaderResponse statusList) { + if (statusList.isNoMessageAvailable()) { + return false; + } + return Optional.ofNullable(statusList.getMessageItemsPending()) + .filter(messagesPending -> !BigInteger.ZERO.equals(messagesPending)) + .isPresent(); + } + + default Stream<XtaMessageMetaData> map(JAXBElement<MsgStatusListType> msgStatusListResponse) { + return msgStatusListResponse.getValue().getMessageMetaData().stream().map(this::fromSoap); + } } diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java new file mode 100644 index 0000000000000000000000000000000000000000..ff04d5df1c24571a7e8e5d4c0f704089536dbe98 --- /dev/null +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeader.java @@ -0,0 +1,15 @@ +package de.ozgcloud.eingang.xta; + +import java.util.stream.Stream; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +class XtaMessageMetaDatasAndHeader { + + private String msgBoxRequestID; + private boolean moreMessagesAvailable; + private Stream<XtaMessageMetaData> messages; +} diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..b12ce91b9ca05f1db26f5ab8b3f8f85fd982ab28 --- /dev/null +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIterator.java @@ -0,0 +1,65 @@ +/* + * 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/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java index 2bfb3d539be7f626ed56f4507e389596ef225bcf..5da39aab1d30059a0e4577686a7427bc860f6278 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java @@ -6,9 +6,11 @@ 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 org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -16,10 +18,17 @@ 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; @@ -28,10 +37,13 @@ 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 jakarta.validation.Valid; import jakarta.xml.bind.JAXBElement; import lombok.NonNull; @@ -62,16 +74,81 @@ class XtaRemoteService { @Qualifier("xoevTransportMarshaller") private Jaxb2Marshaller xoevMarshaller; - public Stream<XtaMessageMetaData> getMessagesMetadata() { - return getStatusList().getMessageMetaData().stream().map(mapper::fromSoap); + public XtaMessageMetaDatasAndHeader getMessagesMetadata() { + return mapper.msgStatusListFromSoap(getStatusList()); } - @SuppressWarnings("unchecked") - MsgStatusListType getStatusList() { - var callback = new ActionCallback(properties.getActions().getStatusList(), new Addressing10(), getTargetUri()); + 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 ((JAXBElement<MsgStatusListType>) template.marshalSendAndReceive(buildListRequest(), callback)).getValue(); + 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() { @@ -82,16 +159,27 @@ class XtaRemoteService { 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( - XtaRemoteServiceConfiguration.URI_TEMPLATE.formatted(properties.getServer().getProtocol(), - properties.getServer().getName())); + 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) { return XtaMessage.builder() .metaData(null) diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java index d823bc31854f7f7946590c3ab8299686d752539e..0c497d51f85560d84085d663c2bc32aaf46a408e 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRunner.java @@ -29,7 +29,7 @@ class XtaRunner implements ApplicationListener<ContextRefreshedEvent> { void runGetXtaMessages() { try { - service.getMessagesAsFormData().forEach(this::processAndAcknowledge); + service.getMessages().forEach(this::processAndAcknowledge); } catch (RuntimeException e) { LOG.error("Error fetch XTA Message List.", e); } diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java index d19edb54f5074385d8b0b7cd811ff04dcfc6ae48..0fe6d495bf3382335bbb41a8fc186feeb30ba300 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java @@ -1,6 +1,8 @@ package de.ozgcloud.eingang.xta; +import java.util.Spliterators; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -21,17 +23,18 @@ class XtaService { @Autowired private XtaMessageMapper mapper; - public Stream<FormData> getMessagesAsFormData() { - return getMessagesMetaData().map(this::getFormData); + public Stream<FormData> getMessages() { + return createXtaMessageStream().filter(this::filterByMessageType).map(this::getFormData); } - public Stream<XtaMessageMetaData> getMessagesMetaData() { - return remoteService.getMessagesMetadata().filter(this::filterByMessageType); + Stream<XtaMessageMetaData> createXtaMessageStream() { + var iterator = new XtaMessageMetadataRemoteIterator(remoteService); + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); } // filter criteria for dFoerdermittelantrag // https://jira.mgm-tp.com/jira/browse/OZG-3659 - private boolean filterByMessageType(XtaMessageMetaData metaData) { + boolean filterByMessageType(XtaMessageMetaData metaData) { if (StringUtils.equals(metaData.getMessageType(), DFOERDERMITTELANTRAG_MESSAGE_TYPE)) { return true; } diff --git a/xta-adapter/src/main/resources/XTA.wsdl b/xta-adapter/src/main/resources/XTA.wsdl index 30b538eb9383b128630db8874a5cd565ed52c1d8..d7ca5a364f4864a44ea0c2c5cbff4a76ae63a042 100644 --- a/xta-adapter/src/main/resources/XTA.wsdl +++ b/xta-adapter/src/main/resources/XTA.wsdl @@ -119,6 +119,9 @@ <message name="FetchListResponse"> <part name="FetchResponse" element="osci:MsgStatusList"/> </message> + <message name="GetNextRequest"> + <part name="FetchRequest" element="osci:MsgBoxGetNextListRequest"/> + </message> <!--Nachrichten - SOAP-Exceptions--> <message name="PermissionDeniedException"> <part name="permissionDeniedException" element="xta:PermissionDeniedException"/> diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponseTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponseTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..955fab809aa6298bfc494cae57dfc57b2937d249 --- /dev/null +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/MsgStatusListTypeAndHeaderResponseTestFactory.java @@ -0,0 +1,20 @@ +package de.ozgcloud.eingang.xta; + +import java.util.stream.Stream; + +import eu.osci.ws._2014._10.transport.MessageMetaData; + +class MsgStatusListTypeAndHeaderResponseTestFactory { + + public static final MessageMetaData MESSAGE1 = MessageMetaDataTestFactory.create(); + + public static MsgStatusListTypeAndHeaderResponse create() { + return createBuilder().build(); + } + + public static MsgStatusListTypeAndHeaderResponse.MsgStatusListTypeAndHeaderResponseBuilder createBuilder() { + return MsgStatusListTypeAndHeaderResponse.builder() + .msgBoxRequestID(null) + .messages(Stream.of(MESSAGE1)); + } +} diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java index 60f55923518b5e9622bd99219dc1b54dd807b098..3f6525b5134515108a8b290cdd8f8ae03ba37f9e 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java @@ -5,8 +5,6 @@ import static org.assertj.core.api.InstanceOfAssertFactories.*; 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.Test; import org.mockito.ArgumentCaptor; @@ -41,8 +39,8 @@ class XtaITCase { @BeforeEach void prepareXtaRemoteService() { - when(remoteService.getMessagesMetadata()).thenReturn(Stream.of(XtaMessageMetaDataTestFactory.create())); - + when(remoteService.getMessagesMetadata()).thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()); + when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn( XtaMessageTestFactory.createBuilder() .clearMessageFiles().messageFile(XtaFileTestFactory.withFileContent(TestUtils.loadFile("test_content.zip"), "test_content.zip")) diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0b26412b73ffb000e3214c0e73fcddce166f6372 --- /dev/null +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java @@ -0,0 +1,68 @@ +package de.ozgcloud.eingang.xta; + +import static org.assertj.core.api.Assertions.*; + +import java.math.BigInteger; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.Spy; + +class XtaMessageMetaDataMapperTest { + + @Spy + private final XtaMessageMetaDataMapper mapper = Mappers.getMapper(XtaMessageMetaDataMapper.class); + + @Nested + class TestMoreMessagesAvailable { + + @Test + void shouldReturnFalseOnNoMessagesAvailable() { + + var response = mapper.moreMessagesAvailable(buildWithNoMessageAvailable()); + + assertThat(response).isFalse(); + } + + private MsgStatusListTypeAndHeaderResponse buildWithNoMessageAvailable() { + return MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().noMessageAvailable(true).build(); + } + + @Test + void shouldReturnFalseOnPendingMessagesNull() { + + var response = mapper.moreMessagesAvailable(buildPendingMessagesNull()); + + assertThat(response).isFalse(); + } + + private MsgStatusListTypeAndHeaderResponse buildPendingMessagesNull() { + return MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().messageItemsPending(null).build(); + } + + @Test + void shouldReturnFalseOnNoMessagesPending() { + + var response = mapper.moreMessagesAvailable(buildWithoutPendingMessages()); + + assertThat(response).isFalse(); + } + + private MsgStatusListTypeAndHeaderResponse buildWithoutPendingMessages() { + return MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().messageItemsPending(null).build(); + } + + @Test + void shouldReturnTrueOnMessagesPending() { + + var response = mapper.moreMessagesAvailable(buildWithPendingMessages()); + + assertThat(response).isTrue(); + } + + private MsgStatusListTypeAndHeaderResponse buildWithPendingMessages() { + return MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().messageItemsPending(BigInteger.ONE).build(); + } + } +} diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..df3f26ef4d12eadfd7902ab56d88301a2f7e2f4a --- /dev/null +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDatasAndHeaderTestFactory.java @@ -0,0 +1,21 @@ +package de.ozgcloud.eingang.xta; + +import java.util.UUID; +import java.util.stream.Stream; + +class XtaMessageMetaDatasAndHeaderTestFactory { + + public static final String MSG_BOX_REQUEST_ID = UUID.randomUUID().toString(); + + public static final XtaMessageMetaData MESSAGE1 = XtaMessageMetaDataTestFactory.create(); + + public static XtaMessageMetaDatasAndHeader create() { + return createBuilder().build(); + } + + public static XtaMessageMetaDatasAndHeader.XtaMessageMetaDatasAndHeaderBuilder createBuilder() { + return XtaMessageMetaDatasAndHeader.builder() + .msgBoxRequestID(MSG_BOX_REQUEST_ID) + .messages(Stream.of(MESSAGE1)); + } +} diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3afc5fb59dca7c2b626cefe83bfaed5726b81643 --- /dev/null +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetadataRemoteIteratorTest.java @@ -0,0 +1,120 @@ +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/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java index f6579fd837658c475b4081955a3fcedcc84c1db5..dd6b6d41529a9446a78b76bdf8ccd2bf404a3cb0 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceTest.java @@ -30,27 +30,60 @@ class XtaRemoteServiceTest { @BeforeEach void init() { - doReturn(MsgStatusListTypeTestFactory.create()).when(service).getStatusList(); - when(mapper.fromSoap(any())).thenReturn(XtaMessageMetaDataTestFactory.create()); + doReturn(MsgStatusListTypeAndHeaderResponseTestFactory.create()).when(service).getStatusList(); + when(mapper.msgStatusListFromSoap(any(MsgStatusListTypeAndHeaderResponse.class))) + .thenReturn(XtaMessageMetaDatasAndHeaderTestFactory.create()); } @Test void shouldCallGetStatusList() { - service.getMessagesMetadata().toList(); + service.getMessagesMetadata().getMessages().toList(); verify(service).getStatusList(); } @Test void shouldCallMapper() { - service.getMessagesMetadata().toList(); + service.getMessagesMetadata(); - verify(mapper).fromSoap(notNull()); + verify(mapper).msgStatusListFromSoap(notNull()); } @Test void shouldReturnMessageId() { - var metaData = service.getMessagesMetadata(); + 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()); } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java index 7ae08fc8eabf0012c13c6d87d8a5fe95616d6557..08ab8ed4b2e078005773560f1a71156878bb89a3 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRunnerTest.java @@ -26,25 +26,25 @@ class XtaRunnerTest { @Nested class TestRunGetXtaMessages { - private FormData formData = FormDataTestFactory.create(); + public static final FormData MESSAGE = FormDataTestFactory.create(); @BeforeEach void init() { - when(service.getMessagesAsFormData()).thenReturn(Stream.of(formData)); + when(service.getMessages()).thenReturn(Stream.of(MESSAGE)); } @Test - void shouldCallXtaService() { + void shouldCallXtaServiceGetNextMessages() { scheduler.runGetXtaMessages(); - verify(service).getMessagesAsFormData(); + verify(service).getMessages(); } @Test void shouldHandOverFormDataToSemantikAdapter() { scheduler.runGetXtaMessages(); - verify(semantikAdapter).processFormData(formData); + verify(semantikAdapter).processFormData(MESSAGE); } @Test @@ -54,5 +54,4 @@ class XtaRunnerTest { verify(service).acknowledgeReceive(XtaMessageTestFactory.MESSAGE_ID); } } - } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java index 18d24bff8acc8fe3501cbd8a6bdc7b039b16e1f5..643602f8918e4082a2c71cc0cf6223a79945a596 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java @@ -1,6 +1,5 @@ package de.ozgcloud.eingang.xta; -import static de.ozgcloud.eingang.xta.XtaService.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -18,6 +17,8 @@ import org.mockito.Spy; class XtaServiceTest { + private static final String MESSAGE_TYPE_OTHER = "MESSAGE_TYPE_OTHER"; + @Spy @InjectMocks private XtaService service; @@ -30,69 +31,71 @@ class XtaServiceTest { @Nested class TestGetMessagesAsFormData { - private XtaMessageMetaData metaData = XtaMessageMetaDataTestFactory.create(); + private XtaMessageMetaDatasAndHeader metaData = XtaMessageMetaDatasAndHeaderTestFactory.create(); + private XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create(); + private XtaMessage message = XtaMessageTestFactory.create(); @BeforeEach - void init() { - when(service.getMessagesMetaData()).thenReturn(Stream.of(metaData)); + void setup() { + doReturn(Stream.of(messageMetaData)).when(service).createXtaMessageStream(); } @Test - void shouldCallGetFormData() { - doReturn(FormDataTestFactory.create()).when(service).getFormData(any()); - - service.getMessagesAsFormData().toList(); + void shouldCallCreateStream() { + service.getMessages(); - verify(service).getFormData(metaData); + verify(service).createXtaMessageStream(); } @Test - void shouldReturnFormData() { - var formData = FormDataTestFactory.create(); - doReturn(formData).when(service).getFormData(any()); + void shouldCallFilterByMessageType() { + when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn(message); - var result = service.getMessagesAsFormData(); + service.getMessages().toList(); - assertThat(result).hasSize(1).contains(formData); + verify(service).filterByMessageType(messageMetaData); } - } - @Nested - class TestGetMessages { + @Test + void shouldCallGetFormData() { + when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn(message); + doReturn(true).when(service).filterByMessageType(messageMetaData); - private XtaMessageMetaData metaData = XtaMessageMetaDataTestFactory.createBuilder().messageType(DFOERDERMITTELANTRAG_MESSAGE_TYPE).build(); + service.getMessages().toList(); - @BeforeEach - void init() { - when(remoteService.getMessagesMetadata()).thenReturn(Stream.of(metaData)); + verify(service).getFormData(messageMetaData); } @Test - void shouldCallRemoteService() { - service.getMessagesMetaData(); + void shouldNotCallGetFormData() { + doReturn(false).when(service).filterByMessageType(messageMetaData); - verify(remoteService).getMessagesMetadata(); + service.getMessages().toList(); + + verify(service, never()).getFormData(any()); } + } + + @Nested + class TestFilterByMessageType { @Test - void shouldReturnMetaData() { - var result = service.getMessagesMetaData(); + void shouldAcceptDFoerdermittel() { + var metaDataDFoerder = XtaMessageMetaDataTestFactory.create(); - assertThat(result).hasSize(1).contains(metaData); + assertThat(service.filterByMessageType(metaDataDFoerder)).isTrue(); } @Test - void shouldOnlyReturnMatchingMessageCode() { - when(remoteService.getMessagesMetadata()).thenReturn(Stream.of(XtaMessageMetaDataTestFactory.createBuilder().messageType("other").build())); - - var result = service.getMessagesMetaData(); + void shouldNotAcceptOtherMessageType() { + var metaDataDFoerder = XtaMessageMetaDataTestFactory.createBuilder().messageType(MESSAGE_TYPE_OTHER).build(); - assertThat(result).isEmpty(); + assertThat(service.filterByMessageType(metaDataDFoerder)).isFalse(); } } @Nested - class TestFetFormData { + class TestGetFormData { private XtaMessage message = XtaMessageTestFactory.create();