From 8400a1f99e7377e164a0d995359ff8c00a52c4e2 Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Tue, 18 Feb 2020 12:19:01 +0100 Subject: Timeout & Assync Fixes - Fix: Parser Error that occurs when MOA ZS goes into service timeout. - Fix: Improve exception handling on MOA ZS Async. - Before: When MOA ZS processes delivery request but hits a timeout, MOA ZS would answer syncronously to the Sender app and forward the result assynchronously at a later point. If an exception were to occur after the timeout, MOA ZS would swallow this exception. - Now: If an exception occurs, MOA ZS converts the exception into a response and hands it over to the sink hub for proper processing of the event. --- .../egiz/moazs/backend/SaveResponseToFileSink.java | 2 +- .../java/at/gv/egiz/moazs/service/MzsService.java | 58 ++++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java b/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java index c844511..d442add 100644 --- a/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java +++ b/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java @@ -86,7 +86,7 @@ public class SaveResponseToFileSink { .exceptionally(ex -> logException(ex, responseID)); var binaryResponsePath = generatePath(rootPath, responseID, "binary.xml"); - var storeBinaryResponseToFileSystemFuture = supplyAsync(() -> repository.retrieveBinaryResponse(responseID).get(), taskExecutor) + var storeBinaryResponseToFileSystemFuture = supplyAsync(() -> repository.retrieveBinaryResponse(responseID).orElse(new byte[0]), taskExecutor) .thenAccept(binaryResponseByteArray -> storeToFile(binaryResponsePath, binaryResponseByteArray)) .exceptionally(ex -> logException(ex, responseID)); 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 565e374..a2af4f1 100644 --- a/src/main/java/at/gv/egiz/moazs/service/MzsService.java +++ b/src/main/java/at/gv/egiz/moazs/service/MzsService.java @@ -46,6 +46,9 @@ import java.util.function.Consumer; import static at.gv.egiz.moazs.MoaZSException.moaZSException; import static at.gv.zustellung.app2mzs.xsd.PartialSuccessType.partialSuccessTypeBuilder; +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 java.lang.String.format; import static java.lang.Thread.currentThread; import static java.util.concurrent.CompletableFuture.supplyAsync; @@ -149,15 +152,62 @@ public class MzsService implements App2MzsPortType { log.info(SERVICE_TIME_OUT_REACHED_MSG, appDeliveryID); var sinkParams = request.getConfig().getMsgResponseSinks(); - requestProcessed.thenCompose(response -> hub.applySinks(response, sinkParams)); + requestProcessed + .exceptionally(e -> logErrorAndConvert(e, request)) + .thenCompose(response -> hub.applySinks(response, sinkParams)); - return generatePartialSuccessResponse(appDeliveryID); + var deliverySystem = request.getConfig().getMSGClient().getURL(); + return generatePartialSuccessResponse(appDeliveryID, deliverySystem); } - private DeliveryResponseType generatePartialSuccessResponse(String appDeliveryId) { + private RequestStatusResponse logErrorAndConvert(Throwable exception, DeliveryRequestType request) { + + var appDeliveryID = request.getMetaData().getAppDeliveryID(); + var errorMessage = format(MZS_SERVICE_ERROR_MSG, appDeliveryID); + log.error(errorMessage, exception); + + var explanation = generateExplanation(exception); + var text = format("%s Reason: %s", errorMessage, explanation); + + var errorInfo = errorInfoTypeBuilder() + .withCode("500") + .withText(text) + .build(); + + var deliverySystem = request.getConfig().getMSGClient().getURL(); + var zsDeliveryID = "unknown"; + var error = errorBuilder() + .withErrorInfo(errorInfo) + .withDeliverySystem(deliverySystem) + .withZSDeliveryID(zsDeliveryID) + .withAppDeliveryID(appDeliveryID) + .build(); + + var status = deliveryRequestStatusTypeBuilder() + .withError(error) + .build(); + + return new RequestStatusResponse(status); + } + + private String generateExplanation(Throwable exception) { + + StringBuilder s = new StringBuilder(exception.toString()); + Throwable cause = exception.getCause(); + + while (cause != null && cause != cause.getCause()) { + s.append("; Reason: ").append(cause.toString()); + cause = cause.getCause(); + } + + return s.toString(); + } + + private DeliveryResponseType generatePartialSuccessResponse(String appDeliveryID, String deliverySystem) { var partial = partialSuccessTypeBuilder() - .withAppDeliveryID(appDeliveryId) + .withAppDeliveryID(appDeliveryID) + .withDeliverySystem(deliverySystem) .build(); return DeliveryResponseType.deliveryResponseTypeBuilder() -- cgit v1.2.3