Merge pull request #6 from Izakey/FINCN-129

Migrate provisioner from MariaDB to PostgreSQL
diff --git a/NOTICE.txt b/NOTICE.txt
index 822eedb..d3ebf54 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Apache Fineract CN Provisioner
-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/component-test/build.gradle b/component-test/build.gradle
index 52c1aa3..8ccc60e 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -51,7 +51,8 @@
             [group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
             [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
             [group: 'org.springframework.restdocs', name: 'spring-restdocs-mockmvc'],
-            [group: 'junit', name: 'junit', version: '4.12']
+            [group: 'junit', name: 'junit', version: '4.12'],
+            [group: 'com.opentable.components', name: 'otj-pg-embedded', version: '0.7.1']
     )
 }
 
diff --git a/component-test/src/main/java/org/apache/fineract/cn/provisioner/AbstractServiceTest.java b/component-test/src/main/java/org/apache/fineract/cn/provisioner/AbstractServiceTest.java
index ad4651d..4e1ce2a 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/provisioner/AbstractServiceTest.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/provisioner/AbstractServiceTest.java
@@ -59,15 +59,14 @@
     }
   }
 
-
   private static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private static ProvisionerMariaDBInitializer mariaDBInitializer = new ProvisionerMariaDBInitializer();
+  private static ProvisionerPostgreSQLInitializer postgreSQLInitializer = new ProvisionerPostgreSQLInitializer();
   private static ProvisionerCassandraInitializer cassandraInitializer = new ProvisionerCassandraInitializer();
 
   @ClassRule
   public static TestRule orderClassRules = RuleChain
           .outerRule(testEnvironment)
-          .around(mariaDBInitializer)
+          .around(postgreSQLInitializer)
           .around(cassandraInitializer);
 
   @SuppressWarnings("SpringAutowiredFieldsWarningInspection")
@@ -88,4 +87,4 @@
   protected String getClientId() {
     return CLIENT_ID;
   }
-}
+}
\ No newline at end of file
diff --git a/component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerMariaDBInitializer.java b/component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerPostgreSQLInitializer.java
similarity index 65%
rename from component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerMariaDBInitializer.java
rename to component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerPostgreSQLInitializer.java
index 32e1cb2..b25785c 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerMariaDBInitializer.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/provisioner/ProvisionerPostgreSQLInitializer.java
@@ -18,27 +18,32 @@
  */
 package org.apache.fineract.cn.provisioner;
 
-import ch.vorburger.exec.ManagedProcessException;
-import ch.vorburger.mariadb4j.DB;
+import com.opentable.db.postgres.embedded.EmbeddedPostgres;
 import org.junit.rules.ExternalResource;
 
+import java.io.IOException;
+
 /**
  * @author Myrle Krantz
  */
