aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-05-23 10:20:38 +0200
committerChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-05-23 10:26:08 +0200
commit7665997a90c87a400f92ae9bf1ec6cc5a3099e16 (patch)
treef8a143a834a9204fbdfc64591ce0f61b60cb495b
parent59a13bea5783aa666bcbcec793df19f129965ff3 (diff)
downloadmoa-zs-7665997a90c87a400f92ae9bf1ec6cc5a3099e16.tar.gz
moa-zs-7665997a90c87a400f92ae9bf1ec6cc5a3099e16.tar.bz2
moa-zs-7665997a90c87a400f92ae9bf1ec6cc5a3099e16.zip
MZS Schema Changes + Changes in Interface
- MZS cant reply with a msg:DeliveryRequestStatusType to a mzs:DeliveryRequest. Reason: unmarshalling a msg:DeliveryRequestStatusType with JAXB (after receiving the msg reply) breaks the signature in msg:DeliveryRequestStatusType. Why? Because JAXB marshalling tinkers with the namespaces and, as for the current state of knowledge, we cannot configure the JAXB marshaller to reconstruct a XML Document byte-by-byte such that a signature that went through this process can be verified successfully (see [1]). - For this reason, we revert back to mzs:DeliveryResponse and add new fields / remove obsolete fields / capture all changes between zusemsg 1.5.3 and zusemsg 2.0.0. - The easier solution would be to wrap and transmit signed data + signature in a binary (base64) container, such that apache cxf and other web service frameworks won't unmarshall them. This doesnt work because zusemsg 2.0.0 is final. app2mzs.xsd Changes in Detail : - Add DeliverySystem, ZSDeliveryID and GZ to MessageType (MessageType is the base type of DeliveryResponse.Success, -PartialSuccess, and -Error); Reason: It was added to zusemsg 2.0.0. - Add SignedDeliveryRequestStatus to MessageType. Reason: If msg returns signed reply, this element contains the reply as byte[] such that the signature does not break. - Add optional PreadvicenoteSend to ErrorType (because it was added in zusemsg 2.0.0) - Remove MZSDeliveryID from every instance because this ID does not exist anymore (moa zs does not maintain requests in a database). - Remove DocumentReference from ErrorType as it was removed from zusemsg 2.0.0. - Remove DeliveryConfirmation as node in DeliveryNotificiationType because it does not exist anymore in zusemsg 2.0.0; DeliveryConfirmation is also obsolete because all msg' replies are signed and need to be transferred to the sender application as a byte[], which is done by SignedDeliveryRequestStatus node in MessageType. - Remove DeliveryStatement as node in DeliveryNotificiationType because it does not exist anymore in zusemsg 2.0.0. Other Changes - Adapt codebase: MzsService returns mzs:DeliveryResponse. - Implement conversion from msg:DeliveryRequestStatus to mzs:DeliveryResponse. - Add store / retrieve interface to DeliveryRepository that stores signed delivery request statuses as byte[]. Temporary Changes - Disable integration tests which have external dependencies. [1] https://download.oracle.com/javaee-archive/jaxb.java.net/users/2007/03/6674.html Signed-off-by: Christof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>
-rw-r--r--src/main/java/at/gv/egiz/moazs/MoaZSException.java4
-rw-r--r--src/main/java/at/gv/egiz/moazs/mzs/MzsClient.java3
-rw-r--r--src/main/java/at/gv/egiz/moazs/mzs/MzsService.java28
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java4
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java20
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java10
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/Msg2MzsConverter.java75
-rw-r--r--src/main/resources/mzs/app2mzs.xsd47
-rw-r--r--src/test/java/at/gv/egiz/moazs/MsgClientTest.java7
9 files changed, 152 insertions, 46 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/MoaZSException.java b/src/main/java/at/gv/egiz/moazs/MoaZSException.java
index ad211bd..11d9b4e 100644
--- a/src/main/java/at/gv/egiz/moazs/MoaZSException.java
+++ b/src/main/java/at/gv/egiz/moazs/MoaZSException.java
@@ -13,4 +13,8 @@ public class MoaZSException extends RuntimeException {
return new MoaZSException(String.format(formatString, objects));
}
+ public static MoaZSException moaZSException(String message) {
+ return new MoaZSException(String.format(message));
+ }
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/mzs/MzsClient.java b/src/main/java/at/gv/egiz/moazs/mzs/MzsClient.java
index 5785703..295d11a 100644
--- a/src/main/java/at/gv/egiz/moazs/mzs/MzsClient.java
+++ b/src/main/java/at/gv/egiz/moazs/mzs/MzsClient.java
@@ -1,12 +1,13 @@
package at.gv.egiz.moazs.mzs;
+import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import org.springframework.stereotype.Component;
@Component
public class MzsClient {
- public void sendNotification(DeliveryRequestStatusType status) {
+ public void sendNotification(DeliveryResponseType responseType) {
throw new UnsupportedOperationException("Not implemented.");
}
diff --git a/src/main/java/at/gv/egiz/moazs/mzs/MzsService.java b/src/main/java/at/gv/egiz/moazs/mzs/MzsService.java
index 774f7f4..e031b0b 100644
--- a/src/main/java/at/gv/egiz/moazs/mzs/MzsService.java
+++ b/src/main/java/at/gv/egiz/moazs/mzs/MzsService.java
@@ -4,8 +4,13 @@ import at.gv.egiz.moazs.MoaZSException;
import at.gv.egiz.moazs.pipeline.DeliveryPipeline;
import at.gv.egiz.moazs.preprocess.DeliveryRequestAugmenter;
import at.gv.egiz.moazs.repository.DeliveryRepository;
+import at.gv.egiz.moazs.scheme.Msg2MzsConverter;
+import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
import at.gv.zustellung.app2mzs.xsd.App2MzsPortType;
import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
+import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
+import at.gv.zustellung.app2mzs.xsd.PartialSuccessType;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
import org.apache.cxf.annotations.SchemaValidation;
import org.slf4j.Logger;
@@ -18,8 +23,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static at.gv.egiz.moazs.MoaZSException.moaZSException;
-import static at.gv.zustellung.msg.xsd.DeliveryAnswerType.deliveryAnswerTypeBuilder;
-import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.PartialSuccessType.partialSuccessTypeBuilder;
import static java.lang.String.format;
import static java.util.concurrent.CompletableFuture.supplyAsync;
@@ -37,18 +41,20 @@ public class MzsService implements App2MzsPortType {
private final DeliveryPipeline pipeline;
private final MzsClient appClient;
private final DeliveryRequestAugmenter augmenter;
+ private final Msg2MzsConverter converter;
@Autowired
public MzsService(DeliveryRepository repository, DeliveryPipeline pipeline, MzsClient appClient,
- DeliveryRequestAugmenter augmenter) {
+ DeliveryRequestAugmenter augmenter, Msg2MzsConverter converter) {
this.repository = repository;
this.pipeline = pipeline;
this.appClient = appClient;
this.augmenter = augmenter;
+ this.converter = converter;
}
@Override
- public DeliveryRequestStatusType app2Mzs(
+ public DeliveryResponseType app2Mzs(
@WebParam(partName = "DeliveryRequest",
name = "DeliveryRequest")
DeliveryRequestType deliveryRequest) {
@@ -56,13 +62,15 @@ public class MzsService implements App2MzsPortType {
var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID();
var future = supplyAsync(() -> augmenter.augment(deliveryRequest))
- .thenApply(this::process);
+ .thenApply(this::process)
+ .thenApply(status -> converter.convert(status, repository.getSignedDeliveryRequestStatus(appDeliveryID)));
try {
return future.get(TIMEOUT_FOR_ANWSER, TimeUnit.SECONDS);
} catch (TimeoutException e) {
- future.thenAccept(appClient::sendNotification);
logger.info("Answer Timed Out", e);
+
+ future.thenAccept(appClient::sendNotification);
return generatePartialSuccessResponse(appDeliveryID);
} catch (Exception e ) {
@@ -86,14 +94,14 @@ public class MzsService implements App2MzsPortType {
}
- private DeliveryRequestStatusType generatePartialSuccessResponse(String appDeliveryId) {
+ private DeliveryResponseType generatePartialSuccessResponse(String appDeliveryId) {
- var answer = deliveryAnswerTypeBuilder()
+ var partial = partialSuccessTypeBuilder()
.withAppDeliveryID(appDeliveryId)
.build();
- return deliveryRequestStatusTypeBuilder()
- .withPartialSuccess(answer)
+ return DeliveryResponseType.deliveryResponseTypeBuilder()
+ .withPartialSuccess(partial)
.build();
}
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 228d55e..be61d1e 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
@@ -17,5 +17,9 @@ public interface DeliveryRepository {
Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID);
+ void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId);
+
+ Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID);
+
}
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 570296f..58ec92c 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
@@ -30,6 +30,10 @@ public class InMemoryDeliveryRepository implements DeliveryRepository {
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
+ private static final Cache<String, byte[]> signedStatusRepository = CacheBuilder.newBuilder()
+ .expireAfterWrite(30, TimeUnit.MINUTES)
+ .build();
+
@Override
public void add(DeliveryRequestType request) {
var key = request.getMetaData().getAppDeliveryID();
@@ -38,8 +42,7 @@ public class InMemoryDeliveryRepository implements DeliveryRepository {
@Override
public Optional<DeliveryRequestType> getDeliveryRequest(String appDeliveryID) {
- var deliveryRequestType = requestRepository.getIfPresent(appDeliveryID);
- return ofNullable(deliveryRequestType);
+ return ofNullable(requestRepository.getIfPresent(appDeliveryID));
}
@Override
@@ -51,7 +54,16 @@ public class InMemoryDeliveryRepository implements DeliveryRepository {
@Override
public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
- var deliveryRequestType = statusRepository.getIfPresent(appDeliveryID);
- return ofNullable(deliveryRequestType);
+ return ofNullable(statusRepository.getIfPresent(appDeliveryID));
+ }
+
+ @Override
+ public void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId) {
+ signedStatusRepository.put(appDeliveryId, bytes);
+ }
+
+ @Override
+ public Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID) {
+ return ofNullable(signedStatusRepository.getIfPresent(appDeliveryID));
}
}
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 c24902d..4ffe85d 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
@@ -69,4 +69,14 @@ public class RedisDeliveryRepository implements DeliveryRepository {
public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
throw new UnsupportedOperationException("Not Implemented Yet");
}
+
+ @Override
+ public void addSignedDeliveryRequestStatus(byte[] bytes, String appDeliveryId) {
+ throw new UnsupportedOperationException("Not Implemented Yet");
+ }
+
+ @Override
+ public Optional<byte[]> getSignedDeliveryRequestStatus(String appDeliveryID) {
+ return Optional.empty();
+ }
}
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/Msg2MzsConverter.java b/src/main/java/at/gv/egiz/moazs/scheme/Msg2MzsConverter.java
new file mode 100644
index 0000000..67f3d13
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/scheme/Msg2MzsConverter.java
@@ -0,0 +1,75 @@
+package at.gv.egiz.moazs.scheme;
+
+import at.gv.zustellung.app2mzs.xsd.DeliveryResponseType;
+import at.gv.zustellung.app2mzs.xsd.ErrorType;
+import at.gv.zustellung.app2mzs.xsd.PartialSuccessType;
+import at.gv.zustellung.app2mzs.xsd.SuccessType;
+import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType;
+import org.springframework.stereotype.Component;
+
+import java.math.BigInteger;
+import java.util.Optional;
+
+import static at.gv.zustellung.app2mzs.xsd.DeliveryResponseType.deliveryResponseTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.ErrorType.errorTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.PartialSuccessType.partialSuccessTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.SuccessType.successTypeBuilder;
+
+@Component
+public class Msg2MzsConverter {
+
+ public DeliveryResponseType convert(DeliveryRequestStatusType status, Optional<byte[]> signedStatus) {
+
+ var responseBuilder = deliveryResponseTypeBuilder();
+
+ if (status.getError() != null) {
+ responseBuilder.withError(convert(status.getError(), signedStatus));
+ } else if (status.getSuccess() != null) {
+ responseBuilder.withSuccess(convert(status.getSuccess(), signedStatus));
+ } else {
+ responseBuilder.withPartialSuccess(convert(status.getPartialSuccess(), signedStatus));
+ }
+
+ return responseBuilder.build();
+ }
+
+ private SuccessType convert(DeliveryRequestStatusType.Success success, Optional<byte[]> signedStatus) {
+ return successTypeBuilder()
+ .withAppDeliveryID(success.getAppDeliveryID())
+ .withDeliverySystem(success.getDeliverySystem())
+ .withGZ(success.getGZ())
+ .withZSDeliveryID(success.getZSDeliveryID())
+ .withSignedDeliveryRequestStatus(signedStatus.orElse(null))
+ .withRelayedViaERV(success.isRelayedViaERV())
+ .withDeliveryTimestamp(success.getDeliveryTimestamp())
+ .build();
+ }
+
+ private PartialSuccessType convert(DeliveryAnswerType answer, Optional<byte[]> signedStatus) {
+ return partialSuccessTypeBuilder()
+ .withAppDeliveryID(answer.getAppDeliveryID())
+ .withDeliverySystem(answer.getDeliverySystem())
+ .withGZ(answer.getGZ())
+ .withZSDeliveryID(answer.getZSDeliveryID())
+ .withSignedDeliveryRequestStatus(signedStatus.orElse(null))
+ .build();
+ }
+
+ private ErrorType convert(DeliveryRequestStatusType.Error error, Optional<byte[]> signedStatus) {
+ var builder = errorTypeBuilder()
+ .withAppDeliveryID(error.getAppDeliveryID())
+ .withDeliverySystem(error.getDeliverySystem())
+ .withGZ(error.getGZ())
+ .withZSDeliveryID(error.getZSDeliveryID())
+ .withSignedDeliveryRequestStatus(signedStatus.orElse(null))
+ .withPreAdviceNoteSent(error.getPreAdviceNoteSent())
+ .withCode(new BigInteger(error.getErrorInfo().getCode()));
+
+ if(error.getErrorInfo().getText() != null) builder.withText(error.getErrorInfo().getText());
+
+ return builder.build();
+ }
+
+
+}
diff --git a/src/main/resources/mzs/app2mzs.xsd b/src/main/resources/mzs/app2mzs.xsd
index 74a63db..05a9ea4 100644
--- a/src/main/resources/mzs/app2mzs.xsd
+++ b/src/main/resources/mzs/app2mzs.xsd
@@ -92,7 +92,14 @@
<xs:element name="X509" type="xs:base64Binary" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
- <xs:element name="DeliveryResponse" type="msg:DeliveryRequestStatusType"/>
+ <xs:element name="DeliveryResponse" type="DeliveryResponseType"/>
+ <xs:complexType name="DeliveryResponseType">
+ <xs:choice>
+ <xs:element ref="PartialSuccess"/>
+ <xs:element ref="Success"/>
+ <xs:element ref="Error"/>
+ </xs:choice>
+ </xs:complexType>
<xs:element name="DeliveryNotification" type="DeliveryNotificationType">
<xs:annotation>
<xs:documentation>asynchronous communication moazs2app</xs:documentation>
@@ -102,8 +109,6 @@
<xs:choice>
<xs:element ref="Success"/>
<xs:element ref="Error"/>
- <xs:element name="DeliveryConfirmation" type="xs:base64Binary"/>
- <xs:element ref="DeliveryStatement"/>
</xs:choice>
</xs:complexType>
<xs:element name="DeliveryNotificationACK" type="DeliveryNotificationACKType">
@@ -114,7 +119,6 @@
<xs:complexType name="DeliveryNotificationACKType">
<xs:sequence>
<xs:element ref="AppDeliveryID"/>
- <xs:element ref="MZSDeliveryID"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDeliveryID" nillable="false">
@@ -125,7 +129,6 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
- <xs:element name="MZSDeliveryID" type="xs:string"/>
<xs:element name="Success" type="SuccessType">
<xs:annotation>
<xs:documentation>Zustellstück was successfully delivered to MOA-ZS</xs:documentation>
@@ -133,7 +136,12 @@
</xs:element>
<xs:complexType name="SuccessType">
<xs:complexContent>
- <xs:extension base="MessageType"/>
+ <xs:extension base="MessageType">
+ <xs:sequence>
+ <xs:element ref="msg:DeliveryTimestamp"/>
+ <xs:element ref="msg:RelayedViaERV" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="PartialSuccess" type="PartialSuccessType">
@@ -157,27 +165,7 @@
<xs:sequence>
<xs:element name="Code" type="xs:integer"/>
<xs:element name="Text" type="xs:string"/>
- <xs:element name="DocumentReference" type="xs:anyURI" minOccurs="0">
- <xs:annotation>
- <xs:documentation>download of callback attachment failed</xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="DeliveryStatement" type="DeliveryStatementType">
- <xs:annotation>
- <xs:documentation>Zustellstück was successfully forwarded to the Zustellserver</xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:complexType name="DeliveryStatementType">
- <xs:complexContent>
- <xs:extension base="MessageType">
- <xs:sequence>
- <xs:element name="DeliveryServer" type="xs:anyURI"/>
- <xs:element name="ZSDeliveryID" type="xs:token"/>
- <xs:element name="Timestamp" type="xs:dateTime"/>
+ <xs:element ref="msg:PreAdviceNoteSent" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
@@ -188,7 +176,10 @@
</xs:annotation>
<xs:sequence>
<xs:element ref="AppDeliveryID"/>
- <xs:element ref="MZSDeliveryID"/>
+ <xs:element ref="msg:DeliverySystem"/>
+ <xs:element ref="msg:ZSDeliveryID" />
+ <xs:element ref="msg:GZ" minOccurs="0"/>
+ <xs:element name="SignedDeliveryRequestStatus" type="xs:base64Binary" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
diff --git a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
index 5b6419f..9d79435 100644
--- a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
+++ b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
@@ -23,8 +23,8 @@ import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.ServerType.serverTypeBuilder;
-@RunWith(SpringRunner.class)
-@SpringBootTest
+//@RunWith(SpringRunner.class)
+//@SpringBootTest
public class MsgClientTest {
private final static Logger logger = LoggerFactory.getLogger(MsgClient.class);
@@ -44,7 +44,8 @@ public class MsgClientTest {
// this test requires that a zusemsg service runs under httpServiceUri!
- @Test
+ //tmp disabled. todo: set up integration tests
+ //@Test
public void sendValidMessage() throws IOException {
var request = loadFromFile("validDeliveryRequest.xml");