From 532b4ca0d82e1a879334e55babb8767a27e7627d Mon Sep 17 00:00:00 2001
From: Daniel Gultsch <daniel@gultsch.de>
Date: Sat, 29 Dec 2018 12:35:52 +0100
Subject: [PATCH] change database configuration to make it easier testable

---
 config.json.example                           | 12 ++--
 src/main/java/im/quicksy/server/Main.java     |  1 +
 src/main/java/im/quicksy/server/Utils.java    |  1 +
 .../{ => configuration}/Configuration.java    | 49 ++-----------
 .../configuration/DatabaseConfiguration.java  | 69 +++++++++++++++++++
 .../DatabaseConfigurationBundle.java          | 56 +++++++++++++++
 .../controller/AuthenticationController.java  |  2 +-
 .../server/controller/BaseController.java     |  2 +-
 .../server/controller/EnterController.java    |  3 +-
 .../server/controller/PasswordController.java |  2 +-
 .../controller/SynchronizationController.java |  2 +-
 .../im/quicksy/server/database/Database.java  | 28 ++++----
 .../java/im/quicksy/server/pojo/Voucher.java  |  4 +-
 .../im/quicksy/server/utils/CimUtils.java     |  2 +-
 .../java/im/quicksy/server/utils/PayPal.java  |  2 +-
 .../TwilioVerificationProvider.java           |  2 +-
 .../java/im/quicksy/server/DatabaseTest.java  | 30 +++++---
 17 files changed, 183 insertions(+), 84 deletions(-)
 rename src/main/java/im/quicksy/server/{ => configuration}/Configuration.java (82%)
 create mode 100644 src/main/java/im/quicksy/server/configuration/DatabaseConfiguration.java
 create mode 100644 src/main/java/im/quicksy/server/configuration/DatabaseConfigurationBundle.java

