aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java')
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java b/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java
new file mode 100644
index 0000000..70c20bb
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/scheme/TnvzHelper.java
@@ -0,0 +1,232 @@
+package at.gv.egiz.moazs.scheme;
+
+import at.gv.egiz.moazs.MoaZSException;
+import at.gv.egiz.moazs.scheme.Mzs2MsgConverter;
+import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
+import at.gv.zustellung.app2mzs.xsd.persondata.AbstractAddressType;
+import at.gv.zustellung.msg.xsd.persondata.IdentificationType;
+import at.gv.zustellung.msg.xsd.persondata.ObjectFactory;
+import at.gv.zustellung.msg.xsd.persondata.PostalAddressType;
+import at.gv.zustellung.tnvz.xsd.*;
+import at.gv.zustellung.tnvz.xsd.QueryPersonRequest.QueryEntryList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Nullable;
+import javax.xml.bind.JAXBElement;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static at.gv.zustellung.tnvz.xsd.PersonQueryType.MetaData.metaDataBuilder;
+import static at.gv.zustellung.tnvz.xsd.PersonQueryType.personQueryTypeBuilder;
+import static at.gv.zustellung.tnvz.xsd.QueryPersonRequest.QueryEntryList.queryEntryListBuilder;
+import static at.gv.zustellung.tnvz.xsd.QueryPersonRequest.queryPersonRequestBuilder;
+import static at.gv.zustellung.tnvz.xsd.Receiver.receiverBuilder;
+import static at.gv.zustellung.tnvz.xsd.Sender.senderBuilder;
+import static java.lang.String.join;
+import static java.util.stream.Collectors.toSet;
+
+@Component
+public class TnvzHelper {
+
+ private final Mzs2MsgConverter converter;
+
+ private static final ObjectFactory FACTORY = new at.gv.zustellung.msg.xsd.persondata.ObjectFactory();
+ private static final String ENTRY_ID = "entry-id";
+ private static final String RECEIVER_NOT_ADRESSABLE_ERROR_MSG = "Receiver is not addressable. Reason: %s";
+ private static final String MIMETYPE_MISSMATCH_ERROR_MSG = "Request contains attachment of type(s) %s, but " +
+ "receiver only accepts attachments of type(s) %s.";
+ private static final String MZS_NO_TNVZ_PERSON_QUERY_RESULTS_ERROR_MSG = "tnvz:QueryResultList was empty.";
+
+
+ @Autowired
+ public TnvzHelper(Mzs2MsgConverter converter) {
+ this.converter = converter;
+ }
+
+ /**
+ * Performs all tasks related to making a request to the tnvz service:
+ * Derives a tnvz:QueryPersonRequest from the {@code mzsRequest}, sends the QueryPersonRequest to
+ * {@code tvnzPort}, validates the tnvz's response and extracts the {@code Identification} Element.
+ * @param mzsRequest Data source for the QueryPersonRequest
+ * @param tvnzPort Client for communicating with the tnvz service
+ * @param exceptionBuilder Utility to collect information and build a meaningful exception in case of errors.
+ * @throws MoaZSException in case of an error.
+ * @return
+ */
+ public IdentificationType performQueryPersonRequest(DeliveryRequestType mzsRequest,
+ TNVZServicePort tvnzPort,
+ MoaZSException.Builder exceptionBuilder) {
+
+ var tvnzQuery = buildQuery(mzsRequest);
+ var tvnzResponse = tvnzPort.queryPerson(tvnzQuery);
+ verifyResponse(tvnzResponse, exceptionBuilder);
+
+ var tvnzResult = getResult(tvnzResponse);
+ var typesInRequest = extractListOfMimemtypesIn(mzsRequest);
+ checkMimetypes(tvnzResult, typesInRequest, exceptionBuilder);
+
+ return tvnzResult.getSuccess().getIdentification();
+ }
+
+ private QueryPersonRequest buildQuery(DeliveryRequestType mzsRequest) {
+
+ Sender sender = extractSender(mzsRequest.getSender());
+ Receiver receiver = extractReceiver(mzsRequest.getReceiver());
+ var metadata = extractMetaData(mzsRequest);
+
+ PersonQueryType personQuery = personQueryTypeBuilder()
+ .withEntryID(ENTRY_ID)
+ .withSender(sender)
+ .withReceiver(receiver)
+ .withMetaData(metadata)
+ .build();
+
+ QueryEntryList entryList = queryEntryListBuilder()
+ .withQueryEntry(List.of(personQuery))
+ .build();
+
+ return queryPersonRequestBuilder()
+ .withQueryEntryList(entryList)
+ .build();
+ }
+
+ private PersonQueryType.MetaData extractMetaData(DeliveryRequestType request) {
+
+ var builder = metaDataBuilder();
+
+ var meta = request.getTnvzMetaData();
+
+ if (meta.getDeliveryQuality() != null) {
+ builder.withDeliveryQuality(meta.getDeliveryQuality());
+ } else {
+ builder.withPrivateMessageQuality(meta.getPrivateMessageQuality());
+ }
+
+ return builder
+ .withOrigin(meta.getOrigin())
+ .withPreAdviceNote(request.getReceiver().getPreAdviceNote())
+ .withIgnorePostRedirectionOrder(meta.getIgnorePostRedirectionOrder())
+ .build();
+ }
+
+ private Sender extractSender(DeliveryRequestType.Sender sender) {
+
+ var corporateBody = sender.getCorporateBody();
+ var mzsIdentification = corporateBody.getIdentification().get(0);
+ var msgIdentification = converter.convert(mzsIdentification);
+
+ var msgPerson = FACTORY.createPerson(converter.convert(corporateBody));
+
+ return senderBuilder()
+ .withIdentification(msgIdentification)
+ .withPerson(msgPerson)
+ .build();
+ }
+
+ private Receiver extractReceiver(DeliveryRequestType.Receiver receiver) {
+
+ var builder = receiverBuilder();
+
+ if (receiver.getIdentification() == null) {
+ builder
+ .withPerson(converter.convert(receiver.getPerson()))
+ .withAustrianAddressesOnly(receiver.getAustrianAddressesOnly());
+
+ var postalAddress = findPostalAddress(receiver.getAddress());
+ if (postalAddress != null)
+ builder.withPostalAddress(postalAddress);
+
+ if (receiver.getPreAdviceNote() != null) {
+ builder.withNotificationAddressList(receiver.getPreAdviceNote().getNotificationAddressList());
+ }
+ } else {
+ builder.withIdentification(converter.convert(receiver.getIdentification()));
+ }
+
+ return builder.build();
+ }
+
+ private @Nullable PostalAddressType findPostalAddress(List<JAXBElement<? extends AbstractAddressType>> addresses) {
+
+ if (addresses == null) return null;
+
+ for (JAXBElement<? extends AbstractAddressType> address : addresses) {
+ if(address.getValue() instanceof at.gv.zustellung.app2mzs.xsd.persondata.PostalAddressType) {
+ var mzsPostalAddress = (at.gv.zustellung.app2mzs.xsd.persondata.PostalAddressType) address.getValue();
+ return converter.convert(mzsPostalAddress);
+ }
+ }
+
+ return null;
+
+ }
+
+ private Set<String> extractListOfMimemtypesIn(DeliveryRequestType mzsRequest) {
+ return mzsRequest.getPayload().stream()
+ .map(DeliveryRequestType.Payload::getMIMEType)
+ .collect(toSet());
+ }
+
+ private void verifyResponse(QueryPersonResponse tvnzResponse, MoaZSException.Builder mzsBuilder) {
+
+ var error = tvnzResponse.getError();
+ if (error != null) {
+ throw mzsBuilder.withErrorCode(error.getCode())
+ .withMessage(error.getText())
+ .build();
+ }
+
+ var results = tvnzResponse.getQueryResultList().getQueryResult();
+ if (results.isEmpty()) {
+ throw mzsBuilder.withErrorCode(MoaZSException.ERROR_MZS_NO_TNVZ_PERSON_QUERY_RESULTS)
+ .withMessage(MZS_NO_TNVZ_PERSON_QUERY_RESULTS_ERROR_MSG)
+ .build();
+ }
+
+ var tnvzResult = results.get(0);
+ mzsBuilder.withTnvzResult(tnvzResult);
+ if (tnvzResult.getError() != null) {
+ var info = tnvzResult.getError().getErrorInfo();
+ throw mzsBuilder.withErrorCode(info.getCode())
+ .withMessage(RECEIVER_NOT_ADRESSABLE_ERROR_MSG, info.getText())
+ .build();
+ }
+ }
+
+ private PersonResultType getResult(QueryPersonResponse tvnzResponse) {
+ return tvnzResponse.getQueryResultList().getQueryResult().get(0);
+ }
+
+ private void checkMimetypes(PersonResultType tnvzResult, Set<String> typesInRequest, MoaZSException.Builder mzsBuilder) {
+ var mismatchedTypes = findMimeTypeMismatches(tnvzResult, typesInRequest);
+ if (!mismatchedTypes.isEmpty()) {
+ var acceptedTypesString = join(",", getAcceptedTypes(tnvzResult));
+ var mismatchedTypesString = join(",", mismatchedTypes);
+ throw mzsBuilder.withErrorCode(MoaZSException.ERROR_MZS_MIMETYPE_MISSMATCH)
+ .withMessage(MIMETYPE_MISSMATCH_ERROR_MSG, mismatchedTypesString, acceptedTypesString)
+ .build();
+ }
+ }
+
+ private Collection<String> findMimeTypeMismatches(PersonResultType result, Set<String> typesInRequest) {
+ var acceptedTypes = getAcceptedTypes(result);
+
+ if (acceptedTypes.contains("*/*")) {
+ return List.of();
+ }
+
+ var typesInRequestCopy = new HashSet<>(typesInRequest);
+ typesInRequestCopy.removeAll(acceptedTypes);
+
+ return typesInRequestCopy;
+ }
+
+ private List<String> getAcceptedTypes(PersonResultType result) {
+ return result.getSuccess().getMimeTypeList().getMimeType();
+ }
+
+
+}