From c1db5f577a4567757efa73b559953932aca11efd Mon Sep 17 00:00:00 2001
From: Martin Vogel <martin.vogel@sinc.de>
Date: Fri, 16 Sep 2022 10:55:57 +0200
Subject: [PATCH] refactor(config): remove implicit config loading, config can
 only be loaded via explicit env-var or ApplicationConfigLoader

---
 client/README.md                              | 14 ++++--
 .../factory/ApplicationConfigLoader.java      |  2 +-
 .../client/factory/ClientFactory.java         | 45 ++++++-------------
 client/src/main/resources/sender-banner.txt   |  7 ---
 .../src/main/resources/subscriber-banner.txt  |  7 ---
 5 files changed, 24 insertions(+), 51 deletions(-)
 delete mode 100644 client/src/main/resources/sender-banner.txt
 delete mode 100644 client/src/main/resources/subscriber-banner.txt

diff --git a/client/README.md b/client/README.md
index c8a2130f9..8610bd31a 100644
--- a/client/README.md
+++ b/client/README.md
@@ -6,10 +6,16 @@ The sdk comes with a commandline client to be able to use the sdk without any co
 #### Setup & Build
 1. Build project root wih ``./mvnw clean package``
 2. Go to client/target and find a runnable jar ``client-VERSION.jar``
