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/02 00:04:14 UTC

[fineract-cn-notifications] 27/43: Message Templating

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

commit 13a1f550593b36b72714433d45e431781e83e7eb
Author: Ebenezer Graham <eg...@alustudent.com>
AuthorDate: Fri May 24 16:46:20 2019 +0400

    Message Templating
---
 .../client/ConfigurationAlreadyExistException.java |  14 +-
 .../api/v1/client/NotificationManager.java         |  11 +-
 .../v1/client/TemplateAlreadyExistException.java   |  14 +-
 .../api/v1/client/TemplateNotFoundException.java   |  14 +-
 .../cn/notification/api/v1/domain/Template.java    | 110 +++++
 .../api/v1/events/NotificationEventConstants.java  |   3 +
 component-test/build.gradle                        |   4 +-
 .../cn/notification/AbstractNotificationTest.java  |  11 +-
 .../fineract/cn/notification/TestEmailService.java |  88 ++--
 .../fineract/cn/notification/TestSMSService.java   |   4 +-
 .../apache/fineract/cn/notification/TestSuite.java |   5 +-
 .../notification/importer/TestTemplateImport.java  |  57 +++
 .../main/resources/importdata/test-templates.csv   |  20 +
 component-test/src/main/resources/logback-test.xml |  35 ++
 .../src/main/resources/templates/template.html     | 457 +++++++++++++++++++++
 service/build.gradle                               |   5 +-
 .../CreateTemplateCommand.java}                    |  34 +-
 ...andHandler.java => TemplateCommandHandler.java} |  56 +--
 .../internal/config/NotificationConfiguration.java |  33 +-
 .../internal/importer/TemplateImporter.java        |  92 +++++
 .../internal/mapper/EmailConfigurationMapper.java  |   4 +
 .../service/internal/mapper/TemplateMapper.java    |  51 +++
 .../internal/repository/ApplicationEntity.java     | 106 -----
 .../EmailGatewayConfigurationRepository.java       |   4 +-
 .../SMSGatewayConfigurationRepository.java         |   4 +-
 .../internal/repository/TemplateEntity.java        |  56 ++-
 .../internal/repository/TemplateRepository.java    |   8 +-
 .../service/internal/service/EmailService.java     | 138 +++----
 .../internal/service/NotificationService.java      |  34 +-
 .../service/internal/service/SMSService.java       |  18 +-
 .../service/internal/service/TemplateService.java  |  60 +++
 .../service/internal/service/util/MailBuilder.java |  36 +-
 .../service/listener/CustomerEventListener.java    |  89 ++--
 .../service/rest/EmailServiceRestController.java   |   4 +-
 .../service/rest/SMSServiceRestController.java     |   4 +-
 ...Controller.java => TemplateRestController.java} |  58 ++-
 service/src/main/resources/application.yml         |   4 +
 .../db/migrations/mariadb/V1__initial_setup.sql    |  24 +-
 .../main/resources/templatedetails/templates.csv   |  28 ++
 service/src/main/resources/templates/template.html | 457 +++++++++++++++++++++
 shared.gradle                                      |   4 +-
 41 files changed, 1784 insertions(+), 474 deletions(-)

diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationAlreadyExistException.java
similarity index 71%
copy from component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
copy to api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationAlreadyExistException.java
index ad4208a..cf06584 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationAlreadyExistException.java
@@ -16,17 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification;
+package org.apache.fineract.cn.notification.api.v1.client;
 
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-		TestEmailService.class,
-		TestSMSService.class,
-		EmailApiDocumentation.class,
-		SmsApiDocumentation.class,
-})
-public class TestSuite extends SuiteTestEnvironment {
+public final class ConfigurationAlreadyExistException extends RuntimeException {
 }
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.java
index 8b6c76c..992a5bb 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.java
@@ -23,6 +23,7 @@ import org.apache.fineract.cn.api.annotation.ThrowsExceptions;
 import org.apache.fineract.cn.api.util.CustomFeignClientsConfiguration;
 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.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
@@ -68,6 +69,14 @@ public interface NotificationManager {
 	String createEmailConfiguration(final EmailConfiguration emailConfiguration);
 	
 	@RequestMapping(
+			value = "/template/create",
+			method = RequestMethod.POST,
+			produces = MediaType.APPLICATION_JSON_VALUE,
+			consumes = MediaType.APPLICATION_JSON_VALUE
+	)
+	String createTemplate(final Template template);
+	
+	@RequestMapping(
 			value = "/configuration/sms/{identifier}",
 			method = RequestMethod.GET,
 			produces = MediaType.APPLICATION_JSON_VALUE,
@@ -111,4 +120,4 @@ public interface NotificationManager {
 	)
 	void deleteEmailConfiguration(@PathVariable("identifier") final String identifier);
 	
-}
\ No newline at end of file
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateAlreadyExistException.java
similarity index 71%
copy from component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
copy to api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateAlreadyExistException.java
index ad4208a..75de8db 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateAlreadyExistException.java
@@ -16,17 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification;
+package org.apache.fineract.cn.notification.api.v1.client;
 
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-		TestEmailService.class,
-		TestSMSService.class,
-		EmailApiDocumentation.class,
-		SmsApiDocumentation.class,
-})
-public class TestSuite extends SuiteTestEnvironment {
+public final class TemplateAlreadyExistException extends RuntimeException {
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateNotFoundException.java
similarity index 71%
copy from component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
copy to api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateNotFoundException.java
index ad4208a..6d5b09e 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/TemplateNotFoundException.java
@@ -16,17 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification;
+package org.apache.fineract.cn.notification.api.v1.client;
 
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-		TestEmailService.class,
-		TestSMSService.class,
-		EmailApiDocumentation.class,
-		SmsApiDocumentation.class,
-})
-public class TestSuite extends SuiteTestEnvironment {
+public final class TemplateNotFoundException extends RuntimeException {
 }
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/Template.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/Template.java
new file mode 100644
index 0000000..10ab584
--- /dev/null
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/Template.java
@@ -0,0 +1,110 @@
+/*
+ * 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.api.v1.domain;
+/*
+ebenezergraham created on 5/22/19
+*/
+
+import java.util.Objects;
+
+public class Template {
+	private String templateIdentifier;
+	private String subject;
+	private String senderEmail;
+	private String message;
+	private String url;
+	
+	public Template(String templateIdentifier, String senderEmail, String subject, String message, String url) {
+		this.templateIdentifier = templateIdentifier;
+		this.senderEmail = senderEmail;
+		this.subject = subject;
+		this.message = message;
+		this.url = url;
+	}
+	
+	public Template() {
+	}
+	
+	public String getTemplateIdentifier() {
+		return templateIdentifier;
+	}
+	
+	public void setTemplateIdentifier(String templateIdentifier) {
+		this.templateIdentifier = templateIdentifier;
+	}
+	
+	public String getSubject() {
+		return subject;
+	}
+	
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+	
+	public String getSenderEmail() {
+		return senderEmail;
+	}
+	
+	public void setSenderEmail(String senderEmail) {
+		this.senderEmail = senderEmail;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+	public void setMessage(String message) {
+		this.message = message;
+	}
+	
+	public String getUrl() {
+		return url;
+	}
+	
+	public void setUrl(String url) {
+		this.url = url;
+	}
+	
+	@Override
+	public String toString() {
+		return "Template{" +
+				"templateIdentifier='" + templateIdentifier + '\'' +
+				", subject='" + subject + '\'' +
+				", senderEmail='" + senderEmail + '\'' +
+				", message='" + message + '\'' +
+				", url='" + url + '\'' +
+				'}';
+	}
+	
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+		Template template = (Template) o;
+		return Objects.equals(templateIdentifier, template.templateIdentifier) &&
+				Objects.equals(subject, template.subject) &&
+				Objects.equals(message, template.message) &&
+				Objects.equals(url, template.url);
+	}
+	
+	@Override
+	public int hashCode() {
+		return Objects.hash(templateIdentifier, subject, message, senderEmail,url);
+	}
+}
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.java
index b6855b1..ef54997 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.java
@@ -27,11 +27,13 @@ public interface NotificationEventConstants {
 	
 	String POST_SMS_CONFIGURATION = "post-sms-configuration";
 	String POST_EMAIL_CONFIGURATION = "post-email-configuration";
+	String POST_TEMPLATE = "post-template";
 	String POST_SOURCE_APPLICATION = "post-source-application";
 	String UPDATE_SMS_CONFIGURATION = "update-sms-configuration";
 	String UPDATE_EMAIL_CONFIGURATION = "update-email-configuration";
 	String DELETE_SMS_CONFIGURATION = "delete-sms-configuration";
 	String DELETE_EMAIL_CONFIGURATION = "delete-email-configuration";
+	String DELETE_TEMPLATE = "delete-template";
 	String DELETE_SOURCE_APPLICATION = "delete-source-application";
 	
 	String POST_SEND_EMAIL_NOTIFICATION = "post-send-email-notification";
@@ -47,6 +49,7 @@ public interface NotificationEventConstants {
 	String SELECTOR_INITIALIZE = SELECTOR_NAME + " = '" + INITIALIZE + "'";
 	String SELECTOR_POST_SMS_CONFIGURATION = SELECTOR_NAME + " = '" + POST_SMS_CONFIGURATION + "'";
 	String SELECTOR_POST_EMAIL_CONFIGURATION = SELECTOR_NAME + " = '" + POST_EMAIL_CONFIGURATION + "'";
+	String SELECTOR_POST_TEMPLATE = SELECTOR_NAME + " = '" + POST_TEMPLATE + "'";
 	String SELECTOR_UPDATE_SMS_CONFIGURATION = SELECTOR_NAME + " = '" + UPDATE_SMS_CONFIGURATION + "'";
 	String SELECTOR_UPDATE_EMAIL_CONFIGURATION = SELECTOR_NAME + " = '" + UPDATE_EMAIL_CONFIGURATION + "'";
 	String SELECTOR_DELETE_SMS_CONFIGURATION = SELECTOR_NAME + " = '" + DELETE_SMS_CONFIGURATION + "'";
diff --git a/component-test/build.gradle b/component-test/build.gradle
index c0aaace..f0c2f41 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -49,7 +49,9 @@ dependencies {
             [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: versions.junit]
+            [group: 'junit', name: 'junit', version: versions.junit],
+            [group: 'org.apache.commons', name: 'commons-csv', version: versions.apachecsvreader]
+
     )
 }
 asciidoctor {
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 d80eef2..1f9c45a 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
@@ -20,8 +20,10 @@ package org.apache.fineract.cn.notification;
 
 import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
 import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
 import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
 import org.apache.fineract.cn.notification.service.internal.config.NotificationConfiguration;
+import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
 import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
 import org.apache.fineract.cn.test.listener.EnableEventRecording;
 import org.apache.fineract.cn.test.listener.EventRecorder;
@@ -51,14 +53,21 @@ public class AbstractNotificationTest extends SuiteTestEnvironment {
 	public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
 	public static final String LOGGER_NAME = "test-logger";
 	public static final String TEST_USER = "homer";
+	public static final String TEST_ADDRESS = "egraham15@alustudent.com";
+	public static final String TEST_TEMPLATE= "test_sample";
 	
 	@SuppressWarnings("WeakerAccess")
 	@Autowired
 	@Qualifier(LOGGER_NAME)
-	Logger logger;
+	public Logger logger;
 	public AutoUserContext userContext;
 	@Autowired
 	public EventRecorder eventRecorder;
+	@Autowired
+	public NotificationManager testSubject;
+	@Autowired
+	public NotificationService notificationService;
+	
 	@Rule
 	public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
 			= new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestEmailService.java b/component-test/src/main/java/org/apache/fineract/cn/notification/TestEmailService.java
index 6808678..702e437 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestEmailService.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/TestEmailService.java
@@ -20,29 +20,29 @@ package org.apache.fineract.cn.notification;
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.fineract.cn.api.util.NotFoundException;
-import org.apache.fineract.cn.customer.api.v1.client.CustomerNotFoundException;
+import org.apache.fineract.cn.customer.api.v1.domain.Address;
+import org.apache.fineract.cn.customer.api.v1.domain.Customer;
 import org.apache.fineract.cn.notification.api.v1.client.ConfigurationNotFoundException;
-import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
 import org.apache.fineract.cn.notification.api.v1.domain.EmailConfiguration;
 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.service.EmailService;
-import org.apache.fineract.cn.notification.service.internal.service.EventHelper;
-import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
 import org.apache.fineract.cn.notification.util.DomainObjectGenerator;
-import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
 public class TestEmailService extends AbstractNotificationTest {
 	
 	final EmailConfiguration emailConfiguration;
 	@Autowired
-	private NotificationService notificationService;
-	@Autowired
 	private EmailService emailService;
-	@Autowired
-	private NotificationManager notificationManager;
+	
 	
 	public TestEmailService() {
 		super();
@@ -51,28 +51,62 @@ public class TestEmailService extends AbstractNotificationTest {
 	
 	
 	@Test
-	public void shouldSendAnEmail() throws InterruptedException {
+	public void shouldSendAnEmail() throws InterruptedException, IOException {
 		this.logger.info("Send Email Notification");
-		String messageHash = notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
-				"egraham15@alustudent.com",
-				"Address Details Changed",
-				"Dear Valued Customer," +
-						"\n\nYour address has been changed successfully" +
-						"\nStreet: Test Street" +
-						"\nCity: Test City" +
-						"\nState: Test State" +
-						"\nCountry: Mauritius" +
-						"\n\nBest Regards" +
-						"\nMFI");
+		final TemplateImporter importer = new TemplateImporter(testSubject, logger);
+		final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv");
+		importer.importCSV(uri);
+//		Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE));
+      eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE);
+		
+		notificationService.sendEmail(
+				TEST_ADDRESS,
+				TEST_TEMPLATE,
+				null);
+		//Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS ));
+		this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS );
+	}
+	
+	@Test
+	public void shouldSendFormattedEmail() throws InterruptedException, IOException {
+		this.logger.info("Send Email Notification");
+		final TemplateImporter importer = new TemplateImporter(testSubject, logger);
+		final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv");
+		importer.importCSV(uri);
+		
+		//Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE));
+		eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE);
+		
+		Customer customerPayload = new Customer();
+		customerPayload.setGivenName("Test");
+		customerPayload.setSurname("User");
+		Address address = new Address();
+		address.setCity("Cape Coast");
+		address.setCity("Street");
+		address.setCountry("Ghana");
+		address.setCountryCode("GH");
+		address.setRegion("Central Region");
+		address.setPostalCode("T22022");
+		customerPayload.setAddress(address);
+		
+		Map<String, Object> templateVariables = new HashMap<>();
+		templateVariables.put(customerPayload.getClass().getName().toLowerCase(),customerPayload);
+		
+		notificationService.sendFormattedEmail(
+				TEST_ADDRESS,
+				TEST_TEMPLATE,
+				templateVariables
+		);
 		
-		Assert.assertNotNull(messageHash);
+		//Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS ));
+		this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS );
 	}
 	
 	@Test(expected = NotFoundException.class)
 	public void emailConfigurationNotFound() throws ConfigurationNotFoundException {
 		logger.info("Configuration not found");
 		try {
-			this.notificationManager.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8));
+			this.testSubject.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8));
 		} catch (final ConfigurationNotFoundException ex) {
 			logger.info("Error Asserted");
 		}
