Merge pull request #7 from Izakey/FINCN-114

Migrate test library from MariaDB to PostgreSQL
diff --git a/.gitignore b/.gitignore
index 300fb08..3642fde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 .idea
 build/
 target/
+out
 
 # Ignore Gradle GUI config
 gradle-app.setting
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..daad86e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+language: java
+sudo: false
+jdk:
+- openjdk8
+install: true
+script: "./travis.sh"
+env:
+  global:
+    - BUILD_SNAPSHOTS_BRANCH=develop
+    - ARTIFACTORY_URL=https://mifos.jfrog.io/mifos
+    - ARTIFACTORY_USER=travis-ci
+    - secure: "GpFdEtdt/1IMRW2p3kFTeG6oJW8C/c+aIKLvRsLc3pW5VNFcjpmPy5wbh1JER9LSDEC2TILh0ihp70aOBiZtYaBp5PQ/tffjgIE6bMrAqY3Fa9nrY5UCahlJT5RySyl63WaMnjao67wWhegl9QnCji0Z4oNa0WvByKVyjbr0IxJAcNVD9BPASVaURc26SitlwxtzYNQ9dbs2SVMPQxLk956iShRyAIXhOsNHYy629u80rA2YLzw2xgH4SRTALpxz2JaX1AQ9jeaVkouFgrxEg8O37hCkFyyGAKLON3k/HGfVC7PJ12RPLtxia0jEbySyhgCRPGA6aYY5F7zoy1G4p8AY8y83s+IU3DBgtNF/VPzKV1vF05kQhvmP1j6LyGx+CvOmKP6EwpYl8YZyBGzRb1q4BVJP5vu7N4gYuAWVWSSuyn2dmjDYxURKNT4oohre1uzw/2ECBDmHFCtbryDgBZGORMC0UEHkAFJIi0Q7eEDmYgNdkAtv1wb4MPzLLmbr/G5KWfRcwD5v13Lj1DfHFCSb6hGs97oyFWi+as/nw6FsOC0rWuFhSjqr2v9uuSw21JPkUkE8CqSYkghV8+M7HteZX+ZyINe7I1CZszNCglu8pFYaMK1Nwoj61jejb+r8y8nU0sWowlhI4z1BQ9Kff2U6nsNxaiDP+lJZisLdui0="
+
diff --git a/NOTICE.txt b/NOTICE.txt
index 15413c9..df63679 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Apache Fineract CN Test
-Copyright [2017-2018] The Apache Software Foundation
+Copyright [2017-2019] The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.md b/README.md
index ecd0a52..1dad2f7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Apache Fineract CN Test
+# Apache Fineract CN Test [![Build Status](https://api.travis-ci.com/apache/fineract-cn-test.svg?branch=develop)](https://travis-ci.com/apache/fineract-cn-test)
 
 ## Abstract
 Apache Fineract CN is an application framework for digital financial services, a system to support nationwide and cross-national financial transactions and help to level and speed the creation of an inclusive, interconnected digital economy for every nation in the world.
@@ -7,13 +7,14 @@
 ### Runtime
 Install Java 8 as described at https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html.
 
-### MariaDB
-Install MariaDB as described at https://mariadb.com/kb/en/mariadb/binary-packages/.
+### PostgreSQL
+Install PostgreSQL as described at
+https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-16-04.
 
 After installation you need to create the meta database:
 
-    mysql -u root -pmysql
-    CREATE DATABASE IF NOT EXISTS system_console;
+    sudo -i -u postgres psql
+    CREATE DATABASE system_console;
     
 ### Cassandra
 Install Apache Cassandra as described at https://wiki.apache.org/cassandra/GettingStarted.
@@ -46,4 +47,4 @@
 1.3.5-RELEASE
 
 ## License
-See [LICENSE](LICENSE) file.
+See [LICENSE](LICENSE) file.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index faa83ee..e3795fb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,6 +24,7 @@
 plugins {
     id 'com.github.hierynomus.license' version '0.13.1'
     id("org.nosphere.apache.rat") version "0.3.1"
+    id "com.jfrog.artifactory" version "4.9.5"
 }
 
 group 'org.apache.fineract.cn'
@@ -35,7 +36,6 @@
         gson                      : '2.5',
         findbugs                  : '3.0.1',
         frameworklang             : '0.1.0-BUILD-SNAPSHOT',
