You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by aw...@apache.org on 2019/06/06 07:10:11 UTC

[fineract-cn-notifications] 20/36: Refactored the authentication process to use permitted-feign-client

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

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

commit 6b136f4b0d7d2af8b5514dcdd919e7cd780137b2
Author: Ebenezer Graham <eg...@alustudent.com>
AuthorDate: Thu Mar 7 12:00:30 2019 +0400

    Refactored the authentication process to use permitted-feign-client
    
    Component test updates
    Added Asciidoctor API decumentation
    Refactored Tests
    
    Refactored the Rest Controller and Notification Services
    
    update
    
    
    u
    
    
    oo
    
    
    updated API documentation and authentication
    
    update
    
    Notification Properties
    
    Debugged auth
    
    Debugged auth
    
    update
    
     udpate
    
    udpate
    
    Testing auth
---
 .gitignore                                         |  16 +-
 .../notification/api/v1/PermittableGroupIds.class  | Bin 261 -> 0 bytes
 .../api/v1/client/NotificationManager.class        | Bin 1940 -> 0 bytes
 .../api/v1/domain/EmailConfiguration.class         | Bin 4391 -> 0 bytes
 .../api/v1/domain/SMSConfiguration.class           | Bin 3305 -> 0 bytes
 .../api/v1/events/NotificationEventConstants.class | Bin 1609 -> 0 bytes
 .../notification/api/v1/PermittableGroupIds.java   |   5 +
 .../v1/client/ConfigurationNotFoundException.java  |   8 +-
 .../api/v1/client/NotificationManager.java         |  51 +++-
 .../api/v1/domain/EmailConfiguration.java          |   4 +-
 .../api/v1/domain/SMSConfiguration.java            |   2 +-
 .../api/v1/events/NotificationEventConstants.java  |  22 +-
 component-test/build.gradle                        |  16 ++
 .../notification/NotificationApiDocumentation.java | 289 +++++++++++++++++++++
 .../cn/notification/SuiteTestEnvironment.java      |   2 +
 .../TestApplicationAuthentication.java             |  48 ++++
 .../fineract/cn/notification/TestEmailService.java |  65 +++--
 .../fineract/cn/notification/TestNotification.java |  18 +-
 .../fineract/cn/notification/TestSMSService.java   |  69 +++--
 .../apache/fineract/cn/notification/TestSuite.java |   2 +
 .../listener/NotificationEventListener.java        |  60 -----
 .../notification/util/DomainObjectGenerator.java   |  18 +-
 gradle/wrapper/gradle-wrapper.jar                  | Bin 54212 -> 54212 bytes
 gradle/wrapper/gradle-wrapper.properties           |   2 +-
 local.properties                                   |   9 +
 service/build.gradle                               |   1 +
 service/out/production/resources/application.yml   |  88 -------
 service/out/production/resources/bootstrap.yml     |  22 --
 .../db/migrations/mariadb/V1__initial_setup.sql    |  56 ----
 .../service/NotificationApplication.java           |   1 +
 .../cn/notification/service/ServiceConstants.java  |  11 +
 ...SCommand.java => DeleteApplicationCommand.java} |  45 ++--
 ...d.java => DeleteEmailConfigurationCommand.java} |  10 +-
 ...and.java => DeleteSMSConfigurationCommand.java} |  10 +-
 ...SMSCommand.java => SaveApplicationCommand.java} |  45 ++--
 ...d.java => UpdateEmailConfigurationCommand.java} |  18 +-
 ...and.java => UpdateSMSConfigurationCommand.java} |  18 +-
 ...gregate.java => ApplicationCommandHandler.java} |  42 ++-
 ....java => EmailConfigurationCommandHandler.java} |  30 ++-
 ...Aggregate.java => MigrationCommandHandler.java} |  10 +-
 ...te.java => SMSConfigurationCommandHandler.java} |  26 +-
 .../config}/NotificationConfiguration.java         |  18 +-
 .../internal/config/NotificationProperties.java    |  60 +++++
 .../internal/identity/CustomerPermittedClient.java |  46 ++++
 .../identity/NotificationAuthentication.java       |  68 +++++
 .../internal/mapper/EmailConfigurationMapper.java  |   2 +-
 .../internal/repository/ApplicationEntity.java     | 106 ++++++++
 ...nRepository.java => ApplicationRepository.java} |  14 +-
 .../EmailGatewayConfigurationRepository.java       |   5 +
 .../SMSGatewayConfigurationRepository.java         |   5 +
 .../service/internal/service/EmailService.java     | 141 ++++++++--
 .../service/internal/service/EventHelper.java      |  55 ++++
 .../internal/service/NotificationService.java      |  84 ++----
 .../service/internal/service/SMSService.java       |  87 +++++--
 .../CustomerService.java}                          |   6 +-
 .../helperservice/NotificationAuthentication.java  |  60 -----
 .../service/listener/CustomerEventListener.java    |  44 +++-
 .../service/listener/PortfolioEventListener.java   |  76 +++---
 ...roller.java => EmailServiceRestController.java} |  97 +++----
 .../service/rest/NotificationRestController.java   |  94 -------
 ...ntroller.java => SMSServiceRestController.java} | 107 +++-----
 service/src/main/resources/application.yml         |   6 +-
 .../db/migrations/mariadb/V1__initial_setup.sql    |  20 +-
 .../mariadb/V2__sms_gateway_configurations.sql     |  20 --
 .../mariadb/V3__email_gateway_configurations.sql   |  20 --
 shared.gradle                                      |  40 +--
 66 files changed, 1469 insertions(+), 951 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3f7ccae..3349144 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,13 +2,12 @@
 .idea
 build/
 target/
-build/out
-service/out
-component-test/out
-api/out
-service/build
-component-test/build
-api/build
+api/out/
+api/build/
+service/out/
+service/build/
+component-test/out/
+component-test/build/
 
 # Ignore Gradle GUI config
 gradle-app.setting
@@ -22,4 +21,5 @@ gradle-app.setting
 
 *.toDelete
 
-*.class
\ No newline at end of file
+*.class
+
diff --git a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.class b/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.class
deleted file mode 100644
index 7f31257..0000000
Binary files a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.class and /dev/null differ
diff --git a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.class b/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.class
deleted file mode 100644
index fb44545..0000000
Binary files a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.class and /dev/null differ
diff --git a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.class b/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.class
deleted file mode 100644
index 68d087d..0000000
Binary files a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.class and /dev/null differ
diff --git a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.class b/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.class
deleted file mode 100644
index b0e8563..0000000
Binary files a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.class and /dev/null differ
diff --git a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.class b/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.class
deleted file mode 100644
index 0600369..0000000
Binary files a/api/out/production/classes/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.class and /dev/null differ
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.java
index a5c9de2..ac7350a 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/PermittableGroupIds.java
@@ -21,4 +21,9 @@ package org.apache.fineract.cn.notification.api.v1;
 @SuppressWarnings("unused")
 public interface PermittableGroupIds {
 	String SELF_MANAGEMENT = "notification__v1__self";
+	
+	static String forApplication(final String serviceName) {
+		return serviceName.replace("-", "__") + "__customer";
+	}
+	static String customerGroupEndPoint = "notification__v1__customer__v1";
 }
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationNotFoundException.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationNotFoundException.java
index 4f5d185..66b2a80 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationNotFoundException.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/ConfigurationNotFoundException.java
@@ -18,11 +18,5 @@
  */
 package org.apache.fineract.cn.notification.api.v1.client;
 