@@ -81,11 +115,11 @@ public class TestEmailService extends AbstractNotificationTest {
 	@Test
 	public void shouldCreateAndRetrieveEmailConfigurationEntity() throws InterruptedException {
 		logger.info("Create and Retrieve Email Gateway configuration");
-		this.notificationManager.createEmailConfiguration(emailConfiguration);
+		this.testSubject.createEmailConfiguration(emailConfiguration);
 		
 		this.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier());
 		
-		EmailConfiguration sampleRetrieved = this.notificationManager.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier());
+		EmailConfiguration sampleRetrieved = this.testSubject.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier());
 		Assert.assertNotNull(sampleRetrieved);
 		Assert.assertEquals(sampleRetrieved.getIdentifier(), emailConfiguration.getIdentifier());
 	}
@@ -93,7 +127,7 @@ public class TestEmailService extends AbstractNotificationTest {
 	@Test
 	public void checkEmailConfigurationEntityExist() throws InterruptedException {
 		logger.info("Email Gateway configuration Exist");
-		this.notificationManager.createEmailConfiguration(emailConfiguration);
+		this.testSubject.createEmailConfiguration(emailConfiguration);
 		super.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier());
 		
 		Assert.assertTrue(this.emailService.emailConfigurationExists(emailConfiguration.getIdentifier()));
@@ -102,6 +136,6 @@ public class TestEmailService extends AbstractNotificationTest {
 	@Test
 	public void shouldFindActiveGateway() {
 		this.logger.info("Find Active Gateway");
-		Assert.assertNotNull(this.emailService.findActiveEmailConfigurationEntity());
+		Assert.assertNotNull(this.emailService.getDefaultEmailConfigurationEntity());
 	}
 }
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 37ab85f..0a7738d 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
@@ -20,8 +20,6 @@ package org.apache.fineract.cn.notification;
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.fineract.cn.api.util.NotFoundException;
-import org.apache.fineract.cn.customer.api.v1.client.CustomerNotFoundException;
-import org.apache.fineract.cn.notification.api.v1.client.ConfigurationNotFoundException;
 import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
 import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
 import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
@@ -71,7 +69,7 @@ public class TestSMSService extends AbstractNotificationTest {
 	@Test
 	public void shouldFindActiveGateway() {
 		this.logger.info("Find Active Gateway");
-		Assert.assertNotNull(this.smsService.findActiveSMSConfigurationEntity());
+		Assert.assertNotNull(this.smsService.getDefaultSMSConfiguration());
 	}
 	
 	@Test
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 ad4208a..2efc41c 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,11 +18,14 @@
  */
 package org.apache.fineract.cn.notification;
 
+import org.apache.fineract.cn.notification.importer.TestTemplateImport;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
-@Suite.SuiteClasses({
+@SuiteClasses({
+		TestTemplateImport.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/TestTemplateImport.java
new file mode 100644
index 0000000..57b2dc7
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java
@@ -0,0 +1,57 @@
+/*
+ * 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.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.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.URL;
+
+
+public class TestTemplateImport extends AbstractNotificationTest {
+	
+	public TestTemplateImport() {
+		super();
+	}
+	
+	@Test
+	public void testTemplateImportHappyCase() throws IOException, InterruptedException {
+		final Template template = new Template();
+		template.setTemplateIdentifier("test-sample");
+		template.setSenderEmail("test@example.com");
+		template.setSubject("Test");
+		template.setMessage("Message");
+		template.setUrl("test/url");
+		
+		testSubject.createTemplate(template);
+		//Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier()));
+		eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier());
+		
+		final TemplateImporter importer = new TemplateImporter(testSubject, logger);
+		final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv");
+		importer.importCSV(uri);
+		//Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "sample"));
+		eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "sample");
+	}
+}
diff --git a/component-test/src/main/resources/importdata/test-templates.csv b/component-test/src/main/resources/importdata/test-templates.csv
new file mode 100644
index 0000000..d204bf1
--- /dev/null
+++ b/component-test/src/main/resources/importdata/test-templates.csv
@@ -0,0 +1,20 @@
+-
+- 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.
+-
+template_identifier,sender_email,subject,message,url
+test_sample,DEFAULT,Test Sample,This is a test message,template
diff --git a/component-test/src/main/resources/logback-test.xml b/component-test/src/main/resources/logback-test.xml
new file mode 100644
index 0000000..a3c21c7
--- /dev/null
+++ b/component-test/src/main/resources/logback-test.xml
@@ -0,0 +1,35 @@
+<!--
+
+    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.
+
+-->
+<configuration>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org" level="ERROR"/>
+    <logger name="com" level="OFF"/>
+    <logger name="ch" level="OFF"/>
+
+    <root level="DEBUG">
+        <appender-ref ref="STDOUT"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/component-test/src/main/resources/templates/template.html b/component-test/src/main/resources/templates/template.html
new file mode 100644
index 0000000..d6a4d1c
--- /dev/null
+++ b/component-test/src/main/resources/templates/template.html
@@ -0,0 +1,457 @@
+<!--
+ 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.
+-->
+
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:th="http://www.thymeleaf.org">
+<head>
+	<meta name="viewport" content="width=device-width"/>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+	<title>Simple Email</title>
+	<link href="https://fonts.googleapis.com/css?family=helvatica" rel="stylesheet"/>
+	<style>
+		/* -------------------------------------
+				GLOBAL RESETS
+		------------------------------------- */
+
+		/*All the styling goes here*/
+
+		img {
+			border: none;
+			-ms-interpolation-mode: bicubic;
+			max-width: 100%;
+		}
+
+		body {
+			background-color: #f6f6f6;
+			font-family: sans-serif;
+			-webkit-font-smoothing: antialiased;
+			font-size: 14px;
+			line-height: 1.4;
+			margin: 0;
+			padding: 0;
+			-ms-text-size-adjust: 100%;
+			-webkit-text-size-adjust: 100%;
+		}
+
+		table {
+			border-collapse: separate;
+			mso-table-lspace: 0pt;
+			mso-table-rspace: 0pt;
+			width: 100%;
+		}
+
+		table td {
+			font-family: sans-serif;
+			font-size: 14px;
+			vertical-align: top;
+		}
+
+		/* -------------------------------------
+				CONTAINER
+		------------------------------------- */
+
+		.body {
+			background-color: #f6f6f6;
+			width: 100%;
+		}
+
+		/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
+		.container {
+			display: block;
+			margin: 0 auto !important;
+			/* makes it centered */
+			max-width: 580px;
+			padding: 10px;
+			width: 580px;
+		}
+
+		/* This should also be a block element, so that it will fill 100% of the .container */
+		.content {
+			box-sizing: border-box;
+			display: block;
+			margin: 0 auto;
+			max-width: 580px;
+			padding: 10px;
+		}
+
+		/* -------------------------------------
+				HEADER, FOOTER, MAIN
+		------------------------------------- */
+		.main {
+			background: #ffffff;
+			border-radius: 3px;
+			width: 100%;
+		}
+
+		.wrapper {
+			box-sizing: border-box;
+			padding: 20px;
+		}
+
+		.content-block {
+			padding-bottom: 10px;
+			padding-top: 10px;
+		}
+
+		.footer {
+			clear: both;
+			margin-top: 10px;
+			text-align: center;
+			width: 100%;
+		}
+
+		.footer td,
+		.footer p,
+		.footer span,
+		.footer a {
+			color: #999999;
+			font-size: 12px;
+			text-align: center;
+		}
+
+		/* -------------------------------------
+				TYPOGRAPHY
+		------------------------------------- */
+		h1,
+		h2,
+		h3,
+		h4 {
+			color: #000000;
+			font-family: sans-serif;
+			font-weight: 400;
+			line-height: 1.4;
+			margin: 0;
+			margin-bottom: 30px;
+		}
+
+		h1 {
+			font-size: 35px;
+			font-weight: 300;
+			text-align: center;
+			text-transform: capitalize;
+		}
+
+		p,
+		ul,
+		ol {
+			font-family: sans-serif;
+			font-size: 14px;
+			font-weight: normal;
+			margin: 0;
+			margin-bottom: 15px;
+		}
+
+		p li,
+		ul li,
+		ol li {
+			list-style-position: inside;
+			margin-left: 5px;
+		}
+
+		a {
+			color: #a92334;
+			text-decoration: underline;
+		}
+
+		/* -------------------------------------
+				BUTTONS
+		------------------------------------- */
+		.btn {
+			box-sizing: border-box;
+			width: 100%;
+		}
+
+		.btn > tbody > tr > td {
+			padding-bottom: 15px;
+		}
+
+		.btn table {
+			width: auto;
+		}
+
+		.btn table td {
+			background-color: #ffffff;
+			border-radius: 5px;
+			text-align: center;
+		}
+
+		.btn a {
+			background-color: #ffffff;
+			border: solid 1px #a92334;
+			border-radius: 5px;
+			box-sizing: border-box;
+			color: #a92334;
+			cursor: pointer;
+			display: inline-block;
+			font-size: 14px;
+			font-weight: bold;
+			margin: 0;
+			padding: 12px 25px;
+			text-decoration: none;
+			text-transform: capitalize;
+		}
+
+		.btn-primary table td {
+			background-color: #a92334;
+		}
+
+		.btn-primary a {
+			background-color: #a92334;
+			border-color: #a92334;
+			color: #ffffff;
+		}
+
+		/* -------------------------------------
+				OTHER STYLES THAT MIGHT BE USEFUL
+		------------------------------------- */
+		.last {
+			margin-bottom: 0;
+		}
+
+		.first {
+			margin-top: 0;
+		}
+
+		.align-center {
+			text-align: center;
+		}
+
+		.align-right {
+			text-align: right;
+		}
+
+		.align-left {
+			text-align: left;
+		}
+
+		.clear {
+			clear: both;
+		}
+
+		.mt0 {
+			margin-top: 0;
+		}
+
+		.mb0 {
+			margin-bottom: 0;
+		}
+
+		.preheader {
+			color: transparent;
+			display: none;
+			height: 0;
+			max-height: 0;
+			max-width: 0;
+			opacity: 0;
+			overflow: hidden;
+			mso-hide: all;
+			visibility: hidden;
+			width: 0;
+		}
+
+		.powered-by a {
+			text-decoration: none;
+		}
+
+		hr {
+			border: 0;
+			border-bottom: 1px solid #f6f6f6;
+			margin: 20px 0;
+		}
+
+		/* -------------------------------------
+				RESPONSIVE AND MOBILE FRIENDLY STYLES
+		------------------------------------- */
+		@media only screen and (max-width: 620px) {
+			table[class=body] h1 {
+				font-size: 28px !important;
+				margin-bottom: 10px !important;
+			}
+
+			table[class=body] p,
+			table[class=body] ul,
+			table[class=body] ol,
+			table[class=body] td,
+			table[class=body] span,
+			table[class=body] a {
+				font-size: 16px !important;
+			}
+
+			table[class=body] .wrapper,
+			table[class=body] .article {
+				padding: 10px !important;
+			}
+
+			table[class=body] .content {
+				padding: 0 !important;
+			}
+
+			table[class=body] .container {
+				padding: 0 !important;
+				width: 100% !important;
+			}
+
+			table[class=body] .main {
+				border-left-width: 0 !important;
+				border-radius: 0 !important;
+				border-right-width: 0 !important;
+			}
+
+			table[class=body] .btn table {
+				width: 100% !important;
+			}
+
+			table[class=body] .btn a {
+				width: 100% !important;
+			}
+
+			table[class=body] .img-responsive {
+				height: auto !important;
+				max-width: 100% !important;
+				width: auto !important;
+			}
+		}
+
+		/* -------------------------------------
+				PRESERVE THESE STYLES IN THE HEAD
+		------------------------------------- */
+		@media all {
+			.headTab{
+				height: 60px;
+				width: auto;
+				max-width: 540px;
+				padding: 10px;
+				margin: 0 auto;
+				background-color: #ffffff;
+				/*-webkit-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);
+				-moz-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);
+				box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);*/
+			}
+			.ExternalClass {
+				width: 100%;
+			}
+
+			.ExternalClass,
+			.ExternalClass p,
+			.ExternalClass span,
+			.ExternalClass font,
+			.ExternalClass td,
+			.ExternalClass div {
+				line-height: 100%;
+			}
+
+			.apple-link a {
+				color: inherit !important;
+				font-family: inherit !important;
+				font-size: inherit !important;
+				font-weight: inherit !important;
+				line-height: inherit !important;
+				text-decoration: none !important;
+			}
+
+			.btn-primary table td:hover {
+				background-color: #a92334 !important;
+			}
+
+			.btn-primary a:hover {
+				background-color: #a92334 !important;
+				border-color: #a92334 !important;
+			}
+		}
+
+	</style>
+</head>
+<body>
+<span class="preheader">Header Message</span>
+<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
+
+	<tr>
+		<td>&nbsp;</td>
+
+		<td class="container">
+			<div class="headTab"><img style="height:40px; margin:10px;" class="img-responsive" src="http://fineract.apache.org/images/apache-fineract-logo.png" alt="Logo"></div>
+
+			<div class="content">
+
+				<!-- START CENTERED WHITE CONTAINER -->
+				<table role="presentation" class="main">
+
+					<!-- START MAIN CONTENT AREA -->
+					<tr>
+						<td class="wrapper">
+							<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+								<tr>
+									<td>
+										<p>Dear Valued Customer,</p>
+
+										<p>This is a sample message an account update</p>
+										<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
+											<tbody>
+											<tr>
+												<td align="left">
+													<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+														<tbody>
+														<tr>
+															<td> <a href="http://fineract.apache.org" target="_blank">Call To Action</a> </td>
+														</tr>
+														</tbody>
+													</table>
+												</td>
+											</tr>
+											</tbody>
+										</table>
+										<p>No reply required. This is a computer generated mail.</p>
+										<p>Best Regards,</p>
+										<p>MFI</p>
+									</td>
+								</tr>
+							</table>
+						</td>
+					</tr>
+
+					<!-- END MAIN CONTENT AREA -->
+				</table>
+				<!-- END CENTERED WHITE CONTAINER -->
+
+				<!-- START FOOTER -->
+				<div class="footer">
+					<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+						<tr>
+							<td class="content-block">
+								<span class="apple-link">Apache Software Foundation, Forest Hill, Maryland, United States</span>
+								<p> Don't like these emails? <a href="">Unsubscribe</a>.</p>
+							</td>
+						</tr>
+						<tr>
+							<td class="content-block powered-by">
+								Powered by <a href="http://fineract.apache.org">Apache Fineract</a>.
+							</td>
+						</tr>
+					</table>
+				</div>
+				<!-- END FOOTER -->
+
+			</div>
+		</td>
+		<td>&nbsp;</td>
+	</tr>
+</table>
+</body>
+</html>
diff --git a/service/build.gradle b/service/build.gradle
index 6b8513e..6a9e068 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -49,6 +49,7 @@ dependencies {
     compile(
             [group: 'com.twilio.sdk', name: 'twilio', version: versions.twilioapi],
             [group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: versions.springjavamail],
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'],
 
             [group: 'org.apache.fineract.cn.customer', name: 'api', version: versions.fineractcncustomer],
             [group: 'org.apache.fineract.cn.portfolio', name: 'api', version: versions.fineractcnportfolio],
@@ -67,7 +68,9 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
             [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]
+            [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator],
+            [group: 'org.apache.commons', name: 'commons-csv', version: versions.apachecsvreader]
+
     )
 }
 
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationRepository.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/CreateTemplateCommand.java
similarity index 53%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationRepository.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/CreateTemplateCommand.java
index 9eb4b1c..9137439 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/CreateTemplateCommand.java
@@ -16,19 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification.service.internal.repository;
+package org.apache.fineract.cn.notification.service.internal.command;
 
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Lock;
-import org.springframework.stereotype.Repository;
+import org.apache.fineract.cn.notification.api.v1.domain.Template;
 
-import javax.persistence.LockModeType;
-import java.util.Optional;
-
-@Repository
-public interface ApplicationRepository extends JpaRepository<ApplicationEntity, Long> {
-  @Lock(LockModeType.PESSIMISTIC_WRITE)
-  void deleteByTenantIdentifierAndApplicationIdentifier(String tenantIdentifier, String applicationIdentifier);
-  
-  Optional<ApplicationEntity> findByTenantIdentifierAndApplicationIdentifier(String tenantIdentifier, String applicationIdentifier);
+public class CreateTemplateCommand {
+	
+	private final Template template;
+	
+	public CreateTemplateCommand(final Template template) {
+		super();
+		this.template = template;
+	}
+	
+	public Template getTemplate() {
+		return this.template;
+	}
+	
+	@Override
+	public String toString() {
+		return "CreateTemplateCommand{" +
+				"template=" + template +
+				'}';
+	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/TemplateCommandHandler.java
similarity index 55%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/TemplateCommandHandler.java
index 55de62d..5e60e27 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/TemplateCommandHandler.java
@@ -22,42 +22,42 @@ import org.apache.fineract.cn.command.annotation.Aggregate;
 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.notification.api.v1.domain.SMSConfiguration;
+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.command.SaveApplicationCommand;
-import org.apache.fineract.cn.notification.service.internal.repository.ApplicationEntity;
-import org.apache.fineract.cn.notification.service.internal.repository.ApplicationRepository;
-import org.apache.fineract.cn.notification.service.internal.command.DeleteApplicationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.CreateTemplateCommand;
+import org.apache.fineract.cn.notification.service.internal.command.DeleteSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.UpdateSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.mapper.SMSConfigurationMapper;
+import org.apache.fineract.cn.notification.service.internal.mapper.TemplateMapper;
+import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationEntity;
+import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationRepository;
+import org.apache.fineract.cn.notification.service.internal.repository.TemplateEntity;
+import org.apache.fineract.cn.notification.service.internal.repository.TemplateRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 @SuppressWarnings("unused")
 @Aggregate
-public class ApplicationCommandHandler {
-  private final ApplicationRepository applicationRepository;
-
-  @Autowired
-  public ApplicationCommandHandler(
-          final ApplicationRepository applicationRepository
-          ) {
-    super();
-    this.applicationRepository = applicationRepository;
-  }
-  
-  @CommandHandler(logStart = CommandLogLevel.INFO,logFinish = CommandLogLevel.INFO)
-	@Transactional
-	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME,selectorValue = NotificationEventConstants.POST_SOURCE_APPLICATION)
-	public String process(SaveApplicationCommand saveApplicationCommand){
-	  ApplicationEntity applicationEntity = new ApplicationEntity();
-	  applicationEntity.setApplicationIdentifier(saveApplicationCommand.getApplicationIdentifier());
-	  applicationEntity.setTenantIdentifier(saveApplicationCommand.getTenantIdentifier());
-  	this.applicationRepository.save(applicationEntity);
-  	return saveApplicationCommand.getApplicationIdentifier();
-  }
+public class TemplateCommandHandler {
+	
+	private final TemplateRepository templateRepository;
+	
+	@Autowired
+	public TemplateCommandHandler(TemplateRepository templateRepository) {
+		super();
+		this.templateRepository = templateRepository;
+	}
 	
 	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
 	@Transactional
-	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME,selectorValue = NotificationEventConstants.DELETE_SOURCE_APPLICATION)
-	public void process(final DeleteApplicationCommand deleteApplicationCommand) {
-		this.applicationRepository.deleteByTenantIdentifierAndApplicationIdentifier(deleteApplicationCommand.getTenantIdentifier(), deleteApplicationCommand.getApplicationIdentifier());
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_TEMPLATE)
+	public String process(final CreateTemplateCommand createTemplateCommand) {
+		Template template = createTemplateCommand.getTemplate();
+		final TemplateEntity entity = TemplateMapper.map(template);
+		this.templateRepository.save(entity);
+		
+		return template.getTemplateIdentifier();
 	}
 }
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 8db7f39..ba70234 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
@@ -52,6 +52,11 @@ import org.springframework.jms.config.JmsListenerContainerFactory;
 import org.springframework.jms.core.JmsTemplate;
 import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.thymeleaf.spring4.SpringTemplateEngine;
+import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
+import org.thymeleaf.templatemode.StandardTemplateModeHandlers;
+
+import java.nio.charset.StandardCharsets;
 
 @SuppressWarnings("WeakerAccess")
 @Configuration
@@ -103,23 +108,24 @@ public class NotificationConfiguration extends WebMvcConfigurerAdapter {
 	}
 	
 	@Bean
-	public PooledConnectionFactory jmsFactory() {
+	public PooledConnectionFactory pooledConnectionFactory() {
 		PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory();
 		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
-		activeMQConnectionFactory.setBrokerURL(this.environment.getProperty("activemq.brokerUrl", "vm://localhost?broker.persistent=falseac"));
+		activeMQConnectionFactory.setBrokerURL(this.environment.getProperty("activemq.brokerUrl","vm://localhost?broker.persistent=false"));
 		pooledConnectionFactory.setConnectionFactory(activeMQConnectionFactory);
 		return pooledConnectionFactory;
 	}
 	
 	@Bean
 	public JmsListenerContainerFactory jmsListenerContainerFactory(PooledConnectionFactory jmsFactory) {
-		DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
+		final DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
+		factory.setConnectionFactory(jmsFactory);
 		factory.setPubSubDomain(true);
 		factory.setConnectionFactory(jmsFactory);
 		factory.setErrorHandler(ex -> {
-			loggerBean().error(ex.getCause().toString());
+			loggerBean().warn(ex.getCause().toString());
 		});
-		factory.setConcurrency(this.environment.getProperty("activemq.concurrency", "1-1"));
+		factory.setConcurrency(this.environment.getProperty("activemq.concurrency","1-1"));
 		return factory;
 	}
 	
@@ -133,6 +139,23 @@ public class NotificationConfiguration extends WebMvcConfigurerAdapter {
 		return jmsTemplate;
 	}
 	
+	@Bean
+	public SpringTemplateEngine springTemplateEngine() {
+		SpringTemplateEngine templateEngine = new SpringTemplateEngine();
+		templateEngine.addTemplateResolver(htmlTemplateResolver());
+		return templateEngine;
+	}
+	
+	@Bean
+	public SpringResourceTemplateResolver htmlTemplateResolver(){
+		SpringResourceTemplateResolver emailTemplateResolver = new SpringResourceTemplateResolver();
+		emailTemplateResolver.setPrefix("classpath:/templates/");
+		emailTemplateResolver.setSuffix(".html");
+		emailTemplateResolver.setTemplateMode(StandardTemplateModeHandlers.HTML5.getTemplateModeName());
+		emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
+		return emailTemplateResolver;
+	}
+	
 	@Bean(
 			name = {ServiceConstants.LOGGER_NAME}
 	)
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
new file mode 100644
index 0000000..ee2782f
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/importer/TemplateImporter.java
@@ -0,0 +1,92 @@
+/*
+ * 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/mapper/EmailConfigurationMapper.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/EmailConfigurationMapper.java
index 5dcfbae..9f8b024 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/EmailConfigurationMapper.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/EmailConfigurationMapper.java
@@ -40,6 +40,10 @@ public class EmailConfigurationMapper {
 		emailConfiguration.setPort(emailGatewayConfigurationEntity.getPort());
 		emailConfiguration.setUsername(emailGatewayConfigurationEntity.getUsername());
 		emailConfiguration.setApp_password(emailGatewayConfigurationEntity.getApp_password());
+		emailConfiguration.setProtocol(emailGatewayConfigurationEntity.getProtocol());
+		emailConfiguration.setSmtp_auth(emailGatewayConfigurationEntity.getSmtp_auth());
+		emailConfiguration.setStart_tls(emailGatewayConfigurationEntity.getStart_tls());
+		emailConfiguration.setState(emailGatewayConfigurationEntity.getState());
 		return emailConfiguration;
 	}
 	
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/TemplateMapper.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/TemplateMapper.java
new file mode 100644
index 0000000..257cd07
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/mapper/TemplateMapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.mapper;
+
+import org.apache.fineract.cn.notification.api.v1.domain.Template;
+import org.apache.fineract.cn.notification.service.internal.repository.TemplateEntity;
+
+public class TemplateMapper {
+	
+	private TemplateMapper() {
+		super();
+	}
+	
+	public static Template map(final TemplateEntity templateEntity) {
+		final Template template = new Template();
+		template.setTemplateIdentifier(templateEntity.getTemplateIdentifier());
+		template.setSenderEmail(templateEntity.getSenderEmail());
+		template.setSubject(templateEntity.getSubject());
+		template.setMessage(templateEntity.getMessage());
+		template.setUrl(templateEntity.getUrl());
+		return template;
+	}
+	
+	public static TemplateEntity map(final Template template) {
+		final TemplateEntity templateEntity = new TemplateEntity();
+		templateEntity.setTemplateIdentifier(template.getTemplateIdentifier());
+		templateEntity.setSubject(template.getSubject());
+		templateEntity.setSenderEmail(template.getSenderEmail());
+		templateEntity.setMessage(template.getMessage());
+		templateEntity.setUrl(template.getUrl());
+		return templateEntity;
+	}
+}
+
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationEntity.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationEntity.java
deleted file mode 100644
index 0e22a04..0000000
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationEntity.java
+++ /dev/null
@@ -1,106 +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.repository;
-
-import javax.persistence.*;
-import java.util.Objects;
-
-@SuppressWarnings({"unused", "WeakerAccess"})
-@Entity
-@Table(name = "wada_data_source_application")
-public class ApplicationEntity {
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Column(name = "id")
-  private Long id;
-
-  @Column(name = "tenant_identifier", nullable = false)
-  private String tenantIdentifier;
-
-  @Column(name = "application_identifier", nullable = false)
-  private String applicationIdentifier;
-
-  @Column(name = "permittable_identifier")
-  private String permittableGroupIdentifier;
-
-  public ApplicationEntity() {
-  }
-
-  public ApplicationEntity(String tenantIdentifier, String applicationIdentifier, String permittableGroupIdentifier) {
-    this.tenantIdentifier = tenantIdentifier;
-    this.applicationIdentifier = applicationIdentifier;
-    this.permittableGroupIdentifier = permittableGroupIdentifier;
-  }
-
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public String getTenantIdentifier() {
-    return tenantIdentifier;
-  }
-
-  public void setTenantIdentifier(String tenantIdentifier) {
-    this.tenantIdentifier = tenantIdentifier;
-  }
-
-  public String getApplicationIdentifier() {
-    return applicationIdentifier;
-  }
-
-  public void setApplicationIdentifier(String applicationIdentifier) {
-    this.applicationIdentifier = applicationIdentifier;
-  }
-
-  public String getPermittableGroupIdentifier() {
-    return permittableGroupIdentifier;
-  }
-
-  public void setPermittableGroupIdentifier(String permittableGroupIdentifier) {
-    this.permittableGroupIdentifier = permittableGroupIdentifier;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-    ApplicationEntity that = (ApplicationEntity) o;
-    return Objects.equals(tenantIdentifier, that.tenantIdentifier) &&
-            Objects.equals(applicationIdentifier, that.applicationIdentifier);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(tenantIdentifier, applicationIdentifier);
-  }
-
-  @Override
-  public String toString() {
-    return "ApplicationEntity{" +
-            "id=" + id +
-            ", tenantIdentifier='" + tenantIdentifier + '\'' +
-            ", applicationIdentifier='" + applicationIdentifier + '\'' +
-            ", permittableGroupIdentifier='" + permittableGroupIdentifier + '\'' +
-            '}';
-  }
-}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/EmailGatewayConfigurationRepository.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/EmailGatewayConfigurationRepository.java
index 93785be..2b5ddcb 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/EmailGatewayConfigurationRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/EmailGatewayConfigurationRepository.java
@@ -32,8 +32,8 @@ public interface EmailGatewayConfigurationRepository extends JpaRepository<Email
 	@Query("SELECT CASE WHEN COUNT(c) > 0 THEN 'true' ELSE 'false' END FROM EmailGatewayConfigurationEntity c WHERE c.identifier = :identifier")
 	Boolean existsByIdentifier(@Param("identifier") final String identifier);
 	
-	@Query("SELECT entity FROM EmailGatewayConfigurationEntity entity WHERE entity.state='ACTIVE'")
-	Optional<EmailGatewayConfigurationEntity> active();
+	@Query("SELECT entity FROM EmailGatewayConfigurationEntity entity WHERE entity.identifier='DEFAULT'")
+	Optional<EmailGatewayConfigurationEntity> defaultGateway();
 	
 	void deleteEmailGatewayConfigurationEntityBy(String identifier);
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/SMSGatewayConfigurationRepository.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/SMSGatewayConfigurationRepository.java
index 9b440e5..64e8427 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/SMSGatewayConfigurationRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/SMSGatewayConfigurationRepository.java
@@ -32,8 +32,8 @@ public interface SMSGatewayConfigurationRepository extends JpaRepository<SMSGate
 	@Query("SELECT CASE WHEN COUNT(c) > 0 THEN 'true' ELSE 'false' END FROM SMSGatewayConfigurationEntity c WHERE c.identifier = :identifier")
 	Boolean existsByIdentifier(@Param("identifier") final String identifier);
 	
-	@Query("SELECT entity FROM SMSGatewayConfigurationEntity entity WHERE entity.state='ACTIVE'")
-	Optional<SMSGatewayConfigurationEntity> active();
+	@Query("SELECT entity FROM SMSGatewayConfigurationEntity entity WHERE entity.identifier='DEFAULT'")
+	Optional<SMSGatewayConfigurationEntity> defaultGateway();
 	
 	void deleteSMSGatewayConfigurationEntityBy(String identifier);
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateEntity.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateEntity.java
index c699b9c..4f6f3c8 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateEntity.java
@@ -30,10 +30,14 @@ public class TemplateEntity {
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "id")
 	private Long id;
-	@Column(name = "identifier")
-	private String identifier;
-	@Column(name = "event")
-	private String event;
+	@Column(name = "template_identifier")
+	private String templateIdentifier;
+	@Column(name = "subject")
+	private String subject;
+	@Column(name = "sender_email")
+	private String senderEmail;
+	@Column(name = "message")
+	private String message;
 	@Column(name = "url")
 	private String url;
 	
@@ -50,20 +54,36 @@ public class TemplateEntity {
 		this.id = id;
 	}
 	
-	public String getIdentifier() {
-		return this.identifier;
+	public String getTemplateIdentifier() {
+		return templateIdentifier;
 	}
 	
-	public void setIdentifier(final String identifier) {
-		this.identifier = identifier;
+	public void setTemplateIdentifier(String templateIdentifier) {
+		this.templateIdentifier = templateIdentifier;
 	}
 	
-	public String getEvent() {
-		return event;
+	public String getSubject() {
+		return subject;
 	}
 	
-	public void setEvent(String event) {
-		this.event = event;
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+	
+	public String getSenderEmail() {
+		return senderEmail;
+	}
+	
+	public void setSenderEmail(String senderEmail) {
+		this.senderEmail = senderEmail;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+	public void setMessage(String message) {
+		this.message = message;
 	}
 	
 	public String getUrl() {
@@ -80,22 +100,24 @@ public class TemplateEntity {
 		if (o == null || getClass() != o.getClass()) return false;
 		TemplateEntity that = (TemplateEntity) o;
 		return Objects.equals(id, that.id) &&
-				Objects.equals(identifier, that.identifier) &&
-				Objects.equals(event, that.event) &&
+				Objects.equals(templateIdentifier, that.templateIdentifier) &&
+				Objects.equals(subject, that.subject) &&
 				Objects.equals(url, that.url);
 	}
 	
 	@Override
 	public int hashCode() {
-		return Objects.hash(id, identifier, event, url);
+		return Objects.hash(id, templateIdentifier, subject, message, url);
 	}
 	
 	@Override
 	public String toString() {
 		return "TemplateEntity{" +
 				"id=" + id +
-				", identifier='" + identifier + '\'' +
-				", event='" + event + '\'' +
+				", templateIdentifier='" + templateIdentifier + '\'' +
+				", subject='" + subject + '\'' +
+				", message='" + message + '\'' +
+				", senderEmail='" + senderEmail + '\'' +
 				", url='" + url + '\'' +
 				'}';
 	}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateRepository.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateRepository.java
index 5e82d1f..cbb7b3f 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateRepository.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/TemplateRepository.java
@@ -19,11 +19,17 @@
 package org.apache.fineract.cn.notification.service.internal.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 import java.util.Optional;
 
 @Repository
 public interface TemplateRepository extends JpaRepository<TemplateEntity, Long> {
-	Optional<TemplateEntity> findByIdentifier(String identifier);
+	Optional<TemplateEntity> findByTemplateIdentifier(String identifier);
+	
+	@Query("SELECT CASE WHEN COUNT(c) > 0 THEN 'true' ELSE 'false' END FROM TemplateEntity c WHERE c.templateIdentifier = :template_identifier")
+	Boolean existsByTemplateIdentifier(@Param("template_identifier") final String identifier);
+	
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EmailService.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EmailService.java
index bc006c6..f1f24ed 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EmailService.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EmailService.java
@@ -28,17 +28,20 @@ import org.apache.fineract.cn.notification.service.ServiceConstants;
 import org.apache.fineract.cn.notification.service.internal.mapper.EmailConfigurationMapper;
 import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationRepository;
 
+import org.apache.fineract.cn.notification.service.internal.service.util.MailBuilder;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.mail.MailException;
 import org.springframework.mail.SimpleMailMessage;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.mail.javamail.MimeMessagePreparator;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 
@@ -46,56 +49,35 @@ import java.util.Properties;
 @Aggregate
 public class EmailService {
 	
-	static boolean isConfigured;
-	
 	private final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository;
+	boolean isConfigured;
 	private JavaMailSenderImpl mailSender;
-	
+	private MailBuilder mailBuilder;
 	private Logger logger;
-	private String host;
-	private String email;
-	private int port;
-	private String password;
 	
 	@Autowired
 	public EmailService(final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository,
+	                    final MailBuilder mailBuilder,
 	                    @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
 		super();
 		this.isConfigured = false;
 		this.logger = logger;
 		this.mailSender = new JavaMailSenderImpl();
 		this.emailGatewayConfigurationRepository = emailGatewayConfigurationRepository;
+		this.mailBuilder = mailBuilder;
 	}
 	
-	//@PostConstruct
-	public void init() {
-		if (findActiveEmailConfigurationEntity().isPresent()){
-			configureEmailGatewayWithActiveConfiguration();
-		}else{
-			//Todo: Send an alert on the interface to configure the service
-		}
-	}
-	
-	public boolean configureEmailGatewayWithActiveConfiguration() {
-		EmailConfiguration configuration = findActiveEmailConfigurationEntity().get();
-		
-		this.host = configuration.getHost();
-		this.email = configuration.getUsername();
-		this.port = Integer.parseInt(configuration.getPort());
-		this.password = configuration.getApp_password();
-		return this.isConfigured = setJavaMailSender();
-	}
-	
-	public boolean customConfiguration(String identifier) {
-		return this.isConfigured = setCustomProperties(identifier);
+	public boolean configureEmailGatewayWithDefaultGateway() {
+		EmailConfiguration configuration = getDefaultEmailConfigurationEntity().get();
+		return setNewConfiguration(configuration);
 	}
 	
-	public List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
+	public List<EmailConfiguration> findAllEmailConfigurationEntities() {
 		return EmailConfigurationMapper.map(this.emailGatewayConfigurationRepository.findAll());
 	}
 	
-	public Optional<EmailConfiguration> findActiveEmailConfigurationEntity() {
-		return this.emailGatewayConfigurationRepository.active().map(EmailConfigurationMapper::map);
+	public Optional<EmailConfiguration> getDefaultEmailConfigurationEntity() {
+		return this.emailGatewayConfigurationRepository.defaultGateway().map(EmailConfigurationMapper::map);
 	}
 	
 	public Optional<EmailConfiguration> findEmailConfigurationByIdentifier(final String identifier) {
@@ -106,65 +88,69 @@ public class EmailService {
 		return this.emailGatewayConfigurationRepository.existsByIdentifier(identifier);
 	}
 	
-	public boolean setJavaMailSender() {
-		mailSender.setHost(host);
-		mailSender.setPort(port);
-		mailSender.setUsername(email);
-		mailSender.setPassword(password);
-		
-		switch (host.toLowerCase()) {
-			case ServiceConstants.GOOGLE_MAIL_SERVER:
-				return setProperties();
-			case ServiceConstants.YAHOO_MAIL_SERVER:
-				return setProperties();
-		}
-		return false;
-	}
-	
-	public boolean setProperties() {
-		Properties properties = new Properties();
-		properties.put(ServiceConstants.MAIL_TRANSPORT_PROTOCOL_PROPERTY,
-				ServiceConstants.MAIL_TRANSPORT_PROTOCOL_VALUE);
-		properties.put(ServiceConstants.MAIL_SMTP_AUTH_PROPERTY,
-				ServiceConstants.MAIL_SMTP_AUTH_VALUE);
-		properties.put(ServiceConstants.MAIL_SMTP_STARTTLS_ENABLE_PROPERTY,
-				ServiceConstants.MAIL_SMTP_STARTTLS_ENABLE_VALUE);
-		this.mailSender.setJavaMailProperties(properties);
-		return true;
+	boolean setNewConfiguration(String identifier) {
+		EmailConfiguration configuration = findEmailConfigurationByIdentifier(identifier).get();
+		return setNewConfiguration(configuration);
 	}
 	
-	public boolean setCustomProperties(String identifier) {
-		EmailConfiguration configuration = findEmailConfigurationByIdentifier(identifier).get();
-		this.mailSender.setHost(configuration.getHost());
-		this.mailSender.setPort(Integer.parseInt(configuration.getPort()));
-		this.mailSender.setUsername(configuration.getUsername());
-		this.mailSender.setPassword(configuration.getApp_password());
-		
-		Properties properties = new Properties();
-		properties.put(ServiceConstants.MAIL_TRANSPORT_PROTOCOL_PROPERTY, configuration.getProtocol());
-		properties.put(ServiceConstants.MAIL_SMTP_AUTH_PROPERTY, configuration.getSmtp_auth());
-		properties.put(ServiceConstants.MAIL_SMTP_STARTTLS_ENABLE_PROPERTY, configuration.getStart_tls());
-		//properties.put(ServiceConstants.MAIL_SMTP_TIMEOUT_PROPERTY, ServiceConstants.MAIL_SMTP_TIMEOUT_VALUE);
-		this.mailSender.setJavaMailProperties(properties);
-		return true;
+	private boolean setNewConfiguration(EmailConfiguration configuration) {
+		try {
+			this.mailSender.setHost(configuration.getHost());
+			this.mailSender.setPort(Integer.parseInt(configuration.getPort()));
+			this.mailSender.setUsername(configuration.getUsername());
+			this.mailSender.setPassword(configuration.getApp_password());
+			
+			Properties properties = new Properties();
+			properties.put(ServiceConstants.MAIL_TRANSPORT_PROTOCOL_PROPERTY, configuration.getProtocol());
+			properties.put(ServiceConstants.MAIL_SMTP_AUTH_PROPERTY, configuration.getSmtp_auth());
+			properties.put(ServiceConstants.MAIL_SMTP_STARTTLS_ENABLE_PROPERTY, configuration.getStart_tls());
+			this.mailSender.setJavaMailProperties(properties);
+			this.isConfigured = true;
+			return true;
+		} catch (RuntimeException ignore) {
+			logger.error("Failed to configure the Email Gateway");
+		}
+		return false;
 	}
 	
 	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
 	@Transactional
 	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION)
-	public String sendEmail(String from, String to, String subject, String message) {
+	public String sendPlainEmail(String to, String subject, String message) {
 		SimpleMailMessage mail = new SimpleMailMessage();
 		
 		try {
-			mail.setFrom(from);
 			mail.setTo(to);
 			mail.setSubject(subject);
 			mail.setText(message);
-			
 			this.mailSender.send(mail);
+			return to;
 		} catch (MailException exception) {
 			logger.debug("Caused by:" + exception.getCause().toString());
 		}
-		return to.concat(" - " + mailSender.hashCode());
+		return null;
+	}
+	
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION)
+	public String sendFormattedEmail(String to,
+	                                 String subject,
+	                                 Map<String, Object> message,
+	                                 String emailTemplate) {
+		MimeMessagePreparator messagePreparator = mimeMessage -> {
+			MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
+			messageHelper.setTo(to);
+			messageHelper.setSubject(subject);
+			String content = mailBuilder.build(message, emailTemplate);
+			messageHelper.setText(content, true);
+		};
+		try {
+			this.mailSender.send(messagePreparator);
+			return to;
+		} catch (MailException e) {
+			logger.error("Failed to send Formatted email{}", e.getMessage());
+		}
+		return null;
 	}
-}
\ No newline at end of file
+}
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 02b3621..2b51e8c 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
@@ -19,6 +19,7 @@
 package org.apache.fineract.cn.notification.service.internal.service;
 
 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.identity.CustomerPermittedClient;
 import org.apache.fineract.cn.notification.service.internal.identity.NotificationAuthentication;
@@ -28,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
+import java.util.Map;
 import java.util.Optional;
 
 @Service
@@ -35,6 +37,7 @@ public class NotificationService {
 	
 	private final SMSService smsService;
 	private final EmailService emailService;
+	private final TemplateService templateService;
 	
 	private final NotificationAuthentication notificationAuthentication;
 	private final CustomerService customerService;
@@ -46,6 +49,7 @@ public class NotificationService {
 	public NotificationService(final CustomerService customerService,
 	                           final SMSService smsService,
 	                           final EmailService emailService,
+	                           final TemplateService templateService,
 	                           final NotificationAuthentication notificationAuthentication,
 	                           final CustomerPermittedClient customerPermittedClient,
 	                           @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger
@@ -54,6 +58,7 @@ public class NotificationService {
 		this.customerService = customerService;
 		this.smsService = smsService;
 		this.emailService = emailService;
+		this.templateService = templateService;
 		this.notificationAuthentication = notificationAuthentication;
 		this.customerPermittedClient = customerPermittedClient;
 		this.logger = logger;
@@ -65,25 +70,26 @@ public class NotificationService {
 		return customerService.findCustomer(customerIdentifier);
 	}
 	
-	//SMS Related Operations
-	public SMSService setNewSMSService(SMSService smsService, String configurationId){
-		smsService.customConfiguration(configurationId);
-		return smsService;
-	}
-	
 	public String sendSMS(String receiver, String template) {
-		if (!this.smsService.isConfigured) this.smsService.configureSMSGatewayWithActiveConfiguration();
+		if (!this.smsService.isConfigured) this.smsService.configureServiceWithDefaultGateway();
 		return this.smsService.sendSMS(receiver, template);
 	}
 	
-	//Email Related Operations
-	public String sendEmail(String from, String to, String subject, String message) {
-		if (!emailService.isConfigured) emailService.configureEmailGatewayWithActiveConfiguration();
-		return this.emailService.sendEmail(from, to, subject, message);
+	/*To be used as a backup should Formatted email fail*/
+	public void sendEmail(String to, String templateIdentifier,Object payload) {
+		Template template = this.templateService.findTemplateWithIdentifier(templateIdentifier).get();
+		if (!this.emailService.isConfigured) {
+			this.emailService.setNewConfiguration(template.getSenderEmail());
+		}
+		this.emailService.sendPlainEmail(to, template.getSubject(), template.getMessage());
 	}
 	
-	public EmailService setNewEmailService(EmailService emailService, String configurationId){
-		emailService.customConfiguration(configurationId);
-		return emailService;
+	public void sendFormattedEmail(String to, String templateIdentifier, Map<String,Object> variables) {
+		Template template = this.templateService.findTemplateWithIdentifier(templateIdentifier).get();
+		if (!this.emailService.isConfigured) {
+			this.emailService.setNewConfiguration(template.getSenderEmail());
+		}
+		
+		this.emailService.sendFormattedEmail(to, template.getSubject(), variables,template.getUrl());
 	}
 }
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 f618d1a..966aee3 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
@@ -34,11 +34,9 @@ import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewa
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import java.util.List;
 import java.util.Optional;
 
@@ -63,15 +61,15 @@ public class SMSService {
 	
 	//@PostConstruct
 	public void init() {
-		if (findActiveSMSConfigurationEntity().isPresent()){
-			configureSMSGatewayWithActiveConfiguration();
+		if (getDefaultSMSConfiguration().isPresent()){
+			configureServiceWithDefaultGateway();
 		}else{
 			//Todo: Send an alert on the interface to configure the service
 		}
 	}
 	
-	public boolean configureSMSGatewayWithActiveConfiguration() {
-		SMSConfiguration configuration = findActiveSMSConfigurationEntity().get();
+	public boolean configureServiceWithDefaultGateway() {
+		SMSConfiguration configuration = getDefaultSMSConfiguration().get();
 		this.accountSid = configuration.getAccount_sid();
 		this.authToken = configuration.getAuth_token();
 		this.senderNumber = configuration.getSender_number();
@@ -86,8 +84,8 @@ public class SMSService {
 		return this.isConfigured = true;
 	}
 	
-	public Optional<SMSConfiguration> findActiveSMSConfigurationEntity() {
-		return this.smsGatewayConfigurationRepository.active().map(SMSConfigurationMapper::map);
+	public Optional<SMSConfiguration> getDefaultSMSConfiguration() {
+		return this.smsGatewayConfigurationRepository.defaultGateway().map(SMSConfigurationMapper::map);
 	}
 	
 	public Boolean smsConfigurationExists(final String identifier) {
@@ -98,7 +96,7 @@ public class SMSService {
 		return this.smsGatewayConfigurationRepository.findByIdentifier(identifier).map(SMSConfigurationMapper::map);
 	}
 	
-	public List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
+	public List<SMSConfiguration> findAllSMSConfigurationEntities() {
 		return SMSConfigurationMapper.map(this.smsGatewayConfigurationRepository.findAll());
 	}
 	
@@ -114,4 +112,4 @@ public class SMSService {
 		Message message = messageCreator.create();
 		return message.getTo().concat(" - " + message.getSid());
 	}
-}
\ No newline at end of file
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/TemplateService.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/TemplateService.java
new file mode 100644
index 0000000..055403b
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/TemplateService.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import org.apache.fineract.cn.command.annotation.Aggregate;
+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.mapper.TemplateMapper;
+import org.apache.fineract.cn.notification.service.internal.repository.TemplateRepository;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+@Aggregate
+public class TemplateService {
+	
+	
+	private final TemplateRepository templateRepository;
+	private Logger logger;
+	
+	@Autowired
+	public TemplateService(final TemplateRepository templateRepository,
+	                       @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
+		super();
+		this.logger = logger;
+		this.templateRepository = templateRepository;
+	}
+	public Optional<Template> findTemplateWithIdentifier(final String identifier) {
+		return this.templateRepository.findByTemplateIdentifier(identifier).map(TemplateMapper::map);
+	}
+	
+	public Boolean templateExists(final String identifier) {
+		return this.templateRepository.existsByTemplateIdentifier(identifier);
+	}
+	
+	public Boolean deleteTemplate(final String identifier) {
+		//Todo: Remove html template and template record from repository
+		return false;
+	}
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/util/MailBuilder.java
similarity index 50%
copy from component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/util/MailBuilder.java
index ad4208a..e12c87f 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestSuite.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/util/MailBuilder.java
@@ -16,17 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification;
+package org.apache.fineract.cn.notification.service.internal.service.util;
 
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
 
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-		TestEmailService.class,
-		TestSMSService.class,
-		EmailApiDocumentation.class,
-		SmsApiDocumentation.class,
-})
-public class TestSuite extends SuiteTestEnvironment {
+import java.util.Map;
+/*
+ebenezergraham created on 5/12/19
+*/
+@Service
+public class MailBuilder {
+		private TemplateEngine templateEngine;
+		
+		@Autowired
+		public MailBuilder(TemplateEngine templateEngine) {
+			this.templateEngine = templateEngine;
+		}
+		
+		public String build(Map<String, Object> message, String template) {
+			Context context = new Context();
+			for(Map.Entry m:message.entrySet()){
+				context.setVariable(m.getKey().toString(), m.getValue().toString());
+			}
+			return templateEngine.process(template, context);
+		}
 }
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 ce5325e..96524e4 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
@@ -84,13 +84,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Account created",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been created" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+						    "customerCreatedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -118,13 +115,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Account updated",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Updated" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+						    "customerUpdatedEvents",
+						    payload);
 			    }
 		    });
 	    }
@@ -150,13 +144,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Account activated",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Activated" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+						    "customerActivatedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -182,12 +173,9 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
-						    emailAddress, "Account locked",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Locked" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+				    notificationService.sendEmail(
+						    emailAddress, "customerLockedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -213,13 +201,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Account created",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Unlocked" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+						    "customerUnlockedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -245,12 +230,9 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
-						    emailAddress, "Account closed",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been Closed" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+				    notificationService.sendEmail(
+						    emailAddress, "customerClosedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -276,13 +258,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Account Reopened",
-						    "Dear Valued Customer," +
-								    "\n\nYour account has been reopened" +
-								    "\n\nBest Regards," +
-								    "\nYour MFI");
+						    "customerReopenedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -309,14 +288,10 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Contact Details Changed",
-						    "Dear Valued Customer," +
-								    "\n\nYour contact has been changed successfully" +
-								    "\n\tNew Contact: "+emailAddress+
-								    "\n\nBest Regards" +
-								    "\nYour MFI");
+						    "contactDetailsChangedEvent",
+						    payload);
 			    }
 		    });
 	    }
@@ -347,19 +322,11 @@
 				    String emailAddress = contact.getValue();
 				    // TODO: Localize message
 				    // TODO: Pass message to template
-				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+				    notificationService.sendEmail(
 						    emailAddress,
-						    "Contact Details Changed" +
-								    "New Contact: "+emailAddress,
-						    "Dear Valued Customer," +
-								    "\n\nYour address has been changed successfully" +
-								    "\nStreet: "+ customer.getAddress().getStreet() +
-								    "\nCity: "+ customer.getAddress().getCity() +
-								    "\nState: "+ customer.getAddress().getRegion() +
-								    "\nCountry: "+ customer.getAddress().getCountry() +
-								    "\n\nBest Regards" +
-								    "\nYour MFI");
+						    "addressChangedEvent",
+						    payload);
 			    }
 		    });
 	    }