diff --git a/config.json.example b/config.json.example
index c2cc52c..9486d8a 100644
--- a/config.json.example
+++ b/config.json.example
@@ -13,11 +13,13 @@
         "port": 4567
     },
     "db": {
-        "username": "***",
-        "password": "***",
-        "databases": {
-             "ejabberd": "ejabberd",
-             "quicksy": "quicksy"
+        "ejabberd" : {
+            "url": "jdbc:mariadb://localhost:3306/ejabberd?characterEncoding=utf8"
+            "username": "***",
+            "password": "***"
+        },
+        "quicksy" : {
+            "url": "jdbc:mariadb://localhost:3306/quicksy?characterEncoding=utf8"
         }
     },
     "pay_pal": {
diff --git a/src/main/java/im/quicksy/server/Main.java b/src/main/java/im/quicksy/server/Main.java
index 6438b5b..19417ab 100644
--- a/src/main/java/im/quicksy/server/Main.java
+++ b/src/main/java/im/quicksy/server/Main.java
@@ -16,6 +16,7 @@
 
 package im.quicksy.server;
 
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.controller.*;
 import im.quicksy.server.xmpp.synchronization.Entry;
 import im.quicksy.server.xmpp.synchronization.PhoneBook;
diff --git a/src/main/java/im/quicksy/server/Utils.java b/src/main/java/im/quicksy/server/Utils.java
index 427920f..173bb7c 100644
--- a/src/main/java/im/quicksy/server/Utils.java
+++ b/src/main/java/im/quicksy/server/Utils.java
@@ -18,6 +18,7 @@ package im.quicksy.server;
 
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.Phonenumber;
+import im.quicksy.server.configuration.Configuration;
 import rocks.xmpp.addr.Jid;
 
 public class Utils {
diff --git a/src/main/java/im/quicksy/server/Configuration.java b/src/main/java/im/quicksy/server/configuration/Configuration.java
similarity index 82%
rename from src/main/java/im/quicksy/server/Configuration.java
rename to src/main/java/im/quicksy/server/configuration/Configuration.java
index 98fa098..0cab9aa 100644
--- a/src/main/java/im/quicksy/server/Configuration.java
+++ b/src/main/java/im/quicksy/server/configuration/Configuration.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package im.quicksy.server;
+package im.quicksy.server.configuration;
 
 
 import com.github.zafarkhaja.semver.Version;
@@ -41,7 +41,7 @@ public class Configuration {
 
     private XMPP xmpp = new XMPP();
     private Web web = new Web();
-    private DB db = new DB();
+    private HashMap<String, DatabaseConfiguration> db;
     private PayPal payPal = new PayPal();
     private String twilioAuthToken;
     private String cimAuthToken;
@@ -50,6 +50,7 @@ public class Configuration {
     private String domain;
     private boolean validatePhoneNumbers = true;
     private boolean preventRegistration = true;
+
     private Configuration() {
 
     }
@@ -102,7 +103,7 @@ public class Configuration {
     }
 
     public boolean check() {
-        return domain != null && minVersion != null && web != null && xmpp != null && xmpp.check() && db != null && db.check() && payPal != null && payPal.check();
+        return domain != null && minVersion != null && web != null && xmpp != null && xmpp.check() && db != null && db.size() == 2 && payPal != null && payPal.check();
     }
 
     public Duration getAccountInactivity() {
@@ -125,8 +126,8 @@ public class Configuration {
         return web;
     }
 
-    public DB getDb() {
-        return db;
+    public DatabaseConfigurationBundle getDatabaseConfigurationBundle() {
+        return new DatabaseConfigurationBundle.Builder().setEjabberdConfiguration(db.get("ejabberd")).setQuicksyConfiguration(db.get("quicksy")).build();
     }
 
     public String getTwilioAuthToken() {
@@ -193,44 +194,6 @@ public class Configuration {
         }
     }
 
-    public static class DB {
-        private String host = "127.0.0.1";
-        private int port = 3306;
-        private String username;
-        private String password;
-        private HashMap<String, String> databases;
-        private int poolSize = 1;
-
-        public String getHost() {
-            return host;
-        }
-
-        public int getPort() {
-            return port;
-        }
-
-        public String getUsername() {
-            return username;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-
-        public String getJdbcUri(String database) {
-
-            return String.format("jdbc:mariadb://%s:%d/%s?characterEncoding=utf8", host, port, databases.get(database));
-        }
-
-        public boolean check() {
-            return username != null && password != null && databases != null && databases.containsKey("ejabberd") && databases.containsKey("quicksy");
-        }
-
-        public int getPoolSize() {
-            return poolSize;
-        }
-    }
-
     public static class PayPal {
         private String username;
         private String password;
diff --git a/src/main/java/im/quicksy/server/configuration/DatabaseConfiguration.java b/src/main/java/im/quicksy/server/configuration/DatabaseConfiguration.java
new file mode 100644
index 0000000..1912e4c
--- /dev/null
+++ b/src/main/java/im/quicksy/server/configuration/DatabaseConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 Daniel Gultsch
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.quicksy.server.configuration;
+
+public class DatabaseConfiguration {
+
+    private String url;
+    private String username;
+    private String password;
+    private int poolSize = 1;
+
+    private DatabaseConfiguration() {
+
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String getJdbcUri() {
+        return url;
+    }
+
+    public int getPoolSize() {
+        return poolSize;
+    }
+
+    public static class Builder {
+
+        private final DatabaseConfiguration configuration = new DatabaseConfiguration();
+
+        public DatabaseConfiguration.Builder setUsername(String username) {
+            configuration.username = username;
+            return this;
+        }
+
+        public DatabaseConfiguration.Builder setPassword(String password) {
+            configuration.password = password;
+            return this;
+        }
+
+        public DatabaseConfiguration.Builder setUrl(String url) {
+            configuration.url = url;
+            return this;
+        }
+
+        public DatabaseConfiguration build() {
+            return configuration;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/im/quicksy/server/configuration/DatabaseConfigurationBundle.java b/src/main/java/im/quicksy/server/configuration/DatabaseConfigurationBundle.java
new file mode 100644
index 0000000..cded522
--- /dev/null
+++ b/src/main/java/im/quicksy/server/configuration/DatabaseConfigurationBundle.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 Daniel Gultsch
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.quicksy.server.configuration;
+
+public class DatabaseConfigurationBundle {
+
+    private DatabaseConfiguration ejabberd;
+    private DatabaseConfiguration quicksy;
+
+    private DatabaseConfigurationBundle() {
+
+    }
+
+    public DatabaseConfiguration getEjabberdConfiguration() {
+        return ejabberd;
+    }
+
+    public DatabaseConfiguration getQuicksyConfiguration() {
+        return quicksy;
+    }
+
+
+    public static class Builder {
+
+        private final DatabaseConfigurationBundle bundle = new DatabaseConfigurationBundle();
+
+        public Builder setEjabberdConfiguration(DatabaseConfiguration configuration) {
+            bundle.ejabberd = configuration;
+            return this;
+        }
+
+        public Builder setQuicksyConfiguration(DatabaseConfiguration configuration) {
+            bundle.quicksy = configuration;
+            return this;
+        }
+
+        public DatabaseConfigurationBundle build() {
+            return bundle;
+        }
+
+    }
+}
diff --git a/src/main/java/im/quicksy/server/controller/AuthenticationController.java b/src/main/java/im/quicksy/server/controller/AuthenticationController.java
index 23e7be4..86e6390 100644
--- a/src/main/java/im/quicksy/server/controller/AuthenticationController.java
+++ b/src/main/java/im/quicksy/server/controller/AuthenticationController.java
@@ -19,7 +19,7 @@ package im.quicksy.server.controller;
 import com.google.i18n.phonenumbers.NumberParseException;
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.Phonenumber;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.Utils;
 import im.quicksy.server.ejabberd.MyEjabberdApi;
 import im.quicksy.server.pojo.Device;
diff --git a/src/main/java/im/quicksy/server/controller/BaseController.java b/src/main/java/im/quicksy/server/controller/BaseController.java
index da76067..104bf4d 100644
--- a/src/main/java/im/quicksy/server/controller/BaseController.java
+++ b/src/main/java/im/quicksy/server/controller/BaseController.java
@@ -20,7 +20,7 @@ import com.github.zafarkhaja.semver.ParseException;
 import com.github.zafarkhaja.semver.Version;
 import com.google.common.base.Splitter;
 import com.google.common.net.InetAddresses;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.verification.TwilioVerificationProvider;
 import im.quicksy.server.verification.VerificationProvider;
 import org.slf4j.Logger;
diff --git a/src/main/java/im/quicksy/server/controller/EnterController.java b/src/main/java/im/quicksy/server/controller/EnterController.java
index 8bed8ea..6fb3ad8 100644
--- a/src/main/java/im/quicksy/server/controller/EnterController.java
+++ b/src/main/java/im/quicksy/server/controller/EnterController.java
@@ -21,7 +21,7 @@ import com.google.i18n.phonenumbers.NumberParseException;
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.Phonenumber;
 import de.gultsch.ejabberd.api.RequestFailedException;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.database.Database;
 import im.quicksy.server.ejabberd.MyEjabberdApi;
 import im.quicksy.server.pojo.Entry;
@@ -36,7 +36,6 @@ import im.quicksy.server.verification.VerificationProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import rocks.xmpp.addr.Jid;
-import rocks.xmpp.extensions.hashes.model.Hash;
 import spark.*;
 
 import java.util.HashMap;
diff --git a/src/main/java/im/quicksy/server/controller/PasswordController.java b/src/main/java/im/quicksy/server/controller/PasswordController.java
index 7abbca8..a188aef 100644
--- a/src/main/java/im/quicksy/server/controller/PasswordController.java
+++ b/src/main/java/im/quicksy/server/controller/PasswordController.java
@@ -22,7 +22,7 @@ import com.google.i18n.phonenumbers.NumberParseException;
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.Phonenumber;
 import de.gultsch.ejabberd.api.results.Last;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.Utils;
 import im.quicksy.server.ejabberd.MyEjabberdApi;
 import im.quicksy.server.throttle.RateLimiter;
diff --git a/src/main/java/im/quicksy/server/controller/SynchronizationController.java b/src/main/java/im/quicksy/server/controller/SynchronizationController.java
index 489d2d2..2c68109 100644
--- a/src/main/java/im/quicksy/server/controller/SynchronizationController.java
+++ b/src/main/java/im/quicksy/server/controller/SynchronizationController.java
@@ -16,7 +16,7 @@
 
 package im.quicksy.server.controller;
 
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.database.Database;
 import im.quicksy.server.throttle.Strategy;
 import im.quicksy.server.throttle.VolumeLimiter;
diff --git a/src/main/java/im/quicksy/server/database/Database.java b/src/main/java/im/quicksy/server/database/Database.java
index 10d9d40..7decda6 100644
--- a/src/main/java/im/quicksy/server/database/Database.java
+++ b/src/main/java/im/quicksy/server/database/Database.java
@@ -19,7 +19,9 @@ package im.quicksy.server.database;
 import com.google.i18n.phonenumbers.Phonenumber;
 import com.zaxxer.hikari.HikariDataSource;
 import de.gultsch.xmpp.addr.adapter.Adapter;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
+import im.quicksy.server.configuration.DatabaseConfigurationBundle;
+import im.quicksy.server.configuration.DatabaseConfiguration;
 import im.quicksy.server.pojo.Entry;
 import im.quicksy.server.pojo.Payment;
 import im.quicksy.server.pojo.PaymentStatus;
@@ -59,13 +61,9 @@ public class Database {
         QUIRKS = new NoQuirks(converters);
     }
 
-    private Database() {
-        this(createDatabase("ejabberd"),createDatabase("quicksy"));
-    }
-
-    public Database(Sql2o ejabberdDatabase, Sql2o quicksyDatabase) {
-        this.ejabberdDatabase = ejabberdDatabase;
-        this.quicksyDatabase = quicksyDatabase;
+    public Database(DatabaseConfigurationBundle configurationBundle) {
+        this.ejabberdDatabase = createDatabase(configurationBundle.getEjabberdConfiguration());
+        this.quicksyDatabase = createDatabase(configurationBundle.getQuicksyConfiguration());
         setup(this.quicksyDatabase);
     }
 
@@ -76,19 +74,18 @@ public class Database {
         }
     }
 
-    private static Sql2o createDatabase(String database) {
+    private static Sql2o createDatabase(DatabaseConfiguration configuration) {
         HikariDataSource dataSource = new HikariDataSource();
-        Configuration.DB dbConfig = Configuration.getInstance().getDb();
-        dataSource.setMaximumPoolSize(dbConfig.getPoolSize());
-        dataSource.setJdbcUrl(dbConfig.getJdbcUri(database));
-        dataSource.setUsername(dbConfig.getUsername());
-        dataSource.setPassword(dbConfig.getPassword());
+        dataSource.setMaximumPoolSize(configuration.getPoolSize());
+        dataSource.setJdbcUrl(configuration.getJdbcUri());
+        dataSource.setUsername(configuration.getUsername());
+        dataSource.setPassword(configuration.getPassword());
         return new Sql2o(dataSource, QUIRKS);
     }
 
     public static synchronized  Database getInstance() {
         if (INSTANCE == null) {
-            INSTANCE = new Database();
+            INSTANCE = new Database(Configuration.getInstance().getDatabaseConfigurationBundle());
         }
         return INSTANCE;
     }
@@ -154,7 +151,6 @@ public class Database {
             }
             connection.commit();
         } catch (Exception e) {
-            e.printStackTrace();
             LOGGER.error(e.getMessage());
             return false;
         }
diff --git a/src/main/java/im/quicksy/server/pojo/Voucher.java b/src/main/java/im/quicksy/server/pojo/Voucher.java
index 0b2f9f4..b911edf 100644
--- a/src/main/java/im/quicksy/server/pojo/Voucher.java
+++ b/src/main/java/im/quicksy/server/pojo/Voucher.java
@@ -19,15 +19,13 @@ package im.quicksy.server.pojo;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
-import im.quicksy.server.Configuration;
-import im.quicksy.server.controller.BaseController;
+import im.quicksy.server.configuration.Configuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.FileReader;
 import java.time.Instant;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 
 public class Voucher {
diff --git a/src/main/java/im/quicksy/server/utils/CimUtils.java b/src/main/java/im/quicksy/server/utils/CimUtils.java
index 3bac41f..4dfe5c4 100644
--- a/src/main/java/im/quicksy/server/utils/CimUtils.java
+++ b/src/main/java/im/quicksy/server/utils/CimUtils.java
@@ -17,7 +17,7 @@
 package im.quicksy.server.utils;
 
 import com.google.common.net.UrlEscapers;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import rocks.xmpp.addr.Jid;
diff --git a/src/main/java/im/quicksy/server/utils/PayPal.java b/src/main/java/im/quicksy/server/utils/PayPal.java
index cf7fa2c..e24d10d 100644
--- a/src/main/java/im/quicksy/server/utils/PayPal.java
+++ b/src/main/java/im/quicksy/server/utils/PayPal.java
@@ -16,7 +16,7 @@
 
 package im.quicksy.server.utils;
 
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.pojo.Payment;
 import im.quicksy.server.pojo.ShoppingCartItem;
 
diff --git a/src/main/java/im/quicksy/server/verification/TwilioVerificationProvider.java b/src/main/java/im/quicksy/server/verification/TwilioVerificationProvider.java
index 101d2bc..e389c13 100644
--- a/src/main/java/im/quicksy/server/verification/TwilioVerificationProvider.java
+++ b/src/main/java/im/quicksy/server/verification/TwilioVerificationProvider.java
@@ -20,7 +20,7 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonSyntaxException;
 import com.google.i18n.phonenumbers.Phonenumber;
-import im.quicksy.server.Configuration;
+import im.quicksy.server.configuration.Configuration;
 import im.quicksy.server.verification.twilio.ErrorResponse;
 import im.quicksy.server.verification.twilio.GenericResponse;
 import im.quicksy.server.verification.twilio.StartResponse;
diff --git a/src/test/java/im/quicksy/server/DatabaseTest.java b/src/test/java/im/quicksy/server/DatabaseTest.java
index 9ba1801..d7660ed 100644
--- a/src/test/java/im/quicksy/server/DatabaseTest.java
+++ b/src/test/java/im/quicksy/server/DatabaseTest.java
@@ -16,13 +16,13 @@
 
 package im.quicksy.server;
 
-import com.zaxxer.hikari.HikariDataSource;
+import im.quicksy.server.configuration.DatabaseConfiguration;
+import im.quicksy.server.configuration.DatabaseConfigurationBundle;
 import im.quicksy.server.database.Database;
 import im.quicksy.server.pojo.Entry;
 import im.quicksy.server.pojo.Payment;
 import im.quicksy.server.pojo.PaymentMethod;
 import org.junit.Test;
-import org.sql2o.Sql2o;
 import rocks.xmpp.addr.Jid;
 
 import static junit.framework.TestCase.assertNotNull;
@@ -34,14 +34,23 @@ public class DatabaseTest {
 
     private static final Jid TEST_USER = Jid.of("test@example.com");
 
+    private static final DatabaseConfigurationBundle IN_MEMORY_DATABASE_CONFIGURATION;
+
+    static {
+        IN_MEMORY_DATABASE_CONFIGURATION = new DatabaseConfigurationBundle.Builder()
+                .setEjabberdConfiguration(new DatabaseConfiguration.Builder()
+                        .setUrl(JDBC_URL)
+                        .build())
+                .setQuicksyConfiguration(new DatabaseConfiguration.Builder()
+                        .setUrl(JDBC_URL)
+                        .build())
+                .build();
+    }
+
+
     @Test
     public void makePaymentCreateEntityAndReadBack() {
-        final Sql2o ejabberd = new Sql2o(JDBC_URL, null, null);
-        HikariDataSource dataSource = new HikariDataSource();
-        dataSource.setMaximumPoolSize(1);
-        dataSource.setJdbcUrl(JDBC_URL);
-        final Sql2o quicksy = new Sql2o(dataSource);
-        final Database database = new Database(ejabberd, quicksy);
+        final Database database = new Database(IN_MEMORY_DATABASE_CONFIGURATION);
         final Payment payment = new Payment(TEST_USER, PaymentMethod.VOUCHER);
         payment.setToken("test");
         database.createPayment(payment);
@@ -51,4 +60,9 @@ public class DatabaseTest {
         assertNotNull(entry);
     }
 
+    @Test
+    public void createEntryAddPhoneNumberAndSearch() {
+
+    }
+
 }
-- 
GitLab