diff options
Diffstat (limited to 'src/main/java/at/gv/egiz/moazs/service')
-rw-r--r-- | src/main/java/at/gv/egiz/moazs/service/MsgService.java | 74 | ||||
-rw-r--r-- | src/main/java/at/gv/egiz/moazs/service/MzsService.java | 112 |
2 files changed, 186 insertions, 0 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/service/MsgService.java b/src/main/java/at/gv/egiz/moazs/service/MsgService.java new file mode 100644 index 0000000..93f1ed5 --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/service/MsgService.java @@ -0,0 +1,74 @@ +package at.gv.egiz.moazs.service; +import at.gv.egiz.moazs.process.MsgResponseHandler; +import at.gv.egiz.moazs.repository.DeliveryRepository; +import at.gv.egiz.moazs.scheme.MsgResponse; +import at.gv.egiz.moazs.scheme.NameSpace; +import at.gv.egiz.moazs.scheme.NotificationResponse; +import at.gv.egiz.moazs.scheme.RequestStatusResponse; +import at.gv.zustellung.msg.xsd.*; +import org.apache.cxf.annotations.SchemaValidation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import static at.gv.zustellung.msg.xsd.DeliveryNotificationACKType.deliveryNotificationACKTypeBuilder; +import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusACKType.deliveryRequestStatusACKTypeBuilder; +import static at.gv.zustellung.msg.xsd.GetVersionResponse.getVersionResponseBuilder; +import static java.util.concurrent.CompletableFuture.runAsync; + +@Service +@SchemaValidation(type = SchemaValidation.SchemaValidationType.BOTH) +public class MsgService implements Zuse2AppPort { + + private final DeliveryRepository repository; + private final MsgResponseHandler handler; + + @Autowired + public MsgService(DeliveryRepository repository, MsgResponseHandler handler) { + this.repository = repository; + this.handler = handler; + } + + @Override + public GetVersionResponse getVersion(SimpleRequestType getVersionRequest) { + return getVersionResponseBuilder() + .withVersion(NameSpace.MSG_VERSION) + .build(); + } + + @Override + public DeliveryRequestStatusACKType status(DeliveryRequestStatusType status) { + var response = new RequestStatusResponse(status); + sendToWork(response); + return statusAck(response.getAppDeliveryID(), response.getZSDeliveryID()); + } + + private DeliveryRequestStatusACKType statusAck(String appDeliveryID, String zsDeliveryID) { + return deliveryRequestStatusACKTypeBuilder() + .withAppDeliveryID(appDeliveryID) + .withZSDeliveryID(zsDeliveryID) + .withVersion(NameSpace.MSG_VERSION) + .build(); + } + + @Override + public DeliveryNotificationACKType notification(DeliveryNotificationType notification) { + var response = new NotificationResponse(notification); + sendToWork(response); + return notificationAck(response.getAppDeliveryID(), response.getZSDeliveryID()); + } + + private void sendToWork(MsgResponse response) { + runAsync(() -> repository.add(response)) + .thenRunAsync(() -> handler.handle(response.getResponseID())); + } + + private DeliveryNotificationACKType notificationAck(String appDeliveryID, String zsDeliveryID) { + return deliveryNotificationACKTypeBuilder() + .withAppDeliveryID(appDeliveryID) + .withZSDeliveryID(zsDeliveryID) + .withVersion(NameSpace.MSG_VERSION) + .build(); + } + + +} diff --git a/src/main/java/at/gv/egiz/moazs/service/MzsService.java b/src/main/java/at/gv/egiz/moazs/service/MzsService.java new file mode 100644 index 0000000..c41740f --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/service/MzsService.java @@ -0,0 +1,112 @@ +package at.gv.egiz.moazs.service; + +import at.gv.egiz.moazs.preprocess.DeliveryRequestAugmenter; +import at.gv.egiz.moazs.process.DeliveryPipeline; +import at.gv.egiz.moazs.repository.BinaryRepository; +import at.gv.egiz.moazs.repository.DeliveryRepository; +import at.gv.egiz.moazs.scheme.Msg2MzsConverter; +import at.gv.egiz.moazs.client.MzsClient; +import at.gv.egiz.moazs.scheme.RequestStatusResponse; +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.msg.xsd.DeliveryRequestStatusType; +import org.apache.cxf.annotations.SchemaValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.jws.WebParam; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +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.util.concurrent.CompletableFuture.supplyAsync; + +//todo : validate Schema in both directions. +@Service +@SchemaValidation(type = SchemaValidation.SchemaValidationType.IN) +public class MzsService implements App2MzsPortType { + + private static final Logger logger = LoggerFactory.getLogger(MzsService.class); + + //TODO move timeout and namespaces to config + private static final int TIMEOUT_FOR_ANWSER = 10; + + private final DeliveryRepository repository; + private final DeliveryPipeline pipeline; + private final MzsClient appClient; + private final DeliveryRequestAugmenter augmenter; + private final Msg2MzsConverter converter; + private final BinaryRepository binaryStatusRepository; + + @Autowired + public MzsService(DeliveryRepository repository, DeliveryPipeline pipeline, MzsClient appClient, + DeliveryRequestAugmenter augmenter, Msg2MzsConverter converter, BinaryRepository binaryStatusRepository) { + this.repository = repository; + this.pipeline = pipeline; + this.appClient = appClient; + this.augmenter = augmenter; + this.converter = converter; + this.binaryStatusRepository = binaryStatusRepository; + } + + @Override + public DeliveryResponseType app2Mzs( + @WebParam(partName = "DeliveryRequest", + name = "DeliveryRequest") + DeliveryRequestType deliveryRequest) { + + var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID(); + var responseID = RequestStatusResponse.getResponseID(appDeliveryID); + + var future = supplyAsync(() -> augmenter.augment(deliveryRequest)) + .thenApply(this::process) + .thenApply(status -> converter.convert(status, binaryStatusRepository.get(responseID))); + + try { + return future.get(TIMEOUT_FOR_ANWSER, TimeUnit.SECONDS); + } catch (TimeoutException e) { + logger.info("Answer Timed Out", e); + + future.thenAccept(appClient::sendNotification); + return generatePartialSuccessResponse(appDeliveryID); + + } catch (Exception e) { + throw moaZSExceptionBuilder("An error occurred while processing DeliveryRequest " + + "with AppDeliveryID=%s.", appDeliveryID) + .withCause(e) + .build(); + } + + } + + private DeliveryRequestStatusType process(DeliveryRequestType deliveryRequest) { + + var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID(); + logger.info("Receive request with appDeliveryID = {}.", appDeliveryID); + + repository.add(deliveryRequest); + pipeline.processRequest(appDeliveryID); + + var statusId = RequestStatusResponse.getResponseID(appDeliveryID); + var response = repository.getResponse(statusId) + .orElseThrow(() -> moaZSException("Could not get a response for AppDeliveryID=%s.", appDeliveryID)); + return (DeliveryRequestStatusType) response.getResponse(); + } + + private DeliveryResponseType generatePartialSuccessResponse(String appDeliveryId) { + + var partial = partialSuccessTypeBuilder() + .withAppDeliveryID(appDeliveryId) + .build(); + + return DeliveryResponseType.deliveryResponseTypeBuilder() + .withPartialSuccess(partial) + .build(); + } + +} |