-public class ProvisionerMariaDBInitializer extends ExternalResource {
-  private static DB EMBEDDED_MARIA_DB;
+public class ProvisionerPostgreSQLInitializer extends ExternalResource {
+  private static EmbeddedPostgres EMBEDDED_POSTGRESQL_DB;
   @Override
-  protected void before() throws ManagedProcessException {
-    EMBEDDED_MARIA_DB = DB.newEmbeddedDB(3306);
-    EMBEDDED_MARIA_DB.start();
+  protected void before() throws IOException {
+    try {
+      EMBEDDED_POSTGRESQL_DB = EmbeddedPostgres.builder().setPort(5432).start();
+    }
+    catch (IOException ioex) {
+      System.out.println(ioex);
+    }
   }
 
   @Override
   protected void after() {
     try {
-      EMBEDDED_MARIA_DB.stop();
-    } catch (ManagedProcessException e) {
-      throw new RuntimeException(e);
+      EMBEDDED_POSTGRESQL_DB.close();
+    } catch (IOException io) {
+      System.out.println(io);
     }
   }
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/provisioner/tenant/TestTenantApplicationAssignment.java b/component-test/src/main/java/org/apache/fineract/cn/provisioner/tenant/TestTenantApplicationAssignment.java
index 0fb155c..02b4605 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/provisioner/tenant/TestTenantApplicationAssignment.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/provisioner/tenant/TestTenantApplicationAssignment.java
@@ -25,7 +25,7 @@
 
 import com.google.gson.Gson;
 import org.apache.fineract.cn.provisioner.ProvisionerCassandraInitializer;
-import org.apache.fineract.cn.provisioner.ProvisionerMariaDBInitializer;
+import org.apache.fineract.cn.provisioner.ProvisionerPostgreSQLInitializer;
 import org.apache.fineract.cn.provisioner.api.v1.client.Provisioner;
 import org.apache.fineract.cn.provisioner.api.v1.domain.Application;
 import org.apache.fineract.cn.provisioner.api.v1.domain.AssignedApplication;
@@ -124,7 +124,7 @@
 
 
   private static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
-  private static ProvisionerMariaDBInitializer mariaDBInitializer = new ProvisionerMariaDBInitializer();
+  private static ProvisionerPostgreSQLInitializer postgreSQLInitializer = new ProvisionerPostgreSQLInitializer();
   private static ProvisionerCassandraInitializer cassandraInitializer = new ProvisionerCassandraInitializer();
   private static SystemSecurityEnvironment systemSecurityEnvironment
           = new SystemSecurityEnvironment(testEnvironment.getSystemKeyTimestamp(), testEnvironment.getSystemPublicKey(), testEnvironment.getSystemPrivateKey());
@@ -132,7 +132,7 @@
   @ClassRule
   public static TestRule orderClassRules = RuleChain
           .outerRule(testEnvironment)
-          .around(mariaDBInitializer)
+          .around(postgreSQLInitializer)
           .around(cassandraInitializer);
 
   @SuppressWarnings("SpringAutowiredFieldsWarningInspection")
diff --git a/component-test/src/main/resources/application.yaml b/component-test/src/main/resources/application.yaml
index adc4ffa..9e3bd4f 100644
--- a/component-test/src/main/resources/application.yaml
+++ b/component-test/src/main/resources/application.yaml
@@ -26,4 +26,11 @@
 
 activemq:
   brokerUrl: vm://localhost?broker.persistent=false
-  concurrency: 3-10
\ No newline at end of file
+  concurrency: 3-10
+
+spring:
+  datasource:
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://localhost:5432/seshat
+    username: postgres
+    password: postgres
\ No newline at end of file
diff --git a/service/build.gradle b/service/build.gradle
index b0f7001..ffb7fa1 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -63,7 +63,6 @@
             [group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
             [group: 'org.apache.fineract.cn', name: 'async', version: versions.frameworkasync],
             [group: 'org.apache.fineract.cn', name: 'cassandra', version: versions.frameworkcassandra],
-            [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator],
             [group: 'org.apache.fineract.cn', name: 'crypto', version: versions.frameworkcrypto],
     )
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/config/ProvisionerServiceConfig.java b/service/src/main/java/org/apache/fineract/cn/provisioner/config/ProvisionerServiceConfig.java
index bdb3a69..1e94b6e 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/config/ProvisionerServiceConfig.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/config/ProvisionerServiceConfig.java
@@ -29,7 +29,7 @@
 import org.apache.fineract.cn.crypto.config.EnableCrypto;
 import org.apache.fineract.cn.lang.config.EnableApplicationName;
 import org.apache.fineract.cn.lang.config.EnableServiceException;
-import org.apache.fineract.cn.mariadb.config.EnableMariaDB;
+import org.apache.fineract.cn.postgresql.config.EnablePostgreSQL;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -55,7 +55,7 @@
 @EnableCrypto
 @EnableAsync
 @EnableAnubis(provideSignatureRestController = false)
-@EnableMariaDB
+@EnablePostgreSQL
 @EnableCassandra
 @EnableServiceException
 @EnableApplicationName
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/ProvisionerInitializer.java b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/ProvisionerInitializer.java
index ab4148f..8c86dcf 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/ProvisionerInitializer.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/ProvisionerInitializer.java
@@ -26,18 +26,20 @@
 import org.apache.fineract.cn.provisioner.internal.util.DataSourceUtils;
 import java.nio.ByteBuffer;
 import java.sql.Connection;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Date;
 import java.util.UUID;
 import javax.annotation.PostConstruct;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.fineract.cn.api.util.ApiConstants;
 import org.apache.fineract.cn.cassandra.core.CassandraSessionProvider;
 import org.apache.fineract.cn.cassandra.util.CassandraConnectorConstants;
 import org.apache.fineract.cn.crypto.HashGenerator;
 import org.apache.fineract.cn.crypto.SaltGenerator;
-import org.apache.fineract.cn.mariadb.util.MariaDBConstants;
+import org.apache.fineract.cn.postgresql.util.PostgreSQLConstants;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -58,7 +60,6 @@
   private final HashGenerator hashGenerator;
   private final String initialClientId;
   private String metaKeySpaceName;
-  private String mariaDBName;
 
   @Autowired
   public ProvisionerInitializer(final Environment environment, @Qualifier(ProvisionerConstants.LOGGER_NAME) final Logger logger,
@@ -80,12 +81,11 @@
       metaKeySpaceName = this.environment.getProperty(
           CassandraConnectorConstants.KEYSPACE_PROP,
           CassandraConnectorConstants.KEYSPACE_PROP_DEFAULT);
-      mariaDBName = this.environment.getProperty(
-          MariaDBConstants.MARIADB_DATABASE_NAME_PROP,
-          MariaDBConstants.MARIADB_DATABASE_NAME_DEFAULT);
 
       this.initializeCassandra();
-      this.initializeDatabase();
+      this.initializeDatabase(PostgreSQLConstants.POSTGRESQL_DATABASE_NAME_DEFAULT);
+      this.createTableTenants();
+      //this.initializeDatabase("playground");
     } catch (final Exception ex) {
       throw new IllegalStateException("Could not initialize service!", ex);
     }
@@ -198,28 +198,58 @@
     }
   }
 
-  private void initializeDatabase() throws Exception {
-    final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment);
-    try (final Statement statement = connection.createStatement()) {
-      // create meta data database
-      statement.execute("CREATE DATABASE IF NOT EXISTS " + mariaDBName);
-      statement.execute("USE " + mariaDBName);
-      // create tenants 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(512) 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 sqlex) {
-      throw new IllegalStateException(sqlex.getMessage(), sqlex);
-    } finally {
-      connection.close();
+  private void initializeDatabase(String postgresDbName) throws Exception {
+
+    this.logger.info("Creating meta database {} ", postgresDbName);
+    try (
+            final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment, "postgres");
+            final Statement testStatement = connection.createStatement();
+            final Statement statement = connection.createStatement()
+            ) {
+      final ResultSet validityQuery = testStatement.executeQuery("SELECT 1");
+      if (validityQuery.next()){
+        this.logger.info("Connection to database postgres established");
+        final ResultSet findDB = statement.executeQuery("SELECT datname FROM pg_database WHERE datname = '" + postgresDbName + "'");
+        if (!findDB.next()) {
+          this.logger.info("Database {} does not exists, creating the database {} now.", postgresDbName);
+          statement.execute("CREATE DATABASE " + postgresDbName);
+        } else {
+          this.logger.info("Database {} already exists.", postgresDbName);
+        }
+      } else {
+        this.logger.warn("Could not connect to database postgres");
+        throw new IllegalMonitorStateException("Could not connect to database postgres");
+      }
     }
   }
-}
+
+  private void createTableTenants() throws SQLException {
+    final String databaseName = PostgreSQLConstants.POSTGRESQL_DATABASE_NAME_DEFAULT;
+
+    this.logger.info("Create tenants table in database {} if it does not exists", databaseName);
+    try (
+            final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment, databaseName);
+            final Statement testStatement = provisionerConnection.createStatement();
+            final Statement findSeshatStatement = provisionerConnection.createStatement()
+    ) {
+      final ResultSet validityQuery = testStatement.executeQuery("SELECT 1");
+      if (validityQuery.next()) {
+        this.logger.info("Connection to database {} established", databaseName);
+        final ResultSet resultSet = findSeshatStatement.executeQuery("SELECT datname FROM pg_database where datname = '"+ databaseName +"'");
+        if (resultSet.next()) {
+          this.logger.info("Database {} exists !", databaseName);
+          this.logger.info("Creating table tenants now");
+          findSeshatStatement.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(512) NOT NULL, port VARCHAR(5) NOT NULL, a_user VARCHAR(32) NOT NULL, pwd VARCHAR(32) NOT NULL, PRIMARY KEY (identifier))");
+        } else {
+          this.logger.warn("Database {} does not exists !", databaseName);
+          }
+      } else {
+        this.logger.warn("Could not connect to database seshat");
+        throw new IllegalMonitorStateException("Could not connect to database seshat");
+      }
+    } catch (SQLException sqlex) {
+      this.logger.error(sqlex.getMessage(), sqlex);
+      throw new IllegalStateException("Could not create table tenants");
+    }
+  }
+}
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/TenantDAO.java b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/TenantDAO.java
index 491fb3e..69ec332 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/TenantDAO.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/repository/TenantDAO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.cn.provisioner.internal.repository;
 