-    }
\ No newline at end of file
+    }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
index 2823b6d..d1859a2 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
@@ -24,11 +24,9 @@ import org.apache.fineract.cn.command.gateway.CommandGateway;
 import org.apache.fineract.cn.lang.ServiceException;
 import org.apache.fineract.cn.notification.api.v1.PermittableGroupIds;
 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.service.ServiceConstants;
 import org.apache.fineract.cn.notification.service.internal.command.*;
 import org.apache.fineract.cn.notification.service.internal.service.EmailService;
-import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -95,7 +93,7 @@ public class EmailServiceRestController {
 	public
 	@ResponseBody
 	List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
-		return this.emailService.findAllActiveEmailConfigurationEntities();
+		return this.emailService.findAllEmailConfigurationEntities();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
index b9a6e83..26106bc 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
@@ -24,10 +24,8 @@ import org.apache.fineract.cn.command.gateway.CommandGateway;
 import org.apache.fineract.cn.lang.ServiceException;
 import org.apache.fineract.cn.notification.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
-import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
 import org.apache.fineract.cn.notification.service.internal.command.*;
-import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
 import org.apache.fineract.cn.notification.service.internal.service.SMSService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -69,7 +67,7 @@ public class SMSServiceRestController {
 	public
 	@ResponseBody
 	List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return this.smsService.findAllActiveSMSConfigurationEntities();
+		return this.smsService.findAllSMSConfigurationEntities();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/TemplateRestController.java
similarity index 63%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/rest/TemplateRestController.java
index b9a6e83..aed08f2 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/TemplateRestController.java
@@ -24,11 +24,14 @@ import org.apache.fineract.cn.command.gateway.CommandGateway;
 import org.apache.fineract.cn.lang.ServiceException;
 import org.apache.fineract.cn.notification.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
-import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
+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.command.*;
-import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
+import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.CreateTemplateCommand;
+import org.apache.fineract.cn.notification.service.internal.command.DeleteSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.UpdateSMSConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.service.SMSService;
+import org.apache.fineract.cn.notification.service.internal.service.TemplateService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -42,34 +45,21 @@ import java.util.List;
 
 @SuppressWarnings("unused")
 @RestController
-@RequestMapping("/configuration/sms/")
-public class SMSServiceRestController {
+@RequestMapping("/template")
+public class TemplateRestController {
 	
 	private final Logger logger;
 	private final CommandGateway commandGateway;
-	private final SMSService smsService;
+	private final TemplateService templateService;
 	
 	@Autowired
-	public SMSServiceRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
-	                                final CommandGateway commandGateway,
-	                                final SMSService smsService) {
+	public TemplateRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+	                              final CommandGateway commandGateway,
+	                              final TemplateService templateService) {
 		super();
 		this.logger = logger;
 		this.commandGateway = commandGateway;
-		this.smsService = smsService;
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/active",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return this.smsService.findAllActiveSMSConfigurationEntities();
+		this.templateService = templateService;
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
@@ -81,10 +71,10 @@ public class SMSServiceRestController {
 	)
 	public
 	@ResponseBody
-	ResponseEntity<SMSConfiguration> findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier) {
-		return this.smsService.findSMSConfigurationByIdentifier(identifier)
+	ResponseEntity<Template> findTemplateByIdentifier(@PathVariable("identifier") final String identifier) {
+		return this.templateService.findTemplateWithIdentifier(identifier)
 				.map(ResponseEntity::ok)
-				.orElseThrow(() -> ServiceException.notFound("SMS Gateway Configuration with identifier " + identifier + " doesn't exist."));
+				.orElseThrow(() -> ServiceException.notFound("Template with identifier " + identifier + " doesn't exist."));
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
@@ -96,12 +86,12 @@ public class SMSServiceRestController {
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> createSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) throws InterruptedException {
-		if (this.smsService.smsConfigurationExists(smsConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", smsConfiguration.getIdentifier());
+	ResponseEntity<Void> createTemplate(@RequestBody @Valid final Template template) throws InterruptedException {
+		if (this.templateService.templateExists(template.getTemplateIdentifier())) {
+			throw ServiceException.conflict("Template {0} already exists.", template.getTemplateIdentifier());
 		}
 		
-		this.commandGateway.process(new CreateSMSConfigurationCommand(smsConfiguration));
+		this.commandGateway.process(new CreateTemplateCommand(template));
 		return new ResponseEntity<>(HttpStatus.CREATED);
 	}
 	
@@ -113,8 +103,8 @@ public class SMSServiceRestController {
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> updateSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) {
-		this.commandGateway.process(new UpdateSMSConfigurationCommand(smsConfiguration));
+	ResponseEntity<Void> updateTemplate(@RequestBody @Valid final Template template) {
+		this.commandGateway.process(template);
 		return ResponseEntity.accepted().build();
 	}
 	
@@ -126,8 +116,8 @@ public class SMSServiceRestController {
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> deleteSMSConfiguration(@PathVariable @Valid final String identifier) {
-		this.commandGateway.process(new DeleteSMSConfigurationCommand(identifier));
+	ResponseEntity<Void> deleteTemplate(@PathVariable @Valid final String identifier) {
+		this.commandGateway.process(identifier);
 		return ResponseEntity.ok().build();
 	}
 }
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index d1c0460..23054cf 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -85,3 +85,7 @@ flyway:
 notification:
   user: operator
   password: init1@l
+
+activemq:
+  brokerUrl: vm://localhost?broker.persistent=false
+  concurrency: 1-1
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
index 9e1aba3..19f43bd 100644
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -33,7 +33,7 @@ CREATE TABLE wada_sms_gateway_configurations (
 -- Table wada_email_gateway_configurations
 -- -----------------------------------------------------
 CREATE TABLE wada_email_gateway_configurations (
-  id INT(11) NOT NULL AUTO_INCREMENT,
+  id INT NOT NULL AUTO_INCREMENT,
   identifier VARCHAR(45) NULL DEFAULT NULL,
   host VARCHAR(45) NOT NULL,
   port VARCHAR(45) NOT NULL,
@@ -49,22 +49,14 @@ CREATE TABLE wada_email_gateway_configurations (
 -- Table wada_templates
 -- -----------------------------------------------------
 CREATE TABLE wada_templates (
-  id INT(11) NOT NULL AUTO_INCREMENT,
-  identifier VARCHAR(45) NULL DEFAULT NULL,
-  event VARCHAR(45) NULL DEFAULT NULL,
+  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));
 
--- -----------------------------------------------------
--- Table wada_data_source_application
--- -----------------------------------------------------
-  CREATE TABLE wada_data_source_application (
-  id BIGINT NOT NULL AUTO_INCREMENT,
-  tenant_identifier        VARCHAR(32) NOT NULL,
-  application_identifier   VARCHAR(32) NOT NULL,
-  permittable_identifier   VARCHAR(32) NOT NULL,
-  PRIMARY KEY (id)
-);
 
-INSERT INTO wada_sms_gateway_configurations VALUES ('1', 'Twilio', 'ACdc00866577a42133e16d98456ad15592', '0b2f78b1c083eb71599d014d1af5748e', '+12055486680', 'ACTIVE');
-INSERT INTO wada_email_gateway_configurations VALUES ('1', 'Gmail', 'smtp.gmail.com', '587','fineractcnnotificationdemo@gmail.com', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE');
+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');
diff --git a/service/src/main/resources/templatedetails/templates.csv b/service/src/main/resources/templatedetails/templates.csv
new file mode 100644
index 0000000..ddc76ef
--- /dev/null
+++ b/service/src/main/resources/templatedetails/templates.csv
@@ -0,0 +1,28 @@
+-
+- 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.
+-
+template_identifier,sender_email,subject,message,url
+customerCreatedEvent,DEFAULT,Account created,"Your account has been created",template
+customerUpdatedEvents,DEFAULT,Account updated,Your account has been Updated,template
+customerActivatedEvent,DEFAULT,Account Activated,Your account has been Activated,template
+customerLockedEvent,DEFAULT,Account Locked,Your account has been Locked,template
+customerUnlockedEvent,DEFAULT,Account unlocked,Your account has been Unlocked,template
+customerClosedEvent,DEFAULT,Account closed successfully,Your account has been Closed,template
+customerReopenedEvent,DEFAULT,Account Reopened,Your account has been reopened,template
+contactDetailsChangedEvent,DEFAULT,Contact details has been updated,Your contact has been changed successfully,template
+addressChangedEvent,DEFAULT,Residence address has been changed,Your address has been changed successfully,template
diff --git a/service/src/main/resources/templates/template.html b/service/src/main/resources/templates/template.html
new file mode 100644
index 0000000..d6a4d1c
--- /dev/null
+++ b/service/src/main/resources/templates/template.html
@@ -0,0 +1,457 @@
+<!--
+ 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.
+-->
+
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:th="http://www.thymeleaf.org">
+<head>
+	<meta name="viewport" content="width=device-width"/>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+	<title>Simple Email</title>
+	<link href="https://fonts.googleapis.com/css?family=helvatica" rel="stylesheet"/>
+	<style>
+		/* -------------------------------------
+				GLOBAL RESETS
+		------------------------------------- */
+
+		/*All the styling goes here*/
+
+		img {
+			border: none;
+			-ms-interpolation-mode: bicubic;
+			max-width: 100%;
+		}
+
+		body {
+			background-color: #f6f6f6;
+			font-family: sans-serif;
+			-webkit-font-smoothing: antialiased;
+			font-size: 14px;
+			line-height: 1.4;
+			margin: 0;
+			padding: 0;
+			-ms-text-size-adjust: 100%;
+			-webkit-text-size-adjust: 100%;
+		}
+
+		table {
+			border-collapse: separate;
+			mso-table-lspace: 0pt;
+			mso-table-rspace: 0pt;
+			width: 100%;
+		}
+
+		table td {
+			font-family: sans-serif;
+			font-size: 14px;
+			vertical-align: top;
+		}
+
+		/* -------------------------------------
+				CONTAINER
+		------------------------------------- */
+
+		.body {
+			background-color: #f6f6f6;
+			width: 100%;
+		}
+
+		/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
+		.container {
+			display: block;
+			margin: 0 auto !important;
+			/* makes it centered */
+			max-width: 580px;
+			padding: 10px;
+			width: 580px;
+		}
+
+		/* This should also be a block element, so that it will fill 100% of the .container */
+		.content {
+			box-sizing: border-box;
+			display: block;
+			margin: 0 auto;
+			max-width: 580px;
+			padding: 10px;
+		}
+
+		/* -------------------------------------
+				HEADER, FOOTER, MAIN
+		------------------------------------- */
+		.main {
+			background: #ffffff;
+			border-radius: 3px;
+			width: 100%;
+		}
+
+		.wrapper {
+			box-sizing: border-box;
+			padding: 20px;
+		}
+
+		.content-block {
+			padding-bottom: 10px;
+			padding-top: 10px;
+		}
+
+		.footer {
+			clear: both;
+			margin-top: 10px;
+			text-align: center;
+			width: 100%;
+		}
+
+		.footer td,
+		.footer p,
+		.footer span,
+		.footer a {
+			color: #999999;
+			font-size: 12px;
+			text-align: center;
+		}
+
+		/* -------------------------------------
+				TYPOGRAPHY
+		------------------------------------- */
+		h1,
+		h2,
+		h3,
+		h4 {
+			color: #000000;
+			font-family: sans-serif;
+			font-weight: 400;
+			line-height: 1.4;
+			margin: 0;
+			margin-bottom: 30px;
+		}
+
+		h1 {
+			font-size: 35px;
+			font-weight: 300;
+			text-align: center;
+			text-transform: capitalize;
+		}
+
+		p,
+		ul,
+		ol {
+			font-family: sans-serif;
+			font-size: 14px;
+			font-weight: normal;
+			margin: 0;
+			margin-bottom: 15px;
+		}
+
+		p li,
+		ul li,
+		ol li {
+			list-style-position: inside;
+			margin-left: 5px;
+		}
+
+		a {
+			color: #a92334;
+			text-decoration: underline;
+		}
+
+		/* -------------------------------------
+				BUTTONS
+		------------------------------------- */
+		.btn {
+			box-sizing: border-box;
+			width: 100%;
+		}
+
+		.btn > tbody > tr > td {
+			padding-bottom: 15px;
+		}
+
+		.btn table {
+			width: auto;
+		}
+
+		.btn table td {
+			background-color: #ffffff;
+			border-radius: 5px;
+			text-align: center;
+		}
+
+		.btn a {
+			background-color: #ffffff;
+			border: solid 1px #a92334;
+			border-radius: 5px;
+			box-sizing: border-box;
+			color: #a92334;
+			cursor: pointer;
+			display: inline-block;
+			font-size: 14px;
+			font-weight: bold;
+			margin: 0;
+			padding: 12px 25px;
+			text-decoration: none;
+			text-transform: capitalize;
+		}
+
+		.btn-primary table td {
+			background-color: #a92334;
+		}
+
+		.btn-primary a {
+			background-color: #a92334;
+			border-color: #a92334;
+			color: #ffffff;
+		}
+
+		/* -------------------------------------
+				OTHER STYLES THAT MIGHT BE USEFUL
+		------------------------------------- */
+		.last {
+			margin-bottom: 0;
+		}
+
+		.first {
+			margin-top: 0;
+		}
+
+		.align-center {
+			text-align: center;
+		}
+
+		.align-right {
+			text-align: right;
+		}
+
+		.align-left {
+			text-align: left;
+		}
+
+		.clear {
+			clear: both;
+		}
+
+		.mt0 {
+			margin-top: 0;
+		}
+
+		.mb0 {
+			margin-bottom: 0;
+		}
+
+		.preheader {
+			color: transparent;
+			display: none;
+			height: 0;
+			max-height: 0;
+			max-width: 0;
+			opacity: 0;
+			overflow: hidden;
+			mso-hide: all;
+			visibility: hidden;
+			width: 0;
+		}
+
+		.powered-by a {
+			text-decoration: none;
+		}
+
+		hr {
+			border: 0;
+			border-bottom: 1px solid #f6f6f6;
+			margin: 20px 0;
+		}
+
+		/* -------------------------------------
+				RESPONSIVE AND MOBILE FRIENDLY STYLES
+		------------------------------------- */
+		@media only screen and (max-width: 620px) {
+			table[class=body] h1 {
+				font-size: 28px !important;
+				margin-bottom: 10px !important;
+			}
+
+			table[class=body] p,
+			table[class=body] ul,
+			table[class=body] ol,
+			table[class=body] td,
+			table[class=body] span,
+			table[class=body] a {
+				font-size: 16px !important;
+			}
+
+			table[class=body] .wrapper,
+			table[class=body] .article {
+				padding: 10px !important;
+			}
+
+			table[class=body] .content {
+				padding: 0 !important;
+			}
+
+			table[class=body] .container {
+				padding: 0 !important;
+				width: 100% !important;
+			}
+
+			table[class=body] .main {
+				border-left-width: 0 !important;
+				border-radius: 0 !important;
+				border-right-width: 0 !important;
+			}
+
+			table[class=body] .btn table {
+				width: 100% !important;
+			}
+
+			table[class=body] .btn a {
+				width: 100% !important;
+			}
+
+			table[class=body] .img-responsive {
+				height: auto !important;
+				max-width: 100% !important;
+				width: auto !important;
+			}
+		}
+
+		/* -------------------------------------
+				PRESERVE THESE STYLES IN THE HEAD
+		------------------------------------- */
+		@media all {
+			.headTab{
+				height: 60px;
+				width: auto;
+				max-width: 540px;
+				padding: 10px;
+				margin: 0 auto;
+				background-color: #ffffff;
+				/*-webkit-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);
+				-moz-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);
+				box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);*/
+			}
+			.ExternalClass {
+				width: 100%;
+			}
+
+			.ExternalClass,
+			.ExternalClass p,
+			.ExternalClass span,
+			.ExternalClass font,
+			.ExternalClass td,
+			.ExternalClass div {
+				line-height: 100%;
+			}
+
+			.apple-link a {
+				color: inherit !important;
+				font-family: inherit !important;
+				font-size: inherit !important;
+				font-weight: inherit !important;
+				line-height: inherit !important;
+				text-decoration: none !important;
+			}
+
+			.btn-primary table td:hover {
+				background-color: #a92334 !important;
+			}
+
+			.btn-primary a:hover {
+				background-color: #a92334 !important;
+				border-color: #a92334 !important;
+			}
+		}
+
+	</style>
+</head>
+<body>
+<span class="preheader">Header Message</span>
+<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
+
+	<tr>
+		<td>&nbsp;</td>
+
+		<td class="container">
+			<div class="headTab"><img style="height:40px; margin:10px;" class="img-responsive" src="http://fineract.apache.org/images/apache-fineract-logo.png" alt="Logo"></div>
+
+			<div class="content">
+
+				<!-- START CENTERED WHITE CONTAINER -->
+				<table role="presentation" class="main">
+
+					<!-- START MAIN CONTENT AREA -->
+					<tr>
+						<td class="wrapper">
+							<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+								<tr>
+									<td>
+										<p>Dear Valued Customer,</p>
+
+										<p>This is a sample message an account update</p>
+										<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
+											<tbody>
+											<tr>
+												<td align="left">
+													<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+														<tbody>
+														<tr>
+															<td> <a href="http://fineract.apache.org" target="_blank">Call To Action</a> </td>
+														</tr>
+														</tbody>
+													</table>
+												</td>
+											</tr>
+											</tbody>
+										</table>
+										<p>No reply required. This is a computer generated mail.</p>
+										<p>Best Regards,</p>
+										<p>MFI</p>
+									</td>
+								</tr>
+							</table>
+						</td>
+					</tr>
+
+					<!-- END MAIN CONTENT AREA -->
+				</table>
+				<!-- END CENTERED WHITE CONTAINER -->
+
+				<!-- START FOOTER -->
+				<div class="footer">
+					<table role="presentation" border="0" cellpadding="0" cellspacing="0">
+						<tr>
+							<td class="content-block">
+								<span class="apple-link">Apache Software Foundation, Forest Hill, Maryland, United States</span>
+								<p> Don't like these emails? <a href="">Unsubscribe</a>.</p>
+							</td>
+						</tr>
+						<tr>
+							<td class="content-block powered-by">
+								Powered by <a href="http://fineract.apache.org">Apache Fineract</a>.
+							</td>
+						</tr>
+					</table>
+				</div>
+				<!-- END FOOTER -->
+
+			</div>
+		</td>
+		<td>&nbsp;</td>
+	</tr>
+</table>
+</body>
+</html>
diff --git a/shared.gradle b/shared.gradle
index c270323..7ecfdc6 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -39,7 +39,9 @@ ext.versions = [
         validator                       : '5.3.0.Final',
         springjavamail                  : '1.4.1.RELEASE',
         twilioapi                       : '7.17.+',
-        junit                           : '4.12'
+        junit                           : '4.12',
+        apachecsvreader                 : '1.4'
+    
 ]
 
 apply plugin: 'java'