From a5b8668c0c7916a8fe2b84122d537a3e0bd67002 Mon Sep 17 00:00:00 2001
From: Christof Rabensteiner <christof.rabensteiner@iaik.tugraz.at>
Date: Fri, 29 Nov 2019 14:54:28 +0100
Subject: Alter Case Handling "Get Notification where AppDeliveryID is unknown"

- Former: Fail with Exception.
- Now: Issue a warning and fall back to default configuration profile
  after verifying that sinks in default configuration profile are
  correctly configured.
- Refactor: Make DEFAULT_CONFIG_KEY static.
---
 .../gv/egiz/moazs/backend/MsgResponseBackend.java  | 37 +++++++++++++++++++---
 .../moazs/preprocess/ConfigProfileGenerator.java   | 19 ++++-------
 .../preprocess/MzsDeliveryRequestValidator.java    |  4 +--
 .../gv/egiz/moazs/ConfigProfileGeneratorTest.java  | 25 +++++++--------
 4 files changed, 52 insertions(+), 33 deletions(-)

(limited to 'src')

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 276fb67..0da9c92 100644
--- a/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java
+++ b/src/main/java/at/gv/egiz/moazs/backend/MsgResponseBackend.java
@@ -22,17 +22,24 @@
 package at.gv.egiz.moazs.backend;
 
 import at.gv.egiz.moazs.MoaZSException;
+import at.gv.egiz.moazs.preprocess.MzsDeliveryRequestValidator;
 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.ConfigType;
+import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.Map;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 import static at.gv.egiz.moazs.MoaZSException.*;
+import static at.gv.egiz.moazs.preprocess.ConfigProfileGenerator.DEFAULT_CONFIG_KEY;
+import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder;
 import static java.lang.String.format;
 import static java.util.concurrent.CompletableFuture.supplyAsync;
 
