aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-07-12 15:40:05 +0200
committerChristof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>2019-07-12 15:40:05 +0200
commit25d68c8900c2cc791f03ea3db173955ca237fd55 (patch)
treef4d28b97845d10a709590dce480195b322ba019b
parent9dc0e72571a895e34a55c11d015c5d359b485aff (diff)
downloadmoa-zs-25d68c8900c2cc791f03ea3db173955ca237fd55.tar.gz
moa-zs-25d68c8900c2cc791f03ea3db173955ca237fd55.tar.bz2
moa-zs-25d68c8900c2cc791f03ea3db173955ca237fd55.zip
Allow App To Choose Between MsgResponse Sinks
- MZS Schema Change: Add "MsgResponseSinks" element to mzs:DeliveryRequest/Config that allows sender to configure how MsgResponses should be archived. - ConfigUtil: Interpret MsgResponseSink parameters from Spring Environment and merge with ConfigType. - MsgResponseBackend: Send responses to sinks according to MsgResponseSinks in Config - application.yaml: Add MsgResponseSinks parameter to configuration. - Uncouple Sink implementations from java.util.function.Function, because the sink interfaces are going to differ and there is no need to unite them under one interface. - Add and test LogResponseSink, which logs responses to it's logger. - MsgResponse: Add JAXB getter for response. Reason: Can be passed to marshaller.
-rw-r--r--src/main/java/at/gv/egiz/moazs/backend/LogResponseSink.java44
-rw-r--r--src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java41
-rw-r--r--src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java14
-rw-r--r--src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java62
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java7
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java9
-rw-r--r--src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java10
-rw-r--r--src/main/resources/application.yaml60
-rw-r--r--src/main/resources/mzs/app2mzs.xsd8
-rw-r--r--src/test/java/at/gv/egiz/moazs/LogResponseSinkTest.java78
-rw-r--r--src/test/java/at/gv/egiz/moazs/SaveResponseToFileSinkTest.java2
11 files changed, 286 insertions, 49 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/backend/LogResponseSink.java b/src/main/java/at/gv/egiz/moazs/backend/LogResponseSink.java
new file mode 100644
index 0000000..d419944
--- /dev/null
+++ b/src/main/java/at/gv/egiz/moazs/backend/LogResponseSink.java
@@ -0,0 +1,44 @@
+package at.gv.egiz.moazs.backend;
+
+import at.gv.egiz.moazs.scheme.Marshaller;
+import at.gv.egiz.moazs.scheme.MsgResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.CompletableFuture;
+
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
+@Component
+public class LogResponseSink {
+
+ private static final Logger log = LoggerFactory.getLogger(LogResponseSink.class);
+ private static final String LOG_LEVEL_WARN_MESSAGE = "Will not log response because INFO level is disabled.";
+
+ private final Marshaller msgMarshaller;
+
+ public LogResponseSink(Marshaller msgMarshaller) {
+ this.msgMarshaller = msgMarshaller;
+ }
+
+ /**
+ * Log response to class logger at level=INFO.
+ *
+ * @param msgResponse
+ * @return
+ */
+ public CompletableFuture<Void> log(MsgResponse msgResponse) {
+
+ if(log.isInfoEnabled()) {
+ var builder = new StringBuilder("Received the following Message: \n");
+ builder.append(msgMarshaller.marshallXml(msgResponse.getResponseAsJAXBElement()));
+ log.info(builder.toString());
+ } else {
+ log.warn(LOG_LEVEL_WARN_MESSAGE);
+ }
+
+ return completedFuture(null);
+
+ }
+}
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 414c2dc..1b17f34 100644
--- a/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java
+++ b/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java
@@ -4,14 +4,13 @@ import at.gv.egiz.moazs.MoaZSException;
import at.gv.egiz.moazs.repository.DeliveryRepository;
import at.gv.egiz.moazs.scheme.MsgResponse;
import at.gv.egiz.moazs.service.MsgService;
+import at.gv.zustellung.app2mzs.xsd.MsgResponseSinksType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
-import java.util.function.Function;
import static at.gv.egiz.moazs.MoaZSException.moaZSExceptionBuilder;
import static java.lang.String.format;
@@ -27,29 +26,38 @@ public class MsgResponseBackend implements Consumer<String> {
private final DeliveryRepository repository;
private final Consumer<byte[]> signatureVerifier;
- private final Function<MsgResponse, CompletableFuture<Void>> sink;
+ private final SaveResponseToFileSink saveResponseToFileSink;
+ private final LogResponseSink logResponseSink;
@Autowired
public MsgResponseBackend(DeliveryRepository repository,
Consumer<byte[]> signatureVerifier,
- Function<MsgResponse, CompletableFuture<Void>> sink) {
+ SaveResponseToFileSink saveResponseToFileSink,
+ LogResponseSink logResponseSink) {
this.repository = repository;
this.signatureVerifier = signatureVerifier;
- this.sink = sink;
+ this.saveResponseToFileSink = saveResponseToFileSink;
+ this.logResponseSink = logResponseSink;
}
/**
* Performs all {@code MsgResponse}'s Back-End Tasks, such as verifying
* its signature and archiving the response.
*
+ * Note: When the signature verification fails, this method will not archive
+ * the original response (the one that was received from msg) to the sink,
+ * but an error message.
+ *
* @param responseID refers to MsgResponse Object.
*/
@Override
public void accept(String responseID) {
- supplyAsync(() -> verify(responseID)).thenAcceptAsync(sink::apply);
+
+ supplyAsync(() -> verify(responseID))
+ .thenAcceptAsync(msgResponse -> applySinks(msgResponse));
}
- public MsgResponse verify(String responseID) {
+ private MsgResponse verify(String responseID) {
var response = repository.retrieveResponse(responseID).get();
var builder = moaZSExceptionBuilder().withAllParametersInAnswer(response.getAnswer());
@@ -72,4 +80,23 @@ public class MsgResponseBackend implements Consumer<String> {
}
+ private void applySinks(MsgResponse msgResponse) {
+
+ var sinkParams = getSinkParams(msgResponse);
+
+ if (sinkParams.isSafeResponseToFile()) {
+ supplyAsync(() -> saveResponseToFileSink.save(msgResponse));
+ }
+
+ if (sinkParams.isLogResponse()) {
+ supplyAsync(() -> logResponseSink.log(msgResponse));
+ }
+ }
+
+ private MsgResponseSinksType getSinkParams(MsgResponse msgResponse) {
+ var appDeliveryID = msgResponse.getAppDeliveryID();
+ var request = repository.retrieveDeliveryRequest(appDeliveryID).get();
+ return request.getConfig().getMsgResponseSinks();
+ }
+
}
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 02771a9..7da76ef 100644
--- a/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java
+++ b/src/main/java/at/gv/egiz/moazs/backend/SaveResponseToFileSink.java
@@ -15,7 +15,6 @@ import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
-import java.util.function.Function;
import static at.gv.egiz.moazs.MoaZSException.moaZSException;
import static java.lang.String.format;
@@ -23,10 +22,11 @@ import static java.util.concurrent.CompletableFuture.allOf;
import static java.util.concurrent.CompletableFuture.supplyAsync;
@Component
-public class SaveResponseToFileSink implements Function<MsgResponse, CompletableFuture<Void>> {
+public class SaveResponseToFileSink {
private static final Logger log = LoggerFactory.getLogger(SaveResponseToFileSink.class);
private static final String SAVING_FAILED_MSG = "Could not save response with AppDeliveryId=%s.";
+ private static final String SAVE_RESPONSE_MSG = "Saving response to {}..." ;
private final SimpleDateFormat isoFormatter;
private final Marshaller msgMarshaller;
@@ -41,8 +41,13 @@ public class SaveResponseToFileSink implements Function<MsgResponse, Completable
this.isoFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
}
- @Override
- public CompletableFuture<Void> apply(MsgResponse response) {
+ /**
+ * Save response and it's binary version to the file system.
+ *
+ * @param response
+ * @return Future that completes when both responses have been written to the file system.
+ */
+ public CompletableFuture<Void> save(MsgResponse response) {
var responseID = response.getResponseID();
@@ -79,6 +84,7 @@ public class SaveResponseToFileSink implements Function<MsgResponse, Completable
}
private void storeToFile(String path, byte[] content) {
+ log.trace(SAVE_RESPONSE_MSG, path);
try {
FileUtils.writeByteArrayToFile(new File(path), content);
} catch (IOException e) {
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
index 68f833e..9cdc07a 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java
@@ -1,10 +1,7 @@
package at.gv.egiz.moazs.preprocess;
import at.gv.egiz.moazs.util.StringUtils;
-import at.gv.zustellung.app2mzs.xsd.ClientType;
-import at.gv.zustellung.app2mzs.xsd.ConfigType;
-import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
-import at.gv.zustellung.app2mzs.xsd.SSLType;
+import at.gv.zustellung.app2mzs.xsd.*;
import org.springframework.stereotype.Component;
import java.math.BigInteger;
@@ -13,6 +10,7 @@ import java.util.Map;
import static at.gv.zustellung.app2mzs.xsd.ClientType.clientTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.KeyStoreType.keyStoreTypeBuilder;
+import static at.gv.zustellung.app2mzs.xsd.MsgResponseSinksType.msgResponseSinksTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.SSLType.SSLTypeBuilder;
import static java.util.stream.Collectors.toMap;
@@ -33,7 +31,9 @@ public class ConfigUtil {
public static final String PASSWORD_KEY = "password";
public static final String RECEIVE_TIMEOUT = "receive-timeout";
public static final String CONNECTION_TIMEOUT_KEY = "connection-timeout";
-
+ public static final String MSG_RESPONSE_SINKS_KEY = "msg-response-sinks";
+ public static final String LOG_RESPONSE_KEY = "log-response";
+ public static final String SAVE_RESPONSE_TO_FILE_KEY = "save-response-to-file";
/**
* Convert a map into a Config object.
@@ -53,10 +53,15 @@ public class ConfigUtil {
ClientType tnvzClient = tnvzClientParams.isEmpty()
? null : buildClient(tnvzClientParams);
+ var msgResponseSinksParams = filterMapByPrefix(values, MSG_RESPONSE_SINKS_KEY);
+ MsgResponseSinksType sinks = msgResponseSinksParams.isEmpty()
+ ? null : buildMsgResponseSinks(msgResponseSinksParams);
+
return ConfigType.configTypeBuilder()
.withPerformQueryPersonRequest(performQueryPersonRequest)
.withMSGClient(msgClient)
.withTNVZClient(tnvzClient)
+ .withMsgResponseSinks(sinks)
.build();
}
@@ -102,11 +107,8 @@ public class ConfigUtil {
KeyStoreType trustStore = trustStoreParams.isEmpty()
? null : buildKeyStore(trustStoreParams);
- var trustAll = sslParams.get(TRUST_ALL_KEY) == null
- ? null : Boolean.getBoolean(sslParams.get(TRUST_ALL_KEY));
-
- var laxHostNameVerification = sslParams.get(LAX_HOSTNAME_VERIFICATION_KEY) == null
- ? null : Boolean.getBoolean(sslParams.get(LAX_HOSTNAME_VERIFICATION_KEY));
+ var trustAll = booleanOrNull(sslParams.get(TRUST_ALL_KEY));
+ var laxHostNameVerification = booleanOrNull(sslParams.get(LAX_HOSTNAME_VERIFICATION_KEY));
return SSLTypeBuilder()
.withKeyStore(keyStore)
@@ -126,6 +128,22 @@ public class ConfigUtil {
.build();
}
+ private MsgResponseSinksType buildMsgResponseSinks(Map<String, String> params) {
+
+ var logResponse = booleanOrNull(params.get(LOG_RESPONSE_KEY));
+ var saveResponse = booleanOrNull(params.get(SAVE_RESPONSE_TO_FILE_KEY));
+
+ return msgResponseSinksTypeBuilder()
+ .withLogResponse(logResponse)
+ .withLogResponse(saveResponse)
+ .build();
+ }
+
+ private Boolean booleanOrNull(String value) {
+ return value == null ? null : Boolean.getBoolean(value);
+ }
+
+
/**
* Combine properties of two Configs; {@code primary} overrides {@code fallback}.
*
@@ -149,6 +167,10 @@ public class ConfigUtil {
builder.withMSGClient(merge(primary.getTNVZClient(), fallback.getTNVZClient()));
}
+ if (primary.getMsgResponseSinks() != null) {
+ builder.withMsgResponseSinks(merge(primary.getMsgResponseSinks(), fallback.getMsgResponseSinks()));
+ }
+
return builder.build();
}
@@ -214,4 +236,24 @@ public class ConfigUtil {
}
+ private MsgResponseSinksType merge(MsgResponseSinksType primary, MsgResponseSinksType fallback) {
+
+ if (fallback == null) {
+ return primary;
+ }
+
+ var builder = msgResponseSinksTypeBuilder(fallback);
+
+ if (primary.isLogResponse() != null) {
+ builder.withLogResponse(primary.isLogResponse());
+ }
+
+ if (primary.isSafeResponseToFile() != null) {
+ builder.withLogResponse(primary.isSafeResponseToFile());
+ }
+
+ return builder.build();
+ }
+
+
}
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 80e2059..5370448 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/MsgResponse.java
@@ -3,6 +3,12 @@ package at.gv.egiz.moazs.scheme;
import at.gv.egiz.moazs.MoaZSException;
import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
+import javax.xml.bind.JAXBElement;
+
+/**
+ * Represents responses to DeliveryRequests that were received from the msg service.
+ * @param <T> The type of the response.
+ */
public abstract class MsgResponse <T> {
protected String id;
@@ -20,6 +26,7 @@ public abstract class MsgResponse <T> {
}
public abstract T getResponse();
+ public abstract JAXBElement<T> getResponseAsJAXBElement();
public abstract String getAppDeliveryID();
public abstract String getZSDeliveryID();
public abstract DeliveryAnswerType getAnswer();
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 de1fd38..784d000 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/NotificationResponse.java
@@ -3,6 +3,9 @@ package at.gv.egiz.moazs.scheme;
import at.gv.egiz.moazs.MoaZSException;
import at.gv.zustellung.msg.xsd.DeliveryAnswerType;
import at.gv.zustellung.msg.xsd.DeliveryNotificationType;
+import at.gv.zustellung.msg.xsd.ObjectFactory;
+
+import javax.xml.bind.JAXBElement;
import static at.gv.zustellung.msg.xsd.DeliveryNotificationType.deliveryNotificationTypeBuilder;
@@ -10,6 +13,7 @@ public class NotificationResponse extends MsgResponse<DeliveryNotificationType>
private final DeliveryNotificationType notification;
private static final String ID_SUFFIX = ".NO";
+ private static final ObjectFactory factory = new ObjectFactory();
public NotificationResponse(DeliveryNotificationType notification) {
super.id = createResponseId(notification.getAppDeliveryID(), ID_SUFFIX);
@@ -26,6 +30,11 @@ public class NotificationResponse extends MsgResponse<DeliveryNotificationType>
}
@Override
+ public JAXBElement<DeliveryNotificationType> getResponseAsJAXBElement() {
+ return factory.createDeliveryNotification(notification);
+ }
+
+ @Override
public String getAppDeliveryID() {
return notification.getAppDeliveryID();
}
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 0705698..3b4710b 100644
--- a/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java
+++ b/src/main/java/at/gv/egiz/moazs/scheme/RequestStatusResponse.java
@@ -4,6 +4,9 @@ import at.gv.egiz.moazs.MoaZSException;
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 javax.xml.bind.JAXBElement;
import static at.gv.egiz.moazs.util.NullCoalesce.coalesce;
import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Error.errorBuilder;
@@ -15,6 +18,8 @@ public class RequestStatusResponse extends MsgResponse<DeliveryRequestStatusType
private final DeliveryRequestStatusType status;
private final DeliveryAnswerType answer;
private static final String ID_SUFFIX = ".RS";
+ private static final ObjectFactory factory = new ObjectFactory();
+
public RequestStatusResponse(DeliveryRequestStatusType status) {
this.status = status;
@@ -32,6 +37,11 @@ public class RequestStatusResponse extends MsgResponse<DeliveryRequestStatusType
}
@Override
+ public JAXBElement<DeliveryRequestStatusType> getResponseAsJAXBElement() {
+ return factory.createDeliveryRequestStatus(status);
+ }
+
+ @Override
public String getAppDeliveryID() {
return answer.getAppDeliveryID();
}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 0e7b67e..a04a903 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -1,11 +1,18 @@
-spring:
- redis:
- host: 172.17.0.2
- port: 6379
+### Logging
+logging:
+ level:
+ root: WARN
+ org.springframework: WARN
+ at.gv: INFO #DEBUG
+ iaik: INFO #DEBUG
+ at.gv.egiz.moazs.backend:
+ SignatureVerifier: DEBUG
+ LogResponseSink: INFO
-## activate cluster mode
-# profiles:
-# active: cluster
+# Default type for java's ssl key/trust store
+javax.net.ssl:
+ keyStoreType: jks
+ trustStoreType: jks
# Configure parameters here or in DeliveryRequest/Config.
# Choose a profile in DeliveryRequest/Config/ProfileId.
@@ -23,8 +30,12 @@ delivery-request-configuration-profiles:
# 0 means indefinitely.
receive-timeout: 0
+ # Specifies how MoaZS should
+ msg-response-sinks:
+ save-response-to-file: false
+ log-response: true
+
ssl-profile:
- perform-query-person-request: false
msg-client:
url: https://localhost/zusemsg/services/DeliveryRequest
ssl:
@@ -43,24 +54,10 @@ delivery-request-configuration-profiles:
## JKS or PKCS12
type: PKCS12
-## If set to false, moa zs ignores an incomplete default DeliveryRequest-configuration
-## profile and continues startup. See 'delivery-request-configuration-profiles'.
-## Default value: true
-# verify-completeness-of-default-delivery-request-configuration: false
-
-### logging
-logging:
- level:
- root: WARN
- org.springframework: WARN
- at.gv: INFO #DEBUG
- iaik: INFO #DEBUG
- at.gv.egiz.moazs.backend.SignatureVerifier: DEBUG
-
-# default type for java's ssl key/trust store
-javax.net.ssl:
- keyStoreType: jks
- trustStoreType: jks
+# If set to false, moa zs ignores an incomplete default DeliveryRequest-configuration
+# profile and continues startup. See 'delivery-request-configuration-profiles'.
+# Default value: true
+verify-completeness-of-default-delivery-request-configuration: true
### moa spss config
moa.spss:
@@ -74,6 +71,15 @@ moa.spss:
configuration: moa-spss/MOASPSSConfiguration.xml
default-trustprofile: test-trustprofile
+spring:
+ redis:
+ host: 172.17.0.2
+ port: 6379
+
repository:
# duration in minutes before repository records are evicted.
- expiresAfterWrite: 30 \ No newline at end of file
+ expiresAfterWrite: 30
+
+## activate cluster mode
+# profiles:
+# active: cluster
diff --git a/src/main/resources/mzs/app2mzs.xsd b/src/main/resources/mzs/app2mzs.xsd
index 659bbb9..ba99eab 100644
--- a/src/main/resources/mzs/app2mzs.xsd
+++ b/src/main/resources/mzs/app2mzs.xsd
@@ -98,6 +98,7 @@
<xs:element name="PerformQueryPersonRequest" type="xs:boolean" minOccurs="0" />
<xs:element ref="MSGClient" minOccurs="0" />
<xs:element ref="TNVZClient" minOccurs="0" />
+ <xs:element ref="MsgResponseSinks" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:element name="MSGClient" type="ClientType" />
@@ -128,6 +129,13 @@
<xs:element name="FileType" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
+ <xs:element name="MsgResponseSinks" type="MsgResponseSinksType"/>
+ <xs:complexType name="MsgResponseSinksType">
+ <xs:sequence>
+ <xs:element name="SafeResponseToFile" type="xs:boolean" minOccurs="0" />
+ <xs:element name="LogResponse" type="xs:boolean" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
<xs:element name="DeliveryResponse" type="DeliveryResponseType"/>
<xs:complexType name="DeliveryResponseType">
<xs:choice>
diff --git a/src/test/java/at/gv/egiz/moazs/LogResponseSinkTest.java b/src/test/java/at/gv/egiz/moazs/LogResponseSinkTest.java
new file mode 100644
index 0000000..9e7c49d
--- /dev/null
+++ b/src/test/java/at/gv/egiz/moazs/LogResponseSinkTest.java
@@ -0,0 +1,78 @@
+package at.gv.egiz.moazs;
+
+import at.gv.egiz.moazs.backend.LogResponseSink;
+import at.gv.egiz.moazs.scheme.Marshaller;
+import at.gv.egiz.moazs.scheme.NotificationResponse;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.slf4j.LoggerFactory;
+
+import static at.gv.zustellung.msg.xsd.DeliveryNotificationType.deliveryNotificationTypeBuilder;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.verify;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LogResponseSinkTest {
+
+ private LogResponseSink logResponseSink;
+
+ @Mock
+ private Appender appender;
+ private ch.qos.logback.classic.Logger logger;
+
+ @Before
+ public void setup() {
+ logResponseSink = new LogResponseSink(new Marshaller(false));
+ logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(LogResponseSink.class);
+ logger.addAppender(appender);
+ }
+
+ @Test
+ public void logNotification() {
+ setLogLevel(Level.INFO);
+ var appDeliveryID = "log-notification-id";
+ var notification = setupNotification(appDeliveryID);
+
+ logResponseSink.log(notification)
+ .thenRun(expectSubstringSentToAppender(appDeliveryID));
+ }
+
+ @Test
+ public void warnWhenLogDisabled() {
+ setLogLevel(Level.WARN);
+ var appDeliveryID = "log-info-disabled";
+ var notification = setupNotification(appDeliveryID);
+
+ logResponseSink.log(notification)
+ .thenRun(expectSubstringSentToAppender("WARN"));
+ }
+
+ private Runnable expectSubstringSentToAppender(String expectedSubstring) {
+ return ()-> verify(appender).doAppend(argThat(argument -> {
+ var message = ((ILoggingEvent) argument).getFormattedMessage();
+ return message.contains(expectedSubstring);
+ }));
+ }
+
+ private NotificationResponse setupNotification(String appDeliveryID) {
+
+ var notification = deliveryNotificationTypeBuilder()
+ .withAppDeliveryID(appDeliveryID)
+ .build();
+
+ return new NotificationResponse(notification);
+
+ }
+
+ private void setLogLevel(Level level) {
+ logger.setLevel(level);
+ }
+
+
+}
diff --git a/src/test/java/at/gv/egiz/moazs/SaveResponseToFileSinkTest.java b/src/test/java/at/gv/egiz/moazs/SaveResponseToFileSinkTest.java
index 9ddd37e..58efe6a 100644
--- a/src/test/java/at/gv/egiz/moazs/SaveResponseToFileSinkTest.java
+++ b/src/test/java/at/gv/egiz/moazs/SaveResponseToFileSinkTest.java
@@ -63,7 +63,7 @@ public class SaveResponseToFileSinkTest {
var fileContent = "<xml>some content</xml>";
var status = setupMocks(fileContent);
- sink.apply(status)
+ sink.save(status)
.thenRun(() -> assertFilesCreatedAndContentMatches(fileContent));
}