+import org.apache.fineract.cn.postgresql.util.PostgreSQLConstants;
 import org.apache.fineract.cn.provisioner.api.v1.domain.DatabaseConnectionInfo;
 
 import java.sql.Connection;
@@ -83,28 +84,13 @@
   private static final int INDEX_PASSWORD = 7;
 
   private static final String TABLE_NAME = "tenants";
-  private static final String META_KEYSPACE = "seshat"; //TODO: read MariaDB name from the configuration.
-  private static final String FETCH_ALL_STMT = " SELECT * FROM " +
-      META_KEYSPACE +
-      "." +
-      TenantDAO.TABLE_NAME;
-  private static final String FIND_ONE_STMT = " SELECT * FROM " +
-      META_KEYSPACE +
-      "." +
-      TenantDAO.TABLE_NAME +
-      " WHERE identifier = ?";
-  private static final String INSERT_STMT = " INSERT INTO " +
-      META_KEYSPACE +
-      "." +
-      TenantDAO.TABLE_NAME +
+  private static final String FETCH_ALL_STMT = " SELECT * FROM " + TenantDAO.TABLE_NAME;
+  private static final String FIND_ONE_STMT = " SELECT * FROM " + TenantDAO.TABLE_NAME + " WHERE identifier = ?";
+  private static final String INSERT_STMT = " INSERT INTO " + TenantDAO.TABLE_NAME +
       " (identifier, driver_class, database_name, host, port, a_user, pwd) " +
       " values " +
       " (?, ?, ?, ?, ?, ?, ?) ";
