You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ik...@apache.org on 2019/09/04 07:58:19 UTC

[fineract-cn-notifications] branch develop updated: Migrating MariaDB to PostgreSQL

This is an automated email from the ASF dual-hosted git repository.

ikamga pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-notifications.git


The following commit(s) were added to refs/heads/develop by this push:
     new fb20e5d  Migrating MariaDB to PostgreSQL
     new 7677e86  Merge pull request #17 from ebenezergraham/FINCN-127
fb20e5d is described below

commit fb20e5d066565cb29bff644113f59d4e46449c38
Author: Ebenezer Graham <eb...@gmail.com>
AuthorDate: Wed Sep 4 02:44:34 2019 +0400

    Migrating MariaDB to PostgreSQL
---
 .../cn/notification/AbstractNotificationTest.java  |   4 +-
 .../cn/notification/SuiteTestEnvironment.java      |   8 +-
 .../fineract/cn/notification/TestSMSService.java   |   2 +-
 .../apache/fineract/cn/notification/TestSuite.java |   4 +-
 .../{TestTemplateImport.java => TestImport.java}   |  27 +++-
 .../resources/importdata/test-email-config.csv     |   2 +
 .../main/resources/importdata/test-sms-config.csv  |   2 +
 service/build.gradle                               |   2 +-
 .../command/handler/MigrationCommandHandler.java   |   2 +-
 .../internal/config/NotificationConfiguration.java |   4 +-
 .../service/internal/importer/Importer.java        | 177 +++++++++++++++++++++
 .../internal/importer/TemplateImporter.java        |  92 -----------
 .../internal/service/NotificationService.java      |   5 +
 .../service/internal/service/SMSService.java       |  12 +-
 .../NotificationAuthentication.java                |  59 +++++++
 .../service/listener/CustomerEventListener.java    |  51 ++----
 service/src/main/resources/application.yml         |  16 +-
 .../db/migrations/mariadb/V1__initial_setup.sql    |  76 ---------
 .../db/migrations/postgresql/V1__initial_setup.sql |  58 +++++++
 shared.gradle                                      |   5 +-
 20 files changed, 370 insertions(+), 238 deletions(-)

diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java b/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java
index 4f0dbc1..01ed4b4 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java
@@ -50,11 +50,11 @@ import java.security.interfaces.RSAPrivateKey;
 public class AbstractNotificationTest extends SuiteTestEnvironment {
 	
 	@ClassRule
-	public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+	public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, postgreSQLInitializer);
 	public static final String LOGGER_NAME = "test-logger";
 	public static final String TEST_USER = "homer";
 	public static final String TEST_ADDRESS = "egraham15@alustudent.com"; // Replace with developer's dummy testing email
-	public static final String TEST_TEMPLATE= "sample";
+	public static final String TEST_TEMPLATE= "test_sample";
 	public static final String SMS_TEST_NUMBER= "+23058409206"; // Replace with developers dummy testing number
 	
 	@SuppressWarnings("WeakerAccess")
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java b/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
index 46ca216..cd1eee4 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
@@ -21,7 +21,7 @@ package org.apache.fineract.cn.notification;
 import org.apache.fineract.cn.test.env.TestEnvironment;
 import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
 import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
-import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.fixture.postgresql.PostgreSQLInitializer;
 import org.junit.ClassRule;
 import org.junit.rules.RuleChain;
 import org.junit.rules.RunExternalResourceOnce;
@@ -39,12 +39,12 @@ public class SuiteTestEnvironment {
 	
 	static final TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
 	static final CassandraInitializer cassandraInitializer = new CassandraInitializer();
-	static final MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
-	final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+	static final PostgreSQLInitializer postgreSQLInitializer = new PostgreSQLInitializer();
+	final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, postgreSQLInitializer);
 	
 	@ClassRule
 	public static TestRule orderClassRules = RuleChain
 			.outerRule(new RunExternalResourceOnce(testEnvironment))
 			.around(new RunExternalResourceOnce(cassandraInitializer))
