aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pom.xml6
-rw-r--r--src/main/java/at/gv/egiz/moazs/MoaZSException.java99
-rw-r--r--src/main/java/at/gv/egiz/moazs/client/MzsClient.java (renamed from src/main/java/at/gv/egiz/moazs/scheme/MzsClient.java)2
-rw-r--r--src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java (renamed from src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java)5
-rw-r--r--src/main/java/at/gv/egiz/moazs/config/MzsServiceConfig.java30
-rw-r--r--src/main/java/at/gv/egiz/moazs/config/PreprocessConfig.java2
-rw-r--r--src/main/java/at/gv/egiz/moazs/config/RepositoryConfig.java32
-rw-r--r--src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java46
-rw-r--r--src/main/java/at/gv/egiz/moazs/pipeline/SingleThreadedDeliveryPipeline.java107
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java1
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java1
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java (renamed from src/main/java/at/gv/egiz/moazs/scheme/MzsDeliveryRequestValidator.java)2
-rw-r--r--src/main/java/at/gv/egiz/moazs/process/DeliveryPipeline.java (renamed from src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java)2
-rw-r--r--src/main/java/at/gv/egiz/moazs/process/MsgResponseHandler.java7
-rw-r--r--src/main/java/at/gv/egiz/moazs/process/MsgResponseSink.java11
-rw-r--r--src/main/java/at/gv/egiz/moazs/process/SafeResponseToFileSink.java84
-rw-r--r--src/main/java/at/gv/egiz/moazs/process/SingleNodeResponseHandler.java26
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java10
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java37
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java16
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java15
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java9
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java67
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java87
-rw-r--r--src/main/java/at/gv/egiz/moazs/service/MsgService.java74
-rw-r--r--src/main/java/at/gv/egiz/moazs/service/MzsService.java (renamed from src/main/java/at/gv/egiz/moazs/scheme/MzsService.java)20
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/ClientFactory.java4
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java41
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java2
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java38
-rw-r--r--src/main/java/at/gv/egiz/moazs/verify/MsgResponseVerifier.java59
-rw-r--r--src/main/resources/application.yaml4
-rw-r--r--src/main/resources/zusemsg/zuse2app_p2.wsdl81
-rw-r--r--src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java2
-rw-r--r--src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java2
-rw-r--r--src/test/java/at/gv/egiz/moazs/ITMsgClientTest.java2
-rw-r--r--src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java5
-rw-r--r--src/test/java/at/gv/egiz/moazs/SafeResponseToFileSinkTest.java113
-rw-r--r--src/test/java/at/gv/egiz/moazs/SingleThreadedDeliveryPipelineTest.java78
-rw-r--r--src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java2
40 files changed, 984 insertions, 247 deletions
diff --git a/pom.xml b/pom.xml
index bd135fc..5ad5d11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -196,6 +196,10 @@
<wsdl>${project.basedir}/src/main/resources/zusetnvz/zuse2tnvz_p2.wsdl</wsdl>
<wsdlLocation>classpath:zusetnvz/app2zuse_p2.wsdl</wsdlLocation>
</wsdlOption>
+ <wsdlOption>
+ <wsdl>${project.basedir}/src/main/resources/zusemsg/zuse2app_p2.wsdl</wsdl>
+ <wsdlLocation>classpath:zusemsg/zuse2app_p2.wsdl</wsdlLocation>
+ </wsdlOption>
</wsdlOptions>
</configuration>
<goals>
@@ -244,6 +248,8 @@
<excludes>
<exclude>${exclude-test-pattern}</exclude>
</excludes>
+ <trimStackTrace>false</trimStackTrace>
+ <useFile>false</useFile>
</configuration>
</plugin>
diff --git a/src/main/java/at/gv/egiz/moazs/MoaZSException.java b/src/main/java/at/gv/egiz/moazs/MoaZSException.java
index 322f06b..1e86c22 100644
--- a/src/main/java/at/gv/egiz/moazs/MoaZSException.java
+++ b/src/main/java/at/gv/egiz/moazs/MoaZSException.java
@@ -1,10 +1,13 @@
package at.gv.egiz.moazs;
-import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
-import at.gv.zustellung.msg.xsd.DeliveryRequestType;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+import at.gv.zustellung.msg.xsd.PreAdviceNoteSentType;
import at.gv.zustellung.tnvz.xsd.PersonResultType;
import org.springframework.lang.Nullable;
+import java.util.concurrent.ExecutorService;
+
+
public class MoaZSException extends RuntimeException {
public static final String ERROR_MZS_MIMETYPE_MISSMATCH = "8001";
@@ -14,25 +17,29 @@ public class MoaZSException extends RuntimeException {
@Nullable
private final String errorCode;
@Nullable
- private final PersonResultType tnvzResult;
+ private final PreAdviceNoteSentType preAdviceNoteSent;
+ @Nullable
+ private final String deliverySystem;
@Nullable
- private final DeliveryRequestStatusType msgResult;
+ private final String gz;
@Nullable
- private final DeliveryRequestType msgRequest;
+ private final String zsDeliveryID;
@Nullable
- private final at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest;
+ private final String appDeliveryID;
- private MoaZSException(String message, Throwable cause, String errorCode, PersonResultType tnvzResult,
- DeliveryRequestStatusType msgResult, DeliveryRequestType msgRequest,
- at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest) {
+ private MoaZSException(String message, @Nullable Throwable cause, @Nullable String errorCode, @Nullable PreAdviceNoteSentType preAdviceNoteSent,
+ @Nullable String deliverySystem, @Nullable String gz, @Nullable String zsDeliveryID,
+ @Nullable String appDeliveryID) {
super(message, cause);
this.errorCode = errorCode;
- this.tnvzResult = tnvzResult;
- this.msgResult = msgResult;
- this.msgRequest = msgRequest;
- this.mzsRequest = mzsRequest;
+ this.preAdviceNoteSent = preAdviceNoteSent;
+ this.deliverySystem = deliverySystem;
+ this.gz = gz;
+ this.zsDeliveryID = zsDeliveryID;
+ this.appDeliveryID = appDeliveryID;
}
+
public static MoaZSException moaZSException(String message, Throwable cause) {
return moaZSExceptionBuilder(message).withCause(cause).build();
}
@@ -63,23 +70,28 @@ public class MoaZSException extends RuntimeException {
}
@Nullable
- public PersonResultType getTnvzResult() {
- return tnvzResult;
+ public PreAdviceNoteSentType getPreAdviceNoteSent() {
+ return preAdviceNoteSent;
+ }
+
+ @Nullable
+ public String getDeliverySystem() {
+ return deliverySystem;
}
@Nullable
- public DeliveryRequestStatusType getMsgResult() {
- return msgResult;
+ public String getGz() {
+ return gz;
}
@Nullable
- public at.gv.zustellung.app2mzs.xsd.DeliveryRequestType getMzsRequest() {
- return mzsRequest;
+ public String getZsDeliveryID() {
+ return zsDeliveryID;
}
@Nullable
- public DeliveryRequestType getMsgRequest() {
- return msgRequest;
+ public String getAppDeliveryID() {
+ return appDeliveryID;
}
public static class Builder {
@@ -87,14 +99,26 @@ public class MoaZSException extends RuntimeException {
private String message;
private Throwable cause;
private String errorCode;
- private PersonResultType tnvzResult;
- private DeliveryRequestStatusType msgResult;
- private DeliveryRequestType msgRequest;
- private at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest;
+ private PreAdviceNoteSentType preAdviceNoteSent;
+ private String deliverySystem;
+ private String gz;
+ private String zsDeliveryID;
+ private String appDeliveryID;
private Builder() {
}
+ public Builder(MoaZSException exception){
+ this.message = exception.getMessage();
+ this.cause = exception.getCause();
+ this.errorCode = exception.getErrorCode();
+ this.preAdviceNoteSent = exception.getPreAdviceNoteSent();
+ this.deliverySystem = exception.getDeliverySystem();
+ this.gz = exception.getGz();
+ this.zsDeliveryID = exception.getZsDeliveryID();
+ this.appDeliveryID = exception.getAppDeliveryID();
+ }
+
public Builder withMessage(String message) {
this.message = message;
return this;
@@ -115,28 +139,35 @@ public class MoaZSException extends RuntimeException {
return this;
}
- public Builder withTnvzResult(PersonResultType tnvzResult) {
- this.tnvzResult = tnvzResult;
+ public Builder withPreAdviceNoteSent(PersonResultType personResult) {
+ if (personResult.getError() != null) {
+ this.preAdviceNoteSent = personResult.getError().getPreAdviceNoteSent();
+ }
return this;
}
- public Builder withMsgResult(DeliveryRequestStatusType msgResult) {
- this.msgResult = msgResult;
+ public Builder withDeliverySystem(at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest) {
+ this.deliverySystem = mzsRequest.getConfig().getMSGClient().getURL();
return this;
}
- public Builder withMsgRequest(DeliveryRequestType msgRequest) {
- this.msgRequest = msgRequest;
+
+ public Builder withAllParametersInAnswer(DeliveryAnswerType answer) {
+ this.deliverySystem = answer.getDeliverySystem();
+ this.gz = answer.getGZ();
+ this.zsDeliveryID = answer.getZSDeliveryID();
+ this.appDeliveryID = answer.getAppDeliveryID();
return this;
}
- public Builder withMzsRequest(at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest) {
- this.mzsRequest = mzsRequest;
+ public Builder withAppDeliveryID(String appDeliveryID) {
+ this.appDeliveryID = appDeliveryID;
return this;
}
public MoaZSException build() {
- return new MoaZSException(message, cause, errorCode, tnvzResult, msgResult, msgRequest, mzsRequest);
+ return new MoaZSException(message, cause, errorCode, preAdviceNoteSent, deliverySystem, gz,
+ zsDeliveryID, appDeliveryID);
}
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/MzsClient.java b/src/main/java/at/gv/egiz/moazs/client/MzsClient.java
index 98e0bc8..a8f1d27 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/MzsClient.java
+++ b/src/main/java/at/gv/egiz/moazs/client/MzsClient.java
@@ -1,4 +1,4 @@
-package at.gv.egiz.moazs.scheme;
+package at.gv.egiz.moazs.client;
import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
import org.springframework.stereotype.Component;
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java
index 70c20bb..884be3e 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java
+++ b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java
@@ -1,4 +1,4 @@
-package at.gv.egiz.moazs.scheme;
+package at.gv.egiz.moazs.client;
import at.gv.egiz.moazs.MoaZSException;
import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
@@ -187,7 +187,8 @@ public class TnvzHelper {
}
var tnvzResult = results.get(0);
- mzsBuilder.withTnvzResult(tnvzResult);
+ mzsBuilder.withPreAdviceNoteSent(tnvzResult);
+
if (tnvzResult.getError() != null) {
var info = tnvzResult.getError().getErrorInfo();
throw mzsBuilder.withErrorCode(info.getCode())
diff --git a/src/main/java/at/gv/egiz/moazs/config/MzsServiceConfig.java b/src/main/java/at/gv/egiz/moazs/config/MzsServiceConfig.java
deleted file mode 100644
index 9fd14eb..0000000
--- a/src/main/java/at/gv/egiz/moazs/config/MzsServiceConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package at.gv.egiz.moazs.config;
-
-import at.gv.egiz.moazs.scheme.MzsService;
-import at.gv.zustellung.app2mzs.xsd.App2Mzs;
-import org.apache.cxf.Bus;
-import org.apache.cxf.jaxws.EndpointImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import javax.xml.ws.Endpoint;
-
-@Configuration
-public class MzsServiceConfig {
-
- @Bean
- @Autowired
- public Endpoint endpoint(Bus bus, MzsService mzsService, App2Mzs app2mzs) {
- EndpointImpl endpoint = new EndpointImpl(bus, mzsService);
- endpoint.setAddress("/");
- endpoint.setServiceName(app2mzs.getServiceName());
- endpoint.setWsdlLocation(app2mzs.getWSDLDocumentLocation().toString());
- endpoint.publish();
- return endpoint;
- }
-
- @Bean public App2Mzs app2mzs() {
- return new App2Mzs();
- }
-}
diff --git a/src/main/java/at/gv/egiz/moazs/config/PreprocessConfig.java b/src/main/java/at/gv/egiz/moazs/config/PreprocessConfig.java
index b24db28..76bfb30 100644
--- a/src/main/java/at/gv/egiz/moazs/config/PreprocessConfig.java
+++ b/src/main/java/at/gv/egiz/moazs/config/PreprocessConfig.java
@@ -1,6 +1,6 @@
package at.gv.egiz.moazs.config;
-import at.gv.egiz.moazs.scheme.MzsDeliveryRequestValidator;
+import at.gv.egiz.moazs.preprocess.MzsDeliveryRequestValidator;
import at.gv.egiz.moazs.preprocess.*;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/src/main/java/at/gv/egiz/moazs/config/RepositoryConfig.java b/src/main/java/at/gv/egiz/moazs/config/RepositoryConfig.java
new file mode 100644
index 0000000..ee73b9e
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/config/RepositoryConfig.java
@@ -0,0 +1,32 @@
+package at.gv.egiz.moazs.config;
+
+import at.gv.egiz.moazs.repository.BinaryRepository;
+import at.gv.egiz.moazs.repository.InMemoryBinaryRepository;
+import at.gv.egiz.moazs.scheme.NameSpace;
+import at.gv.egiz.moazs.scheme.NotificationResponse;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+import java.util.Map;
+
+@Configuration
+@Profile("!cluster")
+public class RepositoryConfig {
+
+ @Value("${repository.expiresAfterWrite}")
+ private int expiresAfterWrite;
+
+ @Bean
+ public BinaryRepository binaryRepository() {
+ return new InMemoryBinaryRepository(expiresAfterWrite);
+ }
+
+ @Bean
+ public Map<String, String> idSuffixes() {
+ return Map.of(NameSpace.MSG_DELIVERY_REQUEST_STATUS, RequestStatusResponse.getIdSuffix(),
+ NameSpace.MSG_DELIVERY_NOTIFICATION, NotificationResponse.getIdSuffix());
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java b/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java
new file mode 100644
index 0000000..8e354ab
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/config/ServicesConfig.java
@@ -0,0 +1,46 @@
+package at.gv.egiz.moazs.config;
+
+import at.gv.egiz.moazs.service.MsgService;
+import at.gv.egiz.moazs.service.MzsService;
+import at.gv.egiz.moazs.util.EndpointFactory;
+import at.gv.egiz.moazs.util.StoreSOAPBodyBinaryInRepositoryInterceptor;
+import at.gv.zustellung.app2mzs.xsd.App2Mzs;
+import at.gv.zustellung.msg.xsd.Zuse2AppPortService;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Message;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.xml.ws.Endpoint;
+
+@Configuration
+public class ServicesConfig {
+
+ @Autowired
+ private EndpointFactory endpointFactory;
+
+ @Bean
+ @Autowired
+ public Endpoint msgEndpoint(MsgService msgService,
+ Zuse2AppPortService zuse2app,
+ Interceptor<Message> msgInterceptor) {
+ return endpointFactory.create(msgService, zuse2app, msgInterceptor);
+ }
+
+ @Bean
+ @Autowired
+ public Endpoint mzsEndpoint(MzsService mzsService, App2Mzs app2mzs) {
+ return endpointFactory.create(mzsService, app2mzs);
+ }
+
+ @Bean
+ public Zuse2AppPortService zuse2App() {
+ return new Zuse2AppPortService();
+ }
+
+ @Bean public App2Mzs app2mzs() {
+ return new App2Mzs();
+ }
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/pipeline/SingleThreadedDeliveryPipeline.java b/src/main/java/at/gv/egiz/moazs/pipeline/SingleThreadedDeliveryPipeline.java
index 783df32..69065d7 100644
--- a/src/main/java/at/gv/egiz/moazs/pipeline/SingleThreadedDeliveryPipeline.java
+++ b/src/main/java/at/gv/egiz/moazs/pipeline/SingleThreadedDeliveryPipeline.java
@@ -1,17 +1,17 @@
-package at.gv.egiz.moazs.pipeline;
+package at.gv.egiz.moazs.process;
import at.gv.egiz.moazs.MoaZSException;
-import at.gv.egiz.moazs.util.ClientFactory;
+import at.gv.egiz.moazs.client.ClientFactory;
+import at.gv.egiz.moazs.client.TnvzHelper;
+import at.gv.egiz.moazs.repository.BinaryRepository;
import at.gv.egiz.moazs.repository.DeliveryRepository;
import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
-import at.gv.egiz.moazs.scheme.NameSpace;
-import at.gv.egiz.moazs.scheme.TnvzHelper;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import at.gv.egiz.moazs.verify.MsgResponseVerifier;
import at.gv.egiz.moazs.verify.SignatureVerifier;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import at.gv.zustellung.msg.xsd.App2ZusePort;
-import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
-import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import at.gv.zustellung.tnvz.xsd.TNVZServicePort;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,10 +19,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder;
-import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
-import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Error.errorBuilder;
-import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
-import static at.gv.zustellung.msg.xsd.ErrorInfoType.errorInfoTypeBuilder;
+import static at.gv.egiz.moazs.scheme.RequestStatusResponse.generateErrorFromException;
import static java.lang.String.format;
@Component
@@ -30,8 +27,11 @@ import static java.lang.String.format;
public class SingleThreadedDeliveryPipeline implements DeliveryPipeline {
private static final Logger log = Logger.getLogger(SingleThreadedDeliveryPipeline.class);
+ private static final String MZS_PIPELINE_ERROR_MSG =
+ "An error occured while processing the DeliveryRequest with AppDeliveryID=%s. ";
private final DeliveryRepository repository;
+ private final BinaryRepository binaryRepository;
private final TnvzHelper tnvzHelper;
private final Mzs2MsgConverter converter;
private final ClientFactory clientFactory;
@@ -39,12 +39,13 @@ public class SingleThreadedDeliveryPipeline implements DeliveryPipeline {
@Autowired
public SingleThreadedDeliveryPipeline(DeliveryRepository repository,
+ BinaryRepository binaryStatusRepository,
TnvzHelper tnvzHelper,
Mzs2MsgConverter converter,
ClientFactory clientFactory,
- SignatureVerifier verifier
- ) {
+ SignatureVerifier verifier) {
this.repository = repository;
+ this.binaryRepository = binaryStatusRepository;
this.tnvzHelper = tnvzHelper;
this.converter = converter;
this.clientFactory = clientFactory;
@@ -58,89 +59,49 @@ public class SingleThreadedDeliveryPipeline implements DeliveryPipeline {
try {
var mzsRequest = repository.getDeliveryRequest(appDeliveryId).orElseThrow();
- exceptionBuilder.withMzsRequest(mzsRequest);
+ exceptionBuilder.withDeliverySystem(mzsRequest);
at.gv.zustellung.msg.xsd.DeliveryRequestType msgRequest = buildMsgRequest(mzsRequest, exceptionBuilder);
- exceptionBuilder.withMsgRequest(msgRequest);
var msgClientParams = mzsRequest.getConfig().getMSGClient();
App2ZusePort client = clientFactory.create(msgClientParams, App2ZusePort.class);
var status = client.delivery(msgRequest);
- exceptionBuilder.withMsgResult(status);
- verifySignedStatus(appDeliveryId, exceptionBuilder);
- repository.add(status);
+ var response = new RequestStatusResponse(status);
+ exceptionBuilder.withAllParametersInAnswer(response.getAnswer());
- } catch (MoaZSException exception) {
-
- log.error(format("An error occured while processing the DeliveryRequest with AppDeliveryID=%s. ",
- appDeliveryId), exception);
-
- var errorStatus = generateErrorStatus(exception, appDeliveryId);
- repository.add(errorStatus);
- }
- }
+ verifySignedStatus(response.getResponseID(), exceptionBuilder);
+ repository.add(response);
- private at.gv.zustellung.msg.xsd.DeliveryRequestType buildMsgRequest(DeliveryRequestType mzsRequest,
- MoaZSException.Builder exceptionBuilder) {
- if (mzsRequest.getConfig().isPerformQueryPersonRequest()) {
- var tnvzClientParams = mzsRequest.getConfig().getTNVZClient();
- TNVZServicePort tvnzPort = clientFactory.create(tnvzClientParams, TNVZServicePort.class);
- var identification = tnvzHelper.performQueryPersonRequest(mzsRequest, tvnzPort, exceptionBuilder);
- return converter.convert(mzsRequest, identification);
- } else {
- return converter.convert(mzsRequest);
+ } catch (MoaZSException exception) {
+ log.error(format(MZS_PIPELINE_ERROR_MSG, appDeliveryId), exception);
+ var errorResponse = generateErrorFromException(exception);
+ repository.add(errorResponse);
}
}
private void verifySignedStatus(String appDeliveryId, MoaZSException.Builder exceptionBuilder) throws MoaZSException {
-
try {
- var signedStatus = repository.getSignedDeliveryRequestStatus(appDeliveryId).get();
+ var signedStatus = binaryRepository.get(appDeliveryId).get();
verifier.verify(signedStatus);
- } catch (Exception ex) {
- throw exceptionBuilder.withMessage(format("Signature of DeliveryRequestStatus with AppDeliveryID=%s " +
- " is not valid.", appDeliveryId))
+ } catch (MoaZSException ex) {
+ throw exceptionBuilder.withMessage(format(MsgResponseVerifier.MOASP_SIGNATURE_INVALID_ERROR_MSG, appDeliveryId))
.withErrorCode(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID)
.withCause(ex)
.build();
}
}
- private DeliveryRequestStatusType generateErrorStatus(MoaZSException exception, String appDeliveryId) {
-
- var infoBuilder = errorInfoTypeBuilder()
- .withText(exception.getMessage())
- .withCode(exception.getErrorCode());
-
- var errorBuilder = errorBuilder()
- .withErrorInfo(infoBuilder.build())
- .withAppDeliveryID(appDeliveryId);
-
- if (exception.getMzsRequest() != null) {
- errorBuilder.withDeliverySystem(exception.getMzsRequest().getConfig().getMSGClient().getURL());
- }
-
- if (exception.getTnvzResult() != null && exception.getTnvzResult().getError() != null) {
- errorBuilder.withPreAdviceNoteSent(exception.getTnvzResult().getError().getPreAdviceNoteSent());
- }
-
- if (exception.getMsgResult() != null) {
- var answer = getAnswerFromResult(exception.getMsgResult());
- errorBuilder.withGZ(answer.getGZ());
- errorBuilder.withZSDeliveryID(answer.getZSDeliveryID());
+ private at.gv.zustellung.msg.xsd.DeliveryRequestType buildMsgRequest(DeliveryRequestType mzsRequest,
+ MoaZSException.Builder exceptionBuilder) throws MoaZSException {
+ if (mzsRequest.getConfig().isPerformQueryPersonRequest()) {
+ var tnvzClientParams = mzsRequest.getConfig().getTNVZClient();
+ TNVZServicePort tvnzPort = clientFactory.create(tnvzClientParams, TNVZServicePort.class);
+ var identification = tnvzHelper.performQueryPersonRequest(mzsRequest, tvnzPort, exceptionBuilder);
+ return converter.convert(mzsRequest, identification);
+ } else {
+ return converter.convert(mzsRequest);
}
-
- return deliveryRequestStatusTypeBuilder()
- .withError(errorBuilder.build())
- .withVersion(NameSpace.MSG_VERSION)
- .build();
-
- }
-
- private DeliveryAnswerType getAnswerFromResult(DeliveryRequestStatusType msgResult) {
- return coalesce(msgResult.getSuccess(), msgResult.getPartialSuccess(), msgResult.getError()).get();
}
-
}
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 d651570..5e81f0d 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
@@ -1,7 +1,6 @@
package at.gv.egiz.moazs.preprocess;
import at.gv.egiz.moazs.MoaZSException;
-import at.gv.egiz.moazs.scheme.MzsDeliveryRequestValidator;
import at.gv.egiz.moazs.util.StringUtils;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
import org.slf4j.Logger;
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 783536c..eac7ea6 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java
@@ -1,6 +1,5 @@
package at.gv.egiz.moazs.preprocess;
-import at.gv.egiz.moazs.scheme.MzsDeliveryRequestValidator;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/MzsDeliveryRequestValidator.java b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
index 03f2664..8f9cd27 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/MzsDeliveryRequestValidator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
@@ -1,4 +1,4 @@
-package at.gv.egiz.moazs.scheme;
+package at.gv.egiz.moazs.preprocess;
import at.gv.zustellung.app2mzs.xsd.ClientType;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
diff --git a/src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java b/src/main/java/at/gv/egiz/moazs/process/DeliveryPipeline.java
index f32dfe2..506dd1f 100644
--- a/src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java
+++ b/src/main/java/at/gv/egiz/moazs/process/DeliveryPipeline.java
@@ -1,4 +1,4 @@
-package at.gv.egiz.moazs.pipeline;
+package at.gv.egiz.moazs.process;
public interface DeliveryPipeline {
diff --git a/src/main/java/at/gv/egiz/moazs/process/MsgResponseHandler.java b/src/main/java/at/gv/egiz/moazs/process/MsgResponseHandler.java
new file mode 100644
index 0000000..5a7d39b
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/process/MsgResponseHandler.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.moazs.process;
+
+public interface MsgResponseHandler {
+
+ void handle(String id);
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/process/MsgResponseSink.java b/src/main/java/at/gv/egiz/moazs/process/MsgResponseSink.java
new file mode 100644
index 0000000..67348fc
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/process/MsgResponseSink.java
@@ -0,0 +1,11 @@
+package at.gv.egiz.moazs.process;
+
+import at.gv.egiz.moazs.scheme.MsgResponse;
+
+import java.util.concurrent.CompletableFuture;
+
+public interface MsgResponseSink {
+
+ CompletableFuture<Void> handle(MsgResponse response);
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/process/SafeResponseToFileSink.java b/src/main/java/at/gv/egiz/moazs/process/SafeResponseToFileSink.java
new file mode 100644
index 0000000..ee32768
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/process/SafeResponseToFileSink.java
@@ -0,0 +1,84 @@
+package at.gv.egiz.moazs.process;
+
+import at.gv.egiz.moazs.repository.BinaryRepository;
+import at.gv.egiz.moazs.scheme.Marshaller;
+import at.gv.egiz.moazs.scheme.MsgResponse;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.CompletableFuture;
+
+import static java.lang.String.format;
+import static java.util.concurrent.CompletableFuture.allOf;
+import static java.util.concurrent.CompletableFuture.supplyAsync;
+
+@Component
+public class SafeResponseToFileSink implements MsgResponseSink {
+
+ private static final Logger log = LoggerFactory.getLogger(SafeResponseToFileSink.class);
+ private static final String SAFING_FAILED_MSG = "Could not save response with AppDeliveryId=%s.";
+ private static final SimpleDateFormat ISO_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+ private final Marshaller msgMarshaller;
+ private final BinaryRepository binaryRepository;
+ private final String root;
+
+
+ @Autowired
+ public SafeResponseToFileSink(Marshaller msgMarshaller, BinaryRepository binaryRepository, String root) {
+ this.msgMarshaller = msgMarshaller;
+ this.binaryRepository = binaryRepository;
+ this.root = root;
+ }
+
+ @Override
+ public CompletableFuture<Void> handle(MsgResponse response) {
+
+ var responseId = response.getResponseID();
+
+ var responsePath = generatePath(responseId, "xml");
+ var storeResponseToFileSystemFuture = supplyAsync(() -> msgMarshaller.marshallXml(response.getResponse()))
+ .thenApply(responseString -> responseString.getBytes(StandardCharsets.UTF_8))
+ .thenAccept(responseByteArray -> storeToFile(responsePath, responseByteArray))
+ .exceptionally((ex) -> logException(ex, responseId));
+
+ var binaryResponsePath = generatePath(responseId, "binary.xml");
+ var storeBinaryResponseToFileSystemFuture = supplyAsync(() -> binaryRepository.get(responseId).get())
+ .thenAccept(binaryResponseByteArray -> storeToFile(binaryResponsePath, binaryResponseByteArray))
+ .exceptionally((ex) -> logException(ex, responseId));
+
+ return allOf(storeResponseToFileSystemFuture, storeBinaryResponseToFileSystemFuture);
+
+ }
+
+ private String generatePath(String id, String suffix) {
+ var folder = sanitizeFileString(id);
+ var iso8601_now = ISO_FORMATTER.format(new Date());
+ return format("%s/%s/%s.%s", root, folder, iso8601_now, suffix);
+ }
+
+ private String sanitizeFileString(String fileString) {
+ return fileString.replaceAll("[^a-zA-Z0-9\\._\\-]", "");
+ }
+
+ private Void logException(Throwable ex, String appDeliveryID) {
+ log.error(format(SAFING_FAILED_MSG, appDeliveryID), ex);
+ return null;
+ }
+
+ private void storeToFile(String path, byte[] content) {
+ try {
+ FileUtils.writeByteArrayToFile(new File(path), content);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/process/SingleNodeResponseHandler.java b/src/main/java/at/gv/egiz/moazs/process/SingleNodeResponseHandler.java
new file mode 100644
index 0000000..ec609cb
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/process/SingleNodeResponseHandler.java
@@ -0,0 +1,26 @@
+package at.gv.egiz.moazs.process;
+
+import at.gv.egiz.moazs.verify.MsgResponseVerifier;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import static java.util.concurrent.CompletableFuture.supplyAsync;
+
+@Component
+public class SingleNodeResponseHandler implements MsgResponseHandler {
+
+ private final MsgResponseVerifier verifier;
+ private final MsgResponseSink sink;
+
+ @Autowired
+ public SingleNodeResponseHandler(MsgResponseVerifier verifier, MsgResponseSink sink) {
+ this.verifier = verifier;
+ this.sink = sink;
+ }
+
+ @Override
+ public void handle(String id) {
+ supplyAsync(() -> verifier.verify(id))
+ .thenAcceptAsync((response) -> sink.handle(response));
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
index be61d1e..d0a8148 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
@@ -1,6 +1,8 @@
package at.gv.egiz.moazs.repository;
+import at.gv.egiz.moazs.scheme.MsgResponse;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
+import at.gv.zustellung.msg.xsd.DeliveryNotificationType;
import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import org.springframework.stereotype.Repository;
@@ -13,13 +15,9 @@ public interface DeliveryRepository {
Optional<DeliveryRequestType> getDeliveryRequest(String appDeliveryID);
- void add(DeliveryRequestStatusType status);
+ void add(MsgResponse response);
- Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID);
-
- void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId);
-
- Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID);
+ Optional<MsgResponse> getResponse(String id);
}
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 58ec92c..d9abb7b 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
@@ -1,36 +1,27 @@
package at.gv.egiz.moazs.repository;
+import at.gv.egiz.moazs.scheme.MsgResponse;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
-import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
-import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
import static java.util.Optional.ofNullable;
@Repository
@Profile("!cluster")
public class InMemoryDeliveryRepository implements DeliveryRepository {
- private static final Logger logger = LoggerFactory.getLogger(InMemoryDeliveryRepository.class);
-
- private static final Cache<String, DeliveryRequestType> requestRepository = CacheBuilder.newBuilder()
+ private final Cache<String, DeliveryRequestType> requestRepository = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
- private static final Cache<String, DeliveryRequestStatusType> statusRepository = CacheBuilder.newBuilder()
- .expireAfterWrite(30, TimeUnit.MINUTES)
- .build();
-
- private static final Cache<String, byte[]> signedStatusRepository = CacheBuilder.newBuilder()
+ private final Cache<String, MsgResponse> responseRepository = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
@@ -46,24 +37,14 @@ public class InMemoryDeliveryRepository implements DeliveryRepository {
}
@Override
- public void add(DeliveryRequestStatusType status) {
- var key = coalesce(status.getSuccess(), status.getPartialSuccess(), status.getError())
- .get().getAppDeliveryID();
- statusRepository.put(key, status);
- }
-
- @Override
- public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
- return ofNullable(statusRepository.getIfPresent(appDeliveryID));
- }
-
- @Override
- public void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId) {
- signedStatusRepository.put(appDeliveryId, bytes);
+ public void add(MsgResponse response) {
+ String key = response.getResponseID();
+ System.out.println("storing with response id " + key);
+ responseRepository.put(key, response);
}
@Override
- public Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID) {
- return ofNullable(signedStatusRepository.getIfPresent(appDeliveryID));
+ public Optional<MsgResponse> getResponse(String id) {
+ return ofNullable(responseRepository.getIfPresent(id));
}
}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
index 9b7aefd..7ccd236 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
@@ -1,7 +1,9 @@
package at.gv.egiz.moazs.repository;
import at.gv.egiz.moazs.scheme.Marshaller;
+import at.gv.egiz.moazs.scheme.MsgResponse;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
+import at.gv.zustellung.msg.xsd.DeliveryNotificationType;
import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import at.gv.zustellung.app2mzs.xsd.ObjectFactory;
import org.apache.tools.ant.filters.StringInputStream;
@@ -50,7 +52,7 @@ public class RedisDeliveryRepository implements DeliveryRepository {
@Override
public Optional<DeliveryRequestType> getDeliveryRequest(String appDeliveryID) {
- var serializedRequest = hashOperations.get(KEY, appDeliveryID);
+ String serializedRequest = hashOperations.get(KEY, appDeliveryID);
if (serializedRequest == null) {
return Optional.empty();
@@ -62,22 +64,14 @@ public class RedisDeliveryRepository implements DeliveryRepository {
}
@Override
- public void add(DeliveryRequestStatusType status) {
+ public void add(MsgResponse notification) {
throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
- }
- @Override
- public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
- throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
}
@Override
- public void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId) {
+ public Optional<MsgResponse> getResponse(String id) {
throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
}
- @Override
- public Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID) {
- return Optional.empty();
- }
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java b/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java
new file mode 100644
index 0000000..fe46451
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java
@@ -0,0 +1,15 @@
+package at.gv.egiz.moazs.scheme;
+
+import at.gv.egiz.moazs.MoaZSException;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+
+public interface MsgResponse <T> {
+
+ String getResponseID();
+ T getResponse();
+ String getAppDeliveryID();
+ String getZSDeliveryID();
+ DeliveryAnswerType getAnswer();
+ MsgResponse<T> generateError(MoaZSException exception);
+
+}
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 7c52af1..bb7f621 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java
@@ -4,12 +4,17 @@ public class NameSpace {
private NameSpace() {}
- public static final String MSG = new at.gv.zustellung.msg.xsd.ObjectFactory().createDeliveryRequest(null).getName().getNamespaceURI();
+ private static final at.gv.zustellung.msg.xsd.ObjectFactory MSG_FACTORY = new at.gv.zustellung.msg.xsd.ObjectFactory();
+
public static final String MSG_VERSION = "2.2.0";
+ public static final String MSG = MSG_FACTORY.createDeliveryRequest(null).getName().getNamespaceURI();
public static final String MSGP = new at.gv.zustellung.msg.xsd.persondata.ObjectFactory().createPerson(null).getName().getNamespaceURI();
- public static final String MZS = new at.gv.zustellung.app2mzs.xsd.ObjectFactory().createDeliveryRequest(null).getName().getNamespaceURI();
+ public static final String MZS = new at.gv.zustellung.app2mzs.xsd.ObjectFactory().createDeliveryRequest(null).getName().getNamespaceURI();
public static final String TNVZ = new at.gv.zustellung.tnvz.xsd.ObjectFactory().createAddressabilityQuery(null).getName().getNamespaceURI();
public static final String MZSP = new at.gv.zustellung.app2mzs.xsd.persondata.ObjectFactory().createAbstractPersonData(null).getName().getNamespaceURI();
public static final String DSIG = new org.w3._2000._09.xmldsig_.ObjectFactory().createCanonicalizationMethod(null).getName().getNamespaceURI();
+ public static final String MSG_DELIVERY_REQUEST_STATUS = MSG_FACTORY.createDeliveryRequestStatus(null).getName().getLocalPart();
+ public static final String MSG_DELIVERY_NOTIFICATION = MSG_FACTORY.createDeliveryNotification(null).getName().getLocalPart();
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java b/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java
new file mode 100644
index 0000000..f465a28
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java
@@ -0,0 +1,67 @@
+package at.gv.egiz.moazs.scheme;
+
+import at.gv.egiz.moazs.MoaZSException;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+import at.gv.zustellung.msg.xsd.DeliveryNotificationType;
+
+import static at.gv.zustellung.msg.xsd.DeliveryNotificationType.deliveryNotificationTypeBuilder;
+
+public class NotificationResponse implements MsgResponse<DeliveryNotificationType> {
+
+ private final DeliveryNotificationType notification;
+ private final String id;
+ private static final String ID_SUFFIX = ".NO";
+
+ public NotificationResponse(DeliveryNotificationType notification) {
+ this.notification = notification;
+ this.id = getId(notification.getAppDeliveryID());
+ }
+
+ @Override
+ public String getResponseID() {
+ return this.id;
+ }
+
+ public static String getId(String appDeliveryID) {
+ return appDeliveryID + ID_SUFFIX;
+ }
+
+ @Override
+ public DeliveryNotificationType getResponse() {
+ return notification;
+ }
+
+ @Override
+ public String getAppDeliveryID() {
+ return notification.getAppDeliveryID();
+ }
+
+ @Override
+ public String getZSDeliveryID() {
+ return notification.getZSDeliveryID();
+ }
+
+ @Override
+ public DeliveryAnswerType getAnswer() {
+ return notification;
+ }
+
+ @Override
+ public MsgResponse<DeliveryNotificationType> generateError(MoaZSException exception) {
+
+ //TODO: test this!
+ var notification = deliveryNotificationTypeBuilder()
+ .withAppDeliveryID(exception.getAppDeliveryID())
+ .withDeliverySystem(exception.getDeliverySystem())
+ .withGZ(exception.getGz())
+ .withZSDeliveryID(exception.getZsDeliveryID())
+ .build();
+
+ return new NotificationResponse(notification);
+
+ }
+
+ public static String getIdSuffix() {
+ return ID_SUFFIX;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java b/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java
new file mode 100644
index 0000000..89c8be3
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java
@@ -0,0 +1,87 @@
+package at.gv.egiz.moazs.scheme;
+
+import at.gv.egiz.moazs.MoaZSException;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
+import at.gv.zustellung.msg.xsd.ErrorInfoType;
+
+import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Error.errorBuilder;
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
+import static at.gv.zustellung.msg.xsd.ErrorInfoType.errorInfoTypeBuilder;
+
+public class RequestStatusResponse implements MsgResponse<DeliveryRequestStatusType> {
+
+ private final DeliveryRequestStatusType status;
+ private final DeliveryAnswerType answer;
+ private final String responseID;
+ private static final String ID_SUFFIX = ".RS";
+
+ public RequestStatusResponse(DeliveryRequestStatusType status) {
+ this.status = status;
+ this.answer = coalesce(status.getSuccess(), status.getPartialSuccess(), status.getError()).get();
+ this.responseID = getResponseID(answer.getAppDeliveryID());
+ }
+
+ public static String getResponseID(String appDeliveryID) {
+ return appDeliveryID + ID_SUFFIX;
+ }
+
+ @Override
+ public String getResponseID() {
+ return this.responseID;
+ }
+
+ @Override
+ public DeliveryRequestStatusType getResponse() {
+ return status;
+ }
+
+ @Override
+ public String getAppDeliveryID() {
+ return answer.getAppDeliveryID();
+ }
+
+ @Override
+ public String getZSDeliveryID() {
+ return answer.getZSDeliveryID();
+ }
+
+ @Override
+ public DeliveryAnswerType getAnswer() {
+ return this.answer;
+ }
+
+ @Override
+ public MsgResponse<DeliveryRequestStatusType> generateError(MoaZSException exception) {
+ return generateErrorFromException(exception);
+ }
+
+ public static MsgResponse<DeliveryRequestStatusType> generateErrorFromException(MoaZSException exception) {
+ ErrorInfoType info = errorInfoTypeBuilder()
+ .withText(exception.getMessage())
+ .withCode(exception.getErrorCode())
+ .build();
+
+ DeliveryRequestStatusType.Error error = errorBuilder()
+ .withErrorInfo(info)
+ .withAppDeliveryID(exception.getAppDeliveryID())
+ .withDeliverySystem(exception.getDeliverySystem())
+ .withGZ(exception.getGz())
+ .withPreAdviceNoteSent(exception.getPreAdviceNoteSent())
+ .withZSDeliveryID(exception.getZsDeliveryID())
+ .build();
+
+ var status = deliveryRequestStatusTypeBuilder()
+ .withError(error)
+ .withVersion(NameSpace.MSG_VERSION)
+ .build();
+
+ return new RequestStatusResponse(status);
+
+ }
+
+ public static String getIdSuffix() {
+ return ID_SUFFIX;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/service/MsgService.java b/src/main/java/at/gv/egiz/moazs/service/MsgService.java
new file mode 100644
index 0000000..93f1ed5
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/service/MsgService.java
@@ -0,0 +1,74 @@
+package at.gv.egiz.moazs.service;
+import at.gv.egiz.moazs.process.MsgResponseHandler;
+import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.MsgResponse;
+import at.gv.egiz.moazs.scheme.NameSpace;
+import at.gv.egiz.moazs.scheme.NotificationResponse;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import at.gv.zustellung.msg.xsd.*;
+import org.apache.cxf.annotations.SchemaValidation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import static at.gv.zustellung.msg.xsd.DeliveryNotificationACKType.deliveryNotificationACKTypeBuilder;
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusACKType.deliveryRequestStatusACKTypeBuilder;
+import static at.gv.zustellung.msg.xsd.GetVersionResponse.getVersionResponseBuilder;
+import static java.util.concurrent.CompletableFuture.runAsync;
+
+@Service
+@SchemaValidation(type = SchemaValidation.SchemaValidationType.BOTH)
+public class MsgService implements Zuse2AppPort {
+
+ private final DeliveryRepository repository;
+ private final MsgResponseHandler handler;
+
+ @Autowired
+ public MsgService(DeliveryRepository repository, MsgResponseHandler handler) {
+ this.repository = repository;
+ this.handler = handler;
+ }
+
+ @Override
+ public GetVersionResponse getVersion(SimpleRequestType getVersionRequest) {
+ return getVersionResponseBuilder()
+ .withVersion(NameSpace.MSG_VERSION)
+ .build();
+ }
+
+ @Override
+ public DeliveryRequestStatusACKType status(DeliveryRequestStatusType status) {
+ var response = new RequestStatusResponse(status);
+ sendToWork(response);
+ return statusAck(response.getAppDeliveryID(), response.getZSDeliveryID());
+ }
+
+ private DeliveryRequestStatusACKType statusAck(String appDeliveryID, String zsDeliveryID) {
+ return deliveryRequestStatusACKTypeBuilder()
+ .withAppDeliveryID(appDeliveryID)
+ .withZSDeliveryID(zsDeliveryID)
+ .withVersion(NameSpace.MSG_VERSION)
+ .build();
+ }
+
+ @Override
+ public DeliveryNotificationACKType notification(DeliveryNotificationType notification) {
+ var response = new NotificationResponse(notification);
+ sendToWork(response);
+ return notificationAck(response.getAppDeliveryID(), response.getZSDeliveryID());
+ }
+
+ private void sendToWork(MsgResponse response) {
+ runAsync(() -> repository.add(response))
+ .thenRunAsync(() -> handler.handle(response.getResponseID()));
+ }
+
+ private DeliveryNotificationACKType notificationAck(String appDeliveryID, String zsDeliveryID) {
+ return deliveryNotificationACKTypeBuilder()
+ .withAppDeliveryID(appDeliveryID)
+ .withZSDeliveryID(zsDeliveryID)
+ .withVersion(NameSpace.MSG_VERSION)
+ .build();
+ }
+
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/MzsService.java b/src/main/java/at/gv/egiz/moazs/service/MzsService.java
index f245b93..c41740f 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/MzsService.java
+++ b/src/main/java/at/gv/egiz/moazs/service/MzsService.java
@@ -1,8 +1,12 @@
-package at.gv.egiz.moazs.scheme;
+package at.gv.egiz.moazs.service;
-import at.gv.egiz.moazs.pipeline.DeliveryPipeline;
import at.gv.egiz.moazs.preprocess.DeliveryRequestAugmenter;
+import at.gv.egiz.moazs.process.DeliveryPipeline;
+import at.gv.egiz.moazs.repository.BinaryRepository;
import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.Msg2MzsConverter;
+import at.gv.egiz.moazs.client.MzsClient;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
import at.gv.zustellung.app2mzs.xsd.App2MzsPortType;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
@@ -37,15 +41,17 @@ public class MzsService implements App2MzsPortType {
private final MzsClient appClient;
private final DeliveryRequestAugmenter augmenter;
private final Msg2MzsConverter converter;
+ private final BinaryRepository binaryStatusRepository;
@Autowired
public MzsService(DeliveryRepository repository, DeliveryPipeline pipeline, MzsClient appClient,
- DeliveryRequestAugmenter augmenter, Msg2MzsConverter converter) {
+ DeliveryRequestAugmenter augmenter, Msg2MzsConverter converter, BinaryRepository binaryStatusRepository) {
this.repository = repository;
this.pipeline = pipeline;
this.appClient = appClient;
this.augmenter = augmenter;
this.converter = converter;
+ this.binaryStatusRepository = binaryStatusRepository;
}
@Override
@@ -55,10 +61,11 @@ public class MzsService implements App2MzsPortType {
DeliveryRequestType deliveryRequest) {
var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID();
+ var responseID = RequestStatusResponse.getResponseID(appDeliveryID);
var future = supplyAsync(() -> augmenter.augment(deliveryRequest))
.thenApply(this::process)
- .thenApply(status -> converter.convert(status, repository.getSignedDeliveryRequestStatus(appDeliveryID)));
+ .thenApply(status -> converter.convert(status, binaryStatusRepository.get(responseID)));
try {
return future.get(TIMEOUT_FOR_ANWSER, TimeUnit.SECONDS);
@@ -85,9 +92,10 @@ public class MzsService implements App2MzsPortType {
repository.add(deliveryRequest);
pipeline.processRequest(appDeliveryID);
- return repository.getDeliveryRequestStatus(appDeliveryID)
+ var statusId = RequestStatusResponse.getResponseID(appDeliveryID);
+ var response = repository.getResponse(statusId)
.orElseThrow(() -> moaZSException("Could not get a response for AppDeliveryID=%s.", appDeliveryID));
-
+ return (DeliveryRequestStatusType) response.getResponse();
}
private DeliveryResponseType generatePartialSuccessResponse(String appDeliveryId) {
diff --git a/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java b/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java
index e7761fe..d0a445b 100644
--- a/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java
+++ b/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java
@@ -1,5 +1,7 @@
-package at.gv.egiz.moazs.util;
+package at.gv.egiz.moazs.client;
+import at.gv.egiz.moazs.util.FileUtils;
+import at.gv.egiz.moazs.util.StoreSOAPBodyBinaryInRepositoryInterceptor;
import at.gv.zustellung.app2mzs.xsd.ClientType;
import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
import at.gv.zustellung.app2mzs.xsd.SSLType;
diff --git a/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java b/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java
new file mode 100644
index 0000000..24321e1
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/util/EndpointFactory.java
@@ -0,0 +1,41 @@
+package at.gv.egiz.moazs.util;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.apache.cxf.message.Message;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import javax.xml.ws.Endpoint;
+
+import javax.xml.ws.Service;
+
+@Component
+public class EndpointFactory {
+
+ private final Bus bus;
+
+ @Autowired
+ public EndpointFactory(Bus bus) {
+ this.bus = bus;
+ }
+
+ public Endpoint create(Object implementor, Service service) {
+ return create(implementor, service, null);
+ }
+
+ public Endpoint create(Object implementor, Service service, Interceptor<Message> interceptor) {
+ EndpointImpl endpoint = new EndpointImpl(bus, implementor);
+ endpoint.setAddress("/");
+ endpoint.setServiceName(service.getServiceName());
+ endpoint.setWsdlLocation(service.getWSDLDocumentLocation().toString());
+ endpoint.publish();
+
+ if (interceptor != null) {
+ endpoint.getInInterceptors().add(interceptor);
+ }
+
+ return endpoint;
+ }
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java b/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
index 302bbf0..8fb5d80 100644
--- a/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
+++ b/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
@@ -1,4 +1,4 @@
-package at.gv.egiz.moazs.util;
+package at.gv.egiz.moazs.client;
import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
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 2db81ab..d70c8bd 100644
--- a/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java
+++ b/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java
@@ -1,6 +1,6 @@
package at.gv.egiz.moazs.util;
-import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.repository.BinaryRepository;
import at.gv.egiz.moazs.scheme.SOAPUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
@@ -15,6 +15,7 @@ import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.Map;
import static at.gv.egiz.moazs.MoaZSException.moaZSException;
@@ -25,14 +26,16 @@ public class StoreSOAPBodyBinaryInRepositoryInterceptor extends AbstractPhaseInt
private final CXFMessageUtils messageUtils;
private final SOAPUtils soapUtils;
- private final DeliveryRepository repository;
+ private final Map<String, String> idSuffixes;
+ private final BinaryRepository repository;
@Autowired
public StoreSOAPBodyBinaryInRepositoryInterceptor(CXFMessageUtils extractor, SOAPUtils soapUtils,
- DeliveryRepository repository) {
+ Map<String, String> idSuffixes, BinaryRepository repository) {
super(Phase.RECEIVE);
this.messageUtils = extractor;
this.soapUtils = soapUtils;
+ this.idSuffixes = idSuffixes;
this.repository = repository;
}
@@ -45,17 +48,28 @@ public class StoreSOAPBodyBinaryInRepositoryInterceptor extends AbstractPhaseInt
log.trace("Interceptor received this SOAP message: {}. ", new String(content, StandardCharsets.UTF_8));
}
- if(content.length > 0) {
- Element document = soapUtils.toDOM(content);
- byte[] status = soapUtils.unwrapSoapEnvelope(document);
- String appDeliveryID = soapUtils.getAppDeliveryIDFrom(document);
- repository.addSignedDeliveryRequestStatus(status, appDeliveryID);
+ if (content.length <= 0) {
+ return;
+ }
+
+ Element document = soapUtils.toDOM(content);
+ byte[] response = soapUtils.unwrapSoapEnvelope(document);
+ String appDeliveryID = soapUtils.getAppDeliveryIDFrom(document);
+ String rootTag = document.getTagName();
- if(log.isTraceEnabled()) {
- log.trace("DeliveryRequestStatus with AppDeliveryID={} unwrapped and stored: {}. ",
- appDeliveryID, new String(status, StandardCharsets.UTF_8));
- }
+ if (!idSuffixes.containsKey(rootTag)) {
+ log.trace("Will not add message of type {}. ", rootTag);
+ return;
}
+
+ var id = appDeliveryID + idSuffixes.get(rootTag);
+ repository.add(id, response);
+
+ if(log.isTraceEnabled()) {
+ log.trace("Msg Response with AppDeliveryID={} unwrapped and stored: {}. ",
+ appDeliveryID, new String(response, StandardCharsets.UTF_8));
+ }
+
} catch (ParserConfigurationException | SAXException | IOException | NullPointerException e) {
throw moaZSException("Could not extract signed data from message.", e);
}
diff --git a/src/main/java/at/gv/egiz/moazs/verify/MsgResponseVerifier.java b/src/main/java/at/gv/egiz/moazs/verify/MsgResponseVerifier.java
new file mode 100644
index 0000000..c5e04d9
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/verify/MsgResponseVerifier.java
@@ -0,0 +1,59 @@
+package at.gv.egiz.moazs.verify;
+
+import at.gv.egiz.moazs.MoaZSException;
+import at.gv.egiz.moazs.repository.BinaryRepository;
+import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.MsgResponse;
+import at.gv.egiz.moazs.service.MsgService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder;
+import static java.lang.String.format;
+
+@Component
+public class MsgResponseVerifier {
+
+ private static final Logger log = LoggerFactory.getLogger(MsgService.class);
+ public static final String MOASP_SIGNATURE_INVALID_ERROR_MSG = "Signature of Msg Response " +
+ "with AppDeliveryID=%s is not valid.";
+
+ private final DeliveryRepository repo;
+ private final BinaryRepository binaryRepo;
+ private final SignatureVerifier verifier;
+
+ @Autowired
+ public MsgResponseVerifier(DeliveryRepository repo,
+ BinaryRepository binaryStatusRepository,
+ SignatureVerifier verifier) {
+ this.repo = repo;
+ this.binaryRepo = binaryStatusRepository;
+ this.verifier = verifier;
+ }
+
+ public MsgResponse verify(String id) {
+
+ var response = repo.getResponse(id).get();
+ var builder = moaZSExceptionBuilder().withAllParametersInAnswer(response.getAnswer());
+
+ var binaryResponse = binaryRepo.get(id).get();
+
+ try {
+ verifier.verify(binaryResponse);
+ return response;
+ } catch (MoaZSException ex) {
+ log.error(ex.getMessage(), ex);
+ var wrappingEx = builder
+ .withMessage(format(MOASP_SIGNATURE_INVALID_ERROR_MSG, response.getAppDeliveryID()))
+ .withErrorCode(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID)
+ .withCause(ex)
+ .build();
+
+ return response.generateError(wrappingEx);
+ }
+
+ }
+
+}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 1903067..ca8221c 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -72,3 +72,7 @@ moa.spss:
# - relative path (otherwise, relative to application's class path)
configuration: moa-spss/MOASPSSConfiguration.xml
default-trustprofile: test-trustprofile
+
+repository:
+ # duration in minutes before repository records are evicted.
+ expiresAfterWrite: 30 \ No newline at end of file
diff --git a/src/main/resources/zusemsg/zuse2app_p2.wsdl b/src/main/resources/zusemsg/zuse2app_p2.wsdl
new file mode 100644
index 0000000..d50c3cc
--- /dev/null
+++ b/src/main/resources/zusemsg/zuse2app_p2.wsdl
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:msg="http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:service="http://reference.e-government.gv.at/namespace/zustellung/app2zuse/phase2/20181206#" targetNamespace="http://reference.e-government.gv.at/namespace/zustellung/app2zuse/phase2/20181206#">
+ <wsdl:types>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
+ <xs:import namespace="http://reference.e-government.gv.at/namespace/zustellung/msg/phase2/20181206#" schemaLocation="zuse_p2.xsd"/>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="DeliveryNotification">
+ <wsdl:part name="DeliveryNotification" element="msg:DeliveryNotification">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:message name="DeliveryNotificationACK">
+ <wsdl:part name="DeliveryNotificationACK" element="msg:DeliveryNotificationACK">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:message name="DeliveryRequestStatus">
+ <wsdl:part name="DeliveryRequestStatus" element="msg:DeliveryRequestStatus">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:message name="DeliveryRequestStatusACK">
+ <wsdl:part name="DeliveryRequestStatusACK" element="msg:DeliveryRequestStatusACK">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:message name="GetVersionRequest">
+ <wsdl:part name="GetVersionRequest" element="msg:GetVersionRequest">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:message name="GetVersionResponse">
+ <wsdl:part name="GetVersionResponse" element="msg:GetVersionResponse">
+ </wsdl:part>
+ </wsdl:message>
+ <wsdl:portType name="Zuse2AppPort">
+ <wsdl:operation name="Notification">
+ <wsdl:input name="DeliveryNotification" message="service:DeliveryNotification"/>
+ <wsdl:output name="DeliveryNotificationACK" message="service:DeliveryNotificationACK"/>
+ </wsdl:operation>
+ <wsdl:operation name="Status">
+ <wsdl:input name="DeliveryRequestStatus" message="service:DeliveryRequestStatus"/>
+ <wsdl:output name="DeliveryRequestStatusACK" message="service:DeliveryRequestStatusACK"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetVersion">
+ <wsdl:input name="GetVersionRequest" message="service:GetVersionRequest"/>
+ <wsdl:output name="GetVersionResponse" message="service:GetVersionResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="Zuse2AppPortSoap12" type="service:Zuse2AppPort">
+ <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="Notification">
+ <soap12:operation soapAction="Notification" soapActionRequired="false"/>
+ <wsdl:input name="DeliveryNotification">
+ <soap12:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DeliveryNotificationACK">
+ <soap12:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Status">
+ <soap12:operation soapAction="Status" soapActionRequired="false"/>
+ <wsdl:input name="DeliveryRequestStatus">
+ <soap12:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DeliveryRequestStatusACK">
+ <soap12:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetVersion">
+ <soap12:operation soapAction="GetVersion" soapActionRequired="false"/>
+ <wsdl:input name="GetVersionRequest">
+ <soap12:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetVersionResponse">
+ <soap12:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="Zuse2AppPortService">
+ <wsdl:port name="Zuse2AppPortSoap12" binding="service:Zuse2AppPortSoap12">
+ <soap12:address location="/zuse"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
index ff981a9..f408c3b 100644
--- a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
@@ -1,6 +1,6 @@
package at.gv.egiz.moazs;
-import at.gv.egiz.moazs.scheme.MzsDeliveryRequestValidator;
+import at.gv.egiz.moazs.preprocess.MzsDeliveryRequestValidator;
import at.gv.egiz.moazs.preprocess.*;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java b/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
index 3bc0d3b..12f1dea 100644
--- a/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
+++ b/src/test/java/at/gv/egiz/moazs/DeliveryRequestAugmenterTest.java
@@ -1,6 +1,6 @@
package at.gv.egiz.moazs;
-import at.gv.egiz.moazs.scheme.MzsDeliveryRequestValidator;
+import at.gv.egiz.moazs.preprocess.MzsDeliveryRequestValidator;
import at.gv.egiz.moazs.preprocess.ConfigUtil;
import at.gv.egiz.moazs.preprocess.DeliveryRequestAugmenter;
import at.gv.zustellung.app2mzs.xsd.ConfigType;
diff --git a/src/test/java/at/gv/egiz/moazs/ITMsgClientTest.java b/src/test/java/at/gv/egiz/moazs/ITMsgClientTest.java
index 70e300c..0f87dd6 100644
--- a/src/test/java/at/gv/egiz/moazs/ITMsgClientTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ITMsgClientTest.java
@@ -1,6 +1,6 @@
package at.gv.egiz.moazs;
-import at.gv.egiz.moazs.util.ClientFactory;
+import at.gv.egiz.moazs.client.ClientFactory;
import at.gv.egiz.moazs.scheme.Marshaller;
import at.gv.zustellung.app2mzs.xsd.ClientType;
import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
diff --git a/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java b/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
index 4f24518..22aa03f 100644
--- a/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ITMzsServiceTest.java
@@ -1,7 +1,8 @@
package at.gv.egiz.moazs;
-import at.gv.egiz.moazs.pipeline.DeliveryPipeline;
+import at.gv.egiz.moazs.process.DeliveryPipeline;
import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
@@ -63,7 +64,7 @@ public class ITMzsServiceTest {
.withSuccess(success)
.build();
- repository.add(status);
+ repository.add(new RequestStatusResponse(status));
};
}
diff --git a/src/test/java/at/gv/egiz/moazs/SafeResponseToFileSinkTest.java b/src/test/java/at/gv/egiz/moazs/SafeResponseToFileSinkTest.java
new file mode 100644
index 0000000..9092dfb
--- /dev/null
+++ b/src/test/java/at/gv/egiz/moazs/SafeResponseToFileSinkTest.java
@@ -0,0 +1,113 @@
+package at.gv.egiz.moazs;
+
+import at.gv.egiz.moazs.process.SafeResponseToFileSink;
+import at.gv.egiz.moazs.repository.BinaryRepository;
+import at.gv.egiz.moazs.scheme.Marshaller;
+import at.gv.egiz.moazs.scheme.RequestStatusResponse;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Success.successBuilder;
+import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
+import static java.util.Optional.of;
+import static org.apache.commons.io.FileUtils.readFileToString;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SafeResponseToFileSinkTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SafeResponseToFileSinkTest.class);
+
+ private SafeResponseToFileSink sink;
+
+ private final String root = "./target/tmp/SafeResponseToFileSinkTestOut";
+
+ @Mock
+ private BinaryRepository repository;
+
+ @Mock
+ private Marshaller marshaller;
+
+
+ @Before
+ public void setup() {
+ sink = new SafeResponseToFileSink(marshaller, repository, root);
+ deleteRoot();
+
+ }
+
+ private void deleteRoot() {
+ try {
+ FileUtils.deleteDirectory(new File(root));
+ } catch (IOException e) {
+ log.warn("Could not delete {}", root);
+ }
+ }
+
+ @Test
+ public void safeRequestToFiles() {
+
+ var fileContent = "<xml>some content</xml>";
+ var status = setupMocks(fileContent);
+
+ sink.handle(status)
+ .thenRun(() -> assertFilesCreatedAndContentMatches(fileContent));
+ }
+
+ private void assertFilesCreatedAndContentMatches(String fileContent) {
+ var rootFolder = new File(root);
+ Collection<File> files = FileUtils.listFiles(rootFolder, null, true);
+
+ assertThat(rootFolder.exists()).isTrue();
+ assertThat(rootFolder.isDirectory()).isTrue();
+ assertThat(files).isNotEmpty();
+
+ files.stream()
+ .map(file -> readFile(file))
+ .forEach(content -> assertThat(content).isEqualTo(fileContent));
+ }
+
+ private String readFile(File file) {
+ try {
+ return readFileToString(file, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private RequestStatusResponse setupMocks(String fileContent) {
+
+ var appDeliveryId = "app-delivery-id";
+ var responseId = RequestStatusResponse.getResponseID(appDeliveryId);
+
+ when(repository.get(responseId))
+ .thenReturn(of(fileContent.getBytes(StandardCharsets.UTF_8)));
+ when(marshaller.marshallXml(any())).thenReturn(fileContent);
+
+ var success = successBuilder()
+ .withAppDeliveryID(appDeliveryId)
+ .build();
+
+ var status = deliveryRequestStatusTypeBuilder()
+ .withSuccess(success)
+ .build();
+
+ return new RequestStatusResponse(status);
+
+
+ }
+
+}
diff --git a/src/test/java/at/gv/egiz/moazs/SingleThreadedDeliveryPipelineTest.java b/src/test/java/at/gv/egiz/moazs/SingleThreadedDeliveryPipelineTest.java
index c08d567..e145cd9 100644
--- a/src/test/java/at/gv/egiz/moazs/SingleThreadedDeliveryPipelineTest.java
+++ b/src/test/java/at/gv/egiz/moazs/SingleThreadedDeliveryPipelineTest.java
@@ -1,12 +1,14 @@
package at.gv.egiz.moazs;
-import at.gv.egiz.moazs.util.ClientFactory;
-import at.gv.egiz.moazs.pipeline.DeliveryPipeline;
-import at.gv.egiz.moazs.pipeline.SingleThreadedDeliveryPipeline;
+import at.gv.egiz.moazs.process.DeliveryPipeline;
+import at.gv.egiz.moazs.process.SingleThreadedDeliveryPipeline;
+import at.gv.egiz.moazs.client.TnvzHelper;
+import at.gv.egiz.moazs.repository.BinaryRepository;
+import at.gv.egiz.moazs.repository.InMemoryBinaryRepository;
+import at.gv.egiz.moazs.scheme.*;
+import at.gv.egiz.moazs.client.ClientFactory;
import at.gv.egiz.moazs.repository.DeliveryRepository;
import at.gv.egiz.moazs.repository.InMemoryDeliveryRepository;
-import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
-import at.gv.egiz.moazs.scheme.TnvzHelper;
import at.gv.egiz.moazs.verify.MoaSPSSSignatureVerifier;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
import at.gv.zustellung.msg.xsd.App2ZusePort;
@@ -22,6 +24,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import static at.gv.egiz.moazs.MoaZSException.moaZSException;
import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder;
+import static at.gv.egiz.moazs.scheme.RequestStatusResponse.getResponseID;
import static at.gv.zustellung.app2mzs.xsd.ClientType.clientTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder;
@@ -37,6 +40,7 @@ import static org.mockito.Mockito.*;
public class SingleThreadedDeliveryPipelineTest {
private DeliveryRepository repository = new InMemoryDeliveryRepository();
+ private BinaryRepository binaryRepository = new InMemoryBinaryRepository(30);
@Mock
private TnvzHelper tnvzHelper;
@@ -61,57 +65,70 @@ public class SingleThreadedDeliveryPipelineTest {
@Before
public void setup() {
- pipeline = new SingleThreadedDeliveryPipeline(repository, tnvzHelper, converter, clientFactory, verifier);
+ pipeline = new SingleThreadedDeliveryPipeline(
+ repository,
+ binaryRepository,
+ tnvzHelper,
+ converter,
+ clientFactory,
+ verifier);
}
@Test
public void executePipelineWithoutTnvzRequest() {
- var appDeliveryId = "no-tnvz-request";
- var expectedStatus = setupMocks(appDeliveryId, false);
+ var appDeliveryID = "no-tnvz-request";
+ var expectedStatus = setupMocks(appDeliveryID, false);
- pipeline.processRequest(appDeliveryId);
+ pipeline.processRequest(appDeliveryID);
verifyZeroInteractions(tnvzHelper);
- var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get();
+ var response = repository.getResponse(getResponseID(appDeliveryID)).get();
+ var actualStatus = (DeliveryRequestStatusType) response.getResponse();
assertThat(actualStatus).isEqualTo(expectedStatus);
}
@Test
public void rejectDeliveryWhenReceiverIsNotAddressable() {
- var appDeliveryId = "not-addressable";
- setupMocks(appDeliveryId, true);
+ var appDeliveryID = "not-addressable";
+ setupMocks(appDeliveryID, true);
when(tnvzHelper.performQueryPersonRequest(any(), any(), any()))
- .thenThrow(buildMzsException("400"));
+ .thenThrow(buildMzsException("400", appDeliveryID));
- pipeline.processRequest(appDeliveryId);
- var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get()
- .getError().getErrorInfo().getCode();
+ pipeline.processRequest(appDeliveryID);
+
+ var responseId = getResponseID(appDeliveryID);
+ var response = repository.getResponse(responseId).get();
+ var status = (DeliveryRequestStatusType) response.getResponse();
+ var actualCode = status.getError().getErrorInfo().getCode();
- verify(tnvzHelper).performQueryPersonRequest(any(), any(), any());
assertThat(actualCode).isEqualTo("400");
+ verifyZeroInteractions(converter);
+ verify(tnvzHelper).performQueryPersonRequest(any(), any(), any());
}
@Test
public void executePipelineWithTnvzRequest() {
- var appDeliveryId = "tnvz-request";
- var expectedStatus = setupMocks(appDeliveryId, true);
+ var appDeliveryID = "tnvz-request";
+ var expectedStatus = setupMocks(appDeliveryID, true);
- pipeline.processRequest(appDeliveryId);
- var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get();
+ pipeline.processRequest(appDeliveryID);
+ var response = repository.getResponse(getResponseID(appDeliveryID)).get();
+ var actualStatus = (DeliveryRequestStatusType) response.getResponse();
assertThat(actualStatus).isEqualTo(expectedStatus);
}
@Test
public void rejectInvalidSignature() {
- var appDeliveryId = "invalid-signature";
- setupMocks(appDeliveryId, true);
+ var appDeliveryID = "invalid-signature";
+ setupMocks(appDeliveryID, true);
doThrow(moaZSException("Signature Invalid!")).when(verifier).verify(any());
- pipeline.processRequest(appDeliveryId);
- var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get()
- .getError().getErrorInfo().getCode();
+ pipeline.processRequest(appDeliveryID);
+ var response = repository.getResponse(getResponseID(appDeliveryID)).get();
+ var status = (DeliveryRequestStatusType) response.getResponse();
+ var actualCode = status.getError().getErrorInfo().getCode();
assertThat(actualCode).isEqualTo(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID);
@@ -125,7 +142,7 @@ public class SingleThreadedDeliveryPipelineTest {
var signedStatus = new byte[0];
var identification = IdentificationType.identificationTypeBuilder().build();
repository.add(mzsRequest);
- repository.addSignedDeliveryRequestStatus(signedStatus, appDeliveryId);
+ binaryRepository.add(getResponseID(appDeliveryId), signedStatus);
when(converter.convert(eq(mzsRequest) )).thenReturn(msgRequest);
when(converter.convert(eq(mzsRequest), any())).thenReturn(msgRequest);
@@ -140,8 +157,11 @@ public class SingleThreadedDeliveryPipelineTest {
}
- private MoaZSException buildMzsException(String code) {
- return moaZSExceptionBuilder("").withErrorCode(code).build();
+ private MoaZSException buildMzsException(String code, String appDeliveryID) {
+ return moaZSExceptionBuilder("")
+ .withErrorCode(code)
+ .withAppDeliveryID(appDeliveryID)
+ .build();
}
private DeliveryRequestStatusType setupStatus(String appDeliveryId) {
diff --git a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
index 66873d4..b58002b 100644
--- a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
+++ b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java
@@ -2,7 +2,7 @@ package at.gv.egiz.moazs;
import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
-import at.gv.egiz.moazs.scheme.TnvzHelper;
+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.tnvz.xsd.MimeTypeList;