-3. set environment variable ``FIT_CONNECT_CONFIG`` or drop a configured [config.yml](../config.yml) file next to the runnable jar
-   1. Linux/MacOS: ``export FIT_CONNECT_CONFIG=path/to/config.yml``
-   2. Windows: ``set FIT_CONNECT_CONFIG=C:\Path\To\config.yml``
-4. run client with ``java -jar client-VERSION.jar [COMMAND] [OPTIONS]``
+3. Provide config either via env-var or by loading it programmatically:
+   1. set environment variable ``FIT_CONNECT_CONFIG``:
+      1. Linux/MacOS: ``export FIT_CONNECT_CONFIG=path/to/config.yml``
+      2. Windows: ``set FIT_CONNECT_CONFIG=C:\Path\To\config.yml``
+   2. Initialize client via ApplicationConfigLoader:
+      ````java
+      var config = ApplicationConfigLoader.loadConfig(Path.of("absolute/path/to/config.yml"));
+      var senderClient = ClientFactory.senderClient(config);
+      ````
+5. run client with ``java -jar client-VERSION.jar [COMMAND] [OPTIONS]``
 
 #### SEND Example
 The send command submits a new submission to a destination. Apart from optional attachments, all options are mandatory.
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/factory/ApplicationConfigLoader.java b/client/src/main/java/dev/fitko/fitconnect/client/factory/ApplicationConfigLoader.java
index 259616210..a579dc6d3 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/factory/ApplicationConfigLoader.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/factory/ApplicationConfigLoader.java
@@ -24,7 +24,7 @@ public final class ApplicationConfigLoader {
     public static ApplicationConfig loadConfig(final Path configPath) {
         try {
             return loadConfig(Files.readString(configPath));
-        } catch (final IOException e) {
+        } catch (final IOException | NullPointerException e) {
             throw new InitializationException(e.getMessage(), e);
         }
     }
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java b/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
index 8babca685..b001119b5 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
@@ -30,13 +30,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.web.client.RestTemplate;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.stream.Collectors;
 
 /**
  * Factory that constructs clients for {@link Sender} and {@link Subscriber}.
@@ -45,11 +41,7 @@ public final class ClientFactory {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ClientFactory.class);
 
-    private static final String CONFIG_DEFAULT_LOCATION = "config.yml";
-    private static final String CUSTOM_CONFIG_KEY = "FIT_CONNECT_CONFIG";
-
-    private static final String SENDER_BANNER = getSplashScreenResource("/sender-banner.txt");
-    private static final String SUBSCRIBER_BANNER = getSplashScreenResource("/subscriber-banner.txt");
+    private static final String CONFIG_ENV_KEY_NAME = "FIT_CONNECT_CONFIG";
 
     private ClientFactory() {
     }
@@ -70,7 +62,6 @@ public final class ClientFactory {
      * @return the sender client
      */
     public static SenderClient.Start senderClient(final ApplicationConfig config) {
-        LOGGER.info(SENDER_BANNER);
         LOGGER.info("Initializing sender client ...");
         final Sender sender = getSender(config);
 
@@ -97,7 +88,6 @@ public final class ClientFactory {
      * @return the subscriber client
      */
     public static SubscriberClient.RequestSubmission subscriberClient(final ApplicationConfig config) {
-        LOGGER.info(SUBSCRIBER_BANNER);
         LOGGER.info("Initializing subscriber client ...");
         final Subscriber subscriber = getSubscriber(config);
         final SubscriberConfig subscriberConfig = config.getSubscriberConfig();
@@ -178,8 +168,12 @@ public final class ClientFactory {
     }
 
     private static SecurityEventTokenService getSecurityEventTokenService(final ApplicationConfig config) {
-        LOGGER.info("Reading private signing key from {} ", config.getPrivateSigningKeyPath());
-        final String signingKey = readPath(config.getPrivateSigningKeyPath());
+        final String signingKeyPath = config.getPrivateSigningKeyPath();
+        LOGGER.info("Reading private signing key from {} ", signingKeyPath);
+        final String signingKey = readPath(signingKeyPath);
+        if (signingKey == null) {
+            throw new InitializationException("Signing key is null, please check the path '" + signingKeyPath + "' your current config.yml");
+        }
         return new SecurityEventTokenService(signingKey);
     }
 
@@ -192,9 +186,9 @@ public final class ClientFactory {
         return null;
     }
 
-    private static String readPathFromEnvironment(final String variableName) {
+    private static Path readPathFromEnvironment(final String variableName) {
         try {
-            return System.getenv(variableName);
+            return Path.of(System.getenv(variableName));
         } catch (final NullPointerException e) {
             LOGGER.error("Environment variable {} could not be loaded", variableName);
             return null;
@@ -202,29 +196,16 @@ public final class ClientFactory {
     }
 
     private static ApplicationConfig loadConfig() {
-        final String customConfigLocation = readPathFromEnvironment(CUSTOM_CONFIG_KEY);
-        if (customConfigLocation == null) {
-            return loadConfigFromPath(CONFIG_DEFAULT_LOCATION);
-        }
-        return loadConfigFromPath(customConfigLocation);
-    }
-
-    private static ApplicationConfig loadConfigFromPath(final String configPath) {
         try {
-            final Path pathToConfig = Path.of(configPath);
-            final ApplicationConfig applicationConfig = ApplicationConfigLoader.loadConfig(pathToConfig);
-            LOGGER.info("Using sdk environment config {} with {}", applicationConfig.getCurrentEnvironment(), applicationConfig);
+            final Path configPath = readPathFromEnvironment(CONFIG_ENV_KEY_NAME);
+            final ApplicationConfig applicationConfig = ApplicationConfigLoader.loadConfig(configPath);
+            LOGGER.info("Using sdk environment config `{}` ", applicationConfig.getActiveEnvironment().getName());
             return applicationConfig;
         } catch (final InitializationException e) {
-            LOGGER.error("Config could not be loaded, please provide a 'config.yml' in the root path or in the ENV-var 'FIT_CONNECT_CONFIG'");
+            LOGGER.error("Config could not be loaded, please provide a 'config.yml' by setting the environment variable 'FIT_CONNECT_CONFIG'");
             throw e;
         }
     }
-
-    private static String getSplashScreenResource(final String bannerName) {
-        final InputStream is = ClientFactory.class.getResourceAsStream(bannerName);
-        return new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
-    }
 }
 
 
diff --git a/client/src/main/resources/sender-banner.txt b/client/src/main/resources/sender-banner.txt
deleted file mode 100644
index 0fd3fc638..000000000
--- a/client/src/main/resources/sender-banner.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-    ______ ____ ______      ______                                  __     _____                   __
-   / ____//  _//_  __/     / ____/____   ____   ____   ___   _____ / /_   / ___/ ___   ____   ____/ /___   _____
-  / /_    / /   / /______ / /    / __ \ / __ \ / __ \ / _ \ / ___// __/   \__ \ / _ \ / __ \ / __  // _ \ / ___/
- / __/  _/ /   / //_____// /___ / /_/ // / / // / / //  __// /__ / /_    ___/ //  __// / / // /_/ //  __// /    
-/_/    /___/  /_/        \____/ \____//_/ /_//_/ /_/ \___/ \___/ \__/   /____/ \___//_/ /_/ \__,_/ \___//_/     
-                                                                                                                
\ No newline at end of file
diff --git a/client/src/main/resources/subscriber-banner.txt b/client/src/main/resources/subscriber-banner.txt
deleted file mode 100644
index 02dac0d00..000000000
--- a/client/src/main/resources/subscriber-banner.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-    ______ ____ ______      ______                                  __     _____         __                       _  __
-   / ____//  _//_  __/     / ____/____   ____   ____   ___   _____ / /_   / ___/ __  __ / /_   _____ _____ _____ (_)/ /_   ___   _____
-  / /_    / /   / /______ / /    / __ \ / __ \ / __ \ / _ \ / ___// __/   \__ \ / / / // __ \ / ___// ___// ___// // __ \ / _ \ / ___/
- / __/  _/ /   / //_____// /___ / /_/ // / / // / / //  __// /__ / /_    ___/ // /_/ // /_/ /(__  )/ /__ / /   / // /_/ //  __// /    
-/_/    /___/  /_/        \____/ \____//_/ /_//_/ /_/ \___/ \___/ \__/   /____/ \__,_//_.___//____/ \___//_/   /_//_.___/ \___//_/     
-                                                                                                                                      
\ No newline at end of file
-- 
GitLab