aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java13
-rw-r--r--src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java2
-rw-r--r--src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java8
-rw-r--r--src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java7
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java8
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java9
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java70
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java160
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java15
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/Marshaller.java4
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java5
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java64
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java8
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java20
-rw-r--r--src/main/resources/application.yaml8
-rw-r--r--src/main/resources/mzs/app2mzs.wsdl2
-rw-r--r--src/main/resources/mzs/app2mzs.xsd14
-rw-r--r--src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java7
-rw-r--r--src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java9
-rw-r--r--src/test/java/at/gv/egiz/moazs/ITEndToEndTest.java259
-rw-r--r--src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java46
-rw-r--r--src/test/java/at/gv/egiz/moazs/SOAPUtilsTest.java143
-rw-r--r--src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java16
-rw-r--r--src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-notification.xml100
-rw-r--r--src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-request-status.xml71
-rw-r--r--src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/mzs-delivery-request.xml80
26 files changed, 961 insertions, 187 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java b/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java
index 6a1e0fd..72f8ba0 100644
--- a/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java
+++ b/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java
@@ -18,10 +18,10 @@ import org.springframework.stereotype.Component;
import java.util.function.Consumer;
-import static at.gv.egiz.moazs.scheme.RequestStatusResponse.*;
+import static at.gv.egiz.moazs.MoaZSException.moaZSException;
import static at.gv.egiz.moazs.scheme.RequestStatusResponse.generateError;
+import static at.gv.egiz.moazs.scheme.RequestStatusResponse.getAnswer;
import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Error.errorBuilder;
-import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
import static java.lang.String.format;
@Component
@@ -72,7 +72,7 @@ public class DeliveryRequestBackend implements Consumer<String> {
try {
var mzsRequest = repository.retrieveDeliveryRequest(appDeliveryID).orElseThrow(
- () -> MoaZSException.moaZSException(format(DELIVERY_REQUEST_MISSING_ERROR_MSG, appDeliveryID)));
+ () -> moaZSException(format(DELIVERY_REQUEST_MISSING_ERROR_MSG, appDeliveryID)));
fallbackAnswerBuilder.withDeliverySystem(mzsRequest.getConfig().getMSGClient().getURL());
var msgRequest = buildMsgRequest(mzsRequest);
@@ -98,14 +98,15 @@ public class DeliveryRequestBackend implements Consumer<String> {
}
private void verifySignedStatus(String responseID, String appDeliveryID) throws MoaZSException {
+ var signedStatus = repository.retrieveBinaryResponse(responseID).orElseThrow(() -> moaZSException(
+ format(BINARY_RESPONSE_MISSING_ERROR_MSG, responseID),
+ MoaZSException.ERROR_MZS_BINARY_RESPONSE_MISSING));
try {
- var signedStatus = repository.retrieveBinaryResponse(responseID).orElseThrow(
- () -> MoaZSException.moaZSException(format(BINARY_RESPONSE_MISSING_ERROR_MSG, responseID)));
signatureVerifier.accept(signedStatus);
} catch (MoaZSException ex) {
var message = format(MsgResponseBackend.MOASP_SIGNATURE_INVALID_ERROR_MSG, appDeliveryID);
var code = MoaZSException.ERROR_MOASP_SIGNATURE_INVALID;
- throw MoaZSException.moaZSException(message, code, ex);
+ throw moaZSException(message, code, ex);
}
}
diff --git a/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java b/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java
index 2468ca9..c58e1a5 100644
--- a/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java
+++ b/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java
@@ -50,7 +50,7 @@ public class SaveResponseToFileSink {
var responseID = response.getResponseID();
var responsePath = generatePath(rootPath, responseID, "xml");
- var storeResponseToFileSystemFuture = supplyAsync(() -> msgMarshaller.marshallXml(response.getResponse()))
+ var storeResponseToFileSystemFuture = supplyAsync(() -> msgMarshaller.marshallXml(response.getResponseAsJAXBElement()))
.thenApply(responseString -> responseString.getBytes(StandardCharsets.UTF_8))
.thenAccept(responseByteArray -> storeToFile(responsePath, responseByteArray))
.exceptionally(ex -> logException(ex, responseID));
diff --git a/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java
index de22805..a304bdf 100644
--- a/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java
+++ b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java
@@ -96,18 +96,16 @@ public class TnvzHelper {
var builder = metaDataBuilder();
- var meta = request.getTnvzMetaData();
-
+ var meta = request.getMetaData();
if (meta.getDeliveryQuality() != null) {
builder.withDeliveryQuality(meta.getDeliveryQuality());
} else {
builder.withPrivateMessageQuality(meta.getPrivateMessageQuality());
}
- return builder
- .withOrigin(meta.getOrigin())
- .withPreAdviceNote(request.getReceiver().getPreAdviceNote())
+ return builder.withOrigin(meta.getOrigin())
.withIgnorePostRedirectionOrder(meta.getIgnorePostRedirectionOrder())
+ .withPreAdviceNote(request.getReceiver().getPreAdviceNote())
.build();
}
diff --git a/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java b/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java
index c16dfd2..6f71e50 100644
--- a/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java
+++ b/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java
@@ -23,14 +23,15 @@ public class ServicesConfig {
@Autowired
public Endpoint msgEndpoint(MsgService msgService,
Zuse2AppPortService zuse2app,
- Interceptor<Message> msgInterceptor) {
- return endpointFactory.create(msgService, zuse2app, msgInterceptor);
+ Interceptor<Message> msgInterceptor
+ ) {
+ return endpointFactory.create(msgService, zuse2app, "/msg", msgInterceptor);
}
@Bean
@Autowired
public Endpoint mzsEndpoint(MzsService mzsService, App2Mzs app2mzs) {
- return endpointFactory.create(mzsService, app2mzs);
+ return endpointFactory.create(mzsService, app2mzs, "/mzs");
}
@Bean
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
index 5e81f0d..0637f98 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
@@ -11,6 +11,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import static at.gv.egiz.moazs.MoaZSException.moaZSException;
+import static java.lang.String.format;
import static java.util.stream.Collectors.*;
public class ConfigProfileGenerator {
@@ -70,9 +72,11 @@ public class ConfigProfileGenerator {
var defaultProfile = profiles.get(defaultConfigKey);
- if (!validator.isConfigProfileComplete(defaultProfile)) {
+ try {
+ validator.isConfigProfileComplete(defaultProfile);
+ } catch (MoaZSException ex) {
if (verifyCompletenessOfDefaultConfiguration)
- throw MoaZSException.moaZSException(PROFILE_NOT_COMPLETE_ERROR_MESSAGE);
+ throw moaZSException(format("%s Reason: %s", PROFILE_NOT_COMPLETE_ERROR_MESSAGE, ex.getMessage()));
else {
LOGGER.warn(PROFILE_NOT_COMPLETE_WARNING_MESSAGE);
}
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
index 056f6dc..f49132f 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
@@ -205,7 +205,7 @@ public class ConfigUtil {
}
if (primary.getTNVZClient() != null) {
- builder.withMSGClient(merge(primary.getTNVZClient(), fallback.getTNVZClient()));
+ builder.withTNVZClient(merge(primary.getTNVZClient(), fallback.getTNVZClient()));
}
if (primary.getMsgResponseSinks() != null) {
@@ -240,7 +240,7 @@ public class ConfigUtil {
}
if (primary.getReceiveTimeout() != null) {
- builder.withConnectionTimeout(primary.getReceiveTimeout());
+ builder.withReceiveTimeout(primary.getReceiveTimeout());
}
return builder.build();
@@ -259,7 +259,7 @@ public class ConfigUtil {
}
if (primary.getTrustStore() != null) {
- builder.withKeyStore(merge(primary.getTrustStore(), fallback.getTrustStore()));
+ builder.withTrustStore(merge(primary.getTrustStore(), fallback.getTrustStore()));
}
if (primary.isLaxHostNameVerification() != null) {
@@ -267,8 +267,9 @@ public class ConfigUtil {
}
if (primary.isTrustAll() != null) {
- builder.withLaxHostNameVerification(primary.isTrustAll());
+ builder.withTrustAll(primary.isTrustAll());
}
+
return builder.build();
}
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java b/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java
index e7ee357..240a677 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java
@@ -1,36 +1,41 @@
package at.gv.egiz.moazs.preprocess;
+import at.gv.egiz.moazs.scheme.Marshaller;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
+import at.gv.zustellung.app2mzs.xsd.ObjectFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.util.Map;
import static at.gv.egiz.moazs.MoaZSException.moaZSException;
+import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder;
-import static java.lang.String.format;
@Component
public class DeliveryRequestAugmenter {
+ private static final Logger log = LoggerFactory.getLogger(DeliveryRequestAugmenter.class);
+ private static final ObjectFactory FACTORY = new ObjectFactory();
+
private final ConfigUtil util;
private final Map<String, ConfigType> configs;
private final MzsDeliveryRequestValidator validator;
+ private final Marshaller mzsMarshaller;
- private static final String INCOMPLETE_TNVZ_ERROR_MESSAGE = "mzs:DeliveryRequest is incomplete because mandatory " +
- "fields for sending a tnvz:QueryPersonRequest are missing.";
- private static final String INCOMPLETE_CONFIG_ERROR_MESSAGE = "Could not find a profile for " +
- "the delivery request configuration, and the configuration attached to mzs:DeliveryRequest is incomplete.";
- private static final String INCOMPLETE_MERGED_CONFIG_ERROR_MESSAGE = "I merged parameters from " +
- "mzs:DeliveryRequest/Config with parameters from config profile with ProfileId='%s', but the " +
- "configuration is incomplete.";
+ private static final String CONFIG_MISSING_ERROR_MSG = "Delivery request configuration is missing.";
@Autowired
- public DeliveryRequestAugmenter(Map<String, ConfigType> deliveryRequestConfigs, ConfigUtil util, MzsDeliveryRequestValidator validator) {
+ public DeliveryRequestAugmenter(Map<String, ConfigType> deliveryRequestConfigs, ConfigUtil util,
+ MzsDeliveryRequestValidator validator, Marshaller mzsMarshaller) {
this.configs = deliveryRequestConfigs;
this.util = util;
this.validator = validator;
+ this.mzsMarshaller = mzsMarshaller;
}
/**
@@ -46,41 +51,29 @@ public class DeliveryRequestAugmenter {
var fallbackProfileId = determineProfileIdFrom(requestConfig);
var fallbackConfig = configs.get(fallbackProfileId);
- if (fallbackConfig == null) {
-
- if (!validator.isConfigProfileComplete(request.getConfig())) {
- throw moaZSException(INCOMPLETE_CONFIG_ERROR_MESSAGE);
- } else if (!validator.isTnvzComplete(request)) {
- throw moaZSException(INCOMPLETE_TNVZ_ERROR_MESSAGE);
- } else {
- return request;
- }
+ trace("request config", requestConfig);
+ trace("fallback config", fallbackConfig);
- } else {
+ var augmentedConfig = (requestConfig != null && fallbackConfig != null)
+ ? util.merge(requestConfig, fallbackConfig)
+ : coalesce(requestConfig, fallbackConfig)
+ .orElseThrow(()-> moaZSException(CONFIG_MISSING_ERROR_MSG));
- var mergedConfig = (requestConfig == null)
- ? fallbackConfig
- : util.merge(requestConfig, fallbackConfig);
+ trace("augmented config", augmentedConfig);
- if (!validator.isConfigProfileComplete(mergedConfig)) {
- var message = format(INCOMPLETE_MERGED_CONFIG_ERROR_MESSAGE, fallbackProfileId);
- throw moaZSException(message);
- }
+ validator.isConfigProfileComplete(augmentedConfig);
- var mergedRequest = deliveryRequestTypeBuilder(request)
- .withConfig(mergedConfig)
- .build();
+ var augmentedRequest = deliveryRequestTypeBuilder(request)
+ .withConfig(augmentedConfig)
+ .build();
- if (!validator.isTnvzComplete(mergedRequest)) {
- throw moaZSException(INCOMPLETE_TNVZ_ERROR_MESSAGE);
- }
+ validator.isTnvzComplete(augmentedRequest);
- return mergedRequest;
+ return augmentedRequest;
- }
}
- private String determineProfileIdFrom(ConfigType requestConfig) {
+ private String determineProfileIdFrom(@Nullable ConfigType requestConfig) {
return (requestConfig == null
|| requestConfig.getProfileID() == null
|| isProfileMissing(requestConfig.getProfileID()))
@@ -92,4 +85,11 @@ public class DeliveryRequestAugmenter {
return !configs.containsKey(id);
}
+ private void trace(String description, ConfigType config) {
+ if (log.isTraceEnabled()) {
+ log.trace("{} : {}", description, mzsMarshaller.marshallXml(FACTORY.createConfig(config)));
+ }
+ }
+
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
index 2c2fc36..67086a2 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
@@ -1,90 +1,168 @@
package at.gv.egiz.moazs.preprocess;
+import at.gv.egiz.moazs.MoaZSException;
import at.gv.zustellung.app2mzs.xsd.*;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
+import static at.gv.egiz.moazs.MoaZSException.moaZSException;
+import static at.gv.egiz.moazs.scheme.NameSpace.*;
+import static java.lang.String.format;
+
@Component
public class MzsDeliveryRequestValidator {
/**
* Checks if the mandatory fields that are needed to send a tnvz:QueryPersonRequest are present.
* @param request
- * @return true if mandatory fields are present.
+ * @throws MoaZSException if a field is missing.
*/
- public boolean isTnvzComplete(DeliveryRequestType request) {
- return !request.getConfig().isPerformQueryPersonRequest() ||
- (request.getTnvzMetaData() != null
- && request.getSender().getCorporateBody() != null);
+ public void isTnvzComplete(DeliveryRequestType request) {
+ if (request.getConfig().isPerformQueryPersonRequest()) {
+
+ if (request.getMetaData().getOrigin() == null)
+ throw mzse(MZS_DELIVERY_REQUEST, MZS_DELIVERY_REQUEST + "/MetaData/Origin is missing.");
+
+ if (request.getMetaData().getDeliveryQuality() == null)
+ throw mzse(MZS_DELIVERY_REQUEST, MZS_DELIVERY_REQUEST + "/MetaData/DeliveryQuality missing.");
+
+ if (request.getSender().getCorporateBody() == null)
+ throw mzse(MZS_DELIVERY_REQUEST, MZS_DELIVERY_REQUEST + "/Sender/CorporateBody is missing.");
+ }
}
/**
* Check if all mandatory fields of configuration are present.
*
* @param profile
- * @return true if all mandatory fields are present.
+ * @throws MoaZSException if a field is missing.
*/
- public boolean isConfigProfileComplete(@Nullable ConfigType profile) {
- return profile != null
- && profile.isPerformQueryPersonRequest() != null
- && isTVNZClientConfigured(profile.getTNVZClient(), profile.isPerformQueryPersonRequest())
- && isClientConfigured(profile.getMSGClient())
- && areSinksConfigured(profile.getMsgResponseSinks());
+ public void isConfigProfileComplete(@Nullable ConfigType profile) {
+
+ if (profile == null)
+ throw mzse(MZS_DELIVERY_REQUEST + "/Config");
+
+ if (profile.isPerformQueryPersonRequest() == null)
+ throw mzse(MZS_DELIVERY_REQUEST + "/Config", "PerformQueryPersonRequest is missing.");
+
+ isTNVZClientConfigured(profile.getTNVZClient(), profile.isPerformQueryPersonRequest());
+ areSinksConfigured(profile.getMsgResponseSinks());
+
+ try {
+ isClientConfigured(profile.getMSGClient());
+ } catch (MoaZSException ex) {
+ throw mzse(MZS_MSGCLIENT, ex.getMessage());
+ }
+
}
- private boolean isTVNZClientConfigured(ClientType tnvzClient, Boolean isPerformQueryPersonRequest) {
- return !isPerformQueryPersonRequest || (tnvzClient != null
+ private void isTNVZClientConfigured(@Nullable ClientType tnvzClient, Boolean isPerformQueryPersonRequest) {
+ if (!isPerformQueryPersonRequest) return;
+
+ var isConfigured = tnvzClient != null
&& tnvzClient.getURL() != null
&& tnvzClient.getReceiveTimeout() != null
- && tnvzClient.getConnectionTimeout() != null
- && isSSLConfigured(tnvzClient));
+ && tnvzClient.getConnectionTimeout() != null;
+
+ if (!isConfigured) {
+ if(tnvzClient == null) throw mzse(MZS_TNVZCLIENT);
+
+ var reasons = new StringBuilder("The following elements in " + MZS_TNVZCLIENT + " are missing: ");
+ if(tnvzClient.getURL() == null) reasons.append("URL;");
+ if(tnvzClient.getReceiveTimeout() == null) reasons.append("ReceiveTimeout;");
+ if(tnvzClient.getConnectionTimeout() == null) reasons.append("ConnectionTimeout;");
+ throw mzse(MZS_TNVZCLIENT, reasons.toString());
+ }
+
+ try {
+ isSSLConfigured(tnvzClient);
+ } catch (MoaZSException ex) {
+ throw mzse(MZS_TNVZCLIENT, ex.getMessage());
+ }
}
- private boolean isClientConfigured(ClientType clientParams) {
- return clientParams != null
+ private void isClientConfigured(@Nullable ClientType clientParams) {
+ var isConfigured = clientParams != null
&& clientParams.getURL() != null
- && isSSLConfigured(clientParams)
&& clientParams.getReceiveTimeout() != null
&& clientParams.getConnectionTimeout() != null;
+
+ if (!isConfigured) throw mzse("Client");
+
+ isSSLConfigured(clientParams);
+
}
- private boolean isSSLConfigured(ClientType clientParams) {
- return !clientParams.getURL().startsWith("https") || (clientParams.getSSL() != null
- && clientParams.getSSL().isTrustAll() != null
- && clientParams.getSSL().isLaxHostNameVerification() != null
- && isKeyStoreConfigured(clientParams.getSSL().getKeyStore())
- && isTrustStoreConfigured(clientParams.getSSL().getTrustStore()));
+ private void isSSLConfigured(ClientType clientParams) {
+ if (!clientParams.getURL().startsWith("https")) return;
+
+ var isConfigured = (clientParams.getSSL() != null
+ && clientParams.getSSL().isTrustAll() != null
+ && clientParams.getSSL().isLaxHostNameVerification() != null);
+ if (!isConfigured) throw mzse("SSL");
+
+ try {
+ isKeyStoreConfigured(clientParams.getSSL().getKeyStore());
+ isTrustStoreConfigured(clientParams.getSSL().getTrustStore());
+ } catch (MoaZSException ex) {
+ throw mzse("SSL", ex.getMessage());
+ }
}
- private boolean isKeyStoreConfigured(KeyStoreType keyStore) {
- return keyStore == null || (keyStore.getPassword() != null
+ private void isKeyStoreConfigured(@Nullable KeyStoreType keyStore) {
+ if (keyStore == null) return;
+
+ var isConfigured = keyStore.getPassword() != null
&& keyStore.getFileType() != null
- && keyStore.getFileName() != null);
+ && keyStore.getFileName() != null;
+ if (!isConfigured) throw mzse("KeyStore");
}
- private boolean isTrustStoreConfigured(KeyStoreType trustStore) {
- return trustStore == null || (trustStore.getPassword() != null
+ private void isTrustStoreConfigured(@Nullable KeyStoreType trustStore) {
+ if (trustStore == null) return;
+
+ var isConfigured = trustStore.getPassword() != null
&& "JKS".equals(trustStore.getFileType())
- && trustStore.getFileName() != null);
+ && trustStore.getFileName() != null;
+ if (!isConfigured) throw mzse("TrustStore");
}
- private boolean areSinksConfigured(MsgResponseSinksType sinks) {
- return sinks != null
- && sinks.isLogResponse() != null
- && isSaveResponseToFileConfigured(sinks.getSaveResponseToFile())
- && isForwardResponseToServiceConfigured(sinks.getForwardResponseToService());
+ private void areSinksConfigured(@Nullable MsgResponseSinksType sinks) {
+ var isConfigured = sinks != null && sinks.isLogResponse() != null;
+ if (!isConfigured) throw mzse("MsgResponseSinks");
+
+ isSaveResponseToFileConfigured(sinks.getSaveResponseToFile());
+ isForwardResponseToServiceConfigured(sinks.getForwardResponseToService());
}
- private boolean isSaveResponseToFileConfigured(SaveResponseToFileType fileSink) {
- return fileSink != null
+ private void isSaveResponseToFileConfigured(@Nullable SaveResponseToFileType fileSink) {
+ var isConfigured = fileSink != null
&& (!fileSink.isActive() || fileSink.getPath() != null);
+
+ if (!isConfigured) throw mzse("SaveResponseToFile");
+ }
+
+ private void isForwardResponseToServiceConfigured(@Nullable ForwardResponseToServiceType forwardSink) {
+ if (forwardSink == null) throw mzse("ForwardResponseToService");
+
+ if (forwardSink.isActive()) {
+ try {
+ isClientConfigured(forwardSink.getMzsClient());
+ } catch (MoaZSException e) {
+ throw mzse("ForwardResponseToService", e.getMessage());
+ }
+ }
}
- private boolean isForwardResponseToServiceConfigured(ForwardResponseToServiceType forwardSink) {
- return forwardSink != null
- && (!forwardSink.isActive() || isClientConfigured(forwardSink.getMzsClient()));
+ private MoaZSException mzse(String missing) {
+ return moaZSException(format("%s is not configured.", missing));
}
+ private MoaZSException mzse(String missing, String reason) {
+ return moaZSException(format("%s is not configured. Reason: %s", missing, reason));
+ }
+
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
index 41b742b..b8a6d78 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
@@ -4,6 +4,8 @@ package at.gv.egiz.moazs.repository;
import at.gv.egiz.moazs.scheme.MsgResponse;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import com.google.common.cache.Cache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;
@@ -17,6 +19,8 @@ import static java.util.Optional.ofNullable;
@Profile("!cluster")
public class InMemoryDeliveryRepository implements DeliveryRepository {
+ private static final Logger log = LoggerFactory.getLogger(InMemoryDeliveryRepository.class);
+
private final Cache<String, DeliveryRequestType> requestRepository;
private final Cache<String, MsgResponse> responseRepository;
private final Cache<String, byte[]> binaryResponseRepository;
@@ -31,33 +35,38 @@ public class InMemoryDeliveryRepository implements DeliveryRepository {
@Override
public void store(DeliveryRequestType request) {
var key = request.getMetaData().getAppDeliveryID();
+ log.trace("Store DeliveryRequest by key={}", key);
requestRepository.put(key, request);
}
@Override
public Optional<DeliveryRequestType> retrieveDeliveryRequest(String appDeliveryID) {
+ log.trace("Retrieve DeliveryRequest by key={}", appDeliveryID);
return ofNullable(requestRepository.getIfPresent(appDeliveryID));
}
@Override
public void store(MsgResponse response) {
String key = response.getResponseID();
+ log.trace("Store MsgResponse by key={}", key);
responseRepository.put(key, response);
}
@Override
public Optional<MsgResponse> retrieveResponse(String responseID) {
+ log.trace("Retrieve MsgResponse by key={}", responseID);
return ofNullable(responseRepository.getIfPresent(responseID));
}
@Override
- public void store(String id, byte[] data) {
- binaryResponseRepository.put(id, data);
-
+ public void store(String responseID, byte[] data) {
+ log.trace("Store Binary MsgResponse by key={}", responseID);
+ binaryResponseRepository.put(responseID, data);
}
@Override
public Optional<byte[]> retrieveBinaryResponse(String responseID) {
+ log.trace("Retrieve Binary MsgResponse by key={}", responseID);
return ofNullable(binaryResponseRepository.getIfPresent(responseID));
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/Marshaller.java b/src/main/java/at/gv/egiz/moazs/scheme/Marshaller.java
index 83ace5c..1a86079 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/Marshaller.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/Marshaller.java
@@ -32,6 +32,10 @@ public class Marshaller {
}
public <T> String marshallXml(final T obj) {
+ if (obj == null) {
+ return "null";
+ }
+
StringWriter sw = new StringWriter();
Result result = new StreamResult(sw);
jaxbMarshaller.marshal(obj, result);
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java b/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java
index 6b6f34a..386a7a6 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java
@@ -5,6 +5,7 @@ public class NameSpace {
private NameSpace() {}
private static final at.gv.zustellung.msg.xsd.ObjectFactory MSG_FACTORY = new at.gv.zustellung.msg.xsd.ObjectFactory();
+ private static final at.gv.zustellung.app2mzs.xsd.ObjectFactory MZS_FACTORY = new at.gv.zustellung.app2mzs.xsd.ObjectFactory();
public static final String MSG_VERSION = "2.2.0";
public static final String MSG = MSG_FACTORY.createDeliveryRequest(null).getName().getNamespaceURI();
@@ -18,4 +19,8 @@ public class NameSpace {
public static final String MSG_DELIVERY_NOTIFICATION = MSG_FACTORY.createDeliveryNotification(null).getName().getLocalPart();
public static final String MSG_APP_DELIVERY_ID = MSG_FACTORY.createAppDeliveryID("").getName().getLocalPart();
+ public static final String MZS_DELIVERY_REQUEST = MZS_FACTORY.createDeliveryRequest(null).getName().getLocalPart();
+ public static final String MZS_TNVZCLIENT = MZS_FACTORY.createTNVZClient(null).getName().getLocalPart();
+ public static final String MZS_MSGCLIENT = MZS_FACTORY.createTNVZClient(null).getName().getLocalPart();
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java b/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java
index 6e96a6b..461d8fe 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java
@@ -3,8 +3,12 @@ package at.gv.egiz.moazs.scheme;
import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
import at.gv.egiz.moazs.MoaZSException;
import org.apache.cxf.binding.soap.Soap11;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
@@ -12,34 +16,72 @@ import javax.xml.transform.TransformerException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.LinkedList;
+import java.util.List;
+
+import static at.gv.egiz.moazs.MoaZSException.moaZSException;
@Component
public class SOAPUtils {
+ private static final Logger log = LoggerFactory.getLogger(SOAPUtils.class);
+ private static final String SOAP_BODY_MISSING_ERROR_MSG = "<soap11:Body> is missing.";
+ private static final String SOAP_BODY_CHILDREN_MISSING_ERROR_MSG = "<soap11:Body> has no child elements.";
+ private static final String APP_DELIVERY_ID_MISSING_ERROR_MSG = "<msg:AppDeliveryID> is missing.";
+ private static final String APP_DELIVERY_ID_EMPTY_ERROR_MSG = "<msg:AppDeliveryID> is empty.";
+ private static final String MULTIPLE_MSG = "Found multiple {} elements. Will choose first element.";
+ private static final String APP_DELIVERY_ID_FULL_TAG_NAME = "<msg:" + NameSpace.MSG_APP_DELIVERY_ID + ">";
+
public Element toDOM(byte[] bytes) throws IOException, SAXException, ParserConfigurationException {
var stream = new ByteArrayInputStream(bytes);
return DOMUtils.parseXmlNonValidating(stream);
}
- public byte[] unwrapSoapEnvelope(Element document) {
- try {
- var body = document.getElementsByTagNameNS(Soap11.SOAP_NAMESPACE, "Body");
- var item = body.item(0).getFirstChild();
+ public Node getChildElementOfSoapBody(Element document) throws MoaZSException {
+
+ var bodyList = document.getElementsByTagNameNS(Soap11.SOAP_NAMESPACE, "Body");
+ if (bodyList.getLength() == 0) throw moaZSException(SOAP_BODY_MISSING_ERROR_MSG);
+ if (bodyList.getLength() > 1) log.warn(MULTIPLE_MSG, "<soap11:Body>");
+
+ var body = bodyList.item(0);
+ var children = body.getChildNodes();
+ var candidates = filterNodeByType(children, Node.ELEMENT_NODE);
+
+ if (candidates.isEmpty()) throw moaZSException(SOAP_BODY_CHILDREN_MISSING_ERROR_MSG);
+ if (candidates.size() > 1) log.warn(MULTIPLE_MSG, "<soap11:Body> child");
- return DOMUtils.serializeNode(item, true)
- .getBytes(StandardCharsets.UTF_8);
+ return candidates.get(0);
+ }
- } catch (IOException | TransformerException e) {
- throw MoaZSException.moaZSException("Error while parsing message. ", e);
+ private List<Node> filterNodeByType(NodeList children, short nodeType) {
+ var candidates = new LinkedList<Node>();
+ for (int i = 0; i < children.getLength(); i++) {
+ var child = children.item(i);
+ if (child.getNodeType() == nodeType) {
+ candidates.add(child);
+ }
}
+
+ return candidates;
+ }
+
+ public byte[] toBytes(Node node) throws TransformerException, IOException {
+ return DOMUtils.serializeNode(node, true).getBytes(StandardCharsets.UTF_8);
}
public String getAppDeliveryIDFrom(Element document) {
- var elements = document.getElementsByTagNameNS(NameSpace.MSG, NameSpace.MSG_APP_DELIVERY_ID);
+ var elementList = document.getElementsByTagNameNS(NameSpace.MSG, NameSpace.MSG_APP_DELIVERY_ID);
+
+ if (elementList.getLength() == 0) throw moaZSException(APP_DELIVERY_ID_MISSING_ERROR_MSG);
+ if (elementList.getLength() > 1) log.warn(MULTIPLE_MSG, APP_DELIVERY_ID_FULL_TAG_NAME);
- var appDeliveryIdElement = elements.item(0).getFirstChild();
+ var children = elementList.item(0).getChildNodes();
+ var candidates = filterNodeByType(children, Node.TEXT_NODE);
+ if (candidates.isEmpty() || candidates.get(0).getNodeValue().isBlank())
+ throw moaZSException(APP_DELIVERY_ID_EMPTY_ERROR_MSG);
+ if (candidates.size() > 1) log.warn(MULTIPLE_MSG, APP_DELIVERY_ID_FULL_TAG_NAME);
- return appDeliveryIdElement.getNodeValue();
+ return candidates.get(0).getNodeValue();
}
}
diff --git a/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java b/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java
index 24321e1..9d31596 100644
--- a/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java
+++ b/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java
@@ -20,13 +20,13 @@ public class EndpointFactory {
this.bus = bus;
}
- public Endpoint create(Object implementor, Service service) {
- return create(implementor, service, null);
+ public Endpoint create(Object implementor, Service service, String route) {
+ return create(implementor, service, route, null);
}
- public Endpoint create(Object implementor, Service service, Interceptor<Message> interceptor) {
+ public Endpoint create(Object implementor, Service service, String route, Interceptor<Message> interceptor) {
EndpointImpl endpoint = new EndpointImpl(bus, implementor);
- endpoint.setAddress("/");
+ endpoint.setAddress(route);
endpoint.setServiceName(service.getServiceName());
endpoint.setWsdlLocation(service.getWSDLDocumentLocation().toString());
endpoint.publish();
diff --git a/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java b/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java
index 88ab7e0..d4aa75a 100644
--- a/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java
+++ b/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java
@@ -13,6 +13,7 @@ import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@@ -46,25 +47,22 @@ public class StoreSOAPBodyBinaryInRepositoryInterceptor extends AbstractPhaseInt
try {
byte[] content = messageUtils.copyContent(message);
- if(log.isTraceEnabled()) {
- log.trace("Interceptor received this SOAP message: {}. ", new String(content, StandardCharsets.UTF_8));
- }
-
if (content.length <= 0) {
return;
}
Element document = soapUtils.toDOM(content);
- byte[] response = soapUtils.unwrapSoapEnvelope(document);
- String appDeliveryID = soapUtils.getAppDeliveryIDFrom(document);
- String rootTag = document.getTagName();
+ var rootTagNode = soapUtils.getChildElementOfSoapBody(document);
+ var rootTagLocalName = rootTagNode.getLocalName();
- if (!idGenerators.containsKey(rootTag)) {
- log.trace("Will not store message of type {}. ", rootTag);
+ if (!idGenerators.containsKey(rootTagLocalName)) {
+ log.trace("Child element {} of <soap:Body> is unknown. Will not store message.", rootTagLocalName);
return;
}
- var id = idGenerators.get(rootTag).apply(appDeliveryID);
+ String appDeliveryID = soapUtils.getAppDeliveryIDFrom(document);
+ var id = idGenerators.get(rootTagLocalName).apply(appDeliveryID);
+ byte[] response = soapUtils.toBytes(rootTagNode);
repository.store(id, response);
if(log.isTraceEnabled()) {
@@ -72,7 +70,7 @@ public class StoreSOAPBodyBinaryInRepositoryInterceptor extends AbstractPhaseInt
appDeliveryID, new String(response, StandardCharsets.UTF_8));
}
- } catch (ParserConfigurationException | SAXException | IOException | NullPointerException e) {
+ } catch (ParserConfigurationException | SAXException | IOException | NullPointerException | TransformerException e) {
throw moaZSException("Could not extract signed data from message.", e);
}
}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index a7b7524..ce4d892 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -51,7 +51,9 @@ delivery-request-configuration-profiles:
# addressable. Requires setting up the tvnz-client.
perform-query-person-request: false
- # Optional (Mandatory if perform-query-person-request is true)
+ # TODO: Move tnvz-client into perform-query-person-request to make relationship clearer (also
+ # TODO: add active)
+ # Mandatory (if perform-query-person-request is true)
# Parameters for the connection to tvnz. Specify url,
# connection-timeout, receive-timeout and ssl here. See msg-client
# for an exhaustive description of all parameters.
@@ -166,12 +168,12 @@ moa.spss:
# Select, which trust-profile moa spss uses to verify a signature.
default-trustprofile: test-trustprofile
-# Optional
-# Redis Setup (Cluster Mode)
spring:
+ # Redis Setup (Cluster Mode)
redis:
host: 172.17.0.2
port: 6379
+ main.allow-bean-definition-overriding: true
# Mandatory
repository:
diff --git a/src/main/resources/mzs/app2mzs.wsdl b/src/main/resources/mzs/app2mzs.wsdl
index b3f0f4b..8c0547b 100644
--- a/src/main/resources/mzs/app2mzs.wsdl
+++ b/src/main/resources/mzs/app2mzs.wsdl
@@ -45,7 +45,7 @@
</binding>
<service name="app2mzs">
<port binding="tns:app2mzsBinding" name="app2mzsPort">
- <soap:address location="http://localhost:8080/moazs/services/DeliveryRequest"/>
+ <soap:address location="http://localhost:8080/moazs/services/mzs/DeliveryRequest"/>
</port>
</service>
</definitions>
diff --git a/src/main/resources/mzs/app2mzs.xsd b/src/main/resources/mzs/app2mzs.xsd
index 7e70092..d19ff3b 100644
--- a/src/main/resources/mzs/app2mzs.xsd
+++ b/src/main/resources/mzs/app2mzs.xsd
@@ -56,7 +56,6 @@
</xs:sequence>
</xs:complexType>
</xs:element>
- <xs:element ref="TnvzMetaData" minOccurs="0"/>
<xs:element ref="msg:MetaData" />
<xs:element name="Payload" maxOccurs="unbounded">
<xs:complexType>
@@ -80,21 +79,10 @@
<xs:element ref="Config" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
- <xs:element name="TnvzMetaData" type="TnvzMetaDataType" />
- <xs:complexType name="TnvzMetaDataType">
- <xs:sequence>
- <xs:element ref="msg:Origin" />
- <xs:choice>
- <xs:element ref="msg:DeliveryQuality"/>
- <xs:element ref="msg:PrivateMessageQuality"/>
- </xs:choice>
- <xs:element ref="msg:IgnorePostRedirectionOrder" minOccurs="0"/>
- </xs:sequence>
- </xs:complexType>
<xs:element name="Config" type="ConfigType"/>
<xs:complexType name="ConfigType">
<xs:sequence>
- <xs:element name="ProfileID" type="xs:token" minOccurs="0"></xs:element>
+ <xs:element name="ProfileID" type="xs:token" minOccurs="0" />
<xs:element name="ServiceTimeout" type="xs:nonNegativeInteger" minOccurs="0"/>
<xs:element name="PerformQueryPersonRequest" type="xs:boolean" minOccurs="0" />
<xs:element ref="MSGClient" minOccurs="0" />
diff --git a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
index f408c3b..c056b2c 100644
--- a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
@@ -5,10 +5,12 @@ import at.gv.egiz.moazs.preprocess.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Map;
+import static at.gv.egiz.moazs.MoaZSException.moaZSException;
import static at.gv.egiz.moazs.preprocess.ConfigProfileGenerator.configProfileGeneratorBuilder;
import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder;
import static org.mockito.ArgumentMatchers.any;
@@ -91,7 +93,7 @@ public class ConfigProfileGeneratorTest {
public void cancelAtIncompleteDefaultProfile() {
var propMap = Map.of(PREFIX + "." + DEFAULT + ".property-a", "value-a");
var generator = setupMocksAndBuilder(propMap).build();
- when(validator.isConfigProfileComplete(any())).thenReturn(false);
+ doThrow(moaZSException("Not Complete.")).when(validator).isConfigProfileComplete(any());
generator.generate();
}
@@ -100,7 +102,7 @@ public class ConfigProfileGeneratorTest {
public void continueAtIncompleteDefaultWhenVerificationDisabled() {
var propMap = Map.of(PREFIX + "." + DEFAULT + ".property-a", "value-a");
- when(validator.isConfigProfileComplete(any())).thenReturn(false);
+ doThrow(moaZSException("Not Complete.")).when(validator).isConfigProfileComplete(any());
var generator = setupMocksAndBuilder(propMap)
.withVerifyCompletenessOfDefaultConfiguration(false)
@@ -117,7 +119,6 @@ public class ConfigProfileGeneratorTest {
when(properties.getProperty(any())).thenAnswer(i -> propMap.get(i.getArgument(0)));
when(util.merge(any(), any())).thenAnswer(i -> i.getArgument(0));
when(util.convert(any())).thenReturn(configTypeBuilder().build());
- when(validator.isConfigProfileComplete(any())).thenReturn(true);
return configProfileGeneratorBuilder()
.withProperties(properties)
diff --git a/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java b/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
index 12f1dea..2e9dd80 100644
--- a/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
+++ b/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
@@ -3,6 +3,7 @@ package at.gv.egiz.moazs;
import at.gv.egiz.moazs.preprocess.MzsDeliveryRequestValidator;
import at.gv.egiz.moazs.preprocess.ConfigUtil;
import at.gv.egiz.moazs.preprocess.DeliveryRequestAugmenter;
+import at.gv.egiz.moazs.scheme.Marshaller;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import org.junit.Before;
@@ -31,10 +32,10 @@ public class DeliveryRequestAugmenterTest {
@Mock
private MzsDeliveryRequestValidator validator;
+ private Marshaller mzsMarshaller = new Marshaller(true);
+
@Before
public void setupMock() {
- when(validator.isConfigProfileComplete(any())).thenReturn(true);
- when(validator.isTnvzComplete(any())).thenReturn(true);
when(configUtil.merge(any(), any())).thenCallRealMethod();
}
@@ -109,11 +110,11 @@ public class DeliveryRequestAugmenterTest {
}
private DeliveryRequestAugmenter createAugmenter(ConfigType fallback) {
- return new DeliveryRequestAugmenter(Map.of("default", fallback), configUtil, validator);
+ return new DeliveryRequestAugmenter(Map.of("default", fallback), configUtil, validator, mzsMarshaller);
}
private DeliveryRequestAugmenter createAugmenter(Map<String, ConfigType> profiles) {
- return new DeliveryRequestAugmenter(profiles, configUtil, validator);
+ return new DeliveryRequestAugmenter(profiles, configUtil, validator, mzsMarshaller);
}
private ConfigType createConfig(String url, Boolean performTnvz) {
diff --git a/src/test/java/at/gv/egiz/moazs/ITEndToEndTest.java b/src/test/java/at/gv/egiz/moazs/ITEndToEndTest.java
new file mode 100644
index 0000000..fd2e629
--- /dev/null
+++ b/src/test/java/at/gv/egiz/moazs/ITEndToEndTest.java
@@ -0,0 +1,259 @@
+package at.gv.egiz.moazs;
+
+import at.gv.egiz.moazs.client.ClientFactory;
+import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.NotificationResponse;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import at.gv.zustellung.app2mzs.xsd.DeliveryNotificationACKType;
+import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
+import at.gv.zustellung.app2mzs.xsd.Mzs2AppPortType;
+import at.gv.zustellung.msg.xsd.App2ZusePort;
+import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
+import at.gv.zustellung.msg.xsd.DeliveryRequestType;
+import at.gv.zustellung.tnvz.xsd.TNVZServicePort;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Consumer;
+
+import static at.gv.zustellung.app2mzs.xsd.DeliveryNotificationACKType.deliveryNotificationACKTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.persondata.IdentificationType.Value.valueBuilder;
+import static at.gv.zustellung.app2mzs.xsd.persondata.IdentificationType.identificationTypeBuilder;
+import static at.gv.zustellung.msg.xsd.DeliveryAnswerType.deliveryAnswerTypeBuilder;
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
+import static java.net.http.HttpResponse.BodyHandlers.ofString;
+import static org.apache.commons.io.FileUtils.readFileToString;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ITEndToEndTest {
+
+ private final static Logger log = LoggerFactory.getLogger(ITEndToEndTest.class);
+ public static final String GZ_WATERMARK = "my-secret-watermark-string";
+ public static final String DELIVERY_SYSTEM = "http://localhost/url/to/msg/service";
+
+ @LocalServerPort
+ public int port;
+ private String mzsFrontendURL;
+
+ private final String basePath = "src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/";
+ private static Mzs2AppPortType APP;
+
+ @Before
+ public void setupFrontendURL() {
+ this.mzsFrontendURL = "http://localhost:" + port + "/services";
+ }
+
+ @TestConfiguration
+ public static class MockClientsAndSignatureVerificationConfig {
+
+
+ @Autowired
+ private DeliveryRepository repository;
+
+ @Bean
+ @Primary
+ public Consumer<byte[]> signatureVerifier() {
+ return bytes -> {};
+ }
+
+ @Bean
+ @Primary
+ public ClientFactory mockClientFactory() {
+ var factory = mock(ClientFactory.class);
+ var tnvz = mockTnvz();
+ var msg = mockMsg();
+ APP = mockApp();
+ when(factory.create(any(), same(TNVZServicePort.class))).thenReturn(tnvz);
+ when(factory.create(any(), same(App2ZusePort.class))).thenReturn(msg);
+ when(factory.create(any(), same(Mzs2AppPortType.class))).thenReturn(APP);
+ return factory;
+ }
+
+ private Mzs2AppPortType mockApp() {
+ var app = mock(Mzs2AppPortType.class);
+ when(app.forwardStatus(any())).thenAnswer(i -> ack(i.getArgument(0)));
+ when(app.forwardNotification(any())).thenAnswer(i -> ack(i.getArgument(0)));
+ return app;
+ }
+
+ private DeliveryNotificationACKType ack(DeliveryResponseType response) {
+ return deliveryNotificationACKTypeBuilder()
+ .withAppDeliveryID(response.getSuccess().getAppDeliveryID())
+ .build();
+ }
+
+ private TNVZServicePort mockTnvz() {
+ var tnvz = mock(TNVZServicePort.class);
+ var value = valueBuilder().withId("id").withValue("value").build();
+ var receiverId = identificationTypeBuilder()
+ .withValue(value).withId("id").withType("type").build();
+ var tnvzHelperTest = new TnvzHelperTest();
+ tnvzHelperTest.setup();
+ var tnvzSuccess = tnvzHelperTest.tnvzSuccess(List.of("*/*"), receiverId);
+
+ when(tnvz.queryPerson(any())).thenReturn(tnvzSuccess);
+ return tnvz;
+ }
+
+ private App2ZusePort mockMsg() {
+ var msg = mock(App2ZusePort.class);
+ when(msg.delivery(any())).thenAnswer(i-> partialSuccess(i.getArgument(0)));
+ return msg;
+ }
+
+ private DeliveryRequestStatusType partialSuccess(DeliveryRequestType request) {
+
+ var appDeliveryID = request.getMetaData().getAppDeliveryID();
+ var zsDeliveryID = "ZSDID-" + appDeliveryID;
+ var responseID = RequestStatusResponse.getResponseID(appDeliveryID);
+ var answer = deliveryAnswerTypeBuilder()
+ .withDeliverySystem(DELIVERY_SYSTEM)
+ .withAppDeliveryID(appDeliveryID)
+ .withZSDeliveryID(zsDeliveryID)
+ .withGZ(GZ_WATERMARK)
+ .build();
+ repository.store(responseID, new byte[]{});
+ return deliveryRequestStatusTypeBuilder()
+ .withPartialSuccess(answer)
+ .build();
+ }
+
+ }
+
+ @Test
+ public void testHappyPath() throws IOException, InterruptedException {
+
+ //prepare
+ var appDeliveryID = "delivery-request-id";
+ var zsDeliveryID = "ZSDID-" + appDeliveryID;
+ var timestamp = ITMzsServiceTest.genTimeStamp().toXMLFormat();
+ var saveSinkFolder = "target/tmp/ITEndToEndTestOut";
+ delete(saveSinkFolder);
+
+ //app sends delivery request to moazs and receives partial success
+ var partialSuccess = sendMzsDeliveryRequest("mzs-delivery-request.xml");
+ assertThat(partialSuccess.statusCode()).isEqualTo(200);
+ assertThat(partialSuccess.body()).contains(List.of(GZ_WATERMARK, "PartialSuccess"));
+
+ // zusemsg sends async success
+ var statusResponseID = RequestStatusResponse.getResponseID(appDeliveryID);
+ var msgStatus = formatFile("msg-delivery-request-status.xml", new String[]{
+ DELIVERY_SYSTEM, zsDeliveryID, appDeliveryID, GZ_WATERMARK, timestamp
+ });
+ sendMsgResponse(msgStatus);
+ Thread.sleep(100);
+ verify(APP).forwardStatus(any());
+ assertStatusWrittenToFileSystem(saveSinkFolder, statusResponseID);
+ assertStatusWasLogged();
+
+ // zusemsg sends async notification
+ var notificationResponseID = NotificationResponse.getResponseID(appDeliveryID);
+ var notification = formatFile("msg-delivery-notification.xml", new String[]{
+ DELIVERY_SYSTEM, zsDeliveryID, appDeliveryID, GZ_WATERMARK, timestamp, timestamp
+ });
+ sendMsgResponse(notification);
+ Thread.sleep(100);
+ verify(APP).forwardNotification(any());
+ assertStatusWrittenToFileSystem(saveSinkFolder, notificationResponseID);
+ assertStatusWasLogged();
+
+ }
+
+ private void assertStatusWrittenToFileSystem(String folder, String pathSubString) {
+ var rootFolder = new File(folder);
+ Collection<File> files = FileUtils.listFiles(rootFolder, null, true);
+
+ assertThat(rootFolder.exists()).isTrue();
+ assertThat(rootFolder.isDirectory()).isTrue();
+ assertThat(files).isNotEmpty();
+
+ long count = files.stream()
+ .map(File::getAbsolutePath)
+ .filter(path -> path.contains(pathSubString))
+ .count();
+
+ assertThat(count).isEqualTo(2);
+ }
+
+ private String readFile(File file) {
+ try {
+ return readFileToString(file, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void delete(String file) {
+ try {
+ FileUtils.deleteDirectory(new File(file));
+ } catch (IOException e) {
+ log.warn("Could not delete {}", file);
+ }
+ }
+
+ private void assertStatusWasLogged() {
+ //todo
+ }
+
+
+ private String formatFile(String templateFile, String... values) throws IOException {
+ var path = basePath + templateFile;
+ var templateString = FileUtils.readFileToString(new File(path), StandardCharsets.UTF_8);
+ return String.format(templateString, values);
+ }
+
+ private HttpResponse<String> sendMsgResponse(String bodyString) throws IOException, InterruptedException {
+
+ var body = HttpRequest.BodyPublishers.ofString(bodyString);
+ var client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
+ var request = HttpRequest.newBuilder()
+ .uri(URI.create(mzsFrontendURL + "/msg/"))
+ .header("Content-Type", "text/xml;charset=UTF-8")
+ .header("SOAPAction", "\"\"")
+ .POST(body)
+ .build();
+
+ return client.send(request, ofString());
+
+ }
+
+ private HttpResponse<String> sendMzsDeliveryRequest(String fileName) throws IOException, InterruptedException {
+
+ var path = basePath + fileName;
+ var client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
+ var request = HttpRequest.newBuilder()
+ .uri(URI.create(mzsFrontendURL + "/mzs/"))
+ .header("Content-Type", "text/xml;charset=UTF-8")
+ .header("SOAPAction", "\"\"")
+ .POST(HttpRequest.BodyPublishers.ofFile(Paths.get(path)))
+ .build();
+
+ return client.send(request, ofString());
+
+ }
+
+}
diff --git a/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java b/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
index e9b4f70..3cf0362 100644
--- a/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
@@ -2,12 +2,14 @@ package at.gv.egiz.moazs;
import at.gv.egiz.moazs.repository.DeliveryRepository;
import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.test.context.junit4.SpringRunner;
@@ -27,17 +29,24 @@ import java.util.function.Consumer;
import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Success.successBuilder;
import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
import static java.net.http.HttpClient.Version;
-import static org.junit.Assert.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ITMzsServiceTest {
- private final String serviceUri = "http://localhost:8080/services/DeliveryRequest";
-
private final String basePath = "src/test/resources/at/gv/egiz/moazs/ITMzsServiceTest/";
+ @LocalServerPort
+ public int port;
+ private String serviceUri;
+
+ @Before
+ public void setupServiceURI() {
+ this.serviceUri = "http://localhost:" + port + "/services/mzs";
+ }
+
@TestConfiguration
public static class TestConfig {
@@ -64,50 +73,44 @@ public class ITMzsServiceTest {
};
}
- private XMLGregorianCalendar genTimeStamp() {
- try {
- return DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar());
- } catch (DatatypeConfigurationException e) {
- throw new RuntimeException("ups");
- }
- }
}
@Test
public void acceptValidDeliveryRequest() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("validDeliveryRequest.soap");
- assertEquals(200, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).contains("valid-delivery-request-id");
}
@Test
public void rejectRequestWithoutSender() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("missingSender.soap");
- assertEquals(500, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(500);
}
@Test
public void rejectBothProfileAndCorporateBody() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("profileAndCorporateBody.soap");
- assertEquals(500, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(500);
}
@Test
public void rejectFormallyIncorrectDeliveryRequest() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("formallyIncorrectDeliveryRequest.soap");
- assertEquals(500, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(500);
}
@Test
public void rejectRequestWithoutAppDeliveryID() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("missingAppDeliveryId.soap");
- assertEquals(500, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(500);
}
@Test
public void rejectRequestWithoutMetaData() throws IOException, InterruptedException {
var response = sendDeliveryRequestFile("missingMetaData.soap");
- assertEquals(500, response.statusCode());
+ assertThat(response.statusCode()).isEqualTo(500);
}
private HttpResponse<String> sendDeliveryRequestFile(String fileName) throws IOException, InterruptedException {
@@ -125,4 +128,13 @@ public class ITMzsServiceTest {
}
+ public static XMLGregorianCalendar genTimeStamp() {
+ try {
+ return DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar());
+ } catch (DatatypeConfigurationException e) {
+ throw new RuntimeException("ups");
+ }
+
+ }
+
}
diff --git a/src/test/java/at/gv/egiz/moazs/SOAPUtilsTest.java b/src/test/java/at/gv/egiz/moazs/SOAPUtilsTest.java
index 31aa197..ff0060e 100644
--- a/src/test/java/at/gv/egiz/moazs/SOAPUtilsTest.java
+++ b/src/test/java/at/gv/egiz/moazs/SOAPUtilsTest.java
@@ -4,10 +4,8 @@ import at.gv.egiz.moazs.scheme.SOAPUtils;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
+import org.w3c.dom.Node;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import static org.assertj.core.api.Assertions.assertThat;
@@ -25,39 +23,152 @@ public class SOAPUtilsTest {
"est-id</ZSDeliveryID><AppDeliveryID>valid-delivery-request-id</AppDeliveryID><GZ>12345</GZ>" +
"</PartialSuccess></DeliveryResponse></soap:Body></soap:Envelope>";
+
+ public static final String FORMATTED_MESSAGE =
+ "<soapenv:Envelope\n" +
+ " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
+ " xmlns:msg=\"http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#\">\n" +
+ " <soapenv:Body>\n" +
+ " <msg:DeliveryNotification>\n" +
+ " <msg:AppDeliveryID>formatted-adid</msg:AppDeliveryID>\n" +
+ " </msg:DeliveryNotification>\n" +
+ " </soapenv:Body>\n" +
+ "</soapenv:Envelope>\n";
+
+ public static final String CLUTTERED_MESSAGE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<soapenv:Envelope " +
+ " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n " +
+ " xmlns:msg=\"http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#\">\n" +
+ " <soapenv:Body unexpected-attribute=\"unexpectedvalue\"> \n" +
+ " <msg:DeliveryNotification>\n" +
+ " <msg:AppDeliveryID attribute=\"some-value\"><element-that-got-lost />cluttered-adid</msg:AppDeliveryID>\n" +
+ " </msg:DeliveryNotification>\n" +
+ " </soapenv:Body>\n" +
+ "</soapenv:Envelope>\n";
+
+ private static final String MISSING_BODY_MESSAGE =
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><NotABodyTag></NotABodyTag></soap:Envelope>";
+
+ private static final String EMPTY_BODY_MESSAGE =
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body> </soap:Body></soap:Envelope>";
+
+ public static final String EMPTY_APP_DELIVERY_ID_MESSAGE =
+ "<soapenv:Envelope\n" +
+ " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
+ " xmlns:msg=\"http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#\">\n" +
+ " <soapenv:Body>\n" +
+ " <msg:DeliveryNotification>\n" +
+ " <msg:AppDeliveryID />\n" +
+ " </msg:DeliveryNotification>\n" +
+ " </soapenv:Body>\n" +
+ "</soapenv:Envelope>\n";
+
+ public static final String BLANK_APP_DELIVERY_ID_MESSAGE =
+ "<soapenv:Envelope\n" +
+ " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
+ " xmlns:msg=\"http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#\">\n" +
+ " <soapenv:Body>\n" +
+ " <msg:DeliveryNotification>\n" +
+ " <msg:AppDeliveryID> </msg:AppDeliveryID>\n" +
+ " </msg:DeliveryNotification>\n" +
+ " </soapenv:Body>\n" +
+ "</soapenv:Envelope>\n";
+
@Before
public void setup() {
utils = new SOAPUtils();
}
@Test
- public void toDom() throws ParserConfigurationException, SAXException, IOException {
- byte[] bytes = SOAP_MESSAGE.getBytes(StandardCharsets.UTF_8);
+ public void canParseSoapMessage() throws Exception {
+ parseAndCheckLocalName(SOAP_MESSAGE);
+ }
+
+ @Test
+ public void canParseFormattedSoapMessage() throws Exception {
+ parseAndCheckLocalName(FORMATTED_MESSAGE);
+ }
+
+ @Test
+ public void canParseClutteredSoapMessage() throws Exception {
+ parseAndCheckLocalName(CLUTTERED_MESSAGE);
+ }
+ private void parseAndCheckLocalName(String text) throws Exception {
+ byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
Element root = utils.toDOM(bytes);
+ assertThat(root.getLocalName()).isEqualTo("Envelope");
+ }
+
+ @Test
+ public void canUnwrapSoapMessage() throws Exception {
+ getFirstChildAndCheckLocalName(SOAP_MESSAGE, "DeliveryResponse");
+ }
- assertThat(root.getTagName()).isEqualTo("soap:Envelope");
+ @Test
+ public void canUnwrapFormattedSoapMessage() throws Exception {
+ getFirstChildAndCheckLocalName(FORMATTED_MESSAGE, "DeliveryNotification");
}
@Test
- public void unwrapSoapEnvelope() throws ParserConfigurationException, SAXException, IOException {
- byte[] bytes = SOAP_MESSAGE.getBytes(StandardCharsets.UTF_8);
+ public void canUnwrapClutteredSoapMessage() throws Exception {
+ getFirstChildAndCheckLocalName(CLUTTERED_MESSAGE, "DeliveryNotification");
+ }
+
+ @Test(expected=MoaZSException.class)
+ public void failUnwrapMissingBody() throws Exception {
+ getFirstChildAndCheckLocalName(MISSING_BODY_MESSAGE, "");
+ }
+
+ @Test(expected=MoaZSException.class)
+ public void failUnwrapEmptyBody() throws Exception {
+ getFirstChildAndCheckLocalName(EMPTY_BODY_MESSAGE, "");
+ }
+
+ private void getFirstChildAndCheckLocalName(String message, String expectedLocalNameOfChild) throws Exception {
+ byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
Element soapRoot = utils.toDOM(bytes);
+ Node child = utils.getChildElementOfSoapBody(soapRoot);
+ var actualLocalName = child.getLocalName();
+ assertThat(actualLocalName).isEqualTo(expectedLocalNameOfChild);
+ }
- byte[] unwrappedMessage = utils.unwrapSoapEnvelope(soapRoot);
+ @Test
+ public void getAppDeliveryIDFromSoapMessage() throws Exception {
+ getAppDeliveryIDAndCheck(SOAP_MESSAGE, "valid-delivery-request-id");
+ }
- Element deliveryResponseRoot = utils.toDOM(unwrappedMessage);
- assertThat(deliveryResponseRoot.getTagName()).isEqualTo("DeliveryResponse");
+ @Test
+ public void getAppDeliveryIDFromFormattedMessage() throws Exception {
+ getAppDeliveryIDAndCheck(FORMATTED_MESSAGE, "formatted-adid");
}
@Test
- public void getAppDeliveryID() throws ParserConfigurationException, SAXException, IOException {
- byte[] bytes = SOAP_MESSAGE.getBytes(StandardCharsets.UTF_8);
- Element soapRoot = utils.toDOM(bytes);
+ public void getAppDeliveryIDFromClutteredMessage() throws Exception {
+ getAppDeliveryIDAndCheck(CLUTTERED_MESSAGE, "cluttered-adid");
+ }
+
+ @Test(expected = MoaZSException.class)
+ public void failToRetrieveAppDeliveryIDWhenBodyIsMissing() throws Exception {
+ getAppDeliveryIDAndCheck(MISSING_BODY_MESSAGE, "");
+ }
- String appDeliveryID = utils.getAppDeliveryIDFrom(soapRoot);
+ @Test(expected = MoaZSException.class)
+ public void failToRetrieveEmptyAppDeliveryID() throws Exception {
+ getAppDeliveryIDAndCheck(EMPTY_APP_DELIVERY_ID_MESSAGE, "");
+ }
+
+ @Test(expected = MoaZSException.class)
+ public void failToRetrieveBlankAppDeliveryID() throws Exception {
+ getAppDeliveryIDAndCheck(BLANK_APP_DELIVERY_ID_MESSAGE, "");
+ }
- assertThat(appDeliveryID).isEqualTo("valid-delivery-request-id");
+ private void getAppDeliveryIDAndCheck(String message, String expectedValue) throws Exception {
+ byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
+ Element soapRoot = utils.toDOM(bytes);
+ String actualAppDeliveryID = utils.getAppDeliveryIDFrom(soapRoot);
+ assertThat(actualAppDeliveryID).isEqualTo(expectedValue);
}
}
diff --git a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
index 020e270..550f089 100644
--- a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
+++ b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
@@ -5,6 +5,8 @@ import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
import at.gv.egiz.moazs.client.TnvzHelper;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import at.gv.zustellung.app2mzs.xsd.persondata.IdentificationType;
+import at.gv.zustellung.msg.xsd.MetaData;
+import at.gv.zustellung.msg.xsd.SystemComponentType;
import at.gv.zustellung.tnvz.xsd.MimeTypeList;
import at.gv.zustellung.tnvz.xsd.QueryPersonResponse;
import at.gv.zustellung.tnvz.xsd.TNVZServicePort;
@@ -20,11 +22,12 @@ import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload.payloadBu
import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Receiver.receiverBuilder;
import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Sender.senderBuilder;
import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder;
-import static at.gv.zustellung.app2mzs.xsd.TnvzMetaDataType.tnvzMetaDataTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.persondata.CorporateBodyType.corporateBodyTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.persondata.IdentificationType.Value.valueBuilder;
import static at.gv.zustellung.app2mzs.xsd.persondata.IdentificationType.identificationTypeBuilder;
import static at.gv.zustellung.msg.xsd.ErrorInfoType.errorInfoTypeBuilder;
+import static at.gv.zustellung.msg.xsd.MetaData.metaDataBuilder;
+import static at.gv.zustellung.msg.xsd.SystemComponentType.systemComponentTypeBuilder;
import static at.gv.zustellung.tnvz.xsd.MimeTypeList.mimeTypeListBuilder;
import static at.gv.zustellung.tnvz.xsd.PersonResultSuccessType.personResultSuccessTypeBuilder;
import static at.gv.zustellung.tnvz.xsd.PersonResultType.Error.errorBuilder;
@@ -119,14 +122,19 @@ public class TnvzHelperTest {
.withIdentification(receiverId)
.build();
- var metadata = tnvzMetaDataTypeBuilder()
+ var origin = systemComponentTypeBuilder()
+ .withParticipantID("ID")
+ .build();
+
+ var metadata = metaDataBuilder()
+ .withOrigin(origin)
.build();
return deliveryRequestTypeBuilder()
.withSender(sender)
.withReceiver(receiver)
- .withTnvzMetaData(metadata)
.withPayload(payload(mzsMimeTypes))
+ .withMetaData(metadata)
.build();
}
@@ -148,7 +156,7 @@ public class TnvzHelperTest {
.collect(toList());
}
- private QueryPersonResponse tnvzSuccess(List<String> mimeTypes, IdentificationType receiverId) {
+ public QueryPersonResponse tnvzSuccess(List<String> mimeTypes, IdentificationType receiverId) {
var success = personResultSuccessTypeBuilder()
.withMimeTypeList(setupMimeTypeList(mimeTypes))
diff --git a/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-notification.xml b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-notification.xml
new file mode 100644
index 0000000..3a90d36
--- /dev/null
+++ b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-notification.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:p="http://reference.e-government.gv.at/namespace/persondata/phase2/20181206#"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:msg="http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#">
+ <soapenv:Body>
+ <msg:DeliveryNotification>
+ <msg:DeliverySystem>%s</msg:DeliverySystem>
+ <msg:ZSDeliveryID>%s</msg:ZSDeliveryID>
+ <msg:AppDeliveryID>%s</msg:AppDeliveryID>
+ <msg:GZ>%s</msg:GZ>
+ <msg:SenderDetails>
+ <p:Identification>
+ <p:Value>12345</p:Value>
+ <p:Type>678910</p:Type>
+ </p:Identification>
+ <p:CorporateBody>
+ <p:FullName>Bundesministerium für Testzwecke</p:FullName>
+ </p:CorporateBody>
+ </msg:SenderDetails>
+ <msg:ReceiverDetails>
+ <p:Identification>
+ <p:Value>123</p:Value>
+ <p:Type>654654</p:Type>
+ </p:Identification>
+ <p:PhysicalPerson>
+ <p:Name>
+ <p:GivenName>Maxi</p:GivenName>
+ <p:FamilyName>Mustermann1</p:FamilyName>
+ </p:Name>
+ <p:DateOfBirth>1984-01-24</p:DateOfBirth>
+ </p:PhysicalPerson>
+ </msg:ReceiverDetails>
+ <msg:RelayedViaERV>false</msg:RelayedViaERV>
+ <msg:Timestamp>%s</msg:Timestamp>
+ <msg:Answer xsi:type="msg:AcceptedType">
+ <msg:NotificationsPerformed>
+ <msg:RecipientNotification>
+ <msg:Timestamp>%s</msg:Timestamp>
+ </msg:RecipientNotification>
+ </msg:NotificationsPerformed>
+ </msg:Answer>
+ <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="signature-1-1">
+ <dsig:SignedInfo>
+ <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+ <dsig:Reference Id="reference-1-1" URI="">
+ <dsig:Transforms>
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </dsig:Transforms>
+ <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <dsig:DigestValue>ejvUI0yh/IIyauFe8x5ZonD/i5oznl8vFyS3oLNivzA=</dsig:DigestValue>
+ </dsig:Reference>
+ </dsig:SignedInfo>
+ <dsig:SignatureValue>
+ hmVZrLkMDbXaRLYQKOaV3OtK13TQgMu3csKyw9M4zWqNyva1yxnYkzoX3dKDOdc9
+ O56yQJsjoA3Cuw7pXlGO7jSfVM77dTXbWSDaF95O9Vdsrmr7R6Uki0jA9SmgQLXg
+ hZAUG8JpsHcBn8M0L2BXADKjSn0LuMDL2L7dmU3EM7eRy+OvFwDrXDw1fhjQO6L2
+ KoflAWLgUerDhJSpzr0+YfmkrjzitLUA7oIg8ieOnfGyql31ECmDJEqgnL78hyPZ
+ KaNZImDf3EWFs8je6mt+os1TwsyXYwz+GGbjoDR8lGTS9xVqnXdrgP8Jyv6p9FEu
+ 0IYgSY2FlbI3skPZC8ZVXg==
+ </dsig:SignatureValue>
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIEqzCCBBSgAwIBAgIHANux81oNezANBgkqhkiG9w0BAQUFADBAMSIwIAYDVQQD
+ ExlJQUlLIFRlc3QgSW50ZXJtZWRpYXRlIENBMQ0wCwYDVQQKEwRJQUlLMQswCQYD
+ VQQGEwJBVDAeFw0xMzA5MjcwNTMzMzdaFw0yMzA5MjcwNTMzMzdaMIHkMQswCQYD
+ VQQGEwJBVDENMAsGA1UEBxMER3JhejEmMCQGA1UEChMdR3JheiBVbml2ZXJzaXR5
+ IG9mIFRlY2hub2xvZ3kxSDBGBgNVBAsTP0luc3RpdHV0ZSBmb3IgQXBwbGllZCBJ
+ bmZvcm1hdGlvbiBQcm9jZXNzaW5nIGFuZCBDb21tdW5pY2F0aW9uczEUMBIGA1UE
+ BBMLTU9BLVNTIFRlc3QxGDAWBgNVBCoTD0VHSVogVGVzdHBvcnRhbDEkMCIGA1UE
+ AxMbRUdJWiBUZXN0cG9ydGFsIE1PQS1TUyBUZXN0MIIBIjANBgkqhkiG9w0BAQEF
+ AAOCAQ8AMIIBCgKCAQEAuDjOyf+mY+oQL2FQzzuaiC8C23vVKbq/n2Zi7BqSibZH
+ mtqMJfmj4pT+hWSNHvVvWsaxFcx4KeNqdCMzwnw1r4P3Sf+2o5uFku5KHEMLMokR
+ yYQG9VqY/KkB94ye7Pv6zT8gvKqxGFg96UamECep4swPaSZrA8AOER5WAtyGDzKI
+ Tz+a5zfFaTXDoba7f98PCWR96yKiFjVOhzp38WVz4VJgz+b8ZSY7Xsv5Kn7DXjOL
+ STX4MevFLki3rFPup3+4vGToaMBW3PEj67HXBdqR855Le6+E6rVxORqsXqlVwhsI
+ 6nuS0CO2LWYmBNR1IB0mXteeYH/HfxvuZc+7yDjdPQIDAQABo4IBhDCCAYAwDgYD
+ VR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFEmcH6VY4BG1EAGB
+ TLoNR9vH/g6yMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ ei5hdC9jYXBzby9jcmxzL0lBSUtUZXN0X0ludGVybWVkaWF0ZUNBLmNybDCBqgYI
+ KwYBBQUHAQEEgZ0wgZowSgYIKwYBBQUHMAGGPmh0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ ei5hdC9jYXBzby9PQ1NQP2NhPUlBSUtUZXN0X0ludGVybWVkaWF0ZUNBMEwGCCsG
+ AQUFBzAChkBodHRwOi8vY2EuaWFpay50dWdyYXouYXQvY2Fwc28vY2VydHMvSUFJ
+ S1Rlc3RfSW50ZXJtZWRpYXRlQ0EuY2VyMCEGA1UdEQQaMBiBFnRob21hcy5sZW56
+ QGVnaXouZ3YuYXQwHwYDVR0jBBgwFoAUaKJeEdreL4BrRES/jfplNoEkp28wDQYJ
+ KoZIhvcNAQEFBQADgYEAlFGjUxXLs7SAT8NtXSrv2WrjlklaRnHTFHLQwyVo8JWb
+ gvRkHHDUv2o8ofXUY2R2WJ38dxeDoccgbXrJb/Qhi8IY7YhCwv/TuIZDisyAqo8W
+ ORKSip/6HWlGCSR/Vgoet1GtCmF0FoUxFUIGSAuQ2yyt4fIzt5GJrU1X5ujjI1w=
+ </dsig:X509Certificate>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </dsig:Signature>
+ </msg:DeliveryNotification>
+ </soapenv:Body>
+</soapenv:Envelope>
diff --git a/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-request-status.xml b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-request-status.xml
new file mode 100644
index 0000000..bbeded8
--- /dev/null
+++ b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/msg-delivery-request-status.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:msg="http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#">
+ <soapenv:Body>
+ <msg:DeliveryRequestStatus>
+ <msg:Success>
+ <msg:DeliverySystem>%s</msg:DeliverySystem>
+ <msg:ZSDeliveryID>%s</msg:ZSDeliveryID>
+ <msg:AppDeliveryID>%s</msg:AppDeliveryID>
+ <msg:GZ>%s</msg:GZ>
+ <msg:DeliveryTimestamp>%s</msg:DeliveryTimestamp>
+ <msg:RelayedViaERV>false</msg:RelayedViaERV>
+ </msg:Success>
+ <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="signature-1-1">
+ <dsig:SignedInfo>
+ <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+ <dsig:Reference Id="reference-1-1" URI="">
+ <dsig:Transforms>
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </dsig:Transforms>
+ <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <dsig:DigestValue>ejvUI0yh/IIyauFe8x5ZonD/i5oznl8vFyS3oLNivzA=</dsig:DigestValue>
+ </dsig:Reference>
+ </dsig:SignedInfo>
+ <dsig:SignatureValue>
+ hmVZrLkMDbXaRLYQKOaV3OtK13TQgMu3csKyw9M4zWqNyva1yxnYkzoX3dKDOdc9
+ O56yQJsjoA3Cuw7pXlGO7jSfVM77dTXbWSDaF95O9Vdsrmr7R6Uki0jA9SmgQLXg
+ hZAUG8JpsHcBn8M0L2BXADKjSn0LuMDL2L7dmU3EM7eRy+OvFwDrXDw1fhjQO6L2
+ KoflAWLgUerDhJSpzr0+YfmkrjzitLUA7oIg8ieOnfGyql31ECmDJEqgnL78hyPZ
+ KaNZImDf3EWFs8je6mt+os1TwsyXYwz+GGbjoDR8lGTS9xVqnXdrgP8Jyv6p9FEu
+ 0IYgSY2FlbI3skPZC8ZVXg==
+ </dsig:SignatureValue>
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIEqzCCBBSgAwIBAgIHANux81oNezANBgkqhkiG9w0BAQUFADBAMSIwIAYDVQQD
+ ExlJQUlLIFRlc3QgSW50ZXJtZWRpYXRlIENBMQ0wCwYDVQQKEwRJQUlLMQswCQYD
+ VQQGEwJBVDAeFw0xMzA5MjcwNTMzMzdaFw0yMzA5MjcwNTMzMzdaMIHkMQswCQYD
+ VQQGEwJBVDENMAsGA1UEBxMER3JhejEmMCQGA1UEChMdR3JheiBVbml2ZXJzaXR5
+ IG9mIFRlY2hub2xvZ3kxSDBGBgNVBAsTP0luc3RpdHV0ZSBmb3IgQXBwbGllZCBJ
+ bmZvcm1hdGlvbiBQcm9jZXNzaW5nIGFuZCBDb21tdW5pY2F0aW9uczEUMBIGA1UE
+ BBMLTU9BLVNTIFRlc3QxGDAWBgNVBCoTD0VHSVogVGVzdHBvcnRhbDEkMCIGA1UE
+ AxMbRUdJWiBUZXN0cG9ydGFsIE1PQS1TUyBUZXN0MIIBIjANBgkqhkiG9w0BAQEF
+ AAOCAQ8AMIIBCgKCAQEAuDjOyf+mY+oQL2FQzzuaiC8C23vVKbq/n2Zi7BqSibZH
+ mtqMJfmj4pT+hWSNHvVvWsaxFcx4KeNqdCMzwnw1r4P3Sf+2o5uFku5KHEMLMokR
+ yYQG9VqY/KkB94ye7Pv6zT8gvKqxGFg96UamECep4swPaSZrA8AOER5WAtyGDzKI
+ Tz+a5zfFaTXDoba7f98PCWR96yKiFjVOhzp38WVz4VJgz+b8ZSY7Xsv5Kn7DXjOL
+ STX4MevFLki3rFPup3+4vGToaMBW3PEj67HXBdqR855Le6+E6rVxORqsXqlVwhsI
+ 6nuS0CO2LWYmBNR1IB0mXteeYH/HfxvuZc+7yDjdPQIDAQABo4IBhDCCAYAwDgYD
+ VR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFEmcH6VY4BG1EAGB
+ TLoNR9vH/g6yMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ ei5hdC9jYXBzby9jcmxzL0lBSUtUZXN0X0ludGVybWVkaWF0ZUNBLmNybDCBqgYI
+ KwYBBQUHAQEEgZ0wgZowSgYIKwYBBQUHMAGGPmh0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ ei5hdC9jYXBzby9PQ1NQP2NhPUlBSUtUZXN0X0ludGVybWVkaWF0ZUNBMEwGCCsG
+ AQUFBzAChkBodHRwOi8vY2EuaWFpay50dWdyYXouYXQvY2Fwc28vY2VydHMvSUFJ
+ S1Rlc3RfSW50ZXJtZWRpYXRlQ0EuY2VyMCEGA1UdEQQaMBiBFnRob21hcy5sZW56
+ QGVnaXouZ3YuYXQwHwYDVR0jBBgwFoAUaKJeEdreL4BrRES/jfplNoEkp28wDQYJ
+ KoZIhvcNAQEFBQADgYEAlFGjUxXLs7SAT8NtXSrv2WrjlklaRnHTFHLQwyVo8JWb
+ gvRkHHDUv2o8ofXUY2R2WJ38dxeDoccgbXrJb/Qhi8IY7YhCwv/TuIZDisyAqo8W
+ ORKSip/6HWlGCSR/Vgoet1GtCmF0FoUxFUIGSAuQ2yyt4fIzt5GJrU1X5ujjI1w=
+ </dsig:X509Certificate>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </dsig:Signature>
+ </msg:DeliveryRequestStatus>
+ </soapenv:Body>
+</soapenv:Envelope>
diff --git a/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/mzs-delivery-request.xml b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/mzs-delivery-request.xml
new file mode 100644
index 0000000..ef07686
--- /dev/null
+++ b/src/test/resources/at/gv/egiz/moazs/ITEndToEndTest/mzs-delivery-request.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:mzs="http://reference.e-government.gv.at/namespace/zustellung/mzs/app2mzs#"
+ xmlns:p="http://reference.e-government.gv.at/namespace/zustellung/mzs/persondata#"
+ xmlns:msg="http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#">
+ <soapenv:Body>
+ <mzs:DeliveryRequest>
+ <mzs:Sender>
+ <p:CorporateBody>
+ <p:Identification>
+ <p:Value>kkvj693+tw99uW8UPuEK9en1LzZItkylPajkUUyJJDWQB78VGPkAuhCEk+TD12yQDD/WRglsf+JfQpjubIs/4l/ptluJ9teF3nwkNlu5Dm7mIjzgW1qxrDyomCmPvVxTWOCBuMUbOWRZBhOq+KvDQAu9Vv9KnqSfjYeDZrpHYu4=</p:Value>
+ <p:Type>urn:publicid:gv:at:cemtoken</p:Type>
+ </p:Identification>
+ <p:FullName>Bundesministerium für Testzwecke</p:FullName>
+ </p:CorporateBody>
+ <mzs:WebserviceURL>https://authority.gv.at/delivery_notification</mzs:WebserviceURL>
+ </mzs:Sender>
+ <mzs:Receiver>
+ <p:PhysicalPerson>
+ <p:Name>
+ <p:GivenName>Maxi</p:GivenName>
+ <p:FamilyName>Mustermann1</p:FamilyName>
+ </p:Name>
+ <p:DateOfBirth>1984-01-24</p:DateOfBirth>
+ </p:PhysicalPerson>
+ <p:PostalAddress>
+ <p:CountryCode>AT</p:CountryCode>
+ <p:PostalCode>1010</p:PostalCode>
+ <p:Municipality>Wien</p:Municipality>
+ <p:DeliveryAddress>
+ <p:StreetName>Muststrasse</p:StreetName>
+ <p:BuildingNumber>10</p:BuildingNumber>
+ </p:DeliveryAddress>
+ </p:PostalAddress>
+ </mzs:Receiver>
+ <msg:MetaData>
+ <msg:AppDeliveryID>delivery-request-id</msg:AppDeliveryID>
+ <msg:Origin>
+ <msg:ParticipantID>VKABC</msg:ParticipantID>
+ </msg:Origin>
+ <msg:Subject>WichtigeMitteilung</msg:Subject>
+ <msg:DeliveryQuality>RSa</msg:DeliveryQuality>
+ </msg:MetaData>
+ <mzs:Payload>
+ <mzs:DocumentReference>https://authority.gv.at/files/73bdf969781ba41fa07df1ff8439cf685c0db1c3</mzs:DocumentReference>
+ <mzs:FileName>brief.xml</mzs:FileName>
+ <mzs:MIMEType>text/xml</mzs:MIMEType>
+ <msg:CheckSum>
+ <msg:AlgorithmID>SHA1</msg:AlgorithmID>
+ <msg:Value>9b972c70fdaf5e1b26b3387c87b0ffb72e5940b6</msg:Value>
+ </msg:CheckSum>
+ <mzs:Size>123401</mzs:Size>
+ </mzs:Payload>
+ <mzs:Config>
+ <mzs:PerformQueryPersonRequest>true</mzs:PerformQueryPersonRequest>
+ <mzs:TNVZClient>
+ <mzs:URL>http://localhost/tvnzservice</mzs:URL>
+ <mzs:ConnectionTimeout>0</mzs:ConnectionTimeout>
+ <mzs:ReceiveTimeout>0</mzs:ReceiveTimeout>
+ </mzs:TNVZClient>
+ <mzs:MsgResponseSinks>
+ <mzs:SaveResponseToFile>
+ <mzs:Active>true</mzs:Active>
+ <mzs:Path>target/tmp/ITEndToEndTestOut</mzs:Path>
+ </mzs:SaveResponseToFile>
+ <mzs:LogResponse>true</mzs:LogResponse>
+ <mzs:ForwardResponseToService>
+ <mzs:Active>true</mzs:Active>
+ <mzs:MzsClient>
+ <mzs:URL>http://localhost/appurl</mzs:URL>
+ <mzs:ConnectionTimeout>0</mzs:ConnectionTimeout>
+ <mzs:ReceiveTimeout>0</mzs:ReceiveTimeout>
+ </mzs:MzsClient>
+ </mzs:ForwardResponseToService>
+ </mzs:MsgResponseSinks>
+ </mzs:Config>
+ </mzs:DeliveryRequest>
+ </soapenv:Body>
+</soapenv:Envelope>