-        frameworkmariadb          : '0.1.0-BUILD-SNAPSHOT',
         frameworkcassandra        : '0.1.0-BUILD-SNAPSHOT'
 ]
 
@@ -53,6 +53,7 @@
 repositories {
     jcenter()
     mavenLocal()
+    maven { url 'https://mifos.jfrog.io/mifos/libs-snapshot/' }
 }
 
 dependencies {
@@ -63,11 +64,11 @@
             [group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: versions.springboot],
             [group: 'com.google.code.gson', name: 'gson', version: versions.gson],
             [group: 'org.apache.fineract.cn', name: 'cassandra', version: versions.frameworkcassandra],
-            [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
+            [group: 'org.apache.fineract.cn', name: 'postgresql', version: '0.1.0-BUILD-SNAPSHOT'],
             [group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
             [group: 'io.jsonwebtoken', name: 'jjwt', version: '0.6.0'],
             [group: 'org.cassandraunit', name: 'cassandra-unit', version: '3.0.0.1'],
-            [group: 'ch.vorburger.mariaDB4j', name: 'mariaDB4j', version: '2.1.3'],
+            [group: 'com.opentable.components', name: 'otj-pg-embedded', version: '0.7.1']
     )
 }
 
@@ -77,11 +78,28 @@
             from components.java
             groupId project.group
             artifactId project.name
-            version project.version
+            version project.findProperty('externalVersion') ?: project.version
         }
     }
 }
 
+artifactory {
+    contextUrl = System.getenv("ARTIFACTORY_URL")
+    publish {
+        repository {
+            repoKey = project.findProperty('artifactoryRepoKey')
+            username = System.getenv("ARTIFACTORY_USER")
+            password = System.getenv("ARTIFACTORY_PASSWORD")
+        }
+
+        defaults {
+            publications ('testPublication')
+        }
+    }
+}
+artifactoryPublish.dependsOn('clean','publishToMavenLocal')
+
+
 jar {
     from sourceSets.main.allSource
     duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -106,4 +124,4 @@
             "gradlew.bat",
             "README.md"
     ]
-}
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ba3a06f..fe81d05 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Mar 14 11:47:51 CET 2017
+#Fri Jan 04 23:49:37 WAT 2019
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip
diff --git a/src/main/java/org/apache/fineract/cn/test/env/TestEnvironment.java b/src/main/java/org/apache/fineract/cn/test/env/TestEnvironment.java
index bcd0c35..ed4500c 100644
--- a/src/main/java/org/apache/fineract/cn/test/env/TestEnvironment.java
+++ b/src/main/java/org/apache/fineract/cn/test/env/TestEnvironment.java
@@ -59,23 +59,24 @@
   public static final String CASSANDRA_CONSISTENCY_LEVEL_DELETE_PROPERTY = "cassandra.cl.delete";
   public static final String CASSANDRA_CONSISTENCY_LEVEL_DEFAULT = "ONE";
 
-  public static final String MARIADB_DRIVER_CLASS_PROPERTY = "mariadb.driverClass";
-  public static final String MARIADB_DRIVER_CLASS_DEFAULT = "org.mariadb.jdbc.Driver";
+  public static final String POSTGRESQL_DRIVER_CLASS_PROPERTY = "postgresql.driverClass";
+  public static final String POSTGRESQL_DRIVER_CLASS_DEFAULT = "org.postgresql.Driver";
 
-  public static final String MARIADB_DATABASE_NAME_PROPERTY = "mariadb.database";
-  public static final String MARIADB_DATABASE_NAME_DEFAULT = "seshat";
+  public static final String POSTGRESQL_DATABASE_NAME_PROPERTY = "postgresql.database";
+  public static final String POSTGRESQL_DATABASE_NAME_DEFAULT = "seshat";
+  public static final String POSTGRESQL_DATABASE_NAME = "postgres";
 
-  public static final String MARIADB_HOST_PROPERTY = "mariadb.host";
-  public static final String MARIADB_HOST_DEFAULT = "localhost";
+  public static final String POSTGRESQL_HOST_PROPERTY = "postgresql.host";
+  public static final String POSTGRESQL_HOST_DEFAULT = "localhost";
 
-  public static final String MARIADB_PORT_PROPERTY = "mariadb.port";
-  public static final String MARIADB_PORT_DEFAULT = "3306";
+  public static final String POSTGRESQL_PORT_PROPERTY = "postgresql.port";
+  public static final String POSTGRESQL_PORT_DEFAULT = "5432";
 
-  public static final String MARIADB_USER_PROPERTY = "mariadb.user";
-  public static final String MARIADB_USER_DEFAULT = "root";
+  public static final String POSTGRESQL_USER_PROPERTY = "postgresql.user";
+  public static final String POSTGRESQL_USER_DEFAULT = "postgres";
 
-  public static final String MARIADB_PASSWORD_PROPERTY = "mariadb.password";
-  public static final String MARIADB_PASSWORD_DEFAULT = "mysql";
+  public static final String POSTGRESQL_PASSWORD_PROPERTY = "postgresql.password";
+  public static final String POSTGRESQL_PASSWORD_DEFAULT = "postgres";
 
   public static final String SPRING_CLOUD_DISCOVERY_ENABLED_PROPERTY = "spring.cloud.discovery.enabled";
   public static final String SPRING_CLOUD_DISCOVERY_ENABLED_DEFAULT = "false";
@@ -131,12 +132,12 @@
     return this;
   }
 
-  public String generateUniqueIdentifer(final String prefix) {
-    return generateUniqueIdentifer(prefix, 1);
+  public String generateUniqueIdentifier(final String prefix) {
+    return generateUniqueIdentifier(prefix, 1);
   }
 
   //prefix followed by a positive number.
-  public String generateUniqueIdentifer(final String prefix, final int minimumDigitCount) {
+  public String generateUniqueIdentifier(final String prefix, final int minimumDigitCount) {
     uniquenessSuffix++;
     final String format = String.format("%%0%dd", minimumDigitCount);
     return prefix + String.format(format, uniquenessSuffix);
@@ -211,12 +212,12 @@
     this.properties.setProperty(CASSANDRA_CONSISTENCY_LEVEL_READ_PROPERTY, CASSANDRA_CONSISTENCY_LEVEL_DEFAULT);
     this.properties.setProperty(CASSANDRA_CONSISTENCY_LEVEL_WRITE_PROPERTY, CASSANDRA_CONSISTENCY_LEVEL_DEFAULT);
     this.properties.setProperty(CASSANDRA_CONSISTENCY_LEVEL_DELETE_PROPERTY, CASSANDRA_CONSISTENCY_LEVEL_DEFAULT);
-    this.properties.setProperty(MARIADB_DRIVER_CLASS_PROPERTY, MARIADB_DRIVER_CLASS_DEFAULT);
-    this.properties.setProperty(MARIADB_DATABASE_NAME_PROPERTY, MARIADB_DATABASE_NAME_DEFAULT);
-    this.properties.setProperty(MARIADB_HOST_PROPERTY, MARIADB_HOST_DEFAULT);
-    this.properties.setProperty(MARIADB_PORT_PROPERTY, MARIADB_PORT_DEFAULT);
-    this.properties.setProperty(MARIADB_USER_PROPERTY, MARIADB_USER_DEFAULT);
-    this.properties.setProperty(MARIADB_PASSWORD_PROPERTY, MARIADB_PASSWORD_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_DRIVER_CLASS_PROPERTY, POSTGRESQL_DRIVER_CLASS_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_DATABASE_NAME_PROPERTY, POSTGRESQL_DATABASE_NAME_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_HOST_PROPERTY, POSTGRESQL_HOST_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_PORT_PROPERTY, POSTGRESQL_PORT_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_USER_PROPERTY, POSTGRESQL_USER_DEFAULT);
+    this.properties.setProperty(POSTGRESQL_PASSWORD_PROPERTY, POSTGRESQL_PASSWORD_DEFAULT);
     this.properties.setProperty(SPRING_CLOUD_DISCOVERY_ENABLED_PROPERTY, SPRING_CLOUD_DISCOVERY_ENABLED_DEFAULT);
     this.properties.setProperty(SPRING_CLOUD_CONFIG_ENABLED_PROPERTY, SPRING_CLOUD_CONFIG_ENABLED_DEFAULT);
     this.properties.setProperty(FLYWAY_ENABLED_PROPERTY, FLYWAY_ENABLED_DEFAULT);
diff --git a/src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBInitializer.java b/src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBInitializer.java
deleted file mode 100644
index 9b5de8d..0000000
--- a/src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBInitializer.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.fineract.cn.test.fixture.mariadb;
-
-import ch.vorburger.mariadb4j.DB;
-import org.apache.fineract.cn.test.env.TestEnvironment;
-import org.apache.fineract.cn.test.fixture.DataStoreTenantInitializer;
-
-import java.sql.*;
-import org.apache.fineract.cn.mariadb.util.JdbcUrlBuilder;
-
-@SuppressWarnings({"WeakerAccess", "unused", "SqlNoDataSourceInspection", "SqlDialectInspection"})
-public final class MariaDBInitializer extends DataStoreTenantInitializer {
-
-  private final boolean useExistingDB;
-  private static DB db;
-
-  public MariaDBInitializer() {
-    this(false);
-  }
-
-  public MariaDBInitializer(final boolean useExistingDB) {
-    super();
-    this.useExistingDB = useExistingDB;
-  }
-
-  @Override
-  public void initialize() throws Exception  {
-    MariaDBInitializer.setup(useExistingDB);
-  }
-
-  @Override
-  public void initializeTenant(final String tenantName) {
-    MariaDBInitializer.createDatabaseTenant(tenantName);
-
-  }
-
-  @Override
-  public void finish() {
-    if (!useExistingDB) {
-      try {
-        MariaDBInitializer.tearDown();
-      } catch (final Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  public static void setup() throws Exception {
-    setup(false);
-  }
-  public static void setup(final boolean useExistingDB) throws Exception {
-    if (!useExistingDB) {
-      MariaDBInitializer.startEmbeddedMariaDB();
-      MariaDBInitializer.createDatabaseSeshat();
-    }
-  }
-
-  public static void tearDown() throws Exception {
-    if (MariaDBInitializer.db != null) {
-      MariaDBInitializer.db.stop();
-      MariaDBInitializer.db = null;
-    }
-  }
-
-  private static void startEmbeddedMariaDB() throws Exception {
-    if (MariaDBInitializer.db == null) {
-      MariaDBInitializer.db = DB.newEmbeddedDB(3306);
-      MariaDBInitializer.db.start();
-    }
-  }
-
-  private static void createDatabaseSeshat() {
-    try {
-      Class.forName(System.getProperty(TestEnvironment.MARIADB_DRIVER_CLASS_PROPERTY));
-    } catch (ClassNotFoundException ex) {
-      throw new IllegalArgumentException(ex.getMessage(), ex);
-    }
-    final String jdbcUrl = JdbcUrlBuilder
-        .create(JdbcUrlBuilder.DatabaseType.MARIADB)
-        .host(System.getProperty(TestEnvironment.MARIADB_HOST_PROPERTY))
-        .port(System.getProperty(TestEnvironment.MARIADB_PORT_PROPERTY))
-        .build();
-    try (final Connection connection = DriverManager.getConnection(jdbcUrl,
-        System.getProperty(TestEnvironment.MARIADB_USER_PROPERTY),
-        System.getProperty(TestEnvironment.MARIADB_PASSWORD_PROPERTY))) {
-      try (final Statement statement = connection.createStatement()) {
-        // create meta database seshat
-        statement.execute("CREATE DATABASE IF NOT EXISTS " + System.getProperty(TestEnvironment.MARIADB_DATABASE_NAME_PROPERTY));
-        statement.execute("USE " + System.getProperty(TestEnvironment.MARIADB_DATABASE_NAME_PROPERTY));
-        // create needed tenant management table
-        statement.execute("CREATE TABLE IF NOT EXISTS tenants (" +
-            "  identifier    VARCHAR(32) NOT NULL," +
-            "  driver_class  VARCHAR(255) NOT NULL," +
-            "  database_name VARCHAR(32) NOT NULL," +
-            "  host          VARCHAR(32) NOT NULL," +
-            "  port          VARCHAR(5)  NOT NULL," +
-            "  a_user        VARCHAR(32) NOT NULL," +
-            "  pwd           VARCHAR(32) NOT NULL," +
-            "  PRIMARY KEY (identifier)" +
-            ")");
-      }
-      connection.commit();
-    } catch (final SQLException ex) {
-      ex.printStackTrace();
-    }
-  }
-
-  public static void createDatabaseTenant(final String identifier) {
-    try {
-      Class.forName(System.getProperty(TestEnvironment.MARIADB_DRIVER_CLASS_PROPERTY));
-    } catch (ClassNotFoundException ex) {
-      throw new IllegalArgumentException(ex.getMessage(), ex);
-    }
-    final String jdbcUrl = JdbcUrlBuilder
-        .create(JdbcUrlBuilder.DatabaseType.MARIADB)
-        .host(System.getProperty(TestEnvironment.MARIADB_HOST_PROPERTY))
-        .port(System.getProperty(TestEnvironment.MARIADB_PORT_PROPERTY))
-        .build();
-    try (final Connection connection = DriverManager.getConnection(jdbcUrl,
-        System.getProperty(TestEnvironment.MARIADB_USER_PROPERTY),
-        System.getProperty(TestEnvironment.MARIADB_PASSWORD_PROPERTY))) {
-      try (final Statement statement = connection.createStatement()) {
-        // create tenant database
-        statement.execute("CREATE DATABASE IF NOT EXISTS " + identifier);
-        // insert tenant connection info in management table
-        try (final ResultSet resultSet = statement.executeQuery(
-            "SELECT EXISTS (SELECT * FROM " +
-                System.getProperty(TestEnvironment.MARIADB_DATABASE_NAME_PROPERTY) +
-                ".tenants WHERE identifier = '" + identifier + "')")) {
-          if (resultSet.next()
-              && resultSet.getInt(1) == 0) {
-            final MariaDBTenant mariaDBTenant = new MariaDBTenant();
-            mariaDBTenant.setIdentifier(identifier);
-            mariaDBTenant.setDriverClass(System.getProperty(TestEnvironment.MARIADB_DRIVER_CLASS_PROPERTY));
-            mariaDBTenant.setDatabaseName(identifier);
-            mariaDBTenant.setHost(System.getProperty(TestEnvironment.MARIADB_HOST_PROPERTY));
-            mariaDBTenant.setPort(System.getProperty(TestEnvironment.MARIADB_PORT_PROPERTY));
-            mariaDBTenant.setUser(System.getProperty(TestEnvironment.MARIADB_USER_PROPERTY));
-            mariaDBTenant.setPassword(System.getProperty(TestEnvironment.MARIADB_PASSWORD_PROPERTY));
-            mariaDBTenant.insert(connection);
-          }
-        }
-      }
-      connection.commit();
-    } catch (final SQLException ex) {
-      ex.printStackTrace();
-    }
-  }
-}
diff --git a/src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLInitializer.java b/src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLInitializer.java
new file mode 100644
index 0000000..678abc1
--- /dev/null
+++ b/src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLInitializer.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.fineract.cn.test.fixture.postgresql;
+
+import com.opentable.db.postgres.embedded.EmbeddedPostgres;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.DataStoreTenantInitializer;
+
+import java.sql.*;
+import org.apache.fineract.cn.postgresql.util.JdbcUrlBuilder;
+
+@SuppressWarnings({"WeakerAccess", "unused", "SqlNoDataSourceInspection", "SqlDialectInspection"})
+public final class PostgreSQLInitializer extends DataStoreTenantInitializer {
+
+  private final boolean useExistingDB;
+  private static EmbeddedPostgres pg;
+
+  public PostgreSQLInitializer() {
+    this(false);
+  }
+
+  public PostgreSQLInitializer(final boolean useExistingDB) {
+    super();
+    this.useExistingDB = useExistingDB;
+  }
+
+  @Override
+  public void initialize() throws Exception  {
+    PostgreSQLInitializer.setup(useExistingDB);
+  }
+
+  @Override
+  public void initializeTenant(final String tenantName) {
+    PostgreSQLInitializer.createDatabaseTenant(tenantName);
+
+  }
+
+  @Override
+  public void finish() {
+    if (!useExistingDB) {
+      try {
+        PostgreSQLInitializer.tearDown();
+      } catch (final Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  public static void setup() throws Exception {
+    setup(false);
+  }
+  public static void setup(final boolean useExistingDB) throws Exception {
+    if (!useExistingDB) {
+      PostgreSQLInitializer.startEmbeddedPostgreSQL();
+      PostgreSQLInitializer.createDatabaseSeshat();
+    }
+  }
+
+  public static void tearDown() throws Exception {
+    if (PostgreSQLInitializer.pg != null) {
+      PostgreSQLInitializer.pg.close();
+      PostgreSQLInitializer.pg = null;
+    }
+  }
+
+  private static void startEmbeddedPostgreSQL() throws Exception {
+    PostgreSQLInitializer.pg = EmbeddedPostgres.builder().setPort(Integer.valueOf(TestEnvironment.POSTGRESQL_PORT_DEFAULT)).start();
+    System.setProperty(TestEnvironment.POSTGRESQL_HOST_PROPERTY, TestEnvironment.POSTGRESQL_HOST_DEFAULT);
+    System.setProperty(TestEnvironment.POSTGRESQL_PORT_PROPERTY, TestEnvironment.POSTGRESQL_PORT_DEFAULT);
+  }
+
+  private static void createDatabaseSeshat() {
+    try {
+      Class.forName(System.getProperty(TestEnvironment.POSTGRESQL_DRIVER_CLASS_PROPERTY));
+    } catch (ClassNotFoundException ex) {
+      throw new IllegalArgumentException(ex.getMessage(), ex);
+    }
+
+    final String jdbcUrl = JdbcUrlBuilder
+            .create(JdbcUrlBuilder.DatabaseType.POSTGRESQL)
+            .host(System.getProperty(TestEnvironment.POSTGRESQL_HOST_PROPERTY))
+            .port(System.getProperty(TestEnvironment.POSTGRESQL_PORT_PROPERTY))
+            .instanceName(TestEnvironment.POSTGRESQL_DATABASE_NAME)
+            .build();
+    try (final Connection pgConnection = DriverManager.getConnection(jdbcUrl,
+            System.getProperty(TestEnvironment.POSTGRESQL_USER_PROPERTY),
+            System.getProperty(TestEnvironment.POSTGRESQL_PASSWORD_PROPERTY));
+         final Statement createDbStatement = pgConnection.createStatement()) {
+      pgConnection.setAutoCommit(true);
+      // create meta database seshat
+      createDbStatement.execute("CREATE DATABASE " + System.getProperty(TestEnvironment.POSTGRESQL_DATABASE_NAME_PROPERTY));
+      createDbStatement.execute("CREATE DATABASE playground");
+    } catch (final SQLException ex) {
+      ex.printStackTrace();
+    }
+
+    final String tenantJdbcUrl = JdbcUrlBuilder
+            .create(JdbcUrlBuilder.DatabaseType.POSTGRESQL)
+            .host(System.getProperty(TestEnvironment.POSTGRESQL_HOST_PROPERTY))
+            .port(System.getProperty(TestEnvironment.POSTGRESQL_PORT_PROPERTY))
+            .instanceName(System.getProperty(TestEnvironment.POSTGRESQL_DATABASE_NAME_PROPERTY))
+            .build();
+
+    try (
+            final Connection metaDbConnection = DriverManager.getConnection(tenantJdbcUrl,
+                    System.getProperty(TestEnvironment.POSTGRESQL_USER_PROPERTY),
+                    System.getProperty(TestEnvironment.POSTGRESQL_PASSWORD_PROPERTY));
+            final Statement metaStatement = metaDbConnection.createStatement()
+    ) {
+      metaDbConnection.setAutoCommit(true);
+      // create needed tenant management table
+      metaStatement.execute("CREATE TABLE IF NOT EXISTS tenants (" +
+              "  identifier    VARCHAR(32) NOT NULL," +
+              "  driver_class  VARCHAR(255) NOT NULL," +
+              "  database_name VARCHAR(32) NOT NULL," +
+              "  host          VARCHAR(32) NOT NULL," +
+              "  port          VARCHAR(5)  NOT NULL," +
+              "  a_user        VARCHAR(32) NOT NULL," +
+              "  pwd           VARCHAR(32) NOT NULL," +
+              "  PRIMARY KEY (identifier)" +
+              ")");
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+  }
+
+  public static void createDatabaseTenant(final String identifier) {
+    try {
+      Class.forName(System.getProperty(TestEnvironment.POSTGRESQL_DRIVER_CLASS_PROPERTY));
+    } catch (ClassNotFoundException ex) {
+      throw new IllegalArgumentException(ex.getMessage(), ex);
+    }
+    final String jdbcUrl = JdbcUrlBuilder
+        .create(JdbcUrlBuilder.DatabaseType.POSTGRESQL)
+        .host(System.getProperty(TestEnvironment.POSTGRESQL_HOST_PROPERTY))
+        .port(System.getProperty(TestEnvironment.POSTGRESQL_PORT_PROPERTY))
+        .instanceName(TestEnvironment.POSTGRESQL_DATABASE_NAME_DEFAULT)
+        .build();
+    try (final Connection connection = DriverManager.getConnection(jdbcUrl,
+        System.getProperty(TestEnvironment.POSTGRESQL_USER_PROPERTY),
+        System.getProperty(TestEnvironment.POSTGRESQL_PASSWORD_PROPERTY))) {
+      try (final Statement statement = connection.createStatement()) {
+        connection.setAutoCommit(true);
+        // create tenant database
+        statement.execute("CREATE DATABASE " + identifier);
+        // insert tenant connection info in management table
+        try (final ResultSet resultSet = statement.executeQuery("SELECT * FROM tenants WHERE identifier = '" + identifier + "'")) {
+          if (resultSet.next()
+              && resultSet.getInt(1) == 0) {
+            final PostgreSQLTenant postgreSQLTenant = new PostgreSQLTenant();
+            postgreSQLTenant.setIdentifier(identifier);
+            postgreSQLTenant.setDriverClass(System.getProperty(TestEnvironment.POSTGRESQL_DRIVER_CLASS_PROPERTY));
+            postgreSQLTenant.setDatabaseName(identifier);
+            postgreSQLTenant.setHost(System.getProperty(TestEnvironment.POSTGRESQL_HOST_PROPERTY));
+            postgreSQLTenant.setPort(System.getProperty(TestEnvironment.POSTGRESQL_PORT_PROPERTY));
+            postgreSQLTenant.setUser(System.getProperty(TestEnvironment.POSTGRESQL_USER_PROPERTY));
+            postgreSQLTenant.setPassword(System.getProperty(TestEnvironment.POSTGRESQL_PASSWORD_PROPERTY));
+            postgreSQLTenant.insert(connection);
+          }
+        }
+      }
+    } catch (final SQLException ex) {
+      ex.printStackTrace();
+    }
+  }
+}
diff --git a/src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBTenant.java b/src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLTenant.java
similarity index 87%
rename from src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBTenant.java
rename to src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLTenant.java
index 6cf8b16..779ea8a 100644
--- a/src/main/java/org/apache/fineract/cn/test/fixture/mariadb/MariaDBTenant.java
+++ b/src/main/java/org/apache/fineract/cn/test/fixture/postgresql/PostgreSQLTenant.java
@@ -16,16 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.test.fixture.mariadb;
-
-import org.apache.fineract.cn.test.env.TestEnvironment;
+package org.apache.fineract.cn.test.fixture.postgresql;
 
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 
 @SuppressWarnings({"SqlNoDataSourceInspection", "SqlDialectInspection", "WeakerAccess"})
-class MariaDBTenant {
+class PostgreSQLTenant {
 
   private static final int INDEX_IDENTIFIER = 1;
   private static final int INDEX_DRIVER_CLASS = 2;
@@ -35,9 +33,7 @@
   private static final int INDEX_USER = 6;
   private static final int INDEX_PASSWORD = 7;
 
-  private static final String TABLE_NAME = System.getProperty(TestEnvironment.MARIADB_DATABASE_NAME_PROPERTY) + ".tenants";
-  private static final String INSERT_STMT = " INSERT INTO " +
-      MariaDBTenant.TABLE_NAME +
+  private static final String INSERT_STMT = " INSERT INTO " + "tenants" +
       " (identifier, driver_class, database_name, host, port, a_user, pwd) " +
       " values " +
       " (?, ?, ?, ?, ?, ?, ?) ";
@@ -50,12 +46,12 @@
   private String user;
   private String password;
 
-  MariaDBTenant() {
+  PostgreSQLTenant() {
     super();
   }
 
   void insert(final Connection connection) throws SQLException {
-    try (final PreparedStatement insertTenantStatement = connection.prepareStatement(MariaDBTenant.INSERT_STMT)) {
+    try (final PreparedStatement insertTenantStatement = connection.prepareStatement(PostgreSQLTenant.INSERT_STMT)) {
       insertTenantStatement.setString(INDEX_IDENTIFIER, this.getIdentifier());
       insertTenantStatement.setString(INDEX_DRIVER_CLASS, this.getDriverClass());
       insertTenantStatement.setString(INDEX_DATABASE_NAME, this.getDatabaseName());
diff --git a/src/test/java/org/apache/fineract/cn/test/env/TestEnvironmentTest.java b/src/test/java/org/apache/fineract/cn/test/env/TestEnvironmentTest.java
index 78740dd..4448613 100644
--- a/src/test/java/org/apache/fineract/cn/test/env/TestEnvironmentTest.java
+++ b/src/test/java/org/apache/fineract/cn/test/env/TestEnvironmentTest.java
@@ -42,8 +42,8 @@
   @Test
   public void shouldGenerateUniqueId() {
     final TestEnvironment testEnvironment = new TestEnvironment("fineract-cn-core");
-    final String uniqueId = testEnvironment.generateUniqueIdentifer(UNIQUE_ID_PREFIX);
-    final String uniqueId2 = testEnvironment.generateUniqueIdentifer(UNIQUE_ID_PREFIX);
+    final String uniqueId = testEnvironment.generateUniqueIdentifier(UNIQUE_ID_PREFIX);
+    final String uniqueId2 = testEnvironment.generateUniqueIdentifier(UNIQUE_ID_PREFIX);
     Assert.assertNotEquals(uniqueId, uniqueId2);
     Assert.assertTrue(uniqueId.startsWith(UNIQUE_ID_PREFIX));
     Assert.assertTrue(uniqueId2.startsWith(UNIQUE_ID_PREFIX));
@@ -52,7 +52,7 @@
   @Test
   public void shouldGenerateZeroBufferedUniqueId() {
     final TestEnvironment testEnvironment = new TestEnvironment("fineract-cn-core");
-    final String uniqueId = testEnvironment.generateUniqueIdentifer(UNIQUE_ID_PREFIX, 5);
+    final String uniqueId = testEnvironment.generateUniqueIdentifier(UNIQUE_ID_PREFIX, 5);
     Assert.assertTrue(uniqueId.startsWith(UNIQUE_ID_PREFIX));
     Assert.assertEquals(uniqueId.length() - UNIQUE_ID_PREFIX.length(), 5);
   }
diff --git a/travis.sh b/travis.sh
new file mode 100755
index 0000000..03a75ee
--- /dev/null
+++ b/travis.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# Documentation: https://cwiki.apache.org/confluence/display/FINERACT/Fineract-CN+Artifactory
+
+#Exit immediately if a command exits with a non-zero status.
+set -e
+EXIT_STATUS=0
+
+# Builds and Publishes a SNAPSHOT
+function build_snapshot() {
+  echo -e "Building and publishing a snapshot out of branch [$TRAVIS_BRANCH]"
+  ./gradlew -PartifactoryRepoKey=libs-snapshot-local -DbuildInfo.build.number=${TRAVIS_COMMIT::7} artifactoryPublish --stacktrace || EXIT_STATUS=$?
+}
+
+# Builds a Pull Request
+function build_pullrequest() {
+  echo -e "Building pull request #$TRAVIS_PULL_REQUEST of branch [$TRAVIS_BRANCH]. Won't publish anything to Artifactory."
+  ./gradlew publishToMavenLocal rat || EXIT_STATUS=$?
+}
+
+# For other branches we need to add branch name as prefix
+function build_otherbranch() {
+  echo -e "Building a snapshot out of branch [$TRAVIS_BRANCH] and publishing it with prefix '${TRAVIS_BRANCH}-SNAPSHOT'"
+  ./gradlew -PartifactoryRepoKey=libs-snapshot-local -DbuildInfo.build.number=${TRAVIS_COMMIT::7} -PexternalVersion=${TRAVIS_BRANCH}-SNAPSHOT artifactoryPublish --stacktrace || EXIT_STATUS=$?
+}
+
+# Builds and Publishes a Tag
+function build_tag() {
+  echo -e "Building tag [$TRAVIS_TAG] and publishing it as a release"
+  ./gradlew -PartifactoryRepoKey=libs-release-local -PexternalVersion=$TRAVIS_TAG artifactoryPublish --stacktrace || EXIT_STATUS=$?
+
+}
+
+echo -e "TRAVIS_BRANCH=$TRAVIS_BRANCH"
+echo -e "TRAVIS_TAG=$TRAVIS_TAG"
+echo -e "TRAVIS_COMMIT=${TRAVIS_COMMIT::7}"
+echo -e "TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST"
+
+# Build Logic
+if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
+  build_pullrequest
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" != "$BUILD_SNAPSHOTS_BRANCH" ] && [ "$TRAVIS_TAG" == "" ]  ; then
+  build_otherbranch
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "$BUILD_SNAPSHOTS_BRANCH" ] && [ "$TRAVIS_TAG" == "" ] ; then
+  build_snapshot
+elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
+  build_tag
+else
+  echo -e "WARN: Unexpected env variable values => Branch [$TRAVIS_BRANCH], Tag [$TRAVIS_TAG], Pull Request [#$TRAVIS_PULL_REQUEST]"
+  ./gradlew clean build
+fi
+
+exit ${EXIT_STATUS}