-			.around(new RunExternalResourceOnce(mariaDBInitializer));
+			.around(new RunExternalResourceOnce(postgreSQLInitializer));
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSMSService.java b/component-test/src/main/java/org/apache/fineract/cn/notification/TestSMSService.java
index 5bf34fb..387e790 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSMSService.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/TestSMSService.java
@@ -85,7 +85,7 @@ public class TestSMSService extends AbstractNotificationTest {
 	public void shouldSendAnSMS(){
 		this.logger.info("Send SMS Notification");
 		int to = this.notificationService.sendSMS(SMS_TEST_NUMBER,
-				"Dear Valued Customer\n\nTalk is cheap show me the code\n\nBest Regards\nYour MFI");
+				TEST_TEMPLATE);
 		Assert.assertNotNull(to);
 	}
 	
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java b/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
index 2efc41c..008d7fb 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
@@ -18,14 +18,14 @@
  */
 package org.apache.fineract.cn.notification;
 
-import org.apache.fineract.cn.notification.importer.TestTemplateImport;
+import org.apache.fineract.cn.notification.importer.TestImport;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
 @SuiteClasses({
-		TestTemplateImport.class,
+		TestImport.class,
 		TestEmailService.class,
 		TestSMSService.class,
 		EmailApiDocumentation.class,
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java b/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestImport.java
similarity index 65%
rename from component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java
rename to component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestImport.java
index 17d3bf7..9adf1e2 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestImport.java
@@ -21,7 +21,7 @@ package org.apache.fineract.cn.notification.importer;
 import org.apache.fineract.cn.notification.AbstractNotificationTest;
 import org.apache.fineract.cn.notification.api.v1.domain.Template;
 import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
-import org.apache.fineract.cn.notification.service.internal.importer.TemplateImporter;
+import org.apache.fineract.cn.notification.service.internal.importer.Importer;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -29,9 +29,9 @@ import java.io.IOException;
 import java.net.URL;
 
 
-public class TestTemplateImport extends AbstractNotificationTest {
+public class TestImport extends AbstractNotificationTest {
 	
-	public TestTemplateImport() {
+	public TestImport() {
 		super();
 	}
 	
@@ -47,9 +47,26 @@ public class TestTemplateImport extends AbstractNotificationTest {
 		notificationManager.createTemplate(template);
 		Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier()));
 		
-		final TemplateImporter importer = new TemplateImporter(notificationManager, logger);
+		final Importer importer = new Importer(notificationManager, logger);
 		final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv");
-		importer.importCSV(uri);
+		importer.importTemplateCSV(uri);
 		Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "test_sample"));
 	}
+
+	@Test
+	public void testSmsConfigImportHappyCase() throws IOException, InterruptedException {
+
+		final Importer importer = new Importer(notificationManager, logger);
+		final URL uri = ClassLoader.getSystemResource("importdata/test-sms-config.csv");
+		importer.importSmsConfigurationCSV(uri);
+		Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, "DEFAULT"));
+	}
+
+	@Test
+	public void testEmailConfigImportHappyCase() throws IOException, InterruptedException {
+		final Importer importer = new Importer(notificationManager, logger);
+		final URL uri = ClassLoader.getSystemResource("importdata/test-email-config.csv");
+		importer.importEmailConfigurationCSV(uri);
+		Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, "DEFAULT"));
+	}
 }