@@ -49,19 +56,26 @@ public class MsgResponseBackend implements Consumer<String> {
             "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.";
-    public static final String REQUEST_MISSING_ERROR_MSG = "Request with AppDeliveryID=%s is not in repository.";
+    public static final String REQUEST_MISSING_ERROR_MSG = "Request with AppDeliveryID=%s is not in repository. " +
+            "Falling Back to Default Configuration.";
 
     private final DeliveryRepository repository;
     private final Consumer<byte[]> signatureVerifier;
     private final MsgResponseSinkHub hub;
+    private final Map<String, ConfigType> deliveryRequestConfigs;
+    private final MzsDeliveryRequestValidator validator;
 
     @Autowired
     public MsgResponseBackend(DeliveryRepository repository,
                               Consumer<byte[]> signatureVerifier,
-                              MsgResponseSinkHub hub) {
+                              MsgResponseSinkHub hub,
+                              Map<String, ConfigType> deliveryRequestConfigs,
+                              MzsDeliveryRequestValidator validator) {
         this.repository = repository;
         this.signatureVerifier = signatureVerifier;
         this.hub = hub;
+        this.deliveryRequestConfigs = deliveryRequestConfigs;
+        this.validator = validator;
     }
 
     /**
@@ -111,11 +125,24 @@ public class MsgResponseBackend implements Consumer<String> {
     private void applySinks(MsgResponse msgResponse) {
         var appDeliveryID = msgResponse.getAppDeliveryID();
 
-        var request = repository.retrieveDeliveryRequest(appDeliveryID).orElseThrow(
-                ()-> moaZSException(format(REQUEST_MISSING_ERROR_MSG, appDeliveryID)));
+        var config = repository
+                .retrieveDeliveryRequest(appDeliveryID)
+                .orElseGet(supplyRequestWithDefaultConfig(appDeliveryID))
+                .getConfig();
 
-        var sinkParams = request.getConfig().getMsgResponseSinks();
+        var sinkParams = config.getMsgResponseSinks();
         hub.applySinks(msgResponse, sinkParams);
     }
 
+    private Supplier<DeliveryRequestType> supplyRequestWithDefaultConfig(String appDeliveryID) {
+        return () -> {
+            log.warn(format(REQUEST_MISSING_ERROR_MSG, appDeliveryID));
+            var defaultConfig = deliveryRequestConfigs.get(DEFAULT_CONFIG_KEY);
+            validator.areSinksConfigured(defaultConfig.getMsgResponseSinks());
+            return deliveryRequestTypeBuilder()
+                    .withConfig(defaultConfig)
+                    .build();
+        };
+    }
+
 }
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
index 3191d92..8e2c5e5 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigProfileGenerator.java
@@ -54,12 +54,13 @@ public class ConfigProfileGenerator {
             "mzs:DeliveryRequest/Config needs to be configured completely *for each delivery request* in order to guarantee " +
             "availability.";
 
+    public static final String DEFAULT_CONFIG_KEY = "default";
+
     private final SpringPropertiesFacade properties;
     private final ConfigUtil util;
     private final MzsDeliveryRequestValidator validator;
     private final boolean verifyCompletenessOfDefaultConfiguration;
     private final String profilePrefix;
-    private final String defaultConfigKey;
 
     public static ConfigProfileGeneratorBuilder configProfileGeneratorBuilder() {
         return new ConfigProfileGeneratorBuilder();
@@ -70,14 +71,12 @@ public class ConfigProfileGenerator {
             ConfigUtil util,
             MzsDeliveryRequestValidator validator,
             boolean verifyCompletenessOfDefaultConfiguration,
-            String profilePrefix,
-            String defaultConfigKey) {
+            String profilePrefix) {
         this.util = util;
         this.properties = properties;
         this.validator = validator;
         this.verifyCompletenessOfDefaultConfiguration = verifyCompletenessOfDefaultConfiguration;
         this.profilePrefix = profilePrefix;
-        this.defaultConfigKey = defaultConfigKey;
     }
 
     /**
@@ -96,7 +95,7 @@ public class ConfigProfileGenerator {
         var profiles = groupedKeys.entrySet().stream()
                 .collect(toUnmodifiableMap(Entry::getKey, this::createConfigFromEnv));
 
-        var defaultProfile = profiles.get(defaultConfigKey);
+        var defaultProfile = profiles.get(DEFAULT_CONFIG_KEY);
 
         try {
             validator.isConfigProfileComplete(defaultProfile);
@@ -145,7 +144,6 @@ public class ConfigProfileGenerator {
         private MzsDeliveryRequestValidator validator;
         private boolean verify = true;
         private String profilePrefix = "delivery-request-configuration-profiles";
-        private String defaultConfigKey = "default";
 
         public ConfigProfileGeneratorBuilder withProperties(SpringPropertiesFacade properties) {
             this.properties = properties;
@@ -173,16 +171,11 @@ public class ConfigProfileGenerator {
             return this;
         }
 
-        public ConfigProfileGeneratorBuilder withDefaultConfigKey(String defaultConfigKey) {
-            this.defaultConfigKey = defaultConfigKey;
-            return this;
-        }
-
         public ConfigProfileGenerator build() {
-            if (properties == null || util == null || profilePrefix == null || defaultConfigKey == null || validator == null)
+            if (properties == null || util == null || profilePrefix == null || validator == null)
                 throw new IllegalArgumentException("Cannot build ConfigProfileGenerator: " +
                         "One or more arguments are null.");
-            return new ConfigProfileGenerator(properties, util, validator, verify, profilePrefix, defaultConfigKey);
+            return new ConfigProfileGenerator(properties, util, validator, verify, profilePrefix);
         }
     }
 }
diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
index af8b34c..4693536 100644
--- a/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
+++ b/src/main/java/at/gv/egiz/moazs/preprocess/MzsDeliveryRequestValidator.java
@@ -169,8 +169,8 @@ public class MzsDeliveryRequestValidator {
         if (!isConfigured) throw mzse("TrustStore");
     }
 
-    private void areSinksConfigured(@Nullable MsgResponseSinksType sinks) {
-        var isConfigured = sinks != null && sinks.isLogResponse() != null;
+    public void areSinksConfigured(@Nullable MsgResponseSinksType sinks) {
+        var isConfigured = (sinks != null && sinks.isLogResponse() != null);
         if (!isConfigured) throw mzse("MsgResponseSinks");
 
         isSaveResponseToFileConfigured(sinks.getSaveResponseToFile());
diff --git a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
index 10670ff..1fec8ec 100644
--- a/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
+++ b/src/test/java/at/gv/egiz/moazs/ConfigProfileGeneratorTest.java
@@ -32,6 +32,7 @@ import org.mockito.junit.MockitoJUnitRunner;
 import java.util.Map;
 
 import static at.gv.egiz.moazs.MoaZSException.moaZSException;
+import static at.gv.egiz.moazs.preprocess.ConfigProfileGenerator.DEFAULT_CONFIG_KEY;
 import static at.gv.egiz.moazs.preprocess.ConfigProfileGenerator.configProfileGeneratorBuilder;
 import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder;
 import static org.mockito.ArgumentMatchers.any;
@@ -46,7 +47,6 @@ import static org.mockito.Mockito.*;
 public class ConfigProfileGeneratorTest {
 
     private static final String PREFIX =  "prefix";
-    private static final String DEFAULT = "default";
 
     @Mock
     private ConfigUtil util;
@@ -60,9 +60,9 @@ public class ConfigProfileGeneratorTest {
     @Test
     public void assembleDefaultProfile() {
         var propMap = Map.of(
-                PREFIX + "." + DEFAULT + ".property-a", "value-a",
-                PREFIX + "." + DEFAULT + ".property-b", "value-b",
-                PREFIX + "." + DEFAULT + ".property-c", "value-c");
+                PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-a", "value-a",
+                PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-b", "value-b",
+                PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-c", "value-c");
         var generator = setupMocksAndBuilder(propMap).build();
 
         var profiles = generator.generate();
@@ -71,12 +71,12 @@ public class ConfigProfileGeneratorTest {
                 "property-a", "value-a",
                 "property-b", "value-b",
                 "property-c", "value-c"));
-        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT);
+        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT_CONFIG_KEY);
     }
 
     @Test
     public void assembleEmptyDefault() {
-        var propMap = Map.of(PREFIX + "." + DEFAULT, "");
+        var propMap = Map.of(PREFIX + "." + DEFAULT_CONFIG_KEY, "");
         var generator = setupMocksAndBuilder(propMap).build();
 
         var profiles = generator.generate();
@@ -99,8 +99,8 @@ public class ConfigProfileGeneratorTest {
     @Test
     public void assembleMultipleProfiles() {
         var propMap = Map.of(
-                PREFIX + "." + DEFAULT+ ".property-a", "value-a",
-                PREFIX + "." + DEFAULT+ ".property-b", "value-b",
+                PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-a", "value-a",
+                PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-b", "value-b",
                 PREFIX + "." + "profile-1.property-c", "value-c",
                 PREFIX + "." + "profile-2.property-d", "value-d");
 
@@ -111,12 +111,12 @@ public class ConfigProfileGeneratorTest {
         verify(util).convert(Map.of("property-a", "value-a", "property-b", "value-b"));
         verify(util).convert(Map.of("property-c", "value-c"));
         verify(util).convert(Map.of("property-d", "value-d"));
-        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT, "profile-1", "profile-2");
+        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT_CONFIG_KEY, "profile-1", "profile-2");
     }
 
     @Test(expected = MoaZSException.class)
     public void cancelAtIncompleteDefaultProfile() {
-        var propMap = Map.of(PREFIX + "." + DEFAULT + ".property-a", "value-a");
+        var propMap = Map.of(PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-a", "value-a");
         var generator = setupMocksAndBuilder(propMap).build();
         doThrow(moaZSException("Not Complete.")).when(validator).isConfigProfileComplete(any());
 
@@ -125,7 +125,7 @@ public class ConfigProfileGeneratorTest {
 
     @Test
     public void continueAtIncompleteDefaultWhenVerificationDisabled() {
-        var propMap = Map.of(PREFIX + "." + DEFAULT + ".property-a", "value-a");
+        var propMap = Map.of(PREFIX + "." + DEFAULT_CONFIG_KEY + ".property-a", "value-a");
 
         doThrow(moaZSException("Not Complete.")).when(validator).isConfigProfileComplete(any());
 
@@ -136,7 +136,7 @@ public class ConfigProfileGeneratorTest {
         var profiles = generator.generate();
 
         verify(util).convert(Map.of("property-a", "value-a"));
-        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT);
+        assertThat(profiles.keySet()).containsExactlyInAnyOrder(DEFAULT_CONFIG_KEY);
     }
 
     private ConfigProfileGenerator.ConfigProfileGeneratorBuilder setupMocksAndBuilder(Map<String, String> propMap) {
@@ -148,7 +148,6 @@ public class ConfigProfileGeneratorTest {
         return configProfileGeneratorBuilder()
                 .withProperties(properties)
                 .withConfigUtil(util)
-                .withDefaultConfigKey(DEFAULT)
                 .withProfilePrefix(PREFIX)
                 .withValidator(validator)
                 .withVerifyCompletenessOfDefaultConfiguration(true);
-- 
cgit v1.2.3