-  private static final String DELETE_STMT = " DELETE FROM " +
-      META_KEYSPACE +
-      "." +
-      TenantDAO.TABLE_NAME +
-      " WHERE identifier = ? ";
+  private static final String DELETE_STMT = " DELETE FROM " + TenantDAO.TABLE_NAME + " WHERE identifier = ? ";
 
   private String identifier;
   private String driverClass;
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/service/TenantService.java b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/service/TenantService.java
index 52918de..bc495ff 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/service/TenantService.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/service/TenantService.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.cn.provisioner.internal.service;
 
+import org.apache.fineract.cn.postgresql.util.PostgreSQLConstants;
 import org.apache.fineract.cn.provisioner.api.v1.domain.CassandraConnectionInfo;
 import org.apache.fineract.cn.provisioner.api.v1.domain.DatabaseConnectionInfo;
 import org.apache.fineract.cn.provisioner.api.v1.domain.Tenant;
@@ -30,6 +31,7 @@
 import org.apache.fineract.cn.provisioner.internal.util.DataSourceUtils;
 import org.apache.fineract.cn.provisioner.internal.util.DataStoreOption;
 import java.sql.Connection;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
@@ -49,7 +51,7 @@
 @SuppressWarnings({"SqlNoDataSourceInspection", "SqlDialectInspection"})
 @Component
 public class TenantService {
-  private static final String META_KEYSPACE = "seshat"; //TODO: read MariaDB name from the configuration.
+  private static final String META_KEYSPACE = PostgreSQLConstants.POSTGRESQL_DATABASE_NAME_DEFAULT;
 
   private final Logger logger;
   private final Environment environment;
@@ -165,7 +167,7 @@
     final DataStoreOption dataStoreOption = provisionerProperties.getDataStoreOption();
     if (dataStoreOption.isEnabled(DataStoreOption.RDBMS)) {
       if (tenants.size() > 0) {
-        try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment)) {
+        try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment, META_KEYSPACE)) {
           for (final Tenant tenant : tenants) {
             final Optional<TenantDAO> optionalTenantDAO = TenantDAO.find(connection, tenant.getIdentifier());
             optionalTenantDAO.ifPresent(tenantDAO -> tenant.setDatabaseConnectionInfo(tenantDAO.map()));
@@ -175,7 +177,7 @@
           throw new IllegalStateException("Could not load org.apache.fineract.cn.provisioner.tenant data!");
         }
       } else {
-        try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment)) {
+        try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment, META_KEYSPACE)) {
           final List<TenantDAO> tenantDAOs = TenantDAO.fetchAll(connection);
           for (final TenantDAO tenantDAO : tenantDAOs) {
             final Tenant tenant = new Tenant();
@@ -210,7 +212,7 @@
   private Tenant findInDatabase(final @Nonnull Tenant tenant, final @Nonnull String identifier) {
     final DataStoreOption dataStoreOption = provisionerProperties.getDataStoreOption();
     if (dataStoreOption.isEnabled(DataStoreOption.RDBMS)) {
-      try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment)) {
+      try (final Connection connection = DataSourceUtils.createProvisionerConnection(this.environment, META_KEYSPACE)) {
         final Optional<TenantDAO> optionalTenantDAO = TenantDAO.find(connection, identifier);
         if (optionalTenantDAO.isPresent()) {
           tenant.setDatabaseConnectionInfo(optionalTenantDAO.get().map());
@@ -229,45 +231,36 @@
     if (dataStoreOption.isEnabled(DataStoreOption.RDBMS)) {
 
       try (
-              final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment);
+              final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment, META_KEYSPACE);
               final Statement statement = provisionerConnection.createStatement()
       ) {
-        final java.sql.ResultSet resultSet = statement.executeQuery(
-            " SELECT * FROM " + META_KEYSPACE + ".tenants WHERE identifier = '" + tenant.getIdentifier() + "' ");
+        final ResultSet resultSet = statement.executeQuery(
+            " SELECT * FROM tenants WHERE identifier = '" + tenant.getIdentifier() + "' ");
         if (resultSet.next()) {
+          this.logger.warn("Tenant {} already exists !", tenant.getIdentifier());
           throw ServiceException.conflict("Tenant {0} already exists!", tenant.getIdentifier());
         }
+        else {
+          final DatabaseConnectionInfo databaseConnectionInfo = tenant.getDatabaseConnectionInfo();
+          this.logger.info("Create database for tenant {}", tenant.getIdentifier());
+          statement.execute("CREATE DATABASE " + databaseConnectionInfo.getDatabaseName().toLowerCase());
+
+          final TenantDAO tenantDAO = new TenantDAO();
+          tenantDAO.setIdentifier(tenant.getIdentifier());
+          tenantDAO.setDriverClass(databaseConnectionInfo.getDriverClass());
+          tenantDAO.setDatabaseName(databaseConnectionInfo.getDatabaseName());
+          tenantDAO.setHost(databaseConnectionInfo.getHost());
+          tenantDAO.setPort(databaseConnectionInfo.getPort());
+          tenantDAO.setUser(databaseConnectionInfo.getUser());
+          tenantDAO.setPassword(databaseConnectionInfo.getPassword());
+          tenantDAO.insert(provisionerConnection);
+        }
       } catch (SQLException sqlex) {
         this.logger.error(sqlex.getMessage(), sqlex);
-        throw new IllegalStateException("Could not insert org.apache.fineract.cn.provisioner.tenant info!", sqlex);
+        throw new IllegalStateException("Could not provision database for tenant {}" + tenant.getIdentifier(), sqlex);
       }
-      final DatabaseConnectionInfo databaseConnectionInfo = tenant.getDatabaseConnectionInfo();
-      try (
-          final Connection connection = DataSourceUtils.create(databaseConnectionInfo);
-          final Statement statement = connection.createStatement()
-      ) {
-        statement.execute("CREATE DATABASE IF NOT EXISTS " + databaseConnectionInfo.getDatabaseName());
-        statement.close();
-      } catch (final SQLException sqlex) {
-        this.logger.error(sqlex.getMessage(), sqlex);
-        throw new IllegalStateException("Could not create database!", sqlex);
-      }
-
-      try (final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment)) {
-        final TenantDAO tenantDAO = new TenantDAO();
-        tenantDAO.setIdentifier(tenant.getIdentifier());
-        tenantDAO.setDriverClass(databaseConnectionInfo.getDriverClass());
-        tenantDAO.setDatabaseName(databaseConnectionInfo.getDatabaseName());
-        tenantDAO.setHost(databaseConnectionInfo.getHost());
-        tenantDAO.setPort(databaseConnectionInfo.getPort());
-        tenantDAO.setUser(databaseConnectionInfo.getUser());
-        tenantDAO.setPassword(databaseConnectionInfo.getPassword());
-        tenantDAO.insert(provisionerConnection);
-        provisionerConnection.commit();
-      } catch (SQLException sqlex) {
-        this.logger.error(sqlex.getMessage(), sqlex);
-        throw new IllegalStateException("Could not insert org.apache.fineract.cn.provisioner.tenant info!", sqlex);
-      }
+    } else {
+      this.logger.warn("Datastore option not chosen, Tenant in PostgreSQL RDBMS not created");
     }
   }
 
@@ -286,8 +279,7 @@
   private void deleteDatabase(final String identifier) {
     final DataStoreOption dataStoreOption = provisionerProperties.getDataStoreOption();
     if (dataStoreOption.isEnabled(DataStoreOption.RDBMS)) {
-
-      try (final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment)) {
+      try (final Connection provisionerConnection = DataSourceUtils.createProvisionerConnection(this.environment, META_KEYSPACE)) {
         final Optional<TenantDAO> optionalTenantDAO = TenantDAO.find(provisionerConnection, identifier);
         if (optionalTenantDAO.isPresent()) {
           final DatabaseConnectionInfo databaseConnectionInfo = optionalTenantDAO.get().map();
@@ -296,15 +288,15 @@
               final Statement dropStatement = connection.createStatement()
           ) {
             dropStatement.execute("DROP DATABASE " + databaseConnectionInfo.getDatabaseName());
-            connection.commit();
           }
           TenantDAO.delete(provisionerConnection, identifier);
-          provisionerConnection.commit();
         }
       } catch (final SQLException sqlex) {
         this.logger.error(sqlex.getMessage(), sqlex);
-        throw new IllegalStateException("Could not delete database!");
+        throw new IllegalStateException("Could not delete database {}!" + identifier);
       }
+    } else {
+      this.logger.warn("Datastore option not chosen, Tenant in PostgreSQL RDBMS not created");
     }
   }
 
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/DataSourceUtils.java b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/DataSourceUtils.java
index 4433d38..f8c89a6 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/DataSourceUtils.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/DataSourceUtils.java
@@ -18,7 +18,9 @@
  */
 package org.apache.fineract.cn.provisioner.internal.util;
 
