diff options
author | Christof Rabensteiner <christof.rabensteiner@iaik.tugraz.at> | 2019-07-02 14:19:41 +0200 |
---|---|---|
committer | Christof Rabensteiner <christof.rabensteiner@iaik.tugraz.at> | 2019-07-02 14:19:41 +0200 |
commit | 030488bb7ff9572f35032d80d4101c06cfc98bf5 (patch) | |
tree | 20c563d181a4afe755daed7ec7cc91341a9815ab /src/main/java/at/gv/egiz/moazs/tnvz | |
parent | 45c717760a6efc74f4f15dbc3f55bafc5e9a02d9 (diff) | |
download | moa-zs-030488bb7ff9572f35032d80d4101c06cfc98bf5.tar.gz moa-zs-030488bb7ff9572f35032d80d4101c06cfc98bf5.tar.bz2 moa-zs-030488bb7ff9572f35032d80d4101c06cfc98bf5.zip |
Implement And Integrate tnvz:QueryPersonRequest.
- Merge TnvzClient and TnvzResultVerifier to TnvzHelper; TnvzHelper
now builds the QueryPersonRequest, sends it to the tnvz port and
evaluates the result.
- Publish some interfaces in Mzs2MsgConverter because they are needed
by TnvzHelper.
- Generalize MsgClientFactory to ClientFactory such that it can be
used to generate arbitrary SOAP clients (e.g. also for tnvz!).
Schema Changes to accomodate Tnvz's QueryPersonRequest:
- Add optional tnvz:AustrianAddressesOnly and optional TnvzMetaData to
mzs:mzs:DeliveryRequest.
Removed Unit Tests:
- Remove subset of SameThreadDeliveryPipeline testcases (mimetype
related) because its logic moved to TnvzHelper.
Diffstat (limited to 'src/main/java/at/gv/egiz/moazs/tnvz')
3 files changed, 231 insertions, 82 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/tnvz/TnvzClient.java b/src/main/java/at/gv/egiz/moazs/tnvz/TnvzClient.java deleted file mode 100644 index 3efb564..0000000 --- a/src/main/java/at/gv/egiz/moazs/tnvz/TnvzClient.java +++ /dev/null @@ -1,19 +0,0 @@ -package at.gv.egiz.moazs.tnvz; - -import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Receiver; -import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Sender; -import at.gv.zustellung.tnvz.xsd.PersonResultSuccessType; -import at.gv.zustellung.tnvz.xsd.PersonResultType; -import at.gv.zustellung.tnvz.xsd.PersonResultType.PersonResultTypeBuilder; -import org.springframework.stereotype.Component; - -@Component -public class TnvzClient { - - public PersonResultType query(Sender sender, Receiver receiver) { - //TODO: Replace this stub with actual request. - PersonResultSuccessType success = new PersonResultSuccessType.PersonResultSuccessTypeBuilder().build(); - return new PersonResultTypeBuilder().withSuccess(success).build(); - } - -} diff --git a/src/main/java/at/gv/egiz/moazs/tnvz/TnvzHelper.java b/src/main/java/at/gv/egiz/moazs/tnvz/TnvzHelper.java new file mode 100644 index 0000000..a14df9d --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/tnvz/TnvzHelper.java @@ -0,0 +1,231 @@ +package at.gv.egiz.moazs.tnvz; + +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.TnvzMetaDataType; +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:PersonQueryResult's list 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().getCorporateBody()); + Receiver receiver = extractReceiver(mzsRequest.getReceiver()); + var metadata = extractMetaData(mzsRequest.getTnvzMetaData()); + + 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(@Nullable TnvzMetaDataType meta) { + if (meta == null) { + return null; + } else { + var builder = metaDataBuilder(); + + if (meta.getDeliveryQuality() != null) { + builder.withDeliveryQuality(meta.getDeliveryQuality()); + } else { + builder.withPrivateMessageQuality(meta.getPrivateMessageQuality()); + } + + return builder + .withOrigin(meta.getOrigin()) + .withPreAdviceNote(meta.getPreAdviceNote()) + .withIgnorePostRedirectionOrder(meta.getIgnorePostRedirectionOrder()) + .build(); + } + } + + private Sender extractSender(at.gv.zustellung.app2mzs.xsd.persondata.CorporateBodyType corporateBody) { + + 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.withIdentification(converter.convert(receiver.getIdentification())); + } else { + 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()); + } + } + + return builder.build(); + } + + private @Nullable PostalAddressType findPostalAddress(List<JAXBElement<? extends AbstractAddressType>> addresses) { + + 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(); + } + + +} diff --git a/src/main/java/at/gv/egiz/moazs/tnvz/TnvzResultVerifier.java b/src/main/java/at/gv/egiz/moazs/tnvz/TnvzResultVerifier.java deleted file mode 100644 index 9992246..0000000 --- a/src/main/java/at/gv/egiz/moazs/tnvz/TnvzResultVerifier.java +++ /dev/null @@ -1,63 +0,0 @@ -package at.gv.egiz.moazs.tnvz; - -import at.gv.egiz.moazs.MoaZSException; -import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType; -import at.gv.zustellung.tnvz.xsd.PersonResultType; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.List; - -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; -import static java.lang.String.join; -import static java.util.stream.Collectors.toSet; - -@Component -public class TnvzResultVerifier { - - public void verify(DeliveryRequestType request, PersonResultType result) { - - if (result.getError() != null) { - var info = result.getError().getErrorInfo(); - throw moaZSExceptionBuilder("Receiver is not addressable. Reason: %s", info.getText()) - .withErrorCode(info.getCode()) - .withMzsRequest(request) - .withTnvzResult(result) - .build(); - } - - var mismatchedTypes = findMimeTypeMismatches(result, request); - - if (!mismatchedTypes.isEmpty()) { - var template = "Request contains attachment of type(s) %s, but receiver only accepts attachments" + - " of type(s) %s."; - var acceptedTypesString = join(",", getAcceptedTypes(result)); - var mismatchedTypesString = join(",", mismatchedTypes); - throw moaZSExceptionBuilder(template, mismatchedTypesString, acceptedTypesString) - .withErrorCode(MoaZSException.ERROR_MZS_MIMETYPE_MISSMATCH) - .withMzsRequest(request) - .withTnvzResult(result) - .build(); - } - } - - private Collection<String> findMimeTypeMismatches(PersonResultType result, DeliveryRequestType request) { - var acceptedTypes = getAcceptedTypes(result); - - if (acceptedTypes.contains("*/*")) { - return List.of(); - } - - var typesInRequest = request.getPayload().stream() - .map(DeliveryRequestType.Payload::getMIMEType) - .collect(toSet()); - - typesInRequest.removeAll(acceptedTypes); - - return typesInRequest; - } - - private List<String> getAcceptedTypes(PersonResultType result) { - return result.getSuccess().getMimeTypeList().getMimeType(); - } -} |