diff options
15 files changed, 182 insertions, 261 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/MoaZSException.java b/src/main/java/at/gv/egiz/moazs/MoaZSException.java index dbb2894..499dc14 100644 --- a/src/main/java/at/gv/egiz/moazs/MoaZSException.java +++ b/src/main/java/at/gv/egiz/moazs/MoaZSException.java @@ -1,167 +1,51 @@ package at.gv.egiz.moazs; -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; public class MoaZSException extends RuntimeException { public static final String ERROR_MZS_MIMETYPE_MISSMATCH = "8001"; public static final String ERROR_MZS_NO_TNVZ_PERSON_QUERY_RESULTS = "8002"; + public static final String ERROR_MZS_BINARY_RESPONSE_MISSING = "8003"; + public static final String ERROR_MZS_RESPONSE_MISSING = "8004"; public static final String ERROR_MOASP_SIGNATURE_INVALID = "7001"; - @Nullable - private final String errorCode; - @Nullable - private final PreAdviceNoteSentType preAdviceNoteSent; - @Nullable - private final String deliverySystem; - @Nullable - private final String gz; - @Nullable - private final String zsDeliveryID; - @Nullable - private final String appDeliveryID; + @Nullable private final String code; + @Nullable private final PreAdviceNoteSentType preAdviceNoteSent; - private MoaZSException(Builder builder) { - super(builder.message, builder.cause); - this.errorCode = builder.errorCode; - this.preAdviceNoteSent = builder.preAdviceNoteSent; - this.deliverySystem = builder.deliverySystem; - this.gz = builder.gz; - this.zsDeliveryID = builder.zsDeliveryID; - this.appDeliveryID = builder.appDeliveryID; + private MoaZSException(String message, Throwable cause, @Nullable String code, @Nullable PreAdviceNoteSentType preAdviceNoteSent) { + super(message, cause); + this.code = code; + this.preAdviceNoteSent = preAdviceNoteSent; } - public static MoaZSException moaZSException(String message, Throwable cause) { - return moaZSExceptionBuilder(message).withCause(cause).build(); - } - - public static MoaZSException moaZSException(String formatString, Object... objects) { - return moaZSExceptionBuilder(formatString, objects).build(); - } - - public static MoaZSException moaZSException(String message) { - return moaZSExceptionBuilder(message).build(); - } - - public static Builder moaZSExceptionBuilder(String formatString, Object... objects) { - return new Builder().withMessage(String.format(formatString, objects)); + @Nullable public String getCode() { + return code; } - public static Builder moaZSExceptionBuilder(String message) { - return new Builder().withMessage(message); - } - - public static Builder moaZSExceptionBuilder() { - return new Builder(); - } - - @Nullable - public String getErrorCode() { - return errorCode; - } - - @Nullable - public PreAdviceNoteSentType getPreAdviceNoteSent() { + @Nullable public PreAdviceNoteSentType getPreAdviceNoteSent() { return preAdviceNoteSent; } - @Nullable - public String getDeliverySystem() { - return deliverySystem; + public static MoaZSException moaZSException(String message, Throwable cause) { + return new MoaZSException(message, cause, null, null); } - @Nullable - public String getGz() { - return gz; + public static MoaZSException moaZSException(String message) { + return new MoaZSException(message, null, null, null); } - @Nullable - public String getZsDeliveryID() { - return zsDeliveryID; + public static MoaZSException moaZSException(String message, String code) { + return new MoaZSException(message, null, code, null); } - @Nullable - public String getAppDeliveryID() { - return appDeliveryID; + public static MoaZSException moaZSException(String message, String code, Throwable cause) { + return new MoaZSException(message, cause, code, null); } - public static class Builder { - - private String message; - private Throwable cause; - private String errorCode; - 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; - } - - public Builder withMessage(String formatString, Object... objects ) { - this.message = String.format(formatString, objects); - return this; - } - - public Builder withCause(Throwable cause) { - this.cause = cause; - return this; - } - - public Builder withErrorCode(String errorCode) { - this.errorCode = errorCode; - return this; - } - - public Builder withPreAdviceNoteSent(PersonResultType personResult) { - if (personResult.getError() != null) { - this.preAdviceNoteSent = personResult.getError().getPreAdviceNoteSent(); - } - return this; - } - - public Builder withDeliverySystem(at.gv.zustellung.app2mzs.xsd.DeliveryRequestType mzsRequest) { - this.deliverySystem = mzsRequest.getConfig().getMSGClient().getURL(); - return this; - } - - - 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 withAppDeliveryID(String appDeliveryID) { - this.appDeliveryID = appDeliveryID; - return this; - } - - public MoaZSException build() { - return new MoaZSException(this); - } + public static MoaZSException moaZSException(String message, String code, PreAdviceNoteSentType preAdviceNoteSent) { + return new MoaZSException(message, null, code, preAdviceNoteSent); } } diff --git a/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java b/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java index 06eba80..6a1e0fd 100644 --- a/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java +++ b/src/main/java/at/gv/egiz/moazs/backend/DeliveryRequestBackend.java @@ -9,6 +9,7 @@ import at.gv.egiz.moazs.scheme.Mzs2MsgConverter; import at.gv.egiz.moazs.scheme.RequestStatusResponse; import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType; import at.gv.zustellung.msg.xsd.App2ZusePort; +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; @@ -17,8 +18,10 @@ import org.springframework.stereotype.Component; import java.util.function.Consumer; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; -import static at.gv.egiz.moazs.scheme.RequestStatusResponse.generateErrorFromException; +import static at.gv.egiz.moazs.scheme.RequestStatusResponse.*; +import static at.gv.egiz.moazs.scheme.RequestStatusResponse.generateError; +import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Error.errorBuilder; +import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder; import static java.lang.String.format; @Component @@ -28,6 +31,10 @@ public class DeliveryRequestBackend implements Consumer<String> { private static final Logger log = Logger.getLogger(DeliveryRequestBackend.class); private static final String MZS_PIPELINE_ERROR_MSG = "An error occured while processing the DeliveryRequest with AppDeliveryID=%s. "; + private static final String DELIVERY_REQUEST_MISSING_ERROR_MSG = + "DeliveryRequest for AppDeliveryID=%s is not in repository. " ; + private static final String BINARY_RESPONSE_MISSING_ERROR_MSG = + "Binary DeliveryRequestStatus for AppDeliveryID=%s is not in repository. " ; private final DeliveryRepository repository; private final TnvzHelper tnvzHelper; @@ -60,49 +67,53 @@ public class DeliveryRequestBackend implements Consumer<String> { @Override public void accept(String appDeliveryID) { - var exceptionBuilder = moaZSExceptionBuilder(); + DeliveryRequestStatusType status = null; + var fallbackAnswerBuilder = errorBuilder().withAppDeliveryID(appDeliveryID); try { - var mzsRequest = repository.retrieveDeliveryRequest(appDeliveryID).orElseThrow(); - exceptionBuilder.withDeliverySystem(mzsRequest); - - at.gv.zustellung.msg.xsd.DeliveryRequestType msgRequest = buildMsgRequest(mzsRequest, exceptionBuilder); + var mzsRequest = repository.retrieveDeliveryRequest(appDeliveryID).orElseThrow( + () -> MoaZSException.moaZSException(format(DELIVERY_REQUEST_MISSING_ERROR_MSG, appDeliveryID))); + fallbackAnswerBuilder.withDeliverySystem(mzsRequest.getConfig().getMSGClient().getURL()); + var msgRequest = buildMsgRequest(mzsRequest); var msgClientParams = mzsRequest.getConfig().getMSGClient(); App2ZusePort client = clientFactory.create(msgClientParams, App2ZusePort.class); - var status = client.delivery(msgRequest); + status = client.delivery(msgRequest); var response = new RequestStatusResponse(status); - exceptionBuilder.withAllParametersInAnswer(response.getAnswer()); - verifySignedStatus(response.getResponseID(), appDeliveryID, exceptionBuilder); + verifySignedStatus(response.getResponseID(), appDeliveryID); repository.store(response); } catch (MoaZSException exception) { log.error(format(MZS_PIPELINE_ERROR_MSG, appDeliveryID), exception); - var errorResponse = generateErrorFromException(exception); - repository.store(errorResponse); + + var templateAnswer = (status == null) + ? fallbackAnswerBuilder.build() + : getAnswer(status); + + var errorStatus = generateError(exception, templateAnswer); + repository.store(errorStatus); } } - private void verifySignedStatus(String responseID, String appDeliveryID, MoaZSException.Builder exceptionBuilder) throws MoaZSException { + private void verifySignedStatus(String responseID, String appDeliveryID) throws MoaZSException { try { - var signedStatus = repository.retrieveBinaryResponse(responseID).get(); + var signedStatus = repository.retrieveBinaryResponse(responseID).orElseThrow( + () -> MoaZSException.moaZSException(format(BINARY_RESPONSE_MISSING_ERROR_MSG, responseID))); signatureVerifier.accept(signedStatus); } catch (MoaZSException ex) { - throw exceptionBuilder.withMessage(format(MsgResponseBackend.MOASP_SIGNATURE_INVALID_ERROR_MSG, appDeliveryID)) - .withErrorCode(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID) - .withCause(ex) - .build(); + var message = format(MsgResponseBackend.MOASP_SIGNATURE_INVALID_ERROR_MSG, appDeliveryID); + var code = MoaZSException.ERROR_MOASP_SIGNATURE_INVALID; + throw MoaZSException.moaZSException(message, code, ex); } } - private at.gv.zustellung.msg.xsd.DeliveryRequestType buildMsgRequest(DeliveryRequestType mzsRequest, - MoaZSException.Builder exceptionBuilder) throws MoaZSException { + private at.gv.zustellung.msg.xsd.DeliveryRequestType buildMsgRequest(DeliveryRequestType mzsRequest) 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); + var identification = tnvzHelper.performQueryPersonRequest(mzsRequest, tvnzPort); return converter.convert(mzsRequest, identification); } else { return converter.convert(mzsRequest); diff --git a/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java b/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java index 9e3cd36..8649a32 100644 --- a/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java +++ b/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; import java.util.function.Consumer; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; +import static at.gv.egiz.moazs.MoaZSException.*; import static java.lang.String.format; import static java.util.concurrent.CompletableFuture.supplyAsync; @@ -23,6 +23,8 @@ public class MsgResponseBackend implements Consumer<String> { public static final String MOASP_SIGNATURE_INVALID_ERROR_MSG = "Signature of Msg Response " + "with AppDeliveryID=%s is not valid."; + public static final String BINARY_RESPONSE_MISSING_ERROR_MSG = "Binary Response is not in repository."; + public static final String RESPONSE_MISSING_ERROR_MSG = "Response with ResponseID=%s is not in repository."; private final DeliveryRepository repository; private final Consumer<byte[]> signatureVerifier; @@ -58,28 +60,28 @@ public class MsgResponseBackend implements Consumer<String> { public void accept(String responseID) { supplyAsync(() -> verify(responseID)) - .thenAcceptAsync(msgResponse -> applySinks(msgResponse)); + .thenAcceptAsync(msgResponse -> applySinks(msgResponse)) + .exceptionally(ex -> { + log.error(ex.getMessage(), ex); + return null; + }); } private MsgResponse verify(String responseID) { - var response = repository.retrieveResponse(responseID).get(); - var builder = moaZSExceptionBuilder().withAllParametersInAnswer(response.getAnswer()); - - var binaryResponse = repository.retrieveBinaryResponse(responseID).get(); + var response = repository.retrieveResponse(responseID).orElseThrow( + ()-> moaZSException(format(RESPONSE_MISSING_ERROR_MSG, responseID))); try { + var binaryResponse = repository.retrieveBinaryResponse(responseID).orElseThrow( + () -> moaZSException(BINARY_RESPONSE_MISSING_ERROR_MSG, MoaZSException.ERROR_MZS_BINARY_RESPONSE_MISSING)); signatureVerifier.accept(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); + var text = format(MOASP_SIGNATURE_INVALID_ERROR_MSG, response.getAppDeliveryID()); + var code = ERROR_MOASP_SIGNATURE_INVALID; + return response.generateError(text, code); } } diff --git a/src/main/java/at/gv/egiz/moazs/backend/SignatureVerifier.java b/src/main/java/at/gv/egiz/moazs/backend/SignatureVerifier.java index f9bbeb3..874e4f4 100644 --- a/src/main/java/at/gv/egiz/moazs/backend/SignatureVerifier.java +++ b/src/main/java/at/gv/egiz/moazs/backend/SignatureVerifier.java @@ -3,13 +3,13 @@ package at.gv.egiz.moazs.backend; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.ISignatureVerificationService; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; +import at.gv.egiz.moazs.MoaZSException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.function.Consumer; import static at.gv.egiz.moazs.MoaZSException.moaZSException; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; import static java.lang.String.format; public class SignatureVerifier implements Consumer<byte[]> { @@ -21,6 +21,8 @@ public class SignatureVerifier implements Consumer<byte[]> { private static final String CERT_CODE_ERROR_MSG = "Certificate chain is not valid: Check code was %d. "; private static final String MANIFEST_CODE_ERROR_MSG = "Signature Manifest is not valid: Check code was %d. "; private static final String XMLMANIFEST_CODE_ERROR_MSG = "XmlDSIGManifest is not valid: Check code was %d. "; + + //TODO: Dont make this multiline! private static final String XML_SIGNATURE_RESPONSE_TEMPLATE = " XmlDsigSubjectName: %s\n" + " SignatureManifestCheckCode: %s\n" + @@ -93,14 +95,12 @@ public class SignatureVerifier implements Consumer<byte[]> { var msg = builder.toString(); - if(msg.length() > 0) { + if(!msg.isEmpty()) { throw moaZSException(msg); } } catch (MOASigServiceException e) { - throw moaZSExceptionBuilder(MOASIG_SERVICE_ERROR_MSG) - .withCause(e) - .build(); + throw moaZSException(MOASIG_SERVICE_ERROR_MSG, e); } } diff --git a/src/main/java/at/gv/egiz/moazs/client/SSLContextCreator.java b/src/main/java/at/gv/egiz/moazs/client/SSLContextCreator.java index 8fb5d80..47a2f1c 100644 --- a/src/main/java/at/gv/egiz/moazs/client/SSLContextCreator.java +++ b/src/main/java/at/gv/egiz/moazs/client/SSLContextCreator.java @@ -6,13 +6,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import javax.net.ssl.X509TrustManager; import javax.net.ssl.*; import java.io.IOException; import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import static at.gv.egiz.moazs.MoaZSException.moaZSException; import static java.lang.String.format; diff --git a/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java index 884be3e..de22805 100644 --- a/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java +++ b/src/main/java/at/gv/egiz/moazs/client/TnvzHelper.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import static at.gv.egiz.moazs.MoaZSException.moaZSException; 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; @@ -52,21 +53,19 @@ public class TnvzHelper { * {@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) { + TNVZServicePort tvnzPort) { var tvnzQuery = buildQuery(mzsRequest); var tvnzResponse = tvnzPort.queryPerson(tvnzQuery); - verifyResponse(tvnzResponse, exceptionBuilder); + verifyResponse(tvnzResponse); var tvnzResult = getResult(tvnzResponse); var typesInRequest = extractListOfMimemtypesIn(mzsRequest); - checkMimetypes(tvnzResult, typesInRequest, exceptionBuilder); + checkMimetypes(tvnzResult, typesInRequest); return tvnzResult.getSuccess().getIdentification(); } @@ -170,30 +169,26 @@ public class TnvzHelper { .collect(toSet()); } - private void verifyResponse(QueryPersonResponse tvnzResponse, MoaZSException.Builder mzsBuilder) { + private void verifyResponse(QueryPersonResponse tvnzResponse) { var error = tvnzResponse.getError(); if (error != null) { - throw mzsBuilder.withErrorCode(error.getCode()) - .withMessage(error.getText()) - .build(); + throw MoaZSException.moaZSException(error.getText(), error.getCode()); } 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(); + throw MoaZSException.moaZSException(MZS_NO_TNVZ_PERSON_QUERY_RESULTS_ERROR_MSG, + MoaZSException.ERROR_MZS_NO_TNVZ_PERSON_QUERY_RESULTS); } var tnvzResult = results.get(0); - mzsBuilder.withPreAdviceNoteSent(tnvzResult); if (tnvzResult.getError() != null) { var info = tnvzResult.getError().getErrorInfo(); - throw mzsBuilder.withErrorCode(info.getCode()) - .withMessage(RECEIVER_NOT_ADRESSABLE_ERROR_MSG, info.getText()) - .build(); + var message = String.format(RECEIVER_NOT_ADRESSABLE_ERROR_MSG, info.getText()); + var code = info.getCode(); + throw moaZSException(message, code, tnvzResult.getError().getPreAdviceNoteSent()); } } @@ -201,14 +196,14 @@ public class TnvzHelper { return tvnzResponse.getQueryResultList().getQueryResult().get(0); } - private void checkMimetypes(PersonResultType tnvzResult, Set<String> typesInRequest, MoaZSException.Builder mzsBuilder) { + private void checkMimetypes(PersonResultType tnvzResult, Set<String> typesInRequest) { 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(); + var message = String.format(MIMETYPE_MISSMATCH_ERROR_MSG, mismatchedTypesString, acceptedTypesString); + var code = MoaZSException.ERROR_MZS_MIMETYPE_MISSMATCH; + throw MoaZSException.moaZSException(message, code); } } 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 eac7ea6..e7ee357 100644 --- a/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java +++ b/src/main/java/at/gv/egiz/moazs/preprocess/DeliveryRequestAugmenter.java @@ -9,6 +9,7 @@ import java.util.Map; import static at.gv.egiz.moazs.MoaZSException.moaZSException; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder; +import static java.lang.String.format; @Component public class DeliveryRequestAugmenter { @@ -62,7 +63,8 @@ public class DeliveryRequestAugmenter { : util.merge(requestConfig, fallbackConfig); if (!validator.isConfigProfileComplete(mergedConfig)) { - throw moaZSException(INCOMPLETE_MERGED_CONFIG_ERROR_MESSAGE, fallbackProfileId); + var message = format(INCOMPLETE_MERGED_CONFIG_ERROR_MESSAGE, fallbackProfileId); + throw moaZSException(message); } var mergedRequest = deliveryRequestTypeBuilder(request) diff --git a/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java b/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java index 8bd88d9..c4fd0b7 100644 --- a/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java +++ b/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java @@ -1,6 +1,5 @@ package at.gv.egiz.moazs.scheme; -import at.gv.egiz.moazs.MoaZSException; import at.gv.zustellung.app2mzs.xsd.Mzs2AppPortType; import at.gv.zustellung.msg.xsd.DeliveryAnswerType; @@ -33,7 +32,14 @@ public abstract class MsgResponse <T> { public abstract String getAppDeliveryID(); public abstract String getZSDeliveryID(); public abstract DeliveryAnswerType getAnswer(); - public abstract MsgResponse<T> generateError(MoaZSException exception); + + /** + * Create an error response that is based on the current response. + * @param text describes the error. + * @param code contains an error code. + * @return Deep Copy of response but of "error" type + */ + public abstract MsgResponse<T> generateError(String text, String code); public abstract CompletableFuture<Void> sendToMzsClient(Msg2MzsConverter converter, Optional<byte[]> signedStatus, Mzs2AppPortType client); } 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 bb7f621..6b6f34a 100644 --- a/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java +++ b/src/main/java/at/gv/egiz/moazs/scheme/NameSpace.java @@ -16,5 +16,6 @@ public class NameSpace { 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(); + public static final String MSG_APP_DELIVERY_ID = MSG_FACTORY.createAppDeliveryID("").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 index 21e00a1..4e7abae 100644 --- a/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java +++ b/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java @@ -1,16 +1,17 @@ package at.gv.egiz.moazs.scheme; -import at.gv.egiz.moazs.MoaZSException; import at.gv.zustellung.app2mzs.xsd.Mzs2AppPortType; import at.gv.zustellung.msg.xsd.DeliveryAnswerType; import at.gv.zustellung.msg.xsd.DeliveryNotificationType; +import at.gv.zustellung.msg.xsd.ErrorInfoType; import at.gv.zustellung.msg.xsd.ObjectFactory; import javax.xml.bind.JAXBElement; - +import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import static at.gv.zustellung.msg.xsd.DeliveryErrorType.deliveryErrorTypeBuilder; import static at.gv.zustellung.msg.xsd.DeliveryNotificationType.deliveryNotificationTypeBuilder; public class NotificationResponse extends MsgResponse<DeliveryNotificationType> { @@ -54,14 +55,19 @@ public class NotificationResponse extends MsgResponse<DeliveryNotificationType> } @Override - public NotificationResponse generateError(MoaZSException exception) { - - //TODO: use copy constructor? - var notificationType = deliveryNotificationTypeBuilder() - .withAppDeliveryID(exception.getAppDeliveryID()) - .withDeliverySystem(exception.getDeliverySystem()) - .withGZ(exception.getGz()) - .withZSDeliveryID(exception.getZsDeliveryID()) + public NotificationResponse generateError(String text, String code) { + + var info = ErrorInfoType.errorInfoTypeBuilder() + .withCode(code) + .withText(text) + .build(); + + var error = deliveryErrorTypeBuilder() + .withErrorInfo(info) + .build(); + + var notificationType = deliveryNotificationTypeBuilder(notification) + .withAnswer(List.of(factory.createAnswer(error))) .build(); return new NotificationResponse(notificationType); diff --git a/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java b/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java index 14e22ad..8a4b590 100644 --- a/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java +++ b/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java @@ -6,11 +6,13 @@ import at.gv.zustellung.msg.xsd.DeliveryAnswerType; import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType; import at.gv.zustellung.msg.xsd.ErrorInfoType; import at.gv.zustellung.msg.xsd.ObjectFactory; +import org.springframework.lang.Nullable; import javax.xml.bind.JAXBElement; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import static at.gv.egiz.moazs.MoaZSException.moaZSException; 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; @@ -26,10 +28,19 @@ public class RequestStatusResponse extends MsgResponse<DeliveryRequestStatusType public RequestStatusResponse(DeliveryRequestStatusType status) { this.status = status; - this.answer = coalesce(status.getSuccess(), status.getPartialSuccess(), status.getError()).get(); + this.answer = getAnswer(status); super.id = createResponseId(answer.getAppDeliveryID(), ID_SUFFIX); } + /** + * Convenience method to access DeliveryAnswerType's base fields of Success, PartialSuccess or Error. + * @param status + * @return Success, PartialSuccess, or Error casted to DeliveryAnswerType + */ + public static DeliveryAnswerType getAnswer(DeliveryRequestStatusType status) { + return coalesce(status.getSuccess(), status.getPartialSuccess(), status.getError()).get(); + } + public static String getResponseID(String appDeliveryID) { return appDeliveryID + ID_SUFFIX; } @@ -60,31 +71,42 @@ public class RequestStatusResponse extends MsgResponse<DeliveryRequestStatusType } @Override - public MsgResponse<DeliveryRequestStatusType> generateError(MoaZSException exception) { - return generateErrorFromException(exception); + public MsgResponse<DeliveryRequestStatusType> generateError(String text, String code) { + var auxException = moaZSException(text, code); + return generateError(auxException, answer); } - public static MsgResponse<DeliveryRequestStatusType> generateErrorFromException(MoaZSException exception) { + /** + * Creates A MsgResponse with a DeliveryRequestStatus of type error and merges fields from + * {@code exception} and {@code answer} + * @param exception + * @param answer + * @return + */ + public static MsgResponse<DeliveryRequestStatusType> generateError(MoaZSException exception, + @Nullable DeliveryAnswerType answer) { ErrorInfoType info = errorInfoTypeBuilder() .withText(exception.getMessage()) - .withCode(exception.getErrorCode()) + .withCode(exception.getCode()) .build(); - DeliveryRequestStatusType.Error error = errorBuilder() - .withErrorInfo(info) - .withAppDeliveryID(exception.getAppDeliveryID()) - .withDeliverySystem(exception.getDeliverySystem()) - .withGZ(exception.getGz()) + var errorBuilder = errorBuilder() .withPreAdviceNoteSent(exception.getPreAdviceNoteSent()) - .withZSDeliveryID(exception.getZsDeliveryID()) - .build(); - - var status = deliveryRequestStatusTypeBuilder() - .withError(error) - .withVersion(NameSpace.MSG_VERSION) + .withErrorInfo(info); + + if (answer != null) { + errorBuilder + .withAppDeliveryID(answer.getAppDeliveryID()) + .withDeliverySystem(answer.getDeliverySystem()) + .withZSDeliveryID(answer.getZSDeliveryID()) + .withGZ(answer.getGZ()); + } + + var errorStatus = deliveryRequestStatusTypeBuilder() + .withError(errorBuilder.build()) .build(); - return new RequestStatusResponse(status); + return new RequestStatusResponse(errorStatus); } @Override diff --git a/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java b/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java index 8b8219a..6e96a6b 100644 --- a/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java +++ b/src/main/java/at/gv/egiz/moazs/scheme/SOAPUtils.java @@ -1,6 +1,7 @@ package at.gv.egiz.moazs.scheme; import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; +import at.gv.egiz.moazs.MoaZSException; import org.apache.cxf.binding.soap.Soap11; import org.springframework.stereotype.Component; import org.w3c.dom.Element; @@ -12,7 +13,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; @Component public class SOAPUtils { @@ -31,12 +31,12 @@ public class SOAPUtils { .getBytes(StandardCharsets.UTF_8); } catch (IOException | TransformerException e) { - throw moaZSExceptionBuilder("Error while parsing message. ").withCause(e).build(); + throw MoaZSException.moaZSException("Error while parsing message. ", e); } } public String getAppDeliveryIDFrom(Element document) { - var elements = document.getElementsByTagNameNS(NameSpace.MSG, "AppDeliveryID"); + var elements = document.getElementsByTagNameNS(NameSpace.MSG, NameSpace.MSG_APP_DELIVERY_ID); var appDeliveryIdElement = elements.item(0).getFirstChild(); diff --git a/src/main/java/at/gv/egiz/moazs/service/MzsService.java b/src/main/java/at/gv/egiz/moazs/service/MzsService.java index cbc56e4..8f0ef86 100644 --- a/src/main/java/at/gv/egiz/moazs/service/MzsService.java +++ b/src/main/java/at/gv/egiz/moazs/service/MzsService.java @@ -20,8 +20,8 @@ import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import static at.gv.egiz.moazs.MoaZSException.moaZSException; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; import static at.gv.zustellung.app2mzs.xsd.PartialSuccessType.partialSuccessTypeBuilder; +import static java.lang.String.format; import static java.util.concurrent.CompletableFuture.supplyAsync; //todo : validate Schema in both directions. @@ -33,6 +33,9 @@ public class MzsService implements App2MzsPortType { //TODO move timeout and namespaces to config private static final int TIMEOUT_FOR_ANWSER = 10; + private static final String MZS_SERVICE_ERROR_MSG = "An error occurred while processing DeliveryRequest " + + "with AppDeliveryID=%s."; + private static final String RESPONSE_MISSING_ERROR_MSG = "Could not get a response for AppDeliveryID=%s."; private final DeliveryRepository repository; private final Consumer<String> backend; @@ -71,10 +74,8 @@ public class MzsService implements App2MzsPortType { return generatePartialSuccessResponse(appDeliveryID); } catch (Exception e) { - throw moaZSExceptionBuilder("An error occurred while processing DeliveryRequest " + - "with AppDeliveryID=%s.", appDeliveryID) - .withCause(e) - .build(); + var message = format(MZS_SERVICE_ERROR_MSG, appDeliveryID); + throw moaZSException(message, e); } } @@ -82,6 +83,7 @@ public class MzsService implements App2MzsPortType { private DeliveryRequestStatusType process(DeliveryRequestType deliveryRequest) { var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID(); + //TODO: fix too. logger.info("Receive request with appDeliveryID = {}.", appDeliveryID); repository.store(deliveryRequest); @@ -89,7 +91,7 @@ public class MzsService implements App2MzsPortType { var statusId = RequestStatusResponse.getResponseID(appDeliveryID); var response = repository.retrieveResponse(statusId) - .orElseThrow(() -> moaZSException("Could not get a response for AppDeliveryID=%s.", appDeliveryID)); + .orElseThrow(() -> moaZSException(format(RESPONSE_MISSING_ERROR_MSG, appDeliveryID))); return (DeliveryRequestStatusType) response.getResponse(); } diff --git a/src/test/java/at/gv/egiz/moazs/DeliveryRequestBackendTest.java b/src/test/java/at/gv/egiz/moazs/DeliveryRequestBackendTest.java index ed63489..9ae0a14 100644 --- a/src/test/java/at/gv/egiz/moazs/DeliveryRequestBackendTest.java +++ b/src/test/java/at/gv/egiz/moazs/DeliveryRequestBackendTest.java @@ -20,7 +20,6 @@ import org.mockito.Mock; 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; @@ -57,11 +56,11 @@ public class DeliveryRequestBackendTest { private SignatureVerifier verifier; - private DeliveryRequestBackend pipeline; + private DeliveryRequestBackend backend; @Before public void setup() { - pipeline = new DeliveryRequestBackend( + backend = new DeliveryRequestBackend( repository, tnvzHelper, converter, @@ -74,7 +73,7 @@ public class DeliveryRequestBackendTest { var appDeliveryID = "no-tnvz-request"; var expectedStatus = setupMocks(appDeliveryID, false); - pipeline.accept(appDeliveryID); + backend.accept(appDeliveryID); verifyZeroInteractions(tnvzHelper); var response = repository.retrieveResponse(getResponseID(appDeliveryID)).get(); @@ -87,10 +86,10 @@ public class DeliveryRequestBackendTest { public void rejectDeliveryWhenReceiverIsNotAddressable() { var appDeliveryID = "not-addressable"; setupMocks(appDeliveryID, true); - when(tnvzHelper.performQueryPersonRequest(any(), any(), any())) - .thenThrow(buildMzsException("400", appDeliveryID)); + when(tnvzHelper.performQueryPersonRequest(any(), any())) + .thenThrow(moaZSException("Not addressable", "400")); - pipeline.accept(appDeliveryID); + backend.accept(appDeliveryID); var responseID = getResponseID(appDeliveryID); var response = repository.retrieveResponse(responseID).get(); @@ -99,7 +98,7 @@ public class DeliveryRequestBackendTest { assertThat(actualCode).isEqualTo("400"); verifyZeroInteractions(converter); - verify(tnvzHelper).performQueryPersonRequest(any(), any(), any()); + verify(tnvzHelper).performQueryPersonRequest(any(), any()); } @Test @@ -107,7 +106,7 @@ public class DeliveryRequestBackendTest { var appDeliveryID = "tnvz-request"; var expectedStatus = setupMocks(appDeliveryID, true); - pipeline.accept(appDeliveryID); + backend.accept(appDeliveryID); var response = repository.retrieveResponse(getResponseID(appDeliveryID)).get(); var actualStatus = (DeliveryRequestStatusType) response.getResponse(); @@ -120,7 +119,7 @@ public class DeliveryRequestBackendTest { setupMocks(appDeliveryID, true); doThrow(moaZSException("Signature Invalid!")).when(verifier).accept(any()); - pipeline.accept(appDeliveryID); + backend.accept(appDeliveryID); var response = repository.retrieveResponse(getResponseID(appDeliveryID)).get(); var status = (DeliveryRequestStatusType) response.getResponse(); var actualCode = status.getError().getErrorInfo().getCode(); @@ -146,19 +145,12 @@ public class DeliveryRequestBackendTest { if (tnvzRequest) { when(clientFactory.create(any(), same(TNVZServicePort.class))).thenReturn(tnvzClient); - when(tnvzHelper.performQueryPersonRequest(any(), any(), any())).thenReturn(identification); + when(tnvzHelper.performQueryPersonRequest(any(), any())).thenReturn(identification); } return status; } - private MoaZSException buildMzsException(String code, String appDeliveryID) { - return moaZSExceptionBuilder("") - .withErrorCode(code) - .withAppDeliveryID(appDeliveryID) - .build(); - } - private DeliveryRequestStatusType setupStatus(String appDeliveryId) { var success = successBuilder() diff --git a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java index b58002b..020e270 100644 --- a/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java +++ b/src/test/java/at/gv/egiz/moazs/TnvzHelperTest.java @@ -16,7 +16,6 @@ import org.mockito.junit.MockitoJUnitRunner; import java.util.List; -import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload.payloadBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Receiver.receiverBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Sender.senderBuilder; @@ -62,7 +61,7 @@ public class TnvzHelperTest { var success = tnvzSuccess(acceptedTypes, receiverId); when(port.queryPerson(any())).thenReturn(success); - var actual = helper.performQueryPersonRequest(deliveryRequest, port, moaZSExceptionBuilder()); + var actual = helper.performQueryPersonRequest(deliveryRequest, port); assertThat(actual).isEqualToComparingFieldByFieldRecursively(receiverId); } @@ -75,7 +74,7 @@ public class TnvzHelperTest { var error = tnvzError("400", "Person not found."); when(port.queryPerson(any())).thenReturn(error); - helper.performQueryPersonRequest(deliveryRequest, port, moaZSExceptionBuilder()); + helper.performQueryPersonRequest(deliveryRequest, port); } @Test(expected = MoaZSException.class) @@ -87,7 +86,7 @@ public class TnvzHelperTest { var success = tnvzSuccess(acceptedTypes, receiverId); when(port.queryPerson(any())).thenReturn(success); - helper.performQueryPersonRequest(deliveryRequest, port, moaZSExceptionBuilder()); + helper.performQueryPersonRequest(deliveryRequest, port); } @Test @@ -99,7 +98,7 @@ public class TnvzHelperTest { var success = tnvzSuccess(acceptedTypes, receiverId); when(port.queryPerson(any())).thenReturn(success); - var actual = helper.performQueryPersonRequest(deliveryRequest, port, moaZSExceptionBuilder()); + var actual = helper.performQueryPersonRequest(deliveryRequest, port); assertThat(actual).isEqualToComparingFieldByFieldRecursively(receiverId); } |