+import org.apache.fineract.cn.postgresql.util.PostgreSQLConstants;
 import org.springframework.core.env.Environment;
+import org.apache.fineract.cn.postgresql.util.JdbcUrlBuilder;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -38,33 +40,44 @@
     } catch (ClassNotFoundException cnfex) {
       throw new IllegalArgumentException(cnfex.getMessage(), cnfex);
     }
+
     final String jdbcUrl = JdbcUrlBuilder
-        .create(JdbcUrlBuilder.DatabaseType.MARIADB)
+        .create(JdbcUrlBuilder.DatabaseType.POSTGRESQL)
         .host(databaseConnectionInfo.getHost())
         .port(databaseConnectionInfo.getPort())
+        .instanceName(databaseConnectionInfo.getDatabaseName())
         .build();
     try {
+      try {
+        Class.forName("org.postgresql.Driver");
+      } catch (ClassNotFoundException e) {
+        e.printStackTrace();
+      }
       final Connection connection = DriverManager.getConnection(jdbcUrl, databaseConnectionInfo.getUser(), databaseConnectionInfo.getPassword());
-      connection.setAutoCommit(false);
+      connection.setAutoCommit(true);
       return connection;
     } catch (SQLException sqlex) {
       throw new IllegalStateException(sqlex.getMessage(), sqlex);
     }
   }
 