-import org.apache.fineract.cn.api.util.NotFoundException;
-
-public final class ConfigurationNotFoundException extends NotFoundException {
-	
-	public ConfigurationNotFoundException(String reason) {
-		super(reason);
-	}
+public final class ConfigurationNotFoundException 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 b169cfd..8b6c76c 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
@@ -18,10 +18,13 @@
  */
 package org.apache.fineract.cn.notification.api.v1.client;
 
+import org.apache.fineract.cn.api.annotation.ThrowsException;
+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.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -32,37 +35,40 @@ import org.springframework.web.bind.annotation.RequestMethod;
 public interface NotificationManager {
 	
 	@RequestMapping(
-			value = "/notification/sms/active",
+			value = "/configuration/sms/active",
 			method = RequestMethod.GET,
 			produces = MediaType.ALL_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE)
 	SMSConfiguration findAllActiveSMSConfigurationEntities();
 	
 	@RequestMapping(
-			value = "/notification/email/active",
+			value = "/configuration/email/active",
 			method = RequestMethod.GET,
 			produces = MediaType.ALL_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE)
 	EmailConfiguration findAllActiveEmailConfigurationEntities();
 	
 	@RequestMapping(
-			value = "/notification/sms/create",
+			value = "/configuration/sms/create",
 			method = RequestMethod.POST,
 			produces = MediaType.APPLICATION_JSON_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE
 	)
-	void createSMSConfiguration(final SMSConfiguration smsConfiguration);
+	@ThrowsExceptions({
+			@ThrowsException(status = HttpStatus.NOT_FOUND, exception = ConfigurationNotFoundException.class)
+	})
+	String createSMSConfiguration(final SMSConfiguration smsConfiguration);
 	
 	@RequestMapping(
-			value = "/notification/email/create",
+			value = "/configuration/email/create",
 			method = RequestMethod.POST,
 			produces = MediaType.APPLICATION_JSON_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE
 	)
-	void createEmailConfiguration(final EmailConfiguration emailConfiguration);
+	String createEmailConfiguration(final EmailConfiguration emailConfiguration);
 	
 	@RequestMapping(
-			value = "/notification/sms/{identifier}",
+			value = "/configuration/sms/{identifier}",
 			method = RequestMethod.GET,
 			produces = MediaType.APPLICATION_JSON_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE
@@ -70,10 +76,39 @@ public interface NotificationManager {
 	SMSConfiguration findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier);
 	
 	@RequestMapping(
-			value = "/notification/email/{identifier}",
+			value = "/configuration/email/{identifier}",
 			method = RequestMethod.GET,
 			produces = MediaType.APPLICATION_JSON_VALUE,
 			consumes = MediaType.APPLICATION_JSON_VALUE
 	)
 	EmailConfiguration findEmailConfigurationByIdentifier(@PathVariable("identifier") final String identifier);
+	
+	@RequestMapping(value = "/configuration/sms/update",
+			method = RequestMethod.PUT,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
+			produces = MediaType.APPLICATION_JSON_VALUE
+	)
+	void updateSMSConfiguration(final SMSConfiguration smsConfiguration);
+	
+	@RequestMapping(value = "/configuration/email/update",
+			method = RequestMethod.PUT,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
+			produces = MediaType.APPLICATION_JSON_VALUE
+	)
+	void updateEmailConfiguration(final EmailConfiguration emailConfiguration);
+	
+	@RequestMapping(value = "/configuration/sms/delete/{identifier}",
+			method = RequestMethod.DELETE,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
+			produces = MediaType.APPLICATION_JSON_VALUE
+	)
+	void deleteSMSConfiguration(@PathVariable("identifier") final String identifier);
+	
+	@RequestMapping(value = "/configuration/email/delete/{identifier}",
+			method = RequestMethod.DELETE,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
+			produces = MediaType.APPLICATION_JSON_VALUE
+	)
+	void deleteEmailConfiguration(@PathVariable("identifier") final String identifier);
+	
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.java
index 6b95afd..5809c31 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/EmailConfiguration.java
@@ -26,7 +26,7 @@ import java.util.Objects;
 @SuppressWarnings({"WeakerAccess", "unused"})
 public class EmailConfiguration {
 	@ValidIdentifier
-	@Length(max = 11)
+	@Length(max = 45)
 	private String identifier;
 	@Length(max = 45)
 	private String host;
@@ -42,7 +42,7 @@ public class EmailConfiguration {
 	private String smtp_auth;
 	@Length(max = 45)
 	private String start_tls;
-	@Length(max = 45)
+	@Length(max = 10)
 	private String state;
 	
 	public EmailConfiguration() {
diff --git a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.java b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.java
index dd76852..6143d30 100644
--- a/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.java
+++ b/api/src/main/java/org/apache/fineract/cn/notification/api/v1/domain/SMSConfiguration.java
@@ -34,7 +34,7 @@ public class SMSConfiguration {
 	private String account_sid;
 	@Length(max = 45)
 	private String sender_number;
-	@Length(max = 45)
+	@Length(max = 20)
 	private String state;
 	
 	public SMSConfiguration() {
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 f4d1be1..b6855b1 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,8 +27,15 @@ public interface NotificationEventConstants {
 	
 	String POST_SMS_CONFIGURATION = "post-sms-configuration";
 	String POST_EMAIL_CONFIGURATION = "post-email-configuration";
-	String POST_SMS_NOTIFICATION = "post-sms-notification";
-	String POST_EMAIL_NOTIFICATION = "post-email-notification";
+	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_SOURCE_APPLICATION = "delete-source-application";
+	
+	String POST_SEND_EMAIL_NOTIFICATION = "post-send-email-notification";
+	String POST_SEND_SMS_NOTIFICATION = "post-send-sms-notification";
 	
 	String POST_ENABLE_CUSTOMER_CREATED_EVENT = "post-enable-customer-created-event";
 	String POST_ENABLE_CUSTOMER_UPDATED_EVENT = "post-enable-customer-updated-event";
@@ -40,6 +47,13 @@ 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_SMS_NOTIFICATION = SELECTOR_NAME + " = '" + POST_SMS_NOTIFICATION + "'";
-	String SELECTOR_POST_EMAIL_NOTIFICATION = SELECTOR_NAME + " = '" + POST_EMAIL_NOTIFICATION + "'";
+	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 + "'";
+	String SELECTOR_DELETE_EMAIL_CONFIGURATION = SELECTOR_NAME + " = '" + DELETE_EMAIL_CONFIGURATION + "'";
+	String SELECTOR_POST_SOURCE_APPLICATION = SELECTOR_NAME + " = '" + POST_SOURCE_APPLICATION + "'";
+	String SELECTOR_DELETE_SOURCE_APPLICATION = SELECTOR_NAME + " = '" + DELETE_SOURCE_APPLICATION + "'";
+	
+	String SELECTOR_POST_SEND_EMAIL_NOTIFICATION = SELECTOR_NAME + " = '" + POST_SEND_EMAIL_NOTIFICATION + "'";
+	String SELECTOR_POST_SEND_SMS_NOTIFICATION = SELECTOR_NAME + " = '" + POST_SEND_SMS_NOTIFICATION + "'";
 }
diff --git a/component-test/build.gradle b/component-test/build.gradle
index 2e29cf4..931282e 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -18,6 +18,7 @@
 buildscript {
     ext {
         springBootVersion = '1.4.1.RELEASE'
+        asciidoctorVersion = '1.5.3'
     }
 
     repositories {
@@ -26,6 +27,7 @@ buildscript {
 
     dependencies {
         classpath ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath("org.asciidoctor:asciidoctor-gradle-plugin:${asciidoctorVersion}")
     }
 }
 
@@ -34,6 +36,7 @@ plugins {
     id("org.nosphere.apache.rat") version "0.3.1"
 }
 apply from: '../shared.gradle'
+apply plugin: 'org.asciidoctor.convert'
 
 dependencies {
     compile(
@@ -44,8 +47,17 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
             [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]
     )
 }
+asciidoctor {
+    sourceDir 'build/doc/asciidoc/'
+    outputDir 'build/doc/html5'
+    options backend: "html", doctype: "book"
+    attributes "source-highlighter": "highlightjs",
+            'snippets': file('build/doc/generated-snippets/')
+}
 
 publishing {
     publications {
@@ -54,3 +66,7 @@ publishing {
         }
     }
 }
+
+task generateDocs {
+    dependsOn asciidoctor
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/NotificationApiDocumentation.java b/component-test/src/main/java/org/apache/fineract/cn/notification/NotificationApiDocumentation.java
new file mode 100644
index 0000000..2473159
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/NotificationApiDocumentation.java
@@ -0,0 +1,289 @@
+/*
+ * 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;
+
+import com.google.gson.Gson;
+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.domain.SMSConfiguration;
+import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
+import org.apache.fineract.cn.notification.util.DomainObjectGenerator;
+import org.junit.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
+import static org.springframework.restdocs.payload.PayloadDocumentation.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SuppressWarnings("Unused")
+public class NotificationApiDocumentation extends TestNotification {
+	
+	@Rule
+	public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("build/doc/generated-snippets/test-notification");
+	
+	private final Gson serialize = new Gson();
+	private MockMvc mockMvc;
+	
+	@Autowired
+	NotificationManager notificationManager;
+	@Autowired
+	private WebApplicationContext context;
+	
+	public NotificationApiDocumentation() {
+		super();
+	}
+	
+	@Before
+	public void setUp() {
+		this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+				.apply(documentationConfiguration(this.restDocumentation))
+				.alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+				.build();
+	}
+	
+	@Test
+	public void documentCreateSMSConfiguration() throws Exception {
+		final SMSConfiguration randomSMSConfiguration = DomainObjectGenerator.smsConfiguration();
+		
+		this.mockMvc.perform(post("/configuration/sms/create")
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(randomSMSConfiguration)))
+				.andExpect(status().isCreated())
+				.andDo(document("document-create-sms-configuration", preprocessRequest(prettyPrint()),
+						requestFields(
+								fieldWithPath("identifier").description("Configuration Id for SMS Gateway"),
+								fieldWithPath("auth_token").description("SMS API authentication token"),
+								fieldWithPath("account_sid").description("SMS API account SID"),
+								fieldWithPath("sender_number").description("SMS API sender number"),
+								fieldWithPath("state").description("The state of the Gateway" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentCreateEmailConfiguration() throws Exception {
+		final EmailConfiguration randomEmailConfiguration = DomainObjectGenerator.emailConfiguration();
+		
+		this.mockMvc.perform(post("/configuration/email/create")
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(randomEmailConfiguration)))
+				.andExpect(status().isCreated())
+				.andDo(document("document-create-email-configuration", preprocessRequest(prettyPrint()),
+						requestFields(
+								fieldWithPath("identifier").description("Configuration Id for Email Server"),
+								fieldWithPath("host").description("Email Server host address"),
+								fieldWithPath("port").description("Email Server port number"),
+								fieldWithPath("protocol").description("Type of protocol in use " +
+										"\nSMTP" +
+										"\nPOP3" +
+										"\nIMAP"),
+								fieldWithPath("username").description("Email address"),
+								fieldWithPath("app_password").description("Email app password or normal password"),
+								fieldWithPath("smtp_auth").description("Enable SMTP"),
+								fieldWithPath("start_tls").description("Enable TLS"),
+								fieldWithPath("state").description("" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentFindSMSConfiguration() throws Exception {
+		final SMSConfiguration randomSMSConfiguration = DomainObjectGenerator.smsConfiguration();
+		
+		this.notificationManager.createSMSConfiguration(randomSMSConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, randomSMSConfiguration.getIdentifier());
+		
+		notificationManager.findSMSConfigurationByIdentifier(randomSMSConfiguration.getIdentifier());
+		
+		this.mockMvc.perform(get("/configuration/sms/" + randomSMSConfiguration.getIdentifier())
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(randomSMSConfiguration.getIdentifier())))
+				.andExpect(status().isOk())
+				.andDo(document("document-find-sms-configuration", preprocessRequest(prettyPrint()),
+						responseFields(
+								fieldWithPath("identifier").description("Configuration Id for SMS Gateway"),
+								fieldWithPath("auth_token").description("SMS API authentication token"),
+								fieldWithPath("account_sid").description("SMS API account SID"),
+								fieldWithPath("sender_number").description("SMS API sender number"),
+								fieldWithPath("type").description("Type of Configuration"),
+								fieldWithPath("state").description("The state of the Gateway" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentFindEmailConfiguration() throws Exception {
+		final EmailConfiguration randomEmailConfiguration = DomainObjectGenerator.emailConfiguration();
+		
+		this.notificationManager.createEmailConfiguration(randomEmailConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, randomEmailConfiguration.getIdentifier());
+		
+		this.notificationManager.findEmailConfigurationByIdentifier(randomEmailConfiguration.getIdentifier());
+		
+		this.mockMvc.perform(get("/configuration/email/" + randomEmailConfiguration.getIdentifier())
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(randomEmailConfiguration.getIdentifier())))
+				.andExpect(status().isOk())
+				.andDo(document("document-find-email-configuration", preprocessRequest(prettyPrint()),
+						responseFields(
+								fieldWithPath("identifier").description("Configuration Id for Email Server"),
+								fieldWithPath("host").description("Email Server host address"),
+								fieldWithPath("port").description("Email Server port number"),
+								fieldWithPath("protocol").description("Type of protocol being used by server " +
+										"\nSMTP" +
+										"\nPOP3" +
+										"\nIMAP"),
+								fieldWithPath("username").description("Email address"),
+								fieldWithPath("app_password").description("Email app password or normal password"),
+								fieldWithPath("smtp_auth").description("Enable SMTP"),
+								fieldWithPath("start_tls").description("Enable TLS"),
+								fieldWithPath("state").description("" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentUpdateEmailConfiguration() throws Exception {
+		
+		final EmailConfiguration randomEmailConfiguration = DomainObjectGenerator.emailConfiguration();
+		final EmailConfiguration newRandomConfiguration = DomainObjectGenerator.emailConfiguration();
+		
+		this.notificationManager.createEmailConfiguration(randomEmailConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, randomEmailConfiguration.getIdentifier());
+		
+		newRandomConfiguration.setIdentifier(randomEmailConfiguration.getIdentifier());
+		newRandomConfiguration.setHost("new.host.com");
+		newRandomConfiguration.setApp_password("changePassword");
+		newRandomConfiguration.setPort("554");
+		newRandomConfiguration.setProtocol("pop3");
+		newRandomConfiguration.setUsername("newaddress@example.com");
+		newRandomConfiguration.setSmtp_auth("false");
+		newRandomConfiguration.setStart_tls("false");
+		newRandomConfiguration.setState("ACTIVE");
+		
+		notificationManager.updateEmailConfiguration(newRandomConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.UPDATE_EMAIL_CONFIGURATION, newRandomConfiguration.getIdentifier());
+		
+		this.mockMvc.perform(put("/configuration/sms/update")
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(newRandomConfiguration)))
+				.andExpect(status().isAccepted())
+				.andDo(document("document-update-email-configuration", preprocessRequest(prettyPrint()),
+						requestFields(
+								fieldWithPath("identifier").description("Configuration Id for Email Server"),
+								fieldWithPath("host").description("Email Server host address"),
+								fieldWithPath("port").description("Email Server port number"),
+								fieldWithPath("protocol").description("Type of protocol in use " +
+										"\nSMTP" +
+										"\nPOP3" +
+										"\nIMAP"),
+								fieldWithPath("username").description("Email address"),
+								fieldWithPath("app_password").description("Email app password or normal password"),
+								fieldWithPath("smtp_auth").description("Enable SMTP"),
+								fieldWithPath("start_tls").description("Enable TLS"),
+								fieldWithPath("state").description("" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentUpdateSMSConfiguration() throws Exception {
+		final SMSConfiguration newRandomConfiguration = DomainObjectGenerator.smsConfiguration();
+		final SMSConfiguration randomSMSConfiguration = DomainObjectGenerator.smsConfiguration();
+		
+		this.notificationManager.createSMSConfiguration(randomSMSConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, randomSMSConfiguration.getIdentifier());
+		
+		newRandomConfiguration.setIdentifier(randomSMSConfiguration.getIdentifier());
+		newRandomConfiguration.setSender_number("new.host.com");
+		newRandomConfiguration.setState("ACTIVE");
+		newRandomConfiguration.setAccount_sid("asdLAKSKFssdfasdf554");
+		newRandomConfiguration.setAuth_token("aalkeifjlasdfalje333");
+		
+		notificationManager.updateSMSConfiguration(randomSMSConfiguration);
+		
+		this.mockMvc.perform(put("/configuration/sms/update")
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE)
+				.content(serialize.toJson(randomSMSConfiguration)))
+				.andExpect(status().isAccepted())
+				.andDo(document("document-update-sms-configuration", preprocessRequest(prettyPrint()),
+						requestFields(
+								fieldWithPath("identifier").description("Configuration Id for SMS Gateway"),
+								fieldWithPath("auth_token").description("SMS API authentication token"),
+								fieldWithPath("account_sid").description("SMS API account SID"),
+								fieldWithPath("sender_number").description("SMS API sender number"),
+								fieldWithPath("state").description("The state of the Gateway" +
+										"\n ACTIVE for Gateway to be used" +
+										"\n DEACTIVATED for inactive gateways")
+						)));
+	}
+	
+	@Test
+	public void documentDeleteSMSConfiguration() throws Exception {
+		final SMSConfiguration randomSMSConfiguration = DomainObjectGenerator.smsConfiguration();
+		
+		this.notificationManager.createSMSConfiguration(randomSMSConfiguration);
+		
+		super.eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, randomSMSConfiguration.getIdentifier());
+		
+		System.out.println(randomSMSConfiguration.getIdentifier());
+		this.mockMvc.perform(delete("/configuration/sms/delete/" + randomSMSConfiguration.getIdentifier())
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE))
+				.andExpect(status().isOk())
+				.andDo(document("document-delete-sms-configuration", preprocessRequest(prettyPrint())));
+	}
+	
+	@Test
+	public void documentDeleteEmailConfiguration() throws Exception {
+		final EmailConfiguration randomConfiguration = DomainObjectGenerator.emailConfiguration();
+		
+		notificationManager.createEmailConfiguration(randomConfiguration);
+		super.eventRecorder.wait(NotificationEventConstants.DELETE_EMAIL_CONFIGURATION, randomConfiguration.getIdentifier());
+		
+		this.mockMvc.perform(delete("/configuration/email/delete/" + randomConfiguration.getIdentifier())
+				.accept(MediaType.APPLICATION_JSON_VALUE)
+				.contentType(MediaType.APPLICATION_JSON_VALUE))
+				.andExpect(status().isOk())
+				.andDo(document("document-delete-email-configuration", preprocessResponse(prettyPrint())));
+	}
+}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java b/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
index 5063d2e..46ca216 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/SuiteTestEnvironment.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.cn.notification;
 
 import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
 import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
 import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
 import org.junit.ClassRule;
@@ -39,6 +40,7 @@ public class SuiteTestEnvironment {
 	static final TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
 	static final CassandraInitializer cassandraInitializer = new CassandraInitializer();
 	static final MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+	final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
 	
 	@ClassRule
 	public static TestRule orderClassRules = RuleChain
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestApplicationAuthentication.java b/component-test/src/main/java/org/apache/fineract/cn/notification/TestApplicationAuthentication.java
new file mode 100644
index 0000000..49479be
--- /dev/null
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/TestApplicationAuthentication.java
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
+import org.apache.fineract.cn.notification.service.internal.identity.NotificationAuthentication;
+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.util.Optional;
+
+public class TestApplicationAuthentication extends TestNotification {
+	
+	private final String applicationIdentifier = "customer-v1";
+	
+	@Autowired
+	NotificationAuthentication notificationAuthenticationMock;
+	
+	
+	public TestApplicationAuthentication() {
+		super();
+	}
+	
+	@Test
+	public void createApplicationPermissionForCustomerService() {
+		//Todo : look at it later
+		//Assert.assertFalse(this.notificationAuthenticationMock.authenticateWithCustomerService(super.tenantDataStoreContext.getTenantName()));
+	}
+	
+}
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 90f73c7..a30f8f7 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
@@ -25,6 +25,8 @@ import org.apache.fineract.cn.notification.api.v1.client.ConfigurationNotFoundEx
 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.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;
@@ -34,52 +36,40 @@ import org.springframework.beans.factory.annotation.Autowired;
 
 public class TestEmailService extends TestNotification {
 	
-	private final String configIdentifier = "Gmail";
+	final EmailConfiguration emailConfiguration;
 	@Autowired
 	private NotificationService notificationService;
 	@Autowired
-	private NotificationManager notificationManager;
+	private EmailService emailService;
 	@Autowired
-	private EventRecorder eventRecorder;
+	private NotificationManager notificationManager;
 	
 	public TestEmailService() {
 		super();
+		emailConfiguration = DomainObjectGenerator.emailConfiguration();
 	}
 	
+	
 	@Test
-	public void sendEmail() throws InterruptedException{
+	public void sendEmail() throws InterruptedException {
 		this.logger.info("Send Email Notification");
-		notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
+		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"+
+						"\nStreet: Test Street" +
+						"\nCity: Test City" +
+						"\nState: Test State" +
+						"\nCountry: Mauritius" +
 						"\n\nBest Regards" +
 						"\nMFI");
-	}
-	
-	@Test
-	public void shouldRetrieveEmailConfigurationEntity() {
-		logger.info("Create and retrieve Email Gateway configuration");
-		EmailConfiguration sampleRetrieved = this.notificationManager.findEmailConfigurationByIdentifier(configIdentifier);
-		Assert.assertNotNull(sampleRetrieved);
-		Assert.assertEquals(sampleRetrieved.getIdentifier(), configIdentifier);
-	}
-	
-	@Test
-	public void shouldCreateNewEmailConfigurationEntity() throws InterruptedException{
-		logger.info("Create Email Gateway configuration");
-		this.notificationManager.createEmailConfiguration(DomainObjectGenerator.emailConfiguration());
 		
-		eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION,EmailConfiguration.class);
+		Assert.assertNotNull(messageHash);
 	}
 	
 	@Test(expected = NotFoundException.class)
-	public void emailConfigurationNotFound() throws CustomerNotFoundException {
+	public void emailConfigurationNotFound() throws ConfigurationNotFoundException {
 		logger.info("Configuration not found");
 		try {
 			this.notificationManager.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8));
@@ -89,8 +79,29 @@ public class TestEmailService extends TestNotification {
 	}
 	
 	@Test
-	public void checkEmailConfigurationEntityExist() {
+	public void shouldCreateAndRetrieveEmailConfigurationEntity() throws InterruptedException {
+		logger.info("Create and Retrieve Email Gateway configuration");
+		this.notificationManager.createEmailConfiguration(emailConfiguration);
+		
+		this.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier());
+		
+		EmailConfiguration sampleRetrieved = this.notificationManager.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier());
+		Assert.assertNotNull(sampleRetrieved);
+		Assert.assertEquals(sampleRetrieved.getIdentifier(), emailConfiguration.getIdentifier());
+	}
+	
+	@Test
+	public void checkEmailConfigurationEntityExist() throws InterruptedException {
 		logger.info("Email Gateway configuration Exist");
-		Assert.assertTrue(this.notificationService.emailConfigurationExists(configIdentifier));
+		this.notificationManager.createEmailConfiguration(emailConfiguration);
+		super.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier());
+		
+		Assert.assertTrue(this.emailService.emailConfigurationExists(emailConfiguration.getIdentifier()));
+	}
+	
+	@Test
+	public void shouldFindActiveGateway() {
+		this.logger.info("Find Active Gateway");
+		Assert.assertNotNull(this.emailService.findActiveEmailConfigurationEntity());
 	}
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/TestNotification.java b/component-test/src/main/java/org/apache/fineract/cn/notification/TestNotification.java
index 6a6bf6b..521776a 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/TestNotification.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/TestNotification.java
@@ -21,14 +21,11 @@ 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.events.NotificationEventConstants;
-import org.apache.fineract.cn.notification.service.NotificationConfiguration;
+import org.apache.fineract.cn.notification.service.internal.config.NotificationConfiguration;
 import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
 import org.apache.fineract.cn.test.listener.EnableEventRecording;
 import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,15 +49,16 @@ public class TestNotification extends SuiteTestEnvironment {
 	
 	@ClassRule
 	public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-	private static final String LOGGER_NAME = "test-logger";
-	private static final String TEST_USER = "homer";
+	public static final String LOGGER_NAME = "test-logger";
+	public static final String TEST_USER = "homer";
+	
 	@SuppressWarnings("WeakerAccess")
 	@Autowired
 	@Qualifier(LOGGER_NAME)
 	Logger logger;
-	private AutoUserContext userContext;
+	public AutoUserContext userContext;
 	@Autowired
-	private EventRecorder eventRecorder;
+	public EventRecorder eventRecorder;
 	@Rule
 	public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
 			= new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
@@ -96,7 +94,7 @@ public class TestNotification extends SuiteTestEnvironment {
 	@RibbonClient(name = APP_NAME)
 	@ComponentScan({"org.apache.fineract.cn.notification.listener",
 			"org.apache.fineract.cn.notification.service.internal.service",
-			"org.apache.fineract.cn.notification.service.internal.service.helperservice"
+			"org.apache.fineract.cn.notification.service.internal.service.externalServiceClients"
 	})
 	@Import({NotificationConfiguration.class})
 	public static class TestConfiguration {
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 e25a3e8..06af8c0 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
@@ -27,6 +27,7 @@ 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.events.NotificationEventConstants;
 import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
+import org.apache.fineract.cn.notification.service.internal.service.SMSService;
 import org.apache.fineract.cn.notification.util.DomainObjectGenerator;
 import org.apache.fineract.cn.test.listener.EventRecorder;
 import org.junit.Assert;
@@ -35,68 +36,60 @@ import org.springframework.beans.factory.annotation.Autowired;
 
 public class TestSMSService extends TestNotification {
 	
+	final SMSConfiguration smsConfiguration;
 	@Autowired
 	private NotificationService notificationService;
-	
+	@Autowired
+	private SMSService smsService;
 	@Autowired
 	private NotificationManager notificationManager;
-	
 	@Autowired
 	private EventRecorder eventRecorder;
 	
-	private String configIdentifier = "Twilio";
-	
 	public TestSMSService() {
 		super();
+		this.smsConfiguration = DomainObjectGenerator.smsConfiguration();
 	}
 	
-	
-	@Test
-	public void shouldCreateNewSMSConfigurationEntity() throws InterruptedException{
-		logger.info("Create SMS Gateway configuration");
-		this.notificationManager.createSMSConfiguration(DomainObjectGenerator.smsConfiguration());
-		
-		eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, SMSConfiguration.class);
+	@Test(expected = NotFoundException.class)
+	public void smsConfigurationNotFound() {
+		super.logger.info("SMS Gateway configuration Not Found");
+		this.notificationManager.findSMSConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8));
 	}
 	
 	@Test
-	public void shouldTriggerCustomerCreated() throws InterruptedException{
-		logger.info("Create SMS Gateway configuration");
+	public void shouldCreateAndRetrieveSMSConfigurationEntity() throws InterruptedException {
+		logger.info("Create and Retrieve SMS Gateway configuration");
+		this.notificationManager.createSMSConfiguration(smsConfiguration);
 		
-		eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, SMSConfiguration.class);
-	}
-	
-	@Test(expected = NotFoundException.class)
-	public void smsConfigurationNotFound() throws CustomerNotFoundException {
-		logger.info("SMS Gateway configuration Not Found");
-		try {
-			this.notificationManager.findSMSConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8));
-		} catch (final ConfigurationNotFoundException ex) {
-			logger.info("Error Asserted");
-		}
+		this.eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, smsConfiguration.getIdentifier());
+		
+		SMSConfiguration sampleRetrieved = this.notificationManager.findSMSConfigurationByIdentifier(smsConfiguration.getIdentifier());
+		Assert.assertNotNull(sampleRetrieved);
+		Assert.assertEquals(sampleRetrieved.getIdentifier(), smsConfiguration.getIdentifier());
 	}
 	
 	@Test
-	public void sendSMS() {
-		this.logger.info("Send SMS Notification");
-		this.notificationService.sendSMS("+23058409206",
-				"Dear Valued Customer\n\nTalk is cheap show me the code\n\nBest Regards\nYour MFI");
-}
+	public void shouldFindActiveGateway() {
+		this.logger.info("Find Active Gateway");
+		Assert.assertNotNull(this.smsService.findActiveSMSConfigurationEntity());
+	}
 	
 	@Test
-	public void shouldCreateAndRetrieveSMSConfigurationEntity() {
-		logger.info("Create and Retrieve SMS Gateway configuration");
-		final SMSConfiguration smsConfiguration = DomainObjectGenerator.smsConfiguration();
+	public void checkIfConfigurationAlreadyExists() throws InterruptedException{
+		logger.info("SMS Gateway configuration Exist");
+		
 		this.notificationManager.createSMSConfiguration(smsConfiguration);
+		this.eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, smsConfiguration.getIdentifier());
 		
-		SMSConfiguration sampleRetrieved = this.notificationManager.findSMSConfigurationByIdentifier(configIdentifier);
-		Assert.assertNotNull(sampleRetrieved);
-		Assert.assertEquals(sampleRetrieved.getIdentifier(), configIdentifier);
+		Assert.assertTrue(this.smsService.smsConfigurationExists(this.smsConfiguration.getIdentifier()));
 	}
 	
 	@Test
-	public void checkSMSConfigurationEntityExist() {
-		logger.info("SMS Gateway configuration Exist");
-		Assert.assertTrue(this.notificationService.smsConfigurationExists(configIdentifier));
+	public void sendSMS() {
+		this.logger.info("Send SMS Notification");
+		String messageHash = this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer\n\nTalk is cheap show me the code\n\nBest Regards\nYour MFI");
+		Assert.assertNotNull(messageHash);
 	}
 }
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 868e949..af10e31 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
@@ -25,6 +25,8 @@ import org.junit.runners.Suite;
 @Suite.SuiteClasses({
 		TestEmailService.class,
 		TestSMSService.class,
+		TestApplicationAuthentication.class,
+		NotificationApiDocumentation.class
 })
 public class TestSuite extends SuiteTestEnvironment {
 }
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/listener/NotificationEventListener.java b/component-test/src/main/java/org/apache/fineract/cn/notification/listener/NotificationEventListener.java
deleted file mode 100644
index 838b2c7..0000000
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/listener/NotificationEventListener.java
+++ /dev/null
@@ -1,60 +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.listener;
-
-import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
-import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
-import org.apache.fineract.cn.test.listener.EventRecorder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jms.annotation.JmsListener;
-import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.stereotype.Component;
-
-@SuppressWarnings("unused")
-@Component
-public class NotificationEventListener {
-	
-	private final EventRecorder eventRecorder;
-	
-	@Autowired
-	public NotificationEventListener(@SuppressWarnings("SpringJavaAutowiringInspection") final EventRecorder eventRecorder) {
-		super();
-		this.eventRecorder = eventRecorder;
-	}
-	
-	@JmsListener(
-			subscription = NotificationEventConstants.DESTINATION,
-			destination = NotificationEventConstants.DESTINATION,
-			selector = NotificationEventConstants.SELECTOR_POST_SMS_NOTIFICATION
-	)
-	public void onPostSMS(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-	                      final String payload) {
-		this.eventRecorder.event(tenant, NotificationEventConstants.POST_SMS_NOTIFICATION, payload, String.class);
-	}
-	
-	@JmsListener(
-			subscription = NotificationEventConstants.DESTINATION,
-			destination = NotificationEventConstants.DESTINATION,
-			selector = NotificationEventConstants.SELECTOR_POST_SMS_CONFIGURATION
-	)
-	public void onCreateSMSConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-	                                     final String payload) {
-		this.eventRecorder.event(tenant, NotificationEventConstants.POST_SMS_NOTIFICATION, payload, String.class);
-	}
-}
diff --git a/component-test/src/main/java/org/apache/fineract/cn/notification/util/DomainObjectGenerator.java b/component-test/src/main/java/org/apache/fineract/cn/notification/util/DomainObjectGenerator.java
index d323eea..b39a7b4 100644
--- a/component-test/src/main/java/org/apache/fineract/cn/notification/util/DomainObjectGenerator.java
+++ b/component-test/src/main/java/org/apache/fineract/cn/notification/util/DomainObjectGenerator.java
@@ -28,11 +28,11 @@ import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
 public class DomainObjectGenerator {
 	
 	public static EmailConfiguration emailConfiguration() {
-		EmailConfiguration emailConfiguration = EmailConfiguration.create("emailtest",
-				"smtp.google.com",
-				"1233",
+		EmailConfiguration emailConfiguration = EmailConfiguration.create(RandomStringUtils.randomAlphanumeric(14),
+				"smtp.example.com",
+				"8443",
 				"smtp",
-				"example",
+				"user@example.com",
 				RandomStringUtils.randomAlphanumeric(16),
 				"true",
 				"true",
@@ -42,11 +42,11 @@ public class DomainObjectGenerator {
 	
 	public static SMSConfiguration smsConfiguration() {
 		SMSConfiguration smsConfiguration = SMSConfiguration.create(
-				RandomStringUtils.randomAlphanumeric(8),
-				RandomStringUtils.randomAlphanumeric(16),
-				RandomStringUtils.randomAlphanumeric(16),
-				"+309483932",
-				"ACTIVE");
+				RandomStringUtils.randomAlphanumeric(10),
+				RandomStringUtils.randomAlphanumeric(24),
+				RandomStringUtils.randomAlphanumeric(24),
+				"+233 27 309 4932",
+				"DEACTIVATED");
 		
 		return smsConfiguration;
 	}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 400f155..341fca8 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c563c1a..b586735 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Fri May 18 16:18:58 MUT 2018
+#Sat Dec 01 23:10:38 MUT 2018
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/local.properties b/local.properties
new file mode 100644
index 0000000..3fea7c3
--- /dev/null
+++ b/local.properties
@@ -0,0 +1,9 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Sat Dec 01 15:14:19 MUT 2018
+ndk.dir=/home/ebenezergraham/Android/Sdk/ndk-bundle
+sdk.dir=/home/ebenezergraham/Android/Sdk
diff --git a/service/build.gradle b/service/build.gradle
index cb2d88c..3bf06c1 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -64,6 +64,7 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'cassandra', version: versions.frameworkcassandra],
             [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
             [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
+            [group: 'org.apache.fineract.cn.permitted-feign-client', name: 'library', version: versions.frameworkpermittedfeignclient],
             [group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator]
     )
 }
diff --git a/service/out/production/resources/application.yml b/service/out/production/resources/application.yml
deleted file mode 100644
index fa7165e..0000000
--- a/service/out/production/resources/application.yml
+++ /dev/null
@@ -1,88 +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.
-#
-
-spring:
-  cloud:
-    discovery:
-      enabled: false
-    config:
-      enabled: false
-    mail:
-      host: smtp.gmail.com
-      port: 587
-      username:
-      password:
-      properties:
-        debug: true
-        mail:
-          smtp:
-            auth: true
-            starttls:
-              enable: true
-
-
-
-eureka:
-  client:
-    serviceUrl:
-      defaultZone: http://localhost:8761/eureka/
-
-server:
-  port: 8081
-  contextPath: /notification/v1/*
-
-cassandra:
-  clusterName: staging_cluster
-  contactPoints: 127.0.0.1:9042,127.0.0.2:9042,127.0.0.3:9042
-  keyspace: seshat
-  cl:
-    read: LOCAL_QUORUM
-    write: LOCAL_QUORUM
-    delete: LOCAL_QUORUM
-
-mariadb:
-  driverClass: org.mariadb.jdbc.Driver
-  database: seshat
-  host: localhost
-  port: 3306
-  user: root
-  password: mysql
-
-bonecp:
-  idleMaxAgeInMinutes: 240
-  idleConnectionTestPeriodInMinutes: 60
-  maxConnectionsPerPartition: 10
-  minConnectionsPerPartition: 1
-  partitionCount: 2
-  acquireIncrement: 5
-  statementsCacheSize: 100
-
-async:
-  corePoolSize: 32
-  maxPoolSize: 16384
-  queueCapacity: 0
-  threadName: async-processor-
-
-flyway:
-  enabled: false
-
-smssender:
-  accountSID: AC1fde2c6f26f367b93231c5fdb944c908
-  authToken: bc9a53e41745b8471e0ecafc859d86aa
-  senderNumber: +1 510-944-1898
diff --git a/service/out/production/resources/bootstrap.yml b/service/out/production/resources/bootstrap.yml
deleted file mode 100644
index 76c2441..0000000
--- a/service/out/production/resources/bootstrap.yml
+++ /dev/null
@@ -1,22 +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.
-#
-
-spring:
-    application:
-        name: notification-v1
diff --git a/service/out/production/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/out/production/resources/db/migrations/mariadb/V1__initial_setup.sql
deleted file mode 100644
index 57cefe1..0000000
--- a/service/out/production/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ /dev/null
@@ -1,56 +0,0 @@
---
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
---
-
--- -----------------------------------------------------
--- Table wada_sms_gateway_configurations
--- -----------------------------------------------------
-CREATE TABLE wada_sms_gateway_configurations (
-  id INT(11) NOT NULL AUTO_INCREMENT,
-  identifier VARCHAR(45) NULL DEFAULT NULL,
-  account_sid VARCHAR(255) NOT NULL,
-  auth_token VARCHAR(255) NOT NULL,
-  sender_number VARCHAR(45) NOT NULL,
-  state VARCHAR(45) NULL DEFAULT NULL,
-  PRIMARY KEY (id));
-
--- -----------------------------------------------------
--- Table wada_email_gateway_configurations
--- -----------------------------------------------------
-CREATE TABLE wada_email_gateway_configurations (
-  id INT(11) NOT NULL AUTO_INCREMENT,
-  identifier VARCHAR(45) NULL DEFAULT NULL,
-  host VARCHAR(45) NOT NULL,
-  port VARCHAR(45) NOT NULL,
-  username VARCHAR(45) NOT NULL,
-  app_password VARCHAR(255) NOT NULL,
-  protocol VARCHAR(45)NOT NULL,
-  smtp_auth VARCHAR (45)NOT NULL,
-  start_tls VARCHAR (45)NOT NULL,
-  state VARCHAR(45)NOT NULL,
-  PRIMARY KEY (id));
-
--- -----------------------------------------------------
--- 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,
-  url VARCHAR(255) NOT NULL,
-  PRIMARY KEY (id));
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationApplication.java b/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationApplication.java
index 29d448b..53be40c 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationApplication.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationApplication.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.cn.notification.service;
 
+import org.apache.fineract.cn.notification.service.internal.config.NotificationConfiguration;
 import org.springframework.boot.SpringApplication;
 
 public class NotificationApplication {
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/ServiceConstants.java b/service/src/main/java/org/apache/fineract/cn/notification/service/ServiceConstants.java
index dc96c42..50816ad 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/ServiceConstants.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/ServiceConstants.java
@@ -21,10 +21,21 @@ package org.apache.fineract.cn.notification.service;
 public interface ServiceConstants {
 	String LOGGER_NAME = "notification-logger";
 	
+	String CUSTOMER_SERVICE_NAME ="customer-v1";
+	String ACCOUNT_SERVICE_NAME ="account-v1";
+	String PORTFOLIO_SERVICE_NAME ="porfolio-v1";
+	
 	String MAIL_TRANSPORT_PROTOCOL_PROPERTY = "mail.transport.protocol";
 	String MAIL_TRANSPORT_PROTOCOL_VALUE = "smtp";
 	String MAIL_SMTP_AUTH_PROPERTY = "mail.smtp.auth";
 	String MAIL_SMTP_AUTH_VALUE = "true";
 	String MAIL_SMTP_STARTTLS_ENABLE_PROPERTY = "mail.smtp.starttls.enable";
 	String MAIL_SMTP_STARTTLS_ENABLE_VALUE = "true";
+	
+	String GOOGLE_MAIL_SERVER = "smtp.gmail.com";
+	String YAHOO_MAIL_SERVER = "smtp.mail.yahoo.com";
+	
+	String MAIL_SMTP_TIMEOUT_PROPERTY = "";
+	String MAIL_SMTP_TIMEOUT_VALUE = "";
+	
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteApplicationCommand.java
similarity index 54%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteApplicationCommand.java
index 2ffc416..ecdae58 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteApplicationCommand.java
@@ -18,23 +18,30 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
-	
-	private final String identifier;
-	
-	public PostSMSCommand(final String identifier) {
-		super();
-		this.identifier = identifier;
-	}
-	
-	public String getIdentifier() {
-		return this.identifier;
-	}
-	
-	@Override
-	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
-				+ '}';
-	}
+public class DeleteApplicationCommand {
+
+  private final String tenantIdentifier;
+  private final String applicationIdentifier;
+
+  public DeleteApplicationCommand(String tenantIdentifier, final String applicationIdentifier) {
+    super();
+    this.tenantIdentifier = tenantIdentifier;
+    this.applicationIdentifier = applicationIdentifier;
+  }
+
+  public String getTenantIdentifier() {
+    return tenantIdentifier;
+  }
+
+  public String getApplicationIdentifier() {
+    return this.applicationIdentifier;
+  }
+
+  @Override
+  public String toString() {
+    return "DeleteApplicationCommand{" +
+            "tenantIdentifier='" + tenantIdentifier + '\'' +
+            ", applicationIdentifier='" + applicationIdentifier + '\'' +
+            '}';
+  }
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteEmailConfigurationCommand.java
similarity index 83%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteEmailConfigurationCommand.java
index 2ffc416..d7ce1d0 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteEmailConfigurationCommand.java
@@ -18,11 +18,11 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
+public class DeleteEmailConfigurationCommand {
 	
 	private final String identifier;
 	
-	public PostSMSCommand(final String identifier) {
+	public DeleteEmailConfigurationCommand(final String identifier) {
 		super();
 		this.identifier = identifier;
 	}
@@ -33,8 +33,8 @@ public class PostSMSCommand {
 	
 	@Override
 	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
-				+ '}';
+		return "DeleteEmailConfigurationCommand{" +
+				"identifier='" + identifier + '\'' +
+				'}';
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteSMSConfigurationCommand.java
similarity index 84%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteSMSConfigurationCommand.java
index 2ffc416..3547c3d 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/DeleteSMSConfigurationCommand.java
@@ -18,11 +18,11 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
+public class DeleteSMSConfigurationCommand {
 	
 	private final String identifier;
 	
-	public PostSMSCommand(final String identifier) {
+	public DeleteSMSConfigurationCommand(final String identifier) {
 		super();
 		this.identifier = identifier;
 	}
@@ -33,8 +33,8 @@ public class PostSMSCommand {
 	
 	@Override
 	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
-				+ '}';
+		return "DeleteSMSConfigurationCommand{" +
+				"identifier='" + identifier + '\'' +
+				'}';
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/SaveApplicationCommand.java
similarity index 54%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/SaveApplicationCommand.java
index 2ffc416..5bb8879 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/SaveApplicationCommand.java
@@ -18,23 +18,30 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
-	
-	private final String identifier;
-	
-	public PostSMSCommand(final String identifier) {
-		super();
-		this.identifier = identifier;
-	}
-	
-	public String getIdentifier() {
-		return this.identifier;
-	}
-	
-	@Override
-	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
-				+ '}';
-	}
+public class SaveApplicationCommand {
+
+  private final String tenantIdentifier;
+  private final String applicationIdentifier;
+
+  public SaveApplicationCommand(String tenantIdentifier, final String applicationIdentifier) {
+    super();
+    this.tenantIdentifier = tenantIdentifier;
+    this.applicationIdentifier = applicationIdentifier;
+  }
+
+  public String getTenantIdentifier() {
+    return tenantIdentifier;
+  }
+
+  public String getApplicationIdentifier() {
+    return this.applicationIdentifier;
+  }
+
+  @Override
+  public String toString() {
+    return "SaveApplicationCommand{" +
+            "tenantIdentifier='" + tenantIdentifier + '\'' +
+            ", applicationIdentifier='" + applicationIdentifier + '\'' +
+            '}';
+  }
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateEmailConfigurationCommand.java
similarity index 65%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateEmailConfigurationCommand.java
index 2ffc416..cf47bc5 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateEmailConfigurationCommand.java
@@ -18,23 +18,25 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
+import org.apache.fineract.cn.notification.api.v1.domain.EmailConfiguration;
+
+public class UpdateEmailConfigurationCommand {
 	
-	private final String identifier;
+	private final EmailConfiguration emailConfiguration;
 	
-	public PostSMSCommand(final String identifier) {
+	public UpdateEmailConfigurationCommand(final EmailConfiguration emailConfiguration) {
 		super();
-		this.identifier = identifier;
+		this.emailConfiguration = emailConfiguration;
 	}
 	
-	public String getIdentifier() {
-		return this.identifier;
+	public EmailConfiguration getEmailConfiguration() {
+		return this.emailConfiguration;
 	}
 	
 	@Override
 	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
+		return "UpdateEmailConfigurationCommand{"
+				+ "EmailConfiguration=" + emailConfiguration.getIdentifier()
 				+ '}';
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateSMSConfigurationCommand.java
similarity index 66%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateSMSConfigurationCommand.java
index 2ffc416..a2ecf6c 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/PostSMSCommand.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/UpdateSMSConfigurationCommand.java
@@ -18,23 +18,25 @@
  */
 package org.apache.fineract.cn.notification.service.internal.command;
 
-public class PostSMSCommand {
+import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
+
+public class UpdateSMSConfigurationCommand {
 	
-	private final String identifier;
+	private final SMSConfiguration smsConfiguration;
 	
-	public PostSMSCommand(final String identifier) {
+	public UpdateSMSConfigurationCommand(final SMSConfiguration smsConfiguration) {
 		super();
-		this.identifier = identifier;
+		this.smsConfiguration = smsConfiguration;
 	}
 	
-	public String getIdentifier() {
-		return this.identifier;
+	public SMSConfiguration getSMSConfiguration() {
+		return this.smsConfiguration;
 	}
 	
 	@Override
 	public String toString() {
-		return "PostSMSCommand{"
-				+ "PostSMS=" + identifier
+		return "UpdateSMSConfigurationCommand{"
+				+ "SMSConfiguration=" + smsConfiguration.getIdentifier()
 				+ '}';
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EventsAggregate.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java
similarity index 55%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EventsAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java
index 27f129b..55de62d 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EventsAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/ApplicationCommandHandler.java
@@ -22,28 +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.events.NotificationEventConstants;
-import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
-import org.apache.fineract.cn.notification.service.internal.command.PostSMSCommand;
-import org.apache.fineract.cn.notification.service.internal.mapper.SMSConfigurationMapper;
-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.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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 @SuppressWarnings("unused")
 @Aggregate
-public class EventsAggregate {
-	
-	public EventsAggregate() {
-		super();
-	}
+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();
+  }
 	
 	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
 	@Transactional
-	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SMS_NOTIFICATION)
-	public String postSMS(final PostSMSCommand postSMSCommand) {
-		return postSMSCommand.getIdentifier();
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME,selectorValue = NotificationEventConstants.DELETE_SOURCE_APPLICATION)
+	public void process(final DeleteApplicationCommand deleteApplicationCommand) {
+		this.applicationRepository.deleteByTenantIdentifierAndApplicationIdentifier(deleteApplicationCommand.getTenantIdentifier(), deleteApplicationCommand.getApplicationIdentifier());
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationAggregate.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationCommandHandler.java
similarity index 57%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationCommandHandler.java
index 6cc80d0..3c7928d 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/EmailConfigurationCommandHandler.java
@@ -24,7 +24,9 @@ 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.EmailConfiguration;
 import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
+import org.apache.fineract.cn.notification.service.internal.command.UpdateEmailConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.command.CreateEmailConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.DeleteEmailConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.mapper.EmailConfigurationMapper;
 import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationEntity;
 import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationRepository;
@@ -33,20 +35,20 @@ import org.springframework.transaction.annotation.Transactional;
 
 @SuppressWarnings("unused")
 @Aggregate
-public class EmailConfigurationAggregate {
+public class EmailConfigurationCommandHandler {
 	
 	private final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository;
 	
 	@Autowired
-	public EmailConfigurationAggregate(EmailGatewayConfigurationRepository emailGatewayConfigurationRepository) {
+	public EmailConfigurationCommandHandler(EmailGatewayConfigurationRepository emailGatewayConfigurationRepository) {
 		super();
 		this.emailGatewayConfigurationRepository = emailGatewayConfigurationRepository;
 	}
 	
-	@CommandHandler(logStart = CommandLogLevel.DEBUG, logFinish = CommandLogLevel.DEBUG)
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
 	@Transactional
 	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_EMAIL_CONFIGURATION)
-	public String createEmailConfiguration(final CreateEmailConfigurationCommand createEmailConfigurationCommand) {
+	public String process(final CreateEmailConfigurationCommand createEmailConfigurationCommand) {
 		
 		EmailConfiguration emailConfiguration = createEmailConfigurationCommand.getEmailConfiguration();
 		final EmailGatewayConfigurationEntity entity = EmailConfigurationMapper.map(emailConfiguration);
@@ -54,4 +56,24 @@ public class EmailConfigurationAggregate {
 		
 		return emailConfiguration.getIdentifier();
 	}
+	
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.UPDATE_EMAIL_CONFIGURATION)
+	public String process(final UpdateEmailConfigurationCommand updateEmailConfigurationCommand) {
+		EmailConfiguration emailConfiguration = updateEmailConfigurationCommand.getEmailConfiguration();
+		final EmailGatewayConfigurationEntity newEntity = EmailConfigurationMapper.map(emailConfiguration);
+		this.emailGatewayConfigurationRepository.deleteEmailGatewayConfigurationEntityBy(newEntity.getIdentifier());
+		this.emailGatewayConfigurationRepository.save(newEntity);
+		
+		return emailConfiguration.getIdentifier();
+	}
+	
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.DELETE_EMAIL_CONFIGURATION)
+	public String process(final DeleteEmailConfigurationCommand deleteEmailConfigurationCommand) {
+		this.emailGatewayConfigurationRepository.deleteEmailGatewayConfigurationEntityBy(deleteEmailConfigurationCommand.getIdentifier());
+		return deleteEmailConfigurationCommand.getIdentifier();
+	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
similarity index 88%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
index 1abc754..7825060 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/MigrationCommandHandler.java
@@ -38,7 +38,7 @@ import javax.sql.DataSource;
 		"unused"
 })
 @Aggregate
-public class MigrationAggregate {
+public class MigrationCommandHandler {
 	
 	private final Logger logger;
 	private final DataSource dataSource;
@@ -46,10 +46,10 @@ public class MigrationAggregate {
 	private final ApplicationName applicationName;
 	
 	@Autowired
-	public MigrationAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
-	                          final DataSource dataSource,
-	                          final FlywayFactoryBean flywayFactoryBean,
-	                          final ApplicationName applicationName) {
+	public MigrationCommandHandler(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+	                               final DataSource dataSource,
+	                               final FlywayFactoryBean flywayFactoryBean,
+	                               final ApplicationName applicationName) {
 		super();
 		this.logger = logger;
 		this.dataSource = dataSource;
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationAggregate.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationCommandHandler.java
similarity index 63%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationAggregate.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationCommandHandler.java
index 1d240fb..e3234db 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationAggregate.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/command/handler/SMSConfigurationCommandHandler.java
@@ -24,7 +24,9 @@ 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.events.NotificationEventConstants;
+import org.apache.fineract.cn.notification.service.internal.command.UpdateSMSConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
+import org.apache.fineract.cn.notification.service.internal.command.DeleteSMSConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.mapper.SMSConfigurationMapper;
 import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationEntity;
 import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationRepository;
@@ -33,12 +35,12 @@ import org.springframework.transaction.annotation.Transactional;
 
 @SuppressWarnings("unused")
 @Aggregate
-public class SMSConfigurationAggregate {
+public class SMSConfigurationCommandHandler {
 	
 	private final SMSGatewayConfigurationRepository smsGatewayConfigurationRepository;
 	
 	@Autowired
-	public SMSConfigurationAggregate(SMSGatewayConfigurationRepository smsGatewayConfigurationRepository) {
+	public SMSConfigurationCommandHandler(SMSGatewayConfigurationRepository smsGatewayConfigurationRepository) {
 		super();
 		this.smsGatewayConfigurationRepository = smsGatewayConfigurationRepository;
 	}
@@ -46,11 +48,29 @@ public class SMSConfigurationAggregate {
 	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
 	@Transactional
 	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SMS_CONFIGURATION)
-	public String createSMSConfiguration(final CreateSMSConfigurationCommand createSMSConfigurationCommand) {
+	public String process(final CreateSMSConfigurationCommand createSMSConfigurationCommand) {
 		SMSConfiguration smsConfiguration = createSMSConfigurationCommand.getSMSConfiguration();
 		final SMSGatewayConfigurationEntity entity = SMSConfigurationMapper.map(smsConfiguration);
 		this.smsGatewayConfigurationRepository.save(entity);
 		
 		return smsConfiguration.getIdentifier();
 	}
+	
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	public String process(final UpdateSMSConfigurationCommand updateSMSConfigurationCommand) {
+		final SMSGatewayConfigurationEntity newEntity = SMSConfigurationMapper.map(updateSMSConfigurationCommand.getSMSConfiguration());
+		this.smsGatewayConfigurationRepository.deleteSMSGatewayConfigurationEntityBy(newEntity.getIdentifier());
+		this.smsGatewayConfigurationRepository.save(newEntity);
+		
+		return newEntity.getIdentifier();
+	}
+	
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.DELETE_SMS_CONFIGURATION)
+	public String process(final DeleteSMSConfigurationCommand deleteSMSConfigurationCommand) {
+		smsGatewayConfigurationRepository.deleteSMSGatewayConfigurationEntityBy(deleteSMSConfigurationCommand.getIdentifier());
+		return deleteSMSConfigurationCommand.getIdentifier();
+	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationConfiguration.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
similarity index 87%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/NotificationConfiguration.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
index 4f9a63c..8db7f39 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/NotificationConfiguration.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationConfiguration.java
@@ -16,25 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification.service;
+package org.apache.fineract.cn.notification.service.internal.config;
 
 import org.apache.activemq.command.ActiveMQTopic;
 import org.apache.activemq.jms.pool.PooledConnectionFactory;
 import org.apache.activemq.spring.ActiveMQConnectionFactory;
-import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
 import org.apache.fineract.cn.anubis.config.EnableAnubis;
 import org.apache.fineract.cn.async.config.EnableAsync;
 import org.apache.fineract.cn.cassandra.config.EnableCassandra;
 import org.apache.fineract.cn.command.config.EnableCommandProcessing;
 import org.apache.fineract.cn.customer.api.v1.client.CustomerManager;
+import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
 import org.apache.fineract.cn.lang.ApplicationName;
 import org.apache.fineract.cn.lang.config.EnableServiceException;
 import org.apache.fineract.cn.lang.config.EnableTenantContext;
 import org.apache.fineract.cn.mariadb.config.EnableMariaDB;
+import org.apache.fineract.cn.notification.service.ServiceConstants;
+import org.apache.fineract.cn.notification.service.internal.identity.CustomerPermittedClient;
+import org.apache.fineract.cn.permittedfeignclient.config.EnablePermissionRequestingFeignClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.cloud.netflix.feign.EnableFeignClients;
 import org.springframework.context.annotation.Bean;
@@ -61,18 +65,23 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
 @EnableAnubis
 @EnableServiceException
 @EnableJms
+@EnableConfigurationProperties
+@EnablePermissionRequestingFeignClient(feignClasses = {CustomerPermittedClient.class})
 @EnableFeignClients(
 		clients = {
 				CustomerManager.class,
-				IdentityManager.class
+				IdentityManager.class,
+				CustomerPermittedClient.class
 		}
 )
 @ComponentScan({
 		"org.apache.fineract.cn.notification.service.rest",
 		"org.apache.fineract.cn.notification.service.listener",
-		"org.apache.fineract.cn.notification.service.internal.service",
+		"org.apache.fineract.cn.notification.service.internal",
 		"org.apache.fineract.cn.notification.service.internal.repository",
 		"org.apache.fineract.cn.notification.service.internal.command.handler",
+		"org.apache.fineract.cn.notification.service.internal.identity",
+		"org.apache.fineract.cn.notification.service.internal.config",
 }
 )
 @EnableJpaRepositories({
@@ -88,7 +97,6 @@ public class NotificationConfiguration extends WebMvcConfigurerAdapter {
 		this.environment = environment;
 	}
 	
-	
 	@Override
 	public void configurePathMatch(final PathMatchConfigurer configurer) {
 		configurer.setUseSuffixPatternMatch(Boolean.FALSE);
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationProperties.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationProperties.java
new file mode 100644
index 0000000..a24b62c
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/config/NotificationProperties.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.
+ */
+/*
+ * 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.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+@Component
+@Configuration
+@ConfigurationProperties(prefix = "notification")
+public class NotificationProperties {
+	
+	private String user;
+	
+	public NotificationProperties() {
+	}
+	
+	public String getUser() {
+		return user;
+	}
+	
+	public void setUser(String user) {
+		this.user = user;
+	}
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/CustomerPermittedClient.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/CustomerPermittedClient.java
new file mode 100644
index 0000000..375d152
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/CustomerPermittedClient.java
@@ -0,0 +1,46 @@
+/*
+ * 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.identity;
+
+import org.apache.fineract.cn.anubis.annotation.Permittable;
+import org.apache.fineract.cn.api.annotation.ThrowsException;
+import org.apache.fineract.cn.customer.api.v1.client.CustomerNotFoundException;
+import org.apache.fineract.cn.customer.api.v1.domain.Customer;
+import org.apache.fineract.cn.permittedfeignclient.annotation.EndpointSet;
+import org.apache.fineract.cn.permittedfeignclient.annotation.PermittedFeignClientsConfiguration;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@EndpointSet(identifier = "notification__v1__customer__v1")
+@FeignClient(name="customer-v1", path="/customer/v1", configuration = PermittedFeignClientsConfiguration.class)
+public interface CustomerPermittedClient {
+	@RequestMapping(
+			value = "/customers/{identifier}",
+			method = RequestMethod.GET,
+			produces = MediaType.ALL_VALUE,
+			consumes = MediaType.APPLICATION_JSON_VALUE
+	)
+	@ThrowsException(status = HttpStatus.NOT_FOUND, exception = CustomerNotFoundException.class)
+	@Permittable(groupId = org.apache.fineract.cn.customer.PermittableGroupIds.CUSTOMER)
+	Customer findCustomer(@PathVariable("identifier") final String identifier);
+}
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/NotificationAuthentication.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/NotificationAuthentication.java
new file mode 100644
index 0000000..d38ba3f
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/identity/NotificationAuthentication.java
@@ -0,0 +1,68 @@
+/*
+ * 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.identity;
+
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.api.util.InvalidTokenException;
+import org.apache.fineract.cn.customer.api.v1.domain.Customer;
+import org.apache.fineract.cn.lang.AutoTenantContext;
+import org.apache.fineract.cn.notification.service.ServiceConstants;
+import org.apache.fineract.cn.notification.service.internal.config.NotificationProperties;
+import org.apache.fineract.cn.permittedfeignclient.service.ApplicationAccessTokenService;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+public class NotificationAuthentication {
+	private final ApplicationAccessTokenService applicationAccessTokenService;
+	private Logger logger;
+	private CustomerPermittedClient customerPermittedClient;
+	private NotificationProperties notificationProperties;
+	
+	@Autowired
+	public NotificationAuthentication(final NotificationProperties notificationPropertities,
+	                                  final CustomerPermittedClient customerPermittedClient,
+	                                  @SuppressWarnings("SpringJavaAutowiringInspection")final ApplicationAccessTokenService applicationAccessTokenService,
+	                                  @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
+		this.logger = logger;
+		this.customerPermittedClient = customerPermittedClient;
+		this.notificationProperties = notificationPropertities;
+		this.applicationAccessTokenService = applicationAccessTokenService;
+	}
+	
+	public Optional<Customer> getCustomer(String tenantIdentifier, String customerId) {
+			try (final AutoTenantContext ignored = new AutoTenantContext(tenantIdentifier)) {
+				final String accessToken = applicationAccessTokenService.getAccessToken(notificationProperties.getUser(), tenantIdentifier);
+				logger.debug("Access token: {}", accessToken);
+				try (final AutoUserContext ignored2 = new AutoUserContext(notificationProperties.getUser(), accessToken)) {
+					try {
+						logger.debug("Getting Customer {}", customerId);
+						return Optional.of(this.customerPermittedClient.findCustomer(customerId));
+					} catch (final InvalidTokenException e) {
+						logger.error("Failed to get customer with id {}, in tenant {} because notification does not have permission to access identity.", customerId, tenantIdentifier, e);
+					}
+				}
+				return Optional.empty();
+			}
+	}
+}
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 d9c5649..5dcfbae 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
@@ -21,6 +21,7 @@ package org.apache.fineract.cn.notification.service.internal.mapper;
 
 import org.apache.fineract.cn.notification.api.v1.domain.EmailConfiguration;
 import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationEntity;
+import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationEntity;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -61,6 +62,5 @@ public class EmailConfigurationMapper {
 		emailConfigurationList.addAll(emailGatewayConfigurationEntity.stream().map(EmailConfigurationMapper::map).collect(Collectors.toList()));
 		return emailConfigurationList;
 	}
-	
 }
 
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
new file mode 100644
index 0000000..0e22a04
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationEntity.java
@@ -0,0 +1,106 @@
+/*
+ * 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/SMSGatewayConfigurationRepository.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationRepository.java
similarity index 66%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/SMSGatewayConfigurationRepository.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/internal/repository/ApplicationRepository.java
index ebac1c7..9eb4b1c 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/ApplicationRepository.java
@@ -19,16 +19,16 @@
 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.data.jpa.repository.Lock;
 import org.springframework.stereotype.Repository;
 
+import javax.persistence.LockModeType;
 import java.util.Optional;
 
 @Repository
-public interface SMSGatewayConfigurationRepository extends JpaRepository<SMSGatewayConfigurationEntity, Long> {
-	Optional<SMSGatewayConfigurationEntity> findByIdentifier(String identifier);
-	
-	@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);
+public interface ApplicationRepository extends JpaRepository<ApplicationEntity, Long> {
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  void deleteByTenantIdentifierAndApplicationIdentifier(String tenantIdentifier, String applicationIdentifier);
+  
+  Optional<ApplicationEntity> findByTenantIdentifierAndApplicationIdentifier(String tenantIdentifier, String applicationIdentifier);
 }
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 1a5af4c..93785be 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
@@ -31,4 +31,9 @@ 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();
+	
+	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 ebac1c7..9b440e5 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
@@ -31,4 +31,9 @@ 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();
+	
+	void deleteSMSGatewayConfigurationEntityBy(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 5260e98..bc006c6 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
@@ -18,62 +18,153 @@
  */
 package org.apache.fineract.cn.notification.service.internal.service;
 
+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.EmailConfiguration;
+import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
+import org.apache.fineract.cn.notification.service.internal.mapper.EmailConfigurationMapper;
+import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationRepository;
+
 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.JavaMailSender;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
 
 @Component
+@Aggregate
 public class EmailService {
 	
+	static boolean isConfigured;
+	
+	private final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository;
+	private JavaMailSenderImpl mailSender;
+	
 	private Logger logger;
+	private String host;
+	private String email;
+	private int port;
+	private String password;
 	
 	@Autowired
-	public EmailService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
+	public EmailService(final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository,
+	                    @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
 		super();
+		this.isConfigured = false;
 		this.logger = logger;
+		this.mailSender = new JavaMailSenderImpl();
+		this.emailGatewayConfigurationRepository = emailGatewayConfigurationRepository;
 	}
 	
-	public void sendEmail(String from, String to, String subject, String message) {
-		
-		JavaMailSender sender = getJavaMailSender();
-		try {
-			SimpleMailMessage mail = new SimpleMailMessage();
-			mail.setFrom(from);
-			mail.setTo(to);
-			mail.setSubject(subject);
-			mail.setText(message);
-			sender.send(mail);
-		} catch (MailException exception) {
-			logger.debug("Caused by:" + exception.getCause().toString());
+	//@PostConstruct
+	public void init() {
+		if (findActiveEmailConfigurationEntity().isPresent()){
+			configureEmailGatewayWithActiveConfiguration();
+		}else{
+			//Todo: Send an alert on the interface to configure the service
 		}
 	}
 	
-	public JavaMailSender getJavaMailSender() {
+	public boolean configureEmailGatewayWithActiveConfiguration() {
+		EmailConfiguration configuration = findActiveEmailConfigurationEntity().get();
 		
-		JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
-		mailSender.setHost("smtp.gmail.com");
-		mailSender.setPort(587);
-		mailSender.setUsername("fineractcnnotificationdemo@gmail.com");
-		//mailSender.setPassword("pnuugpwmcibipdpw");
-		mailSender.setPassword("fineractcnnotification");
+		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 List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
+		return EmailConfigurationMapper.map(this.emailGatewayConfigurationRepository.findAll());
+	}
+	
+	public Optional<EmailConfiguration> findActiveEmailConfigurationEntity() {
+		return this.emailGatewayConfigurationRepository.active().map(EmailConfigurationMapper::map);
+	}
+	
+	public Optional<EmailConfiguration> findEmailConfigurationByIdentifier(final String identifier) {
+		return this.emailGatewayConfigurationRepository.findByIdentifier(identifier).map(EmailConfigurationMapper::map);
+	}
+	
+	public Boolean emailConfigurationExists(final String identifier) {
+		return this.emailGatewayConfigurationRepository.existsByIdentifier(identifier);
+	}
+	
+	public boolean setJavaMailSender() {
+		mailSender.setHost(host);
+		mailSender.setPort(port);
+		mailSender.setUsername(email);
+		mailSender.setPassword(password);
 		
-		Properties properties = mailSender.getJavaMailProperties();
+		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);
-		mailSender.setJavaMailProperties(properties);
+		this.mailSender.setJavaMailProperties(properties);
+		return true;
+	}
+	
+	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());
 		
-		return mailSender;
+		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;
+	}
+	
+	@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) {
+		SimpleMailMessage mail = new SimpleMailMessage();
+		
+		try {
+			mail.setFrom(from);
+			mail.setTo(to);
+			mail.setSubject(subject);
+			mail.setText(message);
+			
+			this.mailSender.send(mail);
+		} catch (MailException exception) {
+			logger.debug("Caused by:" + exception.getCause().toString());
+		}
+		return to.concat(" - " + mailSender.hashCode());
 	}
-}
+}
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EventHelper.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EventHelper.java
new file mode 100644
index 0000000..96685ff
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EventHelper.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.google.gson.Gson;
+import org.apache.fineract.cn.command.util.CommandConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("WeakerAccess")
+@Component
+public class EventHelper {
+	private final Gson gson;
+	private final JmsTemplate jmsTemplate;
+	
+	public EventHelper(final @Qualifier(CommandConstants.SERIALIZER) Gson gson, final JmsTemplate jmsTemplate) {
+		this.gson = gson;
+		this.jmsTemplate = jmsTemplate;
+	}
+	
+	public void sendEvent(final String eventName, final String tenantIdentifier, final Object payload) {
+		this.jmsTemplate.convertAndSend(
+				this.gson.toJson(payload),
+				message -> {
+					message.setStringProperty(
+							TenantHeaderFilter.TENANT_HEADER,
+							tenantIdentifier);
+					message.setStringProperty(
+							NotificationEventConstants.SELECTOR_NAME,
+							eventName
+					);
+					return message;
+				}
+		);
+	}
+}
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 8b25f1b..783adc8 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,100 +19,70 @@
 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.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.mapper.EmailConfigurationMapper;
-import org.apache.fineract.cn.notification.service.internal.mapper.SMSConfigurationMapper;
-import org.apache.fineract.cn.notification.service.internal.repository.EmailGatewayConfigurationRepository;
-import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationRepository;
-import org.apache.fineract.cn.notification.service.internal.service.helperservice.CustomerAdaptor;
-import org.apache.fineract.cn.notification.service.internal.service.helperservice.NotificationAuthentication;
+import org.apache.fineract.cn.notification.service.internal.identity.CustomerPermittedClient;
+import org.apache.fineract.cn.notification.service.internal.identity.NotificationAuthentication;
+import org.apache.fineract.cn.notification.service.internal.service.externalServiceClients.CustomerService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
 import java.util.Optional;
 
 @Service
 public class NotificationService {
+	
 	private final SMSService smsService;
 	private final EmailService emailService;
 	
-	private final SMSGatewayConfigurationRepository smsGatewayConfigurationRepository;
-	private final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository;
-	
 	private final NotificationAuthentication notificationAuthentication;
-	private final CustomerAdaptor customerAdaptor;
+	private final CustomerService customerService;
 	private final Logger logger;
-	
-	private final String configureIdentifier = "Twilio";
+	private final CustomerPermittedClient customerPermittedClient;
 	
 	@Autowired
-	public NotificationService(final SMSGatewayConfigurationRepository smsGatewayConfigurationRepository,
-	                           final EmailGatewayConfigurationRepository emailGatewayConfigurationRepository,
-	                           final CustomerAdaptor customerAdaptor,
+	
+	public NotificationService(final CustomerService customerService,
 	                           final SMSService smsService,
 	                           final EmailService emailService,
 	                           final NotificationAuthentication notificationAuthentication,
+	                           final CustomerPermittedClient customerPermittedClient,
 	                           @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger
 	) {
 		super();
-		this.smsGatewayConfigurationRepository = smsGatewayConfigurationRepository;
-		this.emailGatewayConfigurationRepository = emailGatewayConfigurationRepository;
-		this.customerAdaptor = customerAdaptor;
+		this.customerService = customerService;
 		this.smsService = smsService;
 		this.emailService = emailService;
 		this.notificationAuthentication = notificationAuthentication;
+		this.customerPermittedClient = customerPermittedClient;
 		this.logger = logger;
-		this.logger.debug("{} has been initiated", this.getClass());
-	}
-	
-	
-	public List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return SMSConfigurationMapper.map(this.smsGatewayConfigurationRepository.findAll());
-	}
-	
-	public List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
-		return EmailConfigurationMapper.map(this.emailGatewayConfigurationRepository.findAll());
-	}
-	
-	public Optional<SMSConfiguration> findSMSConfigurationByIdentifier(final String identifier) {
-		return this.smsGatewayConfigurationRepository.findByIdentifier(identifier).map(SMSConfigurationMapper::map);
-	}
-	
-	
-	public Optional<EmailConfiguration> findEmailConfigurationByIdentifier(final String identifier) {
-		return this.emailGatewayConfigurationRepository.findByIdentifier(identifier).map(EmailConfigurationMapper::map);
 	}
 	
 	public Optional<Customer> findCustomer(final String customerIdentifier, String tenant) {
-		notificationAuthentication.authenticate(tenant);
-		return this.customerAdaptor.findCustomer(customerIdentifier);
-	}
-	
-	public Boolean smsConfigurationExists(final String identifier) {
-		return this.smsGatewayConfigurationRepository.existsByIdentifier(identifier);
+		return notificationAuthentication.getCustomer(tenant,customerIdentifier);
+		//return Optional.of(this.customerPermittedClient.findCustomer(customerIdentifier));
 	}
 	
-	public Boolean emailConfigurationExists(final String identifier) {
-		return this.emailGatewayConfigurationRepository.existsByIdentifier(identifier);
+	//SMS Related Operations
+	public SMSService setNewSMSService(SMSService smsService, String configurationId){
+		smsService.customConfiguration(configurationId);
+		return smsService;
 	}
 	
-	public void configureSMSSender() {
-		SMSConfiguration configuration = findSMSConfigurationByIdentifier(configureIdentifier).get();
-		smsService.configure(configuration.getAccount_sid(),
-				configuration.getAuth_token(),
-				configuration.getSender_number());
+	public String sendSMS(String receiver, String template) {
+		if (!this.smsService.isConfigured) this.smsService.configureSMSGatewayWithActiveConfiguration();
+		return this.smsService.sendSMS(receiver, template);
 	}
 	
-	public void sendSMS(String receiver, String template) {
-		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);
 	}
 	
-	public void sendEmail(String from, String to, String subject, String message) {
-		this.emailService.sendEmail(from, to, subject, message);
+	public EmailService setNewEmailService(EmailService emailService, String configurationId){
+		emailService.customConfiguration(configurationId);
+		return emailService;
 	}
 }
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 fca2476..f618d1a 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
@@ -23,46 +23,95 @@ import com.twilio.Twilio;
 import com.twilio.rest.api.v2010.account.Message;
 import com.twilio.rest.api.v2010.account.MessageCreator;
 import com.twilio.type.PhoneNumber;
+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.events.NotificationEventConstants;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
+import org.apache.fineract.cn.notification.service.internal.mapper.SMSConfigurationMapper;
+import org.apache.fineract.cn.notification.service.internal.repository.SMSGatewayConfigurationRepository;
 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;
 
 @Service
 public class SMSService {
 	
+	static boolean isConfigured;
+	private final SMSGatewayConfigurationRepository smsGatewayConfigurationRepository;
 	private final Logger logger;
-	@Value("${smssender.accountSID}")
-	private String ACCOUNT_SID;
-	@Value("${smssender.authToken}")
-	private String AUTH_TOKEN;
-	@Value("${smssender.senderNumber}")
-	private String SENDERNUMBER;
+	private String accountSid;
+	private String authToken;
+	private String senderNumber;
 	
 	@Autowired
-	public SMSService(@Qualifier(ServiceConstants.LOGGER_NAME) Logger logger) {
+	public SMSService(final SMSGatewayConfigurationRepository smsGatewayConfigurationRepository,
+	                  @Qualifier(ServiceConstants.LOGGER_NAME) Logger logger) {
 		super();
 		this.logger = logger;
+		this.isConfigured = false;
+		this.smsGatewayConfigurationRepository = smsGatewayConfigurationRepository;
+	}
+	
+	//@PostConstruct
+	public void init() {
+		if (findActiveSMSConfigurationEntity().isPresent()){
+			configureSMSGatewayWithActiveConfiguration();
+		}else{
+			//Todo: Send an alert on the interface to configure the service
+		}
+	}
+	
+	public boolean configureSMSGatewayWithActiveConfiguration() {
+		SMSConfiguration configuration = findActiveSMSConfigurationEntity().get();
+		this.accountSid = configuration.getAccount_sid();
+		this.authToken = configuration.getAuth_token();
+		this.senderNumber = configuration.getSender_number();
+		return this.isConfigured = true;
+	}
+	
+	public boolean customConfiguration(String identifier) {
+		SMSConfiguration configuration = findSMSConfigurationByIdentifier(identifier).get();
+		this.accountSid = configuration.getAccount_sid();
+		this.authToken = configuration.getAuth_token();
+		this.senderNumber = configuration.getSender_number();
+		return this.isConfigured = true;
+	}
+	
+	public Optional<SMSConfiguration> findActiveSMSConfigurationEntity() {
+		return this.smsGatewayConfigurationRepository.active().map(SMSConfigurationMapper::map);
+	}
+	
+	public Boolean smsConfigurationExists(final String identifier) {
+		return this.smsGatewayConfigurationRepository.existsByIdentifier(identifier);
+	}
+	
+	public Optional<SMSConfiguration> findSMSConfigurationByIdentifier(final String identifier) {
+		return this.smsGatewayConfigurationRepository.findByIdentifier(identifier).map(SMSConfigurationMapper::map);
 	}
 	
-	public void configure(String accountSID,
-	                      String authToken,
-	                      String senderNumber) {
-		ACCOUNT_SID = accountSID;
-		AUTH_TOKEN = authToken;
-		SENDERNUMBER = senderNumber;
+	public List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
+		return SMSConfigurationMapper.map(this.smsGatewayConfigurationRepository.findAll());
 	}
 	
-	public void sendSMS(String receiver, String template) {
-		this.logger.debug("sendSMS invoked");
-		Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
-		MessageCreator messageCreator = Message.creator(ACCOUNT_SID,
+	@CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+	@Transactional
+	@EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SEND_SMS_NOTIFICATION)
+	public String sendSMS(String receiver, String template) {
+		Twilio.init(this.accountSid, this.authToken);
+		MessageCreator messageCreator = Message.creator(this.accountSid,
 				new PhoneNumber(receiver),
-				new PhoneNumber(SENDERNUMBER),
+				new PhoneNumber(this.senderNumber),
 				template);
 		Message message = messageCreator.create();
-		System.out.println(message.getSid());
+		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/helperservice/CustomerAdaptor.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/CustomerService.java
similarity index 94%
rename from service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/helperservice/CustomerAdaptor.java
rename to service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/CustomerService.java
index 33a79f4..0532759 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/helperservice/CustomerAdaptor.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/externalServiceClients/CustomerService.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.cn.notification.service.internal.service.helperservice;
+package org.apache.fineract.cn.notification.service.internal.service.externalServiceClients;
 
 import org.apache.fineract.cn.customer.api.v1.client.CustomerManager;
 import org.apache.fineract.cn.customer.api.v1.client.CustomerNotFoundException;
@@ -30,13 +30,13 @@ import org.springframework.stereotype.Service;
 import java.util.Optional;
 
 @Service
-public class CustomerAdaptor {
+public class CustomerService {
 	
 	private final Logger logger;
 	private final CustomerManager customerManager;
 	
 	@Autowired
-	public CustomerAdaptor(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+	public CustomerService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
 	                       final CustomerManager customerManager) {
 		super();
 		this.logger = logger;
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/helperservice/NotificationAuthentication.java b/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/helperservice/NotificationAuthentication.java
deleted file mode 100644
index a4ab97c..0000000
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/helperservice/NotificationAuthentication.java
+++ /dev/null
@@ -1,60 +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.service.helperservice;
-
-/*
- ebenezergraham created on 8/4/18
-*/
-
-import org.apache.fineract.cn.api.util.UserContextHolder;
-import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
-import org.apache.fineract.cn.identity.api.v1.domain.Authentication;
-import org.apache.fineract.cn.lang.TenantContextHolder;
-import org.apache.fineract.cn.notification.service.ServiceConstants;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Base64Utils;
-
-@Component
-public class NotificationAuthentication {
-	private final String USER_PASSWORD = "init1@l";
-	private final String USER_IDENTIFIER = "operator";
-	
-	private IdentityManager identityManager;
-	private Logger logger;
-	
-	@Autowired
-	public NotificationAuthentication(IdentityManager identityManager,
-	                                 @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) {
-		this.identityManager = identityManager;
-		this.logger = logger;
-		}
-	
-	public void authenticate(String tenant) {
-		TenantContextHolder.clear();
-		TenantContextHolder.setIdentifier(tenant);
-		
-		final Authentication authentication =
-				this.identityManager.login(USER_IDENTIFIER, Base64Utils.encodeToString(USER_PASSWORD.getBytes()));
-		UserContextHolder.clear();
-		UserContextHolder.setAccessToken(USER_IDENTIFIER, authentication.getAccessToken());
-	}
-}
\ No newline at end of file
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 d1cb4d6..ce5325e 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
@@ -1,3 +1,21 @@
+/*
+ * 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.
+ */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one
      * or more contributor license agreements.  See the NOTICE file
@@ -51,7 +69,7 @@
 	    public void customerCreatedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                     final String payload) {
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
-		    this.logger.debug("{} has been invoked", "customerCreatedEvent");
+		    this.logger.info("{} has been invoked", "customerCreatedEvent");
 		
 		    customer.getContactDetails().forEach(contact -> {
 			    if (contact.getType().equals(ContactDetail.Type.PHONE.toString())) {
@@ -83,7 +101,7 @@
 	    )
 	    public void customerUpdatedEvents(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                      final String payload) {
-		    this.logger.debug("{} has been invoked", "customerUpdatedEvents");
+		    this.logger.info("{} has been invoked", "customerUpdatedEvents");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -102,7 +120,7 @@
 				    // TODO: Pass message to template
 				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
 						    emailAddress,
-						    "Account created",
+						    "Account updated",
 						    "Dear Valued Customer," +
 								    "\n\nYour account has been Updated" +
 								    "\n\nBest Regards," +
@@ -117,7 +135,7 @@
 	    )
 	    public void customerActivatedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                       final String payload) {
-		    this.logger.debug("{} has been invoked", "customerActivatedEvent");
+		    this.logger.info("{} has been invoked", "customerActivatedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -134,7 +152,7 @@
 				    // TODO: Pass message to template
 				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
 						    emailAddress,
-						    "Account created",
+						    "Account activated",
 						    "Dear Valued Customer," +
 								    "\n\nYour account has been Activated" +
 								    "\n\nBest Regards," +
@@ -149,7 +167,7 @@
 	    )
 	    public void customerLockedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                    final String payload) {
-		    this.logger.debug("{} has been invoked", "customerLockedEvent");
+		    this.logger.info("{} has been invoked", "customerLockedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -165,7 +183,7 @@
 				    // TODO: Localize message
 				    // TODO: Pass message to template
 				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
-						    emailAddress, "Account created",
+						    emailAddress, "Account locked",
 						    "Dear Valued Customer," +
 								    "\n\nYour account has been Locked" +
 								    "\n\nBest Regards," +
@@ -180,7 +198,7 @@
 	    )
 	    public void customerUnlockedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                      final String payload) {
-		    this.logger.debug("{} has been invoked", "customerUnlockedEvent");
+		    this.logger.info("{} has been invoked", "customerUnlockedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -212,7 +230,7 @@
 	    )
 	    public void customerClosedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                    final String payload) {
-		    this.logger.debug("{} has been invoked", "customerClosedEvent");
+		    this.logger.info("{} has been invoked", "customerClosedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -228,7 +246,7 @@
 				    // TODO: Localize message
 				    // TODO: Pass message to template
 				    notificationService.sendEmail("fineractcnnotificationdemo@gmail.com",
-						    emailAddress, "Account created",
+						    emailAddress, "Account closed",
 						    "Dear Valued Customer," +
 								    "\n\nYour account has been Closed" +
 								    "\n\nBest Regards," +
@@ -243,7 +261,7 @@
 	    )
 	    public void customerReopenedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                      final String payload) {
-		    this.logger.debug("{} has been invoked", "customerReopenedEvent");
+		    this.logger.info("{} has been invoked", "customerReopenedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -275,7 +293,7 @@
 	    )
 	    public void contactDetailsChangedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                           final String payload) {
-		    this.logger.debug("{} has been invoked", "contactDetailsChangedEvent");
+		    this.logger.info("{} has been invoked", "contactDetailsChangedEvent");
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
 		    customer.getContactDetails().forEach(contact -> {
@@ -309,7 +327,7 @@
 	    )
 	    public void addressChangedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                                    final String payload) {
-		    this.logger.debug("{} has been invoked", "addressChangedEvent");
+		    this.logger.info("{} has been invoked", "addressChangedEvent");
 		
 		    Customer customer = this.notificationService.findCustomer(payload, tenant).get();
 		
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/listener/PortfolioEventListener.java b/service/src/main/java/org/apache/fineract/cn/notification/service/listener/PortfolioEventListener.java
index 2f860e5..acb116b 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/listener/PortfolioEventListener.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/listener/PortfolioEventListener.java
@@ -55,6 +55,12 @@ public class PortfolioEventListener {
 	)
 	public void onOpen(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                   final String payload) {
+		logger.debug("Payload: " + payload+ "Tenant" +tenant);
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour loan request has been denied" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -65,7 +71,10 @@ public class PortfolioEventListener {
 	public void onDeny(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                   final String payload) {
 		this.notificationService.sendSMS("+23058409206",
-				"Dear Valued Customer,\n\nYour loan request has been denied\n\nBest Regards\nYour MFI");
+				"Dear Valued Customer," +
+						"\n\nYour loan request has been denied" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -77,7 +86,10 @@ public class PortfolioEventListener {
 	                      final String payload) {
 		logger.info(payload);
 		this.notificationService.sendSMS("+23058409206",
-				"Dear Valued Customer,\n\nYour loan has been Approved and waiting disbursal\n\nBest Regards\nYour MFI");
+				"Dear Valued Customer," +
+						"\n\nYour loan has been Approved and waiting disbursal" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -87,18 +99,12 @@ public class PortfolioEventListener {
 	)
 	public void onDisburse(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                       final String payload) {
-		logger.info(payload);
+		logger.info(payload.toString());
 		this.notificationService.sendSMS("+23058409206",
-			"Dear Valued Customer,\n\nYour loan has been disbursed\n\nBest Regards\nYour MFI");
-	}
-	
-	@JmsListener(
-			subscription = IndividualLoanEventConstants.DESTINATION,
-			destination = IndividualLoanEventConstants.DESTINATION,
-			selector = IndividualLoanEventConstants.SELECTOR_APPLY_INTEREST_INDIVIDUALLOAN_CASE
-	)
-	public void onApplyInterest(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-	                            final String payload) {
+			"Dear Valued Customer," +
+					"\n\nYour loan has been disbursed" +
+					"\n\nBest Regards" +
+					"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -108,15 +114,11 @@ public class PortfolioEventListener {
 	)
 	public void onAcceptPayment(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                            final String payload) {
-	}
-	
-	@JmsListener(
-			subscription = IndividualLoanEventConstants.DESTINATION,
-			destination = IndividualLoanEventConstants.DESTINATION,
-			selector = IndividualLoanEventConstants.SELECTOR_CHECK_LATE_INDIVIDUALLOAN_CASE
-	)
-	public void onCheckLate(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-	                        final String payload) {
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour payment has been accepted" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -126,6 +128,12 @@ public class PortfolioEventListener {
 	)
 	public void onMarkLate(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                       final String payload) {
+		
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour payment for your loan is late" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -135,15 +143,11 @@ public class PortfolioEventListener {
 	)
 	public void onMarkInArrears(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                            final String payload) {
-	}
-	
-	@JmsListener(
-			subscription = IndividualLoanEventConstants.DESTINATION,
-			destination = IndividualLoanEventConstants.DESTINATION,
-			selector = IndividualLoanEventConstants.SELECTOR_WRITE_OFF_INDIVIDUALLOAN_CASE
-	)
-	public void onWriteOff(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
-	                       final String payload) {
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour payment has been marked as arrears for next payment" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -153,6 +157,11 @@ public class PortfolioEventListener {
 	)
 	public void onClose(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                    final String payload) {
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour loan has been closed" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 	
 	@JmsListener(
@@ -162,5 +171,10 @@ public class PortfolioEventListener {
 	)
 	public void onRecover(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
 	                      final String payload) {
+		this.notificationService.sendSMS("+23058409206",
+				"Dear Valued Customer," +
+						"\n\nYour arrears have been recovered" +
+						"\n\nBest Regards" +
+						"\nYour MFI");
 	}
 }
\ No newline at end of file
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
similarity index 56%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
index df36f03..2823b6d 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/EmailServiceRestController.java
@@ -23,18 +23,16 @@ import org.apache.fineract.cn.anubis.annotation.Permittable;
 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.client.ConfigurationNotFoundException;
 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.CreateEmailConfigurationCommand;
-import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
-import org.apache.fineract.cn.notification.service.internal.command.InitializeServiceCommand;
-import org.apache.fineract.cn.notification.service.internal.command.PostSMSCommand;
+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;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
@@ -44,53 +42,52 @@ import java.util.List;
 
 @SuppressWarnings("unused")
 @RestController
-@RequestMapping("/")
-public class NotificationRestController {
+@RequestMapping("/configuration/email")
+public class EmailServiceRestController {
 	
 	private final Logger logger;
 	private final CommandGateway commandGateway;
-	private final NotificationService notificationService;
+	private EmailService emailService;
 	
 	@Autowired
-	public NotificationRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+	public EmailServiceRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
 	                                  final CommandGateway commandGateway,
-	                                  final NotificationService notificationService) {
+	                                  final EmailService emailService) {
 		super();
 		this.logger = logger;
 		this.commandGateway = commandGateway;
-		this.notificationService = notificationService;
+		this.emailService = emailService;
 	}
 	
-	@Permittable(value = AcceptedTokenType.SYSTEM)
-	@RequestMapping(
-			value = "/initialize",
-			method = RequestMethod.POST,
-			consumes = MediaType.ALL_VALUE,
+	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
+	@RequestMapping(value = "/update",
+			method = RequestMethod.PUT,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> initialize() throws InterruptedException {
-		this.commandGateway.process(new InitializeServiceCommand());
+	ResponseEntity<Void> updateEmailConfiguration(@RequestBody @Valid final EmailConfiguration emailConfiguration) {
+		this.commandGateway.process(new UpdateEmailConfigurationCommand(emailConfiguration));
 		return ResponseEntity.accepted().build();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/sms/active",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
+	@RequestMapping(value = "/delete/{identifier}",
+			method = RequestMethod.DELETE,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return this.notificationService.findAllActiveSMSConfigurationEntities();
+	ResponseEntity<Void> deleteEmailConfiguration(@PathVariable @Valid final String identifier) {
+		this.commandGateway.process(new DeleteEmailConfigurationCommand(identifier));
+		return ResponseEntity.ok().build();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/email/active",
+			value = "/active",
 			method = RequestMethod.GET,
 			consumes = MediaType.ALL_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
@@ -98,62 +95,27 @@ public class NotificationRestController {
 	public
 	@ResponseBody
 	List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
-		return this.notificationService.findAllActiveEmailConfigurationEntities();
+		return this.emailService.findAllActiveEmailConfigurationEntities();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/sms/{identifier}",
+			value = "/{identifier}",
 			method = RequestMethod.GET,
 			consumes = MediaType.ALL_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<SMSConfiguration> findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-	throws ConfigurationNotFoundException {
-		return this.notificationService.findSMSConfigurationByIdentifier(identifier)
-				.map(ResponseEntity::ok)
-				.orElseThrow(() -> ServiceException.notFound("SMS Gateway Configuration with identifier " + identifier + " doesn't exist."));
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/{identifier}",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<EmailConfiguration> findEmailConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-			throws ConfigurationNotFoundException {
-		return this.notificationService.findEmailConfigurationByIdentifier(identifier)
+	ResponseEntity<EmailConfiguration> findEmailConfigurationByIdentifier(@PathVariable("identifier") final String identifier) {
+		return this.emailService.findEmailConfigurationByIdentifier(identifier)
 				.map(ResponseEntity::ok)
 				.orElseThrow(() -> ServiceException.notFound("Email Gateway Configuration with identifier " + identifier + " doesn't exist."));
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/sms/create",
-			method = RequestMethod.POST,
-			consumes = MediaType.APPLICATION_JSON_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<Void> createSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) throws InterruptedException {
-		if (this.notificationService.smsConfigurationExists(smsConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", smsConfiguration.getIdentifier());
-		}
-		
-		this.commandGateway.process(new CreateSMSConfigurationCommand(smsConfiguration));
-		return ResponseEntity.accepted().build();
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/create",
+			value = "/create",
 			method = RequestMethod.POST,
 			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
@@ -161,10 +123,11 @@ public class NotificationRestController {
 	public
 	@ResponseBody
 	ResponseEntity<Void> createEmailConfiguration(@RequestBody @Valid final EmailConfiguration emailConfiguration) throws InterruptedException {
-		if (this.notificationService.emailConfigurationExists(emailConfiguration.getIdentifier())) {
+		if (this.emailService.emailConfigurationExists(emailConfiguration.getIdentifier())) {
 			throw ServiceException.conflict("Configuration {0} already exists.", emailConfiguration.getIdentifier());
 		}
+		
 		this.commandGateway.process(new CreateEmailConfigurationCommand(emailConfiguration));
-		return ResponseEntity.accepted().build();
+		return new ResponseEntity<>(HttpStatus.CREATED);
 	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
index df36f03..5c1ceaa 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
@@ -23,14 +23,12 @@ import org.apache.fineract.cn.anubis.annotation.Permittable;
 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.client.ConfigurationNotFoundException;
 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.CreateEmailConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
 import org.apache.fineract.cn.notification.service.internal.command.InitializeServiceCommand;
-import org.apache.fineract.cn.notification.service.internal.command.PostSMSCommand;
 import org.apache.fineract.cn.notification.service.internal.service.NotificationService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -75,96 +73,4 @@ public class NotificationRestController {
 		return ResponseEntity.accepted().build();
 	}
 	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/sms/active",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return this.notificationService.findAllActiveSMSConfigurationEntities();
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/active",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
-		return this.notificationService.findAllActiveEmailConfigurationEntities();
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/sms/{identifier}",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<SMSConfiguration> findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-	throws ConfigurationNotFoundException {
-		return this.notificationService.findSMSConfigurationByIdentifier(identifier)
-				.map(ResponseEntity::ok)
-				.orElseThrow(() -> ServiceException.notFound("SMS Gateway Configuration with identifier " + identifier + " doesn't exist."));
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/{identifier}",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<EmailConfiguration> findEmailConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-			throws ConfigurationNotFoundException {
-		return this.notificationService.findEmailConfigurationByIdentifier(identifier)
-				.map(ResponseEntity::ok)
-				.orElseThrow(() -> ServiceException.notFound("Email Gateway Configuration with identifier " + identifier + " doesn't exist."));
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/sms/create",
-			method = RequestMethod.POST,
-			consumes = MediaType.APPLICATION_JSON_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<Void> createSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) throws InterruptedException {
-		if (this.notificationService.smsConfigurationExists(smsConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", smsConfiguration.getIdentifier());
-		}
-		
-		this.commandGateway.process(new CreateSMSConfigurationCommand(smsConfiguration));
-		return ResponseEntity.accepted().build();
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/create",
-			method = RequestMethod.POST,
-			consumes = MediaType.APPLICATION_JSON_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<Void> createEmailConfiguration(@RequestBody @Valid final EmailConfiguration emailConfiguration) throws InterruptedException {
-		if (this.notificationService.emailConfigurationExists(emailConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", emailConfiguration.getIdentifier());
-		}
-		this.commandGateway.process(new CreateEmailConfigurationCommand(emailConfiguration));
-		return ResponseEntity.accepted().build();
-	}
 }
diff --git a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
similarity index 53%
copy from service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
copy to service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
index df36f03..b9a6e83 100644
--- a/service/src/main/java/org/apache/fineract/cn/notification/service/rest/NotificationRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/notification/service/rest/SMSServiceRestController.java
@@ -23,18 +23,16 @@ import org.apache.fineract.cn.anubis.annotation.Permittable;
 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.client.ConfigurationNotFoundException;
-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.SMSConfiguration;
 import org.apache.fineract.cn.notification.service.ServiceConstants;
-import org.apache.fineract.cn.notification.service.internal.command.CreateEmailConfigurationCommand;
-import org.apache.fineract.cn.notification.service.internal.command.CreateSMSConfigurationCommand;
-import org.apache.fineract.cn.notification.service.internal.command.InitializeServiceCommand;
-import org.apache.fineract.cn.notification.service.internal.command.PostSMSCommand;
+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;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
@@ -44,40 +42,26 @@ import java.util.List;
 
 @SuppressWarnings("unused")
 @RestController
-@RequestMapping("/")
-public class NotificationRestController {
+@RequestMapping("/configuration/sms/")
+public class SMSServiceRestController {
 	
 	private final Logger logger;
 	private final CommandGateway commandGateway;
-	private final NotificationService notificationService;
+	private final SMSService smsService;
 	
 	@Autowired
-	public NotificationRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
-	                                  final CommandGateway commandGateway,
-	                                  final NotificationService notificationService) {
+	public SMSServiceRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+	                                final CommandGateway commandGateway,
+	                                final SMSService smsService) {
 		super();
 		this.logger = logger;
 		this.commandGateway = commandGateway;
-		this.notificationService = notificationService;
-	}
-	
-	@Permittable(value = AcceptedTokenType.SYSTEM)
-	@RequestMapping(
-			value = "/initialize",
-			method = RequestMethod.POST,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	ResponseEntity<Void> initialize() throws InterruptedException {
-		this.commandGateway.process(new InitializeServiceCommand());
-		return ResponseEntity.accepted().build();
+		this.smsService = smsService;
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/sms/active",
+			value = "/active",
 			method = RequestMethod.GET,
 			consumes = MediaType.ALL_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
@@ -85,86 +69,65 @@ public class NotificationRestController {
 	public
 	@ResponseBody
 	List<SMSConfiguration> findAllActiveSMSConfigurationEntities() {
-		return this.notificationService.findAllActiveSMSConfigurationEntities();
-	}
-	
-	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/active",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
-			produces = MediaType.APPLICATION_JSON_VALUE
-	)
-	public
-	@ResponseBody
-	List<EmailConfiguration> findAllActiveEmailConfigurationEntities() {
-		return this.notificationService.findAllActiveEmailConfigurationEntities();
+		return this.smsService.findAllActiveSMSConfigurationEntities();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/sms/{identifier}",
+			value = "/{identifier}",
 			method = RequestMethod.GET,
 			consumes = MediaType.ALL_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<SMSConfiguration> findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-	throws ConfigurationNotFoundException {
-		return this.notificationService.findSMSConfigurationByIdentifier(identifier)
+	ResponseEntity<SMSConfiguration> findSMSConfigurationByIdentifier(@PathVariable("identifier") final String identifier) {
+		return this.smsService.findSMSConfigurationByIdentifier(identifier)
 				.map(ResponseEntity::ok)
 				.orElseThrow(() -> ServiceException.notFound("SMS Gateway Configuration with identifier " + identifier + " doesn't exist."));
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
 	@RequestMapping(
-			value = "/notification/email/{identifier}",
-			method = RequestMethod.GET,
-			consumes = MediaType.ALL_VALUE,
+			value = "/create",
+			method = RequestMethod.POST,
+			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<EmailConfiguration> findEmailConfigurationByIdentifier(@PathVariable("identifier") final String identifier)
-			throws ConfigurationNotFoundException {
-		return this.notificationService.findEmailConfigurationByIdentifier(identifier)
-				.map(ResponseEntity::ok)
-				.orElseThrow(() -> ServiceException.notFound("Email Gateway Configuration with identifier " + identifier + " doesn't exist."));
+	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());
+		}
+		
+		this.commandGateway.process(new CreateSMSConfigurationCommand(smsConfiguration));
+		return new ResponseEntity<>(HttpStatus.CREATED);
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/sms/create",
-			method = RequestMethod.POST,
+	@RequestMapping(value = "/update",
+			method = RequestMethod.PUT,
 			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> createSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) throws InterruptedException {
-		if (this.notificationService.smsConfigurationExists(smsConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", smsConfiguration.getIdentifier());
-		}
-		
-		this.commandGateway.process(new CreateSMSConfigurationCommand(smsConfiguration));
+	ResponseEntity<Void> updateSMSConfiguration(@RequestBody @Valid final SMSConfiguration smsConfiguration) {
+		this.commandGateway.process(new UpdateSMSConfigurationCommand(smsConfiguration));
 		return ResponseEntity.accepted().build();
 	}
 	
 	@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SELF_MANAGEMENT)
-	@RequestMapping(
-			value = "/notification/email/create",
-			method = RequestMethod.POST,
+	@RequestMapping(value = "/delete/{identifier}",
+			method = RequestMethod.DELETE,
 			consumes = MediaType.APPLICATION_JSON_VALUE,
 			produces = MediaType.APPLICATION_JSON_VALUE
 	)
 	public
 	@ResponseBody
-	ResponseEntity<Void> createEmailConfiguration(@RequestBody @Valid final EmailConfiguration emailConfiguration) throws InterruptedException {
-		if (this.notificationService.emailConfigurationExists(emailConfiguration.getIdentifier())) {
-			throw ServiceException.conflict("Configuration {0} already exists.", emailConfiguration.getIdentifier());
-		}
-		this.commandGateway.process(new CreateEmailConfigurationCommand(emailConfiguration));
-		return ResponseEntity.accepted().build();
+	ResponseEntity<Void> deleteSMSConfiguration(@PathVariable @Valid final String identifier) {
+		this.commandGateway.process(new DeleteSMSConfigurationCommand(identifier));
+		return ResponseEntity.ok().build();
 	}
 }
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index fa7165e..a1d6207 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -82,7 +82,5 @@ async:
 flyway:
   enabled: false
 
-smssender:
-  accountSID: AC1fde2c6f26f367b93231c5fdb944c908
-  authToken: bc9a53e41745b8471e0ecafc859d86aa
-  senderNumber: +1 510-944-1898
+notification:
+  user: wadaadmin
\ No newline at end of file
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 57cefe1..7f66214 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
@@ -21,12 +21,12 @@
 -- Table wada_sms_gateway_configurations
 -- -----------------------------------------------------
 CREATE TABLE wada_sms_gateway_configurations (
-  id INT(11) NOT NULL AUTO_INCREMENT,
+  id INT(45) NOT NULL AUTO_INCREMENT,
   identifier VARCHAR(45) NULL DEFAULT NULL,
   account_sid VARCHAR(255) NOT NULL,
   auth_token VARCHAR(255) NOT NULL,
   sender_number VARCHAR(45) NOT NULL,
-  state VARCHAR(45) NULL DEFAULT NULL,
+  state VARCHAR(20) NULL DEFAULT NULL,
   PRIMARY KEY (id));
 
 -- -----------------------------------------------------
@@ -42,7 +42,7 @@ CREATE TABLE wada_email_gateway_configurations (
   protocol VARCHAR(45)NOT NULL,
   smtp_auth VARCHAR (45)NOT NULL,
   start_tls VARCHAR (45)NOT NULL,
-  state VARCHAR(45)NOT NULL,
+  state VARCHAR(10)NOT NULL,
   PRIMARY KEY (id));
 
 -- -----------------------------------------------------
@@ -54,3 +54,17 @@ CREATE TABLE wada_templates (
   event VARCHAR(45) 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', 'AC1fde2c6f26f367b93231c5fdb944c908', 'bc9a53e41745b8471e0ecafc859d86aa', '+1 510-944-1898', 'ACTIVE');
+INSERT INTO wada_email_gateway_configurations VALUES ('1', 'Gmail', 'smtp.gmail.com', '587','fineractcnnotificationdemo@gmail.com', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE');
\ No newline at end of file
diff --git a/service/src/main/resources/db/migrations/mariadb/V2__sms_gateway_configurations.sql b/service/src/main/resources/db/migrations/mariadb/V2__sms_gateway_configurations.sql
deleted file mode 100644
index d795f01..0000000
--- a/service/src/main/resources/db/migrations/mariadb/V2__sms_gateway_configurations.sql
+++ /dev/null
@@ -1,20 +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.
---
-
-INSERT INTO wada_sms_gateway_configurations VALUES ('1', 'Twilio', 'AC1fde2c6f26f367b93231c5fdb944c908', 'c9a53e41745b8471e0ecafc859d86aa', '+1 510-944-1898', 'ACTIVE');
\ No newline at end of file
diff --git a/service/src/main/resources/db/migrations/mariadb/V3__email_gateway_configurations.sql b/service/src/main/resources/db/migrations/mariadb/V3__email_gateway_configurations.sql
deleted file mode 100644
index 9482b7c..0000000
--- a/service/src/main/resources/db/migrations/mariadb/V3__email_gateway_configurations.sql
+++ /dev/null
@@ -1,20 +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.
---
-
-INSERT INTO wada_email_gateway_configurations VALUES ('1', 'Gmail', 'smtp.gmail.com', '587','fineractcnnotificationdemo@gmail.com', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE');
\ No newline at end of file
diff --git a/shared.gradle b/shared.gradle
index 6b000b7..426ccf2 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -19,25 +19,27 @@ group 'org.apache.fineract.cn.notification'
 version '0.1.0-BUILD-SNAPSHOT'
 
 ext.versions = [
-        fineractcnidentity      : '0.1.0-BUILD-SNAPSHOT',
-        fineractcnoffice        : '0.1.0-BUILD-SNAPSHOT',
-        fineractcncustomer      : '0.1.0-BUILD-SNAPSHOT',
-        fineractcnaccounting    : '0.1.0-BUILD-SNAPSHOT',
-        fineractcnportfolio     : '0.1.0-BUILD-SNAPSHOT',
-        fineractcnteller        : '0.1.0-BUILD-SNAPSHOT',
-        fineractcnpayroll       : '0.1.0-BUILD-SNAPSHOT',
-        fineractcngroup         : '0.1.0-BUILD-SNAPSHOT',
-        frameworkapi            : '0.1.0-BUILD-SNAPSHOT',
-        frameworklang           : '0.1.0-BUILD-SNAPSHOT',
-        frameworkasync          : '0.1.0-BUILD-SNAPSHOT',
-        frameworkcassandra      : '0.1.0-BUILD-SNAPSHOT',
-        frameworkmariadb        : '0.1.0-BUILD-SNAPSHOT',
-        frameworkcommand        : '0.1.0-BUILD-SNAPSHOT',
-        frameworktest           : '0.1.0-BUILD-SNAPSHOT',
-        frameworkanubis         : '0.1.0-BUILD-SNAPSHOT',
-        validator               : '5.3.0.Final',
-        springjavamail          : '1.4.1.RELEASE',
-        twilioapi               : '7.17.+'
+        fineractcnidentity              : '0.1.0-BUILD-SNAPSHOT',
+        fineractcnoffice                : '0.1.0-BUILD-SNAPSHOT',
+        fineractcncustomer              : '0.1.0-BUILD-SNAPSHOT',
+        fineractcnaccounting            : '0.1.0-BUILD-SNAPSHOT',
+        fineractcnportfolio             : '0.1.0-BUILD-SNAPSHOT',
+        fineractcnteller                : '0.1.0-BUILD-SNAPSHOT',
+        fineractcnpayroll               : '0.1.0-BUILD-SNAPSHOT',
+        fineractcngroup                 : '0.1.0-BUILD-SNAPSHOT',
+        frameworkapi                    : '0.1.0-BUILD-SNAPSHOT',
+        frameworklang                   : '0.1.0-BUILD-SNAPSHOT',
+        frameworkasync                  : '0.1.0-BUILD-SNAPSHOT',
+        frameworkcassandra              : '0.1.0-BUILD-SNAPSHOT',
+        frameworkmariadb                : '0.1.0-BUILD-SNAPSHOT',
+        frameworkcommand                : '0.1.0-BUILD-SNAPSHOT',
+        frameworktest                   : '0.1.0-BUILD-SNAPSHOT',
+        frameworkanubis                 : '0.1.0-BUILD-SNAPSHOT',
+        frameworkpermittedfeignclient   : '0.1.0-BUILD-SNAPSHOT',
+        validator                       : '5.3.0.Final',
+        springjavamail                  : '1.4.1.RELEASE',
+        twilioapi                       : '7.17.+',
+        junit                           : '4.12'
 ]
 
 apply plugin: 'java'