diff --git a/component-test/src/main/resources/importdata/test-email-config.csv b/component-test/src/main/resources/importdata/test-email-config.csv
new file mode 100644
index 0000000..9f88385
--- /dev/null
+++ b/component-test/src/main/resources/importdata/test-email-config.csv
@@ -0,0 +1,2 @@
+identifier,host,port,username,app_password,protocol,smtp_auth,start_tls,state
+DEFAULT,smtp.gmail.com,587,fineractcnnotificationdemo@gmail.com,pnuugpwmcibipdpw,smtp,true,true,ACTIVE
\ No newline at end of file
diff --git a/component-test/src/main/resources/importdata/test-sms-config.csv b/component-test/src/main/resources/importdata/test-sms-config.csv
new file mode 100644
index 0000000..72aeaae
--- /dev/null
+++ b/component-test/src/main/resources/importdata/test-sms-config.csv
@@ -0,0 +1,2 @@
+identifier,account_sid,auth_token,sender_number,state
+DEFAULT,ACdc00866577a42133e16d98456ad15592,0b2f78b1c083eb71599d014d1af5748e,+12055486680,ACTIVE
diff --git a/service/build.gradle b/service/build.gradle
index c34c60e..900ef20 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -64,7 +64,7 @@ dependencies {
             [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.apache.fineract.cn', name: 'postgresql', version: versions.frameworkpostgresql],
             [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
             [group: 'org.apache.fineract.cn.permitted-feign-client', name: 'library', version: versions.frameworkpermittedfeignclient],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator],
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
index 7825060..9facc6d 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
@@ -23,7 +23,7 @@ import org.apache.fineract.cn.command.annotation.CommandHandler;
 import org.apache.fineract.cn.command.annotation.CommandLogLevel;
 import org.apache.fineract.cn.command.annotation.EventEmitter;
 import org.apache.fineract.cn.lang.ApplicationName;
-import org.apache.fineract.cn.mariadb.domain.FlywayFactoryBean;
+import org.apache.fineract.cn.postgresql.domain.FlywayFactoryBean;
 import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
 import org.apache.fineract.cn.notification.service.internal.command.InitializeServiceCommand;
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
index c99b67c..40a89e4 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
@@ -30,7 +30,7 @@ import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
 import org.apache.fineract.cn.lang.ApplicationName;
 import org.apache.fineract.cn.lang.config.EnableServiceException;
 import org.apache.fineract.cn.lang.config.EnableTenantContext;
-import org.apache.fineract.cn.mariadb.config.EnableMariaDB;
+import org.apache.fineract.cn.postgresql.config.EnablePostgreSQL;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,7 +63,7 @@ import java.nio.charset.StandardCharsets;
 @EnableAsync
 @EnableTenantContext
 @EnableCassandra
-@EnableMariaDB
+@EnablePostgreSQL
 @EnableCommandProcessing
 @EnableAnubis
 @EnableServiceException
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/Importer.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/Importer.java
new file mode 100644
index 0000000..f2d37f4
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/Importer.java
@@ -0,0 +1,177 @@
+/*
+ * 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.notification.service.internal.importer;
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
+import org.apache.fineract.cn.notification.api.v1.client.TemplateAlreadyExistException;
+import org.apache.fineract.cn.notification.api.v1.domain.EmailConfiguration;
+import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
+import org.apache.fineract.cn.notification.api.v1.domain.Template;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+/**
+ * @author Ebenezer Graham
+ */
+@SuppressWarnings("unused")
+public class Importer {
+  private static final String TEMPLATE_IDENTIFIER_COLUMN = "template_identifier";
+  private static final String SENDER_EMAIL_COLUMN = "sender_email";
+  private static final String SUBJECT_COLUMN = "subject";
+  private static final String MESSAGE_COLUMN = "message";
+  private static final String URL_COLUMN = "url";
+
+  private static final String IDENTIFIER_COLUMN = "identifier";
+  private static final String ACCOUNT_SID_COLUMN = "account_sid";
+  private static final String AUTH_TOKEN_COLUMN = "auth_token";
+  private static final String SENDER_NUMBER_COLUMN = "sender_number";
+  private static final String STATE_COLUMN = "state";
+
+  private static final String HOST_EMAIL_COLUMN = "host";
+  private static final String PORT_COLUMN = "port";
+  private static final String USERNAME_COLUMN = "username";
+  private static final String APP_PASSWORD_COLUMN = "app_password";
+  private static final String PROTOCOL_COLUMN = "protocol";
+  private static final String SMTP_AUTH_COLUMN = "smtp_auth";
+  private static final String START_TLS_COLUMN = "start_tls";
+
+  private final NotificationManager notificationManager;
+  private final Logger logger;
+
+  public Importer(final NotificationManager notificationManager, final Logger logger) {
+    this.notificationManager = notificationManager;
+    this.logger = logger;
+  }
+
+  public void importTemplateCSV(final URL toImport) throws IOException {
+    final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
+    final List<Template>templatesList = StreamSupport.stream(parser.spliterator(), false)
+            .map(this::toTemplate)
+            .collect(Collectors.toList());
+    templatesList.forEach(this::createTemplate);
+  }
+
+  public void importSmsConfigurationCSV(final URL toImport) throws IOException {
+    final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
+    final List<SMSConfiguration>list = StreamSupport.stream(parser.spliterator(), false)
+        .map(this::toSmsConfiguration)
+        .collect(Collectors.toList());
+    list.forEach(this::createSmsConfiguration);
+  }
+
+  public void importEmailConfigurationCSV(final URL toImport) throws IOException {
+    final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
+    final List<EmailConfiguration>list = StreamSupport.stream(parser.spliterator(), false)
+        .map(this::toEmailConfiguration)
+        .collect(Collectors.toList());
+    list.forEach(this::createEmailConfiguration);
+  }
+
+  private void createTemplate(final Template toCreate) {
+    try {
+      notificationManager.createTemplate(toCreate);
+    }
+    catch (final TemplateAlreadyExistException ignored) {
+      logger.error("Creation of template {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getTemplateIdentifier(),toCreate.toString());
+    }
+  }
+
+  private void createSmsConfiguration(final SMSConfiguration toCreate) {
+    try {
+      notificationManager.createSMSConfiguration(toCreate);
+    }
+    catch (final Exception ignored) {
+      logger.error("Creation of sms configuration {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getIdentifier(),toCreate.toString());
+    }
+  }
+
+  private void createEmailConfiguration(final EmailConfiguration toCreate) {
+    try {
+      notificationManager.createEmailConfiguration(toCreate);
+    }
+    catch (final Exception ignored) {
+      logger.error("Creation of email configuration {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getIdentifier(),toCreate.toString());
+    }
+  }
+
+  private Template toTemplate(final CSVRecord csvRecord) {
+    try {
+      final String templateIdentifier = csvRecord.get(TEMPLATE_IDENTIFIER_COLUMN);
+      final String subject = csvRecord.get(SUBJECT_COLUMN);
+      final String senderEmail = csvRecord.get(SENDER_EMAIL_COLUMN);
+      final String url = csvRecord.get(URL_COLUMN);
+      String message;
+      try {
+        message = csvRecord.get(MESSAGE_COLUMN);
+      }
+      catch (final NullPointerException e) {
+        message = "Do not reply, This is a computer generate message.";
+      }
+      return new Template(templateIdentifier,senderEmail,subject,message,url);
+    }
+    catch (final IllegalArgumentException e) {
+      logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
+      throw e;
+    }
+  }
+
+  private EmailConfiguration toEmailConfiguration(final CSVRecord csvRecord) {
+    try {
+      final String identifier = csvRecord.get(IDENTIFIER_COLUMN);
+      final String host = csvRecord.get(HOST_EMAIL_COLUMN);
+      final String username = csvRecord.get(USERNAME_COLUMN);
+      final String port = csvRecord.get(PORT_COLUMN);
+      final String app_password = csvRecord.get(APP_PASSWORD_COLUMN);
+      final String protocol = csvRecord.get(PROTOCOL_COLUMN);
+      final String smtp_auth = csvRecord.get(SMTP_AUTH_COLUMN);
+      final String start_tls = csvRecord.get(START_TLS_COLUMN);
+      final String state = csvRecord.get(STATE_COLUMN);
+
+      return EmailConfiguration.create(identifier,host,port,protocol,username,app_password,smtp_auth,start_tls,state);
+    }
+    catch (final IllegalArgumentException e) {
+      logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
+      throw e;
+    }
+  }
+
+  private SMSConfiguration toSmsConfiguration(final CSVRecord csvRecord) {
+    try {
+      final String identifier = csvRecord.get(IDENTIFIER_COLUMN);
+      final String account_sid = csvRecord.get(ACCOUNT_SID_COLUMN);
+      final String auth_token = csvRecord.get(AUTH_TOKEN_COLUMN);
+      final String sender_number = csvRecord.get(SENDER_NUMBER_COLUMN);
+      final String state = csvRecord.get(STATE_COLUMN);
+      return SMSConfiguration.create(identifier,account_sid,auth_token,sender_number,state);
+    }
+    catch (final IllegalArgumentException e) {
+      logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
+      throw e;
+    }
+  }
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/TemplateImporter.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/TemplateImporter.java
deleted file mode 100644
index ee2782f..0000000
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/TemplateImporter.java
+++ /dev/null
@@ -1,92 +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.notification.service.internal.importer;
-
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
-import org.apache.fineract.cn.notification.api.v1.client.TemplateAlreadyExistException;
-import org.apache.fineract.cn.notification.api.v1.domain.Template;
-import org.slf4j.Logger;
-
-import java.io.IOException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-/**
- * @author Ebenezer Graham
- */
-@SuppressWarnings("unused")
-public class TemplateImporter {
-  private static final String TEMPLATE_IDENTIFIER_COLUMN = "template_identifier";
-  private static final String SENDER_EMAIL_COLUMN = "sender_email";
-  private static final String SUBJECT_COLUMN = "subject";
-  private static final String MESSAGE_COLUMN = "message";
-  private static final String URL_COLUMN = "url";
-
-  private final NotificationManager notificationManager;
-  private final Logger logger;
-
-  public TemplateImporter(final NotificationManager notificationManager, final Logger logger) {
-    this.notificationManager = notificationManager;
-    this.logger = logger;
-  }
-
-  public void importCSV(final URL toImport) throws IOException {
-    final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
-    final List<Template>templatesList = StreamSupport.stream(parser.spliterator(), false)
-            .map(this::toTemplate)
-            .collect(Collectors.toList());
-    templatesList.forEach(this::createTemplate);
-  }
-
-  private void createTemplate(final Template toCreate) {
-    try {
-      notificationManager.createTemplate(toCreate);
-    }
-    catch (final TemplateAlreadyExistException ignored) {
-      logger.error("Creation of template {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getTemplateIdentifier(),toCreate.toString());
-    }
-  }
-
-  private Template toTemplate(final CSVRecord csvRecord) {
-    try {
-      final String templateIdentifier = csvRecord.get(TEMPLATE_IDENTIFIER_COLUMN);
-      final String subject = csvRecord.get(SUBJECT_COLUMN);
-      final String senderEmail = csvRecord.get(SENDER_EMAIL_COLUMN);
-      final String url = csvRecord.get(URL_COLUMN);
-      String message;
-      try {
-        message = csvRecord.get(MESSAGE_COLUMN);
-      }
-      catch (final NullPointerException e) {
-        message = "Do not reply, This is a computer generate message.";
-      }
-      return new Template(templateIdentifier,senderEmail,subject,message,url);
-    }
-    catch (final IllegalArgumentException e) {
-      logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
-      throw e;
-    }
-  }
-}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/NotificationService.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/NotificationService.java
index 6ca39b1..3bab440 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/NotificationService.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/NotificationService.java
@@ -22,6 +22,7 @@ import org.apache.fineract.cn.customer.api.v1.domain.Customer;
 import org.apache.fineract.cn.notification.api.v1.domain.Template;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
 import org.apache.fineract.cn.notification.service.internal.service.externalServiceClients.CustomerService;
+import org.apache.fineract.cn.notification.service.internal.service.externalServiceClients.NotificationAuthentication;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -38,6 +39,7 @@ public class NotificationService {
 	private final TemplateService templateService;
 	
 	private final CustomerService customerService;
+	private final NotificationAuthentication notificationAuthentication;
 	private final Logger logger;
 	
 	@Autowired
@@ -46,6 +48,7 @@ public class NotificationService {
 	                           final SMSService smsService,
 	                           final EmailService emailService,
 	                           final TemplateService templateService,
+	                           final NotificationAuthentication notificationAuthentication,
 	                           @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger
 	) {
 		super();
@@ -53,10 +56,12 @@ public class NotificationService {
 		this.smsService = smsService;
 		this.emailService = emailService;
 		this.templateService = templateService;
+		this.notificationAuthentication = notificationAuthentication;
 		this.logger = logger;
 	}
 	
 	public Optional<Customer> findCustomer(final String customerIdentifier, String tenant) {
+		notificationAuthentication.authenticate(tenant);
 		return customerService.findCustomer(customerIdentifier);
 	}
 	
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/SMSService.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/SMSService.java
index 36bd2f2..1c013f8 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/SMSService.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/SMSService.java
@@ -20,6 +20,7 @@ package org.apache.fineract.cn.notification.service.internal.service;
 
 
 import com.twilio.Twilio;
+import com.twilio.exception.ApiException;
 import com.twilio.rest.api.v2010.account.Message;
 import com.twilio.rest.api.v2010.account.MessageCreator;
 import com.twilio.type.PhoneNumber;
@@ -111,9 +112,14 @@ public class SMSService {
 				new PhoneNumber(receiver),
 				new PhoneNumber(this.senderNumber),
 				template);
-		Message message = messageCreator.create();
-		
-		System.out.println("\n\n\nsent");
+		Message message = null;
+		try{
+			message = messageCreator.create();
+
+		}catch (ApiException apiException){
+			logger.error("Error: {}" ,apiException.getMoreInfo());
+		}
+
 		return message.hashCode();
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/NotificationAuthentication.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/NotificationAuthentication.java
new file mode 100644
index 0000000..456e0b4
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/NotificationAuthentication.java
@@ -0,0 +1,59 @@
+/*
+ * 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.notification.service.internal.service.externalServiceClients;
+
+import org.apache.fineract.cn.api.util.UserContextHolder;
+import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
+import org.apache.fineract.cn.identity.api.v1.domain.Authentication;
+import org.apache.fineract.cn.lang.TenantContextHolder;
+import org.apache.fineract.cn.notification.service.ServiceConstants;
+import org.apache.fineract.cn.notification.service.internal.config.NotificationProperties;
+import org.apache.fineract.cn.permittedfeignclient.service.ApplicationAccessTokenService;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+
+@Component
+public class NotificationAuthentication {
+  private Logger logger;
+  private NotificationProperties notificationProperties;
+  private IdentityManager identityManager;
+
+
+  @Autowired
+  public NotificationAuthentication(final NotificationProperties notificationPropertities,
+                                    final IdentityManager identityManager,
+                                    @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
+    this.logger = logger;
+    this.notificationProperties = notificationPropertities;
+    this.identityManager = identityManager;
+  }
+
+  public void authenticate(String tenant) {
+    TenantContextHolder.clear();
+    TenantContextHolder.setIdentifier(tenant);
+
+    final Authentication authentication =
+        this.identityManager.login(notificationProperties.getUser(), Base64Utils.encodeToString(notificationProperties.getPassword().getBytes()));
+    UserContextHolder.clear();
+    UserContextHolder.setAccessToken(notificationProperties.getUser(), authentication.getAccessToken());
+  }
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/listener/CustomerEventListener.java b/service/src/main/java/org/apache/fineract/cn/notification/service/listener/CustomerEventListener.java
index 2fcc300..533c03a 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/listener/CustomerEventListener.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/listener/CustomerEventListener.java
@@ -76,10 +76,7 @@
 				    String receiverNumber = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendSMS(receiverNumber, "Dear Valued Customer," +
-						    "\n\nYour account has been created" +
-						    "\n\nBest Regards," +
-						    "\nYour MFI");
+				    notificationService.sendSMS(receiverNumber, "customerCreatedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -107,10 +104,8 @@
 				    // TODO: Localize message
 				    // TODO: Pass message to template
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Updated" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"customerUpdatedEvent"
+								);
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -136,10 +131,7 @@
 			    if (contact.getType().equalsIgnoreCase(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Activated" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"customerActivatedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -165,10 +157,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Locked" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"customerLockedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -193,10 +182,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-						    "\n\nYour account has been Unlocked" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"customerUnlockedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -222,10 +208,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-						    "\n\nYour account has been Closed" +
-								    "\n\nBest Regards" +
-								    "\nYour MFI");
+								"customerClosedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -250,10 +233,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been reopened" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"customerReopenedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -279,11 +259,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour contact has been changed successfully" +
-								    "\nNew Contact: "+receiverNumber+
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"contactDetailsChangedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
@@ -310,14 +286,7 @@
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
 				    String receiverNumber = contact.getValue();
 				    notificationService.sendSMS(receiverNumber,
-						    "Dear Valued Customer," +
-								    "\n\nYour address has been changed successfully" +
-								    "\n\tStreet: "+ customer.getAddress().getStreet()+
-								    "\n\tCity: "+ customer.getAddress().getCity()+
-								    "\n\tState: "+ customer.getAddress().getRegion()+
-								    "\n\tCountry: "+ customer.getAddress().getCountry()+
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+								"addressChangedEvent");
 			    } else if (contact.getType().equals(ContactDetail.Type.EMAIL.toString())) {
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index a4182d8..2789b7f 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -23,7 +23,11 @@ spring:
       enabled: false
     config:
       enabled: false
-git
+  datasource:
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://localhost:5432/playground
+    username: postgres
+    password: postgres
 
 eureka:
   client:
@@ -43,13 +47,13 @@ cassandra:
     write: LOCAL_QUORUM
     delete: LOCAL_QUORUM
 
-mariadb:
-  driverClass: org.mariadb.jdbc.Driver
+postgresql:
+  driverClass: org.postgresql.Driver
   database: seshat
   host: localhost
-  port: 3306
-  user: root
-  password: mysql
+  port: 5432
+  user: postgres
+  password: postgres
 
 bonecp:
   idleMaxAgeInMinutes: 240
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
deleted file mode 100644
index 03469b4..0000000
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ /dev/null
@@ -1,76 +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.
---
-
--- -----------------------------------------------------
--- Table wada_sms_gateway_configurations
--- -----------------------------------------------------
-CREATE TABLE wada_sms_gateway_configurations (
-  id INT NOT NULL AUTO_INCREMENT,
-  identifier VARCHAR(45) NULL DEFAULT NULL,
-  account_sid VARCHAR(255) NOT NULL,
-  auth_token VARCHAR(255) NOT NULL,
-  sender_number VARCHAR(45) NOT NULL,
-  state VARCHAR(20) NULL DEFAULT NULL,
-  PRIMARY KEY (id));
-
--- -----------------------------------------------------
--- Table wada_email_gateway_configurations
--- -----------------------------------------------------
-CREATE TABLE wada_email_gateway_configurations (
-  id INT NOT NULL AUTO_INCREMENT,
-  identifier VARCHAR(45) NULL DEFAULT NULL,
-  host VARCHAR(45) NOT NULL,
-  port VARCHAR(45) NOT NULL,
-  username VARCHAR(45) NOT NULL,
-  app_password VARCHAR(255) NOT NULL,
-  protocol VARCHAR(45)NOT NULL,
-  smtp_auth VARCHAR (45)NOT NULL,
-  start_tls VARCHAR (45)NOT NULL,
-  state VARCHAR(10)NOT NULL,
-  PRIMARY KEY (id));
-
--- -----------------------------------------------------
--- Table wada_templates
--- -----------------------------------------------------
-CREATE TABLE wada_templates (
-  id INT NOT NULL AUTO_INCREMENT,
-  template_identifier VARCHAR(45) NULL DEFAULT NULL,
-  sender_email VARCHAR(255) NULL DEFAULT NULL,
-  subject VARCHAR(255) NULL DEFAULT NULL,
-  message VARCHAR(1024) NULL DEFAULT NULL,
-  url VARCHAR(255) NOT NULL,
-  PRIMARY KEY (id));
-
-
-INSERT INTO wada_sms_gateway_configurations VALUES ('1', 'DEFAULT', 'ACdc00866577a42133e16d98456ad15592', '0b2f78b1c083eb71599d014d1af5748e', '+12055486680', 'ACTIVE');
-INSERT INTO wada_email_gateway_configurations VALUES ('1', 'DEFAULT', 'smtp.gmail.com', '587','fineractcnnotificationdemo@gmail.com', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE');
-
-/*Insert default template for supported events*/
-INSERT INTO wada_templates VALUES ('1','customerCreatedEvent','DEFAULT','Account created','Your account has been created','template');
-INSERT INTO wada_templates VALUES ('2','customerUpdatedEvent','DEFAULT','Account updated','Your account has been Updated','template');
-INSERT INTO wada_templates VALUES ('3','customerActivatedEvent','DEFAULT','Account Activated','Your account has been Activated','template');
-INSERT INTO wada_templates VALUES ('4','customerLockedEvent','DEFAULT','Account Locked','Your account has been Locked','template');
-INSERT INTO wada_templates VALUES ('5','customerUnlockedEvent','DEFAULT','Account unlocked','Your account has been Unlocked','template');
-INSERT INTO wada_templates VALUES ('6','customerClosedEvent','DEFAULT','Account closed successfully','Your account has been Closed','template');
-INSERT INTO wada_templates VALUES ('7','customerReopenedEvent','DEFAULT','Account Reopened','Your account has been reopened','template');
-INSERT INTO wada_templates VALUES ('8','contactDetailsChangedEvent','DEFAULT','Contact details has been updated','Your contact has been changed successfully','template');
-INSERT INTO wada_templates VALUES ('9','addressChangedEvent','DEFAULT','Residence address has been changed','Your address has been changed successfully','template');
-
-INSERT INTO wada_templates VALUES ('10','sample','DEFAULT','Test Subject','Talk is cheap! Show me the code','template');
-
diff --git a/service/src/main/resources/db/migrations/postgresql/V1__initial_setup.sql b/service/src/main/resources/db/migrations/postgresql/V1__initial_setup.sql
new file mode 100644
index 0000000..ceea8cf
--- /dev/null
+++ b/service/src/main/resources/db/migrations/postgresql/V1__initial_setup.sql
@@ -0,0 +1,58 @@
+--
+-- 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.
+--
+
+-- -----------------------------------------------------
+-- Table wada_sms_gateway_configurations
+-- -----------------------------------------------------
+CREATE TABLE wada_sms_gateway_configurations (
+  id SMALLSERIAL PRIMARY KEY,
+  identifier VARCHAR(45) NULL DEFAULT NULL,
+  account_sid VARCHAR(255) NOT NULL,
+  auth_token VARCHAR(255) NOT NULL,
+  sender_number VARCHAR(45) NOT NULL,
+  state VARCHAR(20) NULL DEFAULT NULL
+  );
+
+-- -----------------------------------------------------
+-- Table wada_email_gateway_configurations
+-- -----------------------------------------------------
+CREATE TABLE wada_email_gateway_configurations (
+  id SMALLSERIAL PRIMARY KEY,
+  identifier VARCHAR(45) NULL DEFAULT NULL,
+  host VARCHAR(45) NOT NULL,
+  port VARCHAR(45) NOT NULL,
+  username VARCHAR(45) NOT NULL,
+  app_password VARCHAR(255) NOT NULL,
+  protocol VARCHAR(45)NOT NULL,
+  smtp_auth VARCHAR (45)NOT NULL,
+  start_tls VARCHAR (45)NOT NULL,
+  state VARCHAR(10)NOT NULL
+  );
+
+-- -----------------------------------------------------
+-- Table wada_templates
+-- -----------------------------------------------------
+CREATE TABLE wada_templates (
+  id SERIAL PRIMARY KEY,
+  template_identifier VARCHAR(45) NULL DEFAULT NULL,
+  sender_email VARCHAR(255) NULL DEFAULT NULL,
+  subject VARCHAR(255) NULL DEFAULT NULL,
+  message VARCHAR(1024) NULL DEFAULT NULL,
+  url VARCHAR(255) NOT NULL
+);
diff --git a/shared.gradle b/shared.gradle
index 3162af1..f909215 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -31,7 +31,7 @@ ext.versions = [
         frameworklang                   : '0.1.0-BUILD-SNAPSHOT',
         frameworkasync                  : '0.1.0-BUILD-SNAPSHOT',
         frameworkcassandra              : '0.1.0-BUILD-SNAPSHOT',
-        frameworkmariadb                : '0.1.0-BUILD-SNAPSHOT',
+        frameworkpostgresql             : '0.1.0-BUILD-SNAPSHOT',
         frameworkcommand                : '0.1.0-BUILD-SNAPSHOT',
         frameworktest                   : '0.1.0-BUILD-SNAPSHOT',
         frameworkanubis                 : '0.1.0-BUILD-SNAPSHOT',
@@ -75,7 +75,8 @@ ext['spring-data-releasetrain.version'] = 'Gosling-SR2A'
 
 dependencies {
     compile(
-            [group: 'com.google.code.findbugs', name: 'jsr305']
+            [group: 'com.google.code.findbugs', name: 'jsr305'],
+            [group: 'org.apache.fineract.cn', name: 'postgresql', version: versions.frameworkpostgresql]
     )
 
     testCompile(