-  public static Connection createProvisionerConnection(final Environment environment) {
+  public static Connection createProvisionerConnection(final Environment environment, String databaseName) {
     final DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo();
-    databaseConnectionInfo.setDriverClass(environment.getProperty("mariadb.driverClass"));
-    databaseConnectionInfo.setHost(environment.getProperty("mariadb.host"));
-    databaseConnectionInfo.setPort(environment.getProperty("mariadb.port"));
-    databaseConnectionInfo.setUser(environment.getProperty("mariadb.user"));
-    databaseConnectionInfo.setPassword(environment.getProperty("mariadb.password"));
-    final Connection connection = DataSourceUtils.create(databaseConnectionInfo);
+    databaseConnectionInfo.setDriverClass(environment.getProperty("postgresql.driverClass"));
+    databaseName = databaseName.equals(PostgreSQLConstants.POSTGRESQL_DATABASE_NAME_DEFAULT) ? PostgreSQLConstants.POSTGRESQL_DATABASE_NAME_DEFAULT :
+            (databaseName.equals("playground") ? "playground" : "postgres");
+    databaseConnectionInfo.setDatabaseName(databaseName);
+    databaseConnectionInfo.setHost(environment.getProperty("postgresql.host"));
+    databaseConnectionInfo.setPort(environment.getProperty("postgresql.port"));
+    databaseConnectionInfo.setUser(environment.getProperty("postgresql.user"));
+    databaseConnectionInfo.setPassword(environment.getProperty("postgresql.password"));
+
     try {
-      connection.setAutoCommit(false);
-    } catch (SQLException e) {
-      // do nothing
+      final Connection connection = DataSourceUtils.create(databaseConnectionInfo);
+      connection.setAutoCommit(true);
+      return connection;
+    } catch (SQLException error) {
+      throw new IllegalStateException(error.getMessage(), error);
     }
-    return connection;
   }
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/JdbcUrlBuilder.java b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/JdbcUrlBuilder.java
index 6f4d689..f09434a 100644
--- a/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/JdbcUrlBuilder.java
+++ b/service/src/main/java/org/apache/fineract/cn/provisioner/internal/util/JdbcUrlBuilder.java
@@ -21,7 +21,7 @@
 final class JdbcUrlBuilder {
 
   enum DatabaseType {
-    MARIADB("jdbc:mariadb://");
+    POSTGRESQL("jdbc:postgresql:");
 
     private final String prefix;
 
@@ -65,7 +65,7 @@
 
   String build() {
     switch (this.type) {
-      case MARIADB:
+      case POSTGRESQL:
         return this.type.prefix()
             + this.host + ":"
             + this.port
diff --git a/service/src/main/resources/application.yaml b/service/src/main/resources/application.yaml
index 139e3b1..d584204 100644
--- a/service/src/main/resources/application.yaml
+++ b/service/src/main/resources/application.yaml
@@ -37,10 +37,17 @@
       type: Network
       replicas: datacenter1:3
 
-mariadb:
-  driverClass: org.mariadb.jdbc.Driver
+postgresql:
+  driverClass: org.postgresql.Driver
   database: seshat
   host: localhost
-  port: 3306
-  user: root
-  password: mysql
\ No newline at end of file
+  port: 5432
+  user: postgres
+  password: postgres
+
+spring:
+  datasource:
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://localhost:5432/seshat
+    username: postgres
+    password: postgres
\ No newline at end of file
diff --git a/shared.gradle b/shared.gradle
index 485b568..5ded62e 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -66,7 +66,9 @@
 
 dependencies {
     compile(
-            [group: 'com.google.code.findbugs', name: 'jsr305']
+            [group: 'com.google.code.findbugs', name: 'jsr305'],
+            [group: 'org.apache.fineract.cn', name: 'postgresql', version: '0.1.0-BUILD-SNAPSHOT'],
+            [group: 'postgresql', name: 'postgresql', version: '9.0-801.jdbc4']
     )
 
     testCompile(