aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-04-18 11:05:31 +0200
committerChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-04-18 14:48:17 +0200
commitaed1250912476f47fd772b0cedd20c850cdcff6e (patch)
treee7fe6aed56b12e53a9b2a7eef62d339e7d23b8b2 /src
parent4215362c64064947cea880d55c4aae7894304783 (diff)
downloadmoa-zs-aed1250912476f47fd772b0cedd20c850cdcff6e.tar.gz
moa-zs-aed1250912476f47fd772b0cedd20c850cdcff6e.tar.bz2
moa-zs-aed1250912476f47fd772b0cedd20c850cdcff6e.zip
Change App2mzs Interface and Init Delivery Pipeline
- Change app2mzs interface: output message from app2mzs:DeliveryRequest was app2mzs:DeliveryResponse, now its msg:DeliveryRequestStatus. Reason: ZD returns msg:DeliveryRequestStatus which is signed. Moazs does not convert msg:DeliveryRequestStatus into app2mzs:DeliveryResponse because the conversion woudl break the signature. - App2MzsService: Make beans final and inject them with constructor; Refactor DeliveryRequestHandler into App2MZSService. - DeliveryPipeline: Add Interface and a "SameThreadImplementation" that executes the pipeline in the same threat and can be used in single mode. - DeliveryRepository: Augment interface for storing and retrieving request status objects; Add in-memory-implementation for status objects. - Utils: Add helper function for coalescing multiple values
Diffstat (limited to 'src')
-rw-r--r--src/main/java/at/gv/egiz/moazs/App2MzsService.java89
-rw-r--r--src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java38
-rw-r--r--src/main/java/at/gv/egiz/moazs/Mzs2AppClient.java4
-rw-r--r--src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java12
-rw-r--r--src/main/java/at/gv/egiz/moazs/pipeline/SameThreadDeliveryPipeline.java49
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java6
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java34
-rw-r--r--src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java10
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/NullCoalesce.java33
-rw-r--r--src/main/resources/mzs/app2mzs.xsd14
-rw-r--r--src/test/java/at/gv/egiz/moazs/App2MzsServiceTest.java2
11 files changed, 200 insertions, 91 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/App2MzsService.java b/src/main/java/at/gv/egiz/moazs/App2MzsService.java
index f8c00fc..8626c24 100644
--- a/src/main/java/at/gv/egiz/moazs/App2MzsService.java
+++ b/src/main/java/at/gv/egiz/moazs/App2MzsService.java
@@ -1,18 +1,21 @@
package at.gv.egiz.moazs;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.ObjectFactory;
import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs.App2MzsPortType;
-import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.*;
+import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
+import at.gv.egiz.moazs.pipeline.DeliveryPipeline;
+import at.gv.egiz.moazs.repository.DeliveryRepository;
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.math.BigInteger;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import static java.text.MessageFormat.format;
import static java.util.concurrent.CompletableFuture.supplyAsync;
@Service
@@ -20,63 +23,93 @@ public class App2MzsService implements App2MzsPortType {
private static final Logger logger = LoggerFactory.getLogger(App2MzsService.class);
- //TODO move timeout to config
- private final int timeoutForAnwser = 10;
- private final String MZSTNS = "http://reference.e-government.gv.at/namespace/zustellung/mzs/app2mzs#";
+ //TODO move timeout and namespaces to config
+ private static final int TIMEOUT_FOR_ANWSER = 10;
+ private static final String MZSTNS = "http://reference.e-government.gv.at/namespace/zustellung/mzs/app2mzs#";
- @Autowired
- private DeliveryRequestHandler deliveryRequestHandler;
+ private final DeliveryRepository repository;
+ private final DeliveryPipeline pipeline;
+ private final Mzs2AppClient appClient;
+ private final ObjectFactory objectFactory = new ObjectFactory();
- @Autowired
- private Mzs2AppClient appClient;
-
- @Autowired
- private ObjectFactory objectFactory;
+ public App2MzsService(@Autowired DeliveryRepository repository, @Autowired DeliveryPipeline pipeline, @Autowired Mzs2AppClient appClient) {
+ this.repository = repository;
+ this.pipeline = pipeline;
+ this.appClient = appClient;
+ }
@Override
- public DeliveryResponseType app2Mzs(
+ public DeliveryRequestStatusType app2Mzs(
@WebParam(partName = "DeliveryRequest",
name = "DeliveryRequest",
targetNamespace = MZSTNS)
DeliveryRequestType deliveryRequest) {
- var future = supplyAsync(() -> deliveryRequestHandler.apply(deliveryRequest));
+ final var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID();
+
+ var future = supplyAsync(() -> process(deliveryRequest));
try {
- return future.get(timeoutForAnwser, TimeUnit.SECONDS);
+ return future.get(TIMEOUT_FOR_ANWSER, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.thenAccept(appClient::sendNotification);
- logger.warn("Answer Timed Out", e);
- return generatePartialSuccessResponse(deliveryRequest);
+ logger.info("Answer Timed Out", e);
+ return generatePartialSuccessResponse(appDeliveryID, "Your request timed out; Wait until X for receiving a notification.");
} catch (Exception e ) {
logger.error("Could not deliver request.", e);
- return generateErrorResponse();
+ final var message = format("An error occured while delivering request: {}", e.getMessage());
+ return generateErrorResponse(appDeliveryID, message);
}
}
- private DeliveryResponseType generatePartialSuccessResponse(DeliveryRequestType deliveryRequest) {
+ private DeliveryRequestStatusType generatePartialSuccessResponse(String appDeliveryId, String message) {
- var partialSuccess = objectFactory.createPartialSuccessType();
- partialSuccess.setAppDeliveryID(deliveryRequest.getMetaData().getAppDeliveryID());
+ var partialSuccess = objectFactory.createDeliveryAnswerType();
+ partialSuccess.setAppDeliveryID(appDeliveryId);
- var response = objectFactory.createDeliveryResponseType();
+ var response = objectFactory.createDeliveryRequestStatusType();
response.setPartialSuccess(partialSuccess);
+ response.setSignature(null);
+
return response;
}
- private DeliveryResponseType generateErrorResponse() {
+ private DeliveryRequestStatusType generateErrorResponse(String appDeliveryId, String message) {
- var error = objectFactory.createErrorType();
- error.setText("Error Occurred");
- error.setCode(BigInteger.valueOf(500));
+ var error = objectFactory.createDeliveryRequestStatusTypeError();
+ error.setAppDeliveryID(appDeliveryId);
- var response = objectFactory.createDeliveryResponseType();
+ var info = objectFactory.createErrorInfoType();
+ info.setCode("500");
+ info.setText(message);
+ error.setErrorInfo(info);
+
+ var response = objectFactory.createDeliveryRequestStatusType();
response.setError(error);
+ response.setSignature(null);
return response;
}
+ private DeliveryRequestStatusType process(DeliveryRequestType deliveryRequest) throws RuntimeException {
+
+ var appDeliveryID = deliveryRequest.getMetaData().getAppDeliveryID();
+ logger.info("Receive request with appDeliveryID = {}.", appDeliveryID);
+
+ repository.add(deliveryRequest);
+ pipeline.processRequest(appDeliveryID);
+
+ var status = repository.getDeliveryRequestStatus(appDeliveryID);
+
+ if (status.isEmpty()) {
+ throw new RuntimeException(format("Could not get a response for request with appDeliveryId = {}", appDeliveryID));
+ }
+
+ return status.get();
+
+ }
+
} \ No newline at end of file
diff --git a/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java b/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java
deleted file mode 100644
index 0dc0a15..0000000
--- a/src/main/java/at/gv/egiz/moazs/DeliveryRequestHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package at.gv.egiz.moazs;
-
-import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
-import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryResponseType;
-import at.gv.egiz.moazs.repository.DeliveryRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.function.Function;
-
-@Component
-public class DeliveryRequestHandler implements Function<DeliveryRequestType, DeliveryResponseType> {
-
- private static final Logger logger = LoggerFactory.getLogger(DeliveryRequestHandler.class);
-
- @Autowired
- private DeliveryRepository repository;
-
- /**
- * Handles the Delivery Request
- */
- @Override
- public DeliveryResponseType apply(DeliveryRequestType deliveryRequest) {
-
- var deliveryId = deliveryRequest.getMetaData().getAppDeliveryID();
- logger.info(String.format("Received Request with AppDeliveryID = %s", deliveryId));
-
- //check if DR is complete
-
-
- //store delivery request
- repository.add(deliveryRequest);
-
- return null;
- }
-}
diff --git a/src/main/java/at/gv/egiz/moazs/Mzs2AppClient.java b/src/main/java/at/gv/egiz/moazs/Mzs2AppClient.java
index 01f2787..d0d7936 100644
--- a/src/main/java/at/gv/egiz/moazs/Mzs2AppClient.java
+++ b/src/main/java/at/gv/egiz/moazs/Mzs2AppClient.java
@@ -1,12 +1,12 @@
package at.gv.egiz.moazs;
-import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryResponseType;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
import org.springframework.stereotype.Component;
@Component
public class Mzs2AppClient {
- public void sendNotification(DeliveryResponseType response) {
+ public void sendNotification(DeliveryRequestStatusType status) {
}
diff --git a/src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java b/src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java
new file mode 100644
index 0000000..1d3edb8
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/pipeline/DeliveryPipeline.java
@@ -0,0 +1,12 @@
+package at.gv.egiz.moazs.pipeline;
+
+
+public interface DeliveryPipeline {
+
+ /**
+ * Gets request that is referred by appDeliveryId from cache,
+ * @param appDeliveryId
+ */
+ void processRequest(String appDeliveryId);
+
+}
diff --git a/src/main/java/at/gv/egiz/moazs/pipeline/SameThreadDeliveryPipeline.java b/src/main/java/at/gv/egiz/moazs/pipeline/SameThreadDeliveryPipeline.java
new file mode 100644
index 0000000..3652662
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/pipeline/SameThreadDeliveryPipeline.java
@@ -0,0 +1,49 @@
+package at.gv.egiz.moazs.pipeline;
+
+
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.ObjectFactory;
+import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
+import at.gv.egiz.moazs.repository.DeliveryRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+import static java.text.MessageFormat.format;
+
+@Component
+@Profile("!cluster")
+public class SameThreadDeliveryPipeline implements DeliveryPipeline {
+
+ private final DeliveryRepository repository;
+
+ public SameThreadDeliveryPipeline(@Autowired DeliveryRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void processRequest(String appDeliveryId) {
+
+ Optional<DeliveryRequestType> request = repository.getDeliveryRequest(appDeliveryId);
+ if (request.isEmpty()) {
+ throw new RuntimeException(format(
+ "Request with appDeliveryId = {} does not exist.", appDeliveryId));
+ }
+
+ //do some logic.
+
+ //store response to repository
+ repository.add(generateBogusStatus(appDeliveryId));
+ }
+
+ private DeliveryRequestStatusType generateBogusStatus(String appDeliveryId) {
+ final var factory = new ObjectFactory();
+ final var status = factory.createDeliveryRequestStatusType();
+ final var success = factory.createDeliveryRequestStatusTypeSuccess();
+ success.setAppDeliveryID(appDeliveryId);
+ status.setSuccess(success);
+ return status;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
index d5766b6..f736160 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/DeliveryRepository.java
@@ -1,5 +1,6 @@
package at.gv.egiz.moazs.repository;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
import org.springframework.stereotype.Repository;
@@ -12,4 +13,9 @@ public interface DeliveryRepository {
Optional<DeliveryRequestType> getDeliveryRequest(String appDeliveryID);
+ void add(DeliveryRequestStatusType status);
+
+ Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID);
+
+
}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
index e5486d7..5712c2d 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/InMemoryDeliveryRepository.java
@@ -1,5 +1,6 @@
package at.gv.egiz.moazs.repository;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@@ -11,30 +12,45 @@ import org.springframework.stereotype.Repository;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
+import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
+import static java.util.Optional.ofNullable;
+
@Repository
@Profile("!cluster")
public class InMemoryDeliveryRepository implements DeliveryRepository {
private static final Logger logger = LoggerFactory.getLogger(InMemoryDeliveryRepository.class);
- private static final Cache<String, DeliveryRequestType> rep = CacheBuilder.newBuilder()
+ private static final Cache<String, DeliveryRequestType> requestRepository = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
- public InMemoryDeliveryRepository() {
- logger.info("InMemoryDeliveryRepository()");
- }
+ private static final Cache<String, DeliveryRequestStatusType> statusRepository = CacheBuilder.newBuilder()
+ .expireAfterWrite(30, TimeUnit.MINUTES)
+ .build();
@Override
public void add(DeliveryRequestType request) {
- String key = request.getMetaData().getAppDeliveryID();
- logger.info("Save DeliveryRequest with AppDeliveryId = {} to Cache.", key);
- rep.put(key, request);
+ var key = request.getMetaData().getAppDeliveryID();
+ requestRepository.put(key, request);
}
@Override
public Optional<DeliveryRequestType> getDeliveryRequest(String appDeliveryID) {
- DeliveryRequestType deliveryRequestType = rep.getIfPresent(appDeliveryID);
- return Optional.ofNullable(deliveryRequestType);
+ var deliveryRequestType = requestRepository.getIfPresent(appDeliveryID);
+ return ofNullable(deliveryRequestType);
+ }
+
+ @Override
+ public void add(DeliveryRequestStatusType status) {
+ var key = coalesce(status.getSuccess(), status.getPartialSuccess(), status.getError())
+ .get().getAppDeliveryID();
+ statusRepository.put(key, status);
+ }
+
+ @Override
+ public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
+ var deliveryRequestType = statusRepository.getIfPresent(appDeliveryID);
+ return ofNullable(deliveryRequestType);
}
}
diff --git a/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java b/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
index 4f39f31..cd02dac 100644
--- a/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
+++ b/src/main/java/at/gv/egiz/moazs/repository/RedisDeliveryRepository.java
@@ -1,5 +1,6 @@
package at.gv.egiz.moazs.repository;
+import at.gv.e_government.reference.namespace.zustellung.msg.phase2._20181206_.DeliveryRequestStatusType;
import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.DeliveryRequestType;
import at.gv.e_government.reference.namespace.zustellung.mzs.app2mzs_.ObjectFactory;
import at.gv.egiz.moazs.Marshaller;
@@ -59,4 +60,13 @@ public class RedisDeliveryRepository implements DeliveryRepository {
return Optional.of(request.getValue());
}
+ @Override
+ public void add(DeliveryRequestStatusType status) {
+ throw new RuntimeException("Not Implemented Yet");
+ }
+
+ @Override
+ public Optional<DeliveryRequestStatusType> getDeliveryRequestStatus(String appDeliveryID) {
+ throw new RuntimeException("Not Implemented Yet");
+ }
}
diff --git a/src/main/java/at/gv/egiz/moazs/util/NullCoalesce.java b/src/main/java/at/gv/egiz/moazs/util/NullCoalesce.java
new file mode 100644
index 0000000..4377140
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/util/NullCoalesce.java
@@ -0,0 +1,33 @@
+package at.gv.egiz.moazs.util;
+
+import java.util.Optional;
+
+import static java.util.Optional.ofNullable;
+
+/**
+ * Helper function for coalescing nullables value without cluttering code with if-else cascades
+ * @author les2
+ * @source https://stackoverflow.com/questions/2768054/how-to-get-the-first-non-null-value-in-java
+ */
+public class NullCoalesce {
+
+ /**
+ * @return the first not-null value
+ * @param a
+ * @param b
+ * @param <T>
+ * @return a if a != null, otherwise b.
+ */
+ public static <T> Optional<T> coalesce(T a, T b) {
+ return a != null ? ofNullable(a) : ofNullable(b);
+ }
+
+ public static <T> Optional<T> coalesce(T a, T b, T c) {
+ return a != null ? ofNullable(a) : coalesce(b,c);
+ }
+
+ public static <T> Optional<T> coalesce(T a, T b, T c, T d) {
+ return a != null ? ofNullable(a) : coalesce(b,c,d);
+ }
+
+}
diff --git a/src/main/resources/mzs/app2mzs.xsd b/src/main/resources/mzs/app2mzs.xsd
index 1e0a175..434db23 100644
--- a/src/main/resources/mzs/app2mzs.xsd
+++ b/src/main/resources/mzs/app2mzs.xsd
@@ -80,19 +80,7 @@
</xs:element>
</xs:sequence>
</xs:complexType>
- <xs:element name="DeliveryResponse" type="DeliveryResponseType"/>
- <xs:complexType name="DeliveryResponseType">
- <xs:choice>
- <xs:element ref="PartialSuccess"/>
- <xs:element ref="Success"/>
- <xs:element name="DeliveryConfirmation" type="xs:base64Binary">
- <xs:annotation>
- <xs:documentation>DeliveryConfirmation Base64 encoded</xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element ref="Error"/>
- </xs:choice>
- </xs:complexType>
+ <xs:element name="DeliveryResponse" type="msg:DeliveryRequestStatusType"/>
<xs:element name="DeliveryNotification" type="DeliveryNotificationType">
<xs:annotation>
<xs:documentation>asynchronous communication moazs2app</xs:documentation>
diff --git a/src/test/java/at/gv/egiz/moazs/App2MzsServiceTest.java b/src/test/java/at/gv/egiz/moazs/App2MzsServiceTest.java
index 6874c75..78dafdc 100644
--- a/src/test/java/at/gv/egiz/moazs/App2MzsServiceTest.java
+++ b/src/test/java/at/gv/egiz/moazs/App2MzsServiceTest.java
@@ -15,7 +15,7 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Paths;
-import static java.net.http.HttpClient.*;
+import static java.net.http.HttpClient.Version;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)