This is an automated email from the ASF dual-hosted git repository. ikamga pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-notifications.git
commit 339f83f092537b7fe976b10ae661831b4e98e61d Merge: 13a1f55 6250a32 Author: Ebenezer Graham <[email protected]> AuthorDate: Thu Jun 6 11:48:42 2019 +0400 Merge branch 'develop' into FINCN-156 .travis.yml | 6 +- Dockerfile | 4 +- README.md | 5 +- .../api/v1/client/NotificationManager.java | 3 + .../api/v1/events/NotificationEventConstants.java | 8 +- .../cn/notification/AbstractNotificationTest.java | 4 +- .../fineract/cn/notification/TestEmailService.java | 37 ++--- .../fineract/cn/notification/TestSMSService.java | 9 +- .../notification/importer/TestTemplateImport.java | 10 +- .../cn/notification/listener/EventListener.java | 153 +++++++++++++++++++++ .../main/resources/importdata/test-templates.csv | 18 --- .../src/main/resources/templates/template.html | 2 +- service/build.gradle | 1 - .../service/internal/service/EmailService.java | 6 +- .../service/internal/service/SMSService.java | 6 +- .../db/migrations/mariadb/V1__initial_setup.sql | 13 ++ .../main/resources/templatedetails/templates.csv | 18 --- shared.gradle | 11 +- 18 files changed, 217 insertions(+), 97 deletions(-) diff --cc api/src/main/java/org/apache/fineract/cn/notification/api/v1/client/NotificationManager.java index 992a5bb,8b6c76c..1123f86 --- 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 @@@ -69,14 -68,6 +69,17 @@@ public interface NotificationManager String createEmailConfiguration(final EmailConfiguration emailConfiguration); @RequestMapping( + value = "/template/create", + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE + ) ++ @ThrowsExceptions({ ++ @ThrowsException(status = HttpStatus.UNPROCESSABLE_ENTITY, exception = TemplateAlreadyExistException.class) ++ }) + String createTemplate(final Template template); + + @RequestMapping( value = "/configuration/sms/{identifier}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, diff --cc api/src/main/java/org/apache/fineract/cn/notification/api/v1/events/NotificationEventConstants.java index ef54997,cf4ba28..4711a87 --- 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 @@@ -33,11 -32,10 +33,11 @@@ public interface NotificationEventConst String UPDATE_EMAIL_CONFIGURATION = "update-email-configuration"; String DELETE_SMS_CONFIGURATION = "delete-sms-configuration"; String DELETE_EMAIL_CONFIGURATION = "delete-email-configuration"; + String DELETE_TEMPLATE = "delete-template"; String DELETE_SOURCE_APPLICATION = "delete-source-application"; - String POST_SEND_EMAIL_NOTIFICATION = "post-send-email-notification"; - String POST_SEND_SMS_NOTIFICATION = "post-send-sms-notification"; + String SEND_EMAIL_NOTIFICATION = "post-send-email-notification"; + String 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"; diff --cc component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java index 1f9c45a,d80eef2..194c6c5 --- a/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java +++ b/component-test/src/main/java/org/apache/fineract/cn/notification/AbstractNotificationTest.java @@@ -53,8 -51,6 +53,8 @@@ public class AbstractNotificationTest e public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer); public static final String LOGGER_NAME = "test-logger"; public static final String TEST_USER = "homer"; + public static final String TEST_ADDRESS = "[email protected]"; - public static final String TEST_TEMPLATE= "test_sample"; ++ public static final String TEST_TEMPLATE= "sample"; @SuppressWarnings("WeakerAccess") @Autowired @@@ -63,11 -59,6 +63,11 @@@ public AutoUserContext userContext; @Autowired public EventRecorder eventRecorder; + @Autowired - public NotificationManager testSubject; ++ public NotificationManager notificationManager; + @Autowired + public NotificationService notificationService; + @Rule public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize); diff --cc component-test/src/main/java/org/apache/fineract/cn/notification/TestEmailService.java index 702e437,69a1133..bfeb5b7 --- 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 @@@ -49,64 -46,30 +49,49 @@@ public class TestEmailService extends A emailConfiguration = DomainObjectGenerator.emailConfiguration(); } - + @Test - public void shouldSendAnEmail() throws InterruptedException, IOException { ++ public void shouldSendAnEmail() throws InterruptedException,IOException { + this.logger.info("Send Email Notification"); - final TemplateImporter importer = new TemplateImporter(testSubject, logger); - final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv"); - importer.importCSV(uri); - // Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE)); - eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE); - + notificationService.sendEmail( + TEST_ADDRESS, + TEST_TEMPLATE, + null); - //Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS )); - this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS ); ++ //Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.SEND_EMAIL_NOTIFICATION,TEST_ADDRESS )); + } @Test - public void shouldSendAnEmail() throws InterruptedException { + public void shouldSendFormattedEmail() throws InterruptedException, IOException { this.logger.info("Send Email Notification"); - final TemplateImporter importer = new TemplateImporter(testSubject, logger); - final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv"); - importer.importCSV(uri); - - //Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE)); - eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, TEST_TEMPLATE); - String to = notificationService.sendEmail("[email protected]", - "[email protected]", - "Address Details Changed", - "Dear Valued Customer," + - "\n\nYour address has been changed successfully" + - "\nStreet: Test Street" + - "\nCity: Test City" + - "\nState: Test State" + - "\nCountry: Mauritius" + - "\n\nBest Regards" + - "\nMFI"); - Assert.assertNotNull(to); + Customer customerPayload = new Customer(); + customerPayload.setGivenName("Test"); + customerPayload.setSurname("User"); + Address address = new Address(); + address.setCity("Cape Coast"); + address.setCity("Street"); + address.setCountry("Ghana"); + address.setCountryCode("GH"); + address.setRegion("Central Region"); + address.setPostalCode("T22022"); + customerPayload.setAddress(address); + + Map<String, Object> templateVariables = new HashMap<>(); + templateVariables.put(customerPayload.getClass().getName().toLowerCase(),customerPayload); + + notificationService.sendFormattedEmail( + TEST_ADDRESS, + TEST_TEMPLATE, + templateVariables + ); + - //Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS )); - this.eventRecorder.wait(NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION,TEST_ADDRESS ); ++ //Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.SEND_EMAIL_NOTIFICATION,TEST_ADDRESS )); } @Test(expected = NotFoundException.class) public void emailConfigurationNotFound() throws ConfigurationNotFoundException { logger.info("Configuration not found"); try { - this.testSubject.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8)); - this.notificationManager.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8)); ++ notificationManager.findEmailConfigurationByIdentifier(RandomStringUtils.randomAlphanumeric(8)); } catch (final ConfigurationNotFoundException ex) { logger.info("Error Asserted"); } @@@ -115,21 -78,19 +100,19 @@@ @Test public void shouldCreateAndRetrieveEmailConfigurationEntity() throws InterruptedException { logger.info("Create and Retrieve Email Gateway configuration"); - this.testSubject.createEmailConfiguration(emailConfiguration); - this.notificationManager.createEmailConfiguration(emailConfiguration); ++ notificationManager.createEmailConfiguration(emailConfiguration); - this.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier()); + Assert.assertTrue(this.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier())); - EmailConfiguration sampleRetrieved = this.testSubject.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier()); - Assert.assertNotNull(sampleRetrieved); - Assert.assertEquals(sampleRetrieved.getIdentifier(), emailConfiguration.getIdentifier()); - EmailConfiguration sampleRetrieved = this.notificationManager.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier()); ++ EmailConfiguration sampleRetrieved = notificationManager.findEmailConfigurationByIdentifier(emailConfiguration.getIdentifier()); + Assert.assertEquals(sampleRetrieved.getIdentifier(),emailConfiguration.getIdentifier()); } @Test public void checkEmailConfigurationEntityExist() throws InterruptedException { logger.info("Email Gateway configuration Exist"); - this.testSubject.createEmailConfiguration(emailConfiguration); - super.eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier()); - - this.notificationManager.createEmailConfiguration(emailConfiguration); ++ notificationManager.createEmailConfiguration(emailConfiguration); + Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, emailConfiguration.getIdentifier())); Assert.assertTrue(this.emailService.emailConfigurationExists(emailConfiguration.getIdentifier())); } diff --cc component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java index 57b2dc7,0000000..17d3bf7 mode 100644,000000..100644 --- a/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java +++ b/component-test/src/main/java/org/apache/fineract/cn/notification/importer/TestTemplateImport.java @@@ -1,57 -1,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.importer; + +import org.apache.fineract.cn.notification.AbstractNotificationTest; +import org.apache.fineract.cn.notification.api.v1.domain.Template; +import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants; +import org.apache.fineract.cn.notification.service.internal.importer.TemplateImporter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URL; + + +public class TestTemplateImport extends AbstractNotificationTest { + + public TestTemplateImport() { + super(); + } + + @Test + public void testTemplateImportHappyCase() throws IOException, InterruptedException { + final Template template = new Template(); + template.setTemplateIdentifier("test-sample"); + template.setSenderEmail("[email protected]"); + template.setSubject("Test"); + template.setMessage("Message"); + template.setUrl("test/url"); + - testSubject.createTemplate(template); - //Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier())); - eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier()); ++ notificationManager.createTemplate(template); ++ Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier())); + - final TemplateImporter importer = new TemplateImporter(testSubject, logger); ++ final TemplateImporter importer = new TemplateImporter(notificationManager, logger); + final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv"); + importer.importCSV(uri); - //Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "sample")); - eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "sample"); ++ Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "test_sample")); + } +} diff --cc component-test/src/main/java/org/apache/fineract/cn/notification/listener/EventListener.java index 0000000,8aab1ca..8db258b mode 000000,100644..100644 --- a/component-test/src/main/java/org/apache/fineract/cn/notification/listener/EventListener.java +++ b/component-test/src/main/java/org/apache/fineract/cn/notification/listener/EventListener.java @@@ -1,0 -1,103 +1,153 @@@ + /* + * 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.listener; + + import org.apache.fineract.cn.lang.config.TenantHeaderFilter; + import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants; + import org.apache.fineract.cn.notification.service.ServiceConstants; + import org.apache.fineract.cn.test.listener.EventRecorder; + import org.slf4j.Logger; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.jms.annotation.JmsListener; + import org.springframework.messaging.handler.annotation.Header; + import org.springframework.stereotype.Component; + + @SuppressWarnings("unused") + @Component + public class EventListener { + private final EventRecorder eventRecorder; + private final Logger logger; + + @Autowired + public EventListener(final EventRecorder eventRecorder, + @Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger) { + this.logger = logger; + this.eventRecorder = eventRecorder; + } + + @JmsListener( + subscription = NotificationEventConstants.DESTINATION, + destination = NotificationEventConstants.DESTINATION, + selector = NotificationEventConstants.SELECTOR_POST_EMAIL_CONFIGURATION + ) + public void postEmailConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, NotificationEventConstants.POST_EMAIL_CONFIGURATION, payload, String.class); + } + + @JmsListener( + subscription = NotificationEventConstants.DESTINATION, + destination = NotificationEventConstants.DESTINATION, + selector = NotificationEventConstants.SELECTOR_POST_SMS_CONFIGURATION + ) + public void postSMSConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, NotificationEventConstants.POST_SMS_CONFIGURATION, payload, String.class); + } + + @JmsListener( + subscription = NotificationEventConstants.DESTINATION, + destination = NotificationEventConstants.DESTINATION, + selector = NotificationEventConstants.SELECTOR_SEND_EMAIL_NOTIFICATION + ) + public void onSendEmailTrigger(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, NotificationEventConstants.SEND_EMAIL_NOTIFICATION, payload, String.class); + } + + @JmsListener( + subscription = NotificationEventConstants.DESTINATION, + destination = NotificationEventConstants.DESTINATION, + selector = NotificationEventConstants.SELECTOR_SEND_SMS_NOTIFICATION + ) + public void onSendSmsTrigger(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, NotificationEventConstants.SEND_SMS_NOTIFICATION, payload, String.class); + } + ++ @JmsListener( ++ subscription = NotificationEventConstants.DESTINATION, ++ destination = NotificationEventConstants.DESTINATION, ++ selector = NotificationEventConstants.SELECTOR_DELETE_EMAIL_CONFIGURATION ++ ) ++ public void onDeleteEmailConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, ++ final String payload) { ++ this.eventRecorder.event(tenant, NotificationEventConstants.DELETE_EMAIL_CONFIGURATION, payload, String.class); ++ } ++ ++ @JmsListener( ++ subscription = NotificationEventConstants.DESTINATION, ++ destination = NotificationEventConstants.DESTINATION, ++ selector = NotificationEventConstants.SELECTOR_DELETE_SMS_CONFIGURATION ++ ) ++ public void onDeleteSmsConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, ++ final String payload) { ++ this.eventRecorder.event(tenant, NotificationEventConstants.DELETE_SMS_CONFIGURATION, payload, String.class); ++ } ++ ++ @JmsListener( ++ subscription = NotificationEventConstants.DESTINATION, ++ destination = NotificationEventConstants.DESTINATION, ++ selector = NotificationEventConstants.SELECTOR_UPDATE_EMAIL_CONFIGURATION ++ ) ++ public void onUpdateEmailConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, ++ final String payload) { ++ this.eventRecorder.event(tenant, NotificationEventConstants.UPDATE_EMAIL_CONFIGURATION, payload, String.class); ++ } ++ ++ @JmsListener( ++ subscription = NotificationEventConstants.DESTINATION, ++ destination = NotificationEventConstants.DESTINATION, ++ selector = NotificationEventConstants.SELECTOR_UPDATE_SMS_CONFIGURATION ++ ) ++ public void onUpdateSmsConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, ++ final String payload) { ++ this.eventRecorder.event(tenant, NotificationEventConstants.UPDATE_SMS_CONFIGURATION, payload, String.class); ++ } ++ ++ @JmsListener( ++ subscription = NotificationEventConstants.DESTINATION, ++ destination = NotificationEventConstants.DESTINATION, ++ selector = NotificationEventConstants.SELECTOR_POST_TEMPLATE ++ ) ++ public void onPostTemplate(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, ++ final String payload) { ++ this.eventRecorder.event(tenant, NotificationEventConstants.POST_TEMPLATE, payload, String.class); ++ } ++ + } diff --cc component-test/src/main/resources/importdata/test-templates.csv index d204bf1,0000000..4c01285 mode 100644,000000..100644 --- a/component-test/src/main/resources/importdata/test-templates.csv +++ b/component-test/src/main/resources/importdata/test-templates.csv @@@ -1,20 -1,0 +1,2 @@@ - - - - Licensed to the Apache Software Foundation (ASF) under one - - or more contributor license agreements. See the NOTICE file - - distributed with this work for additional information - - regarding copyright ownership. The ASF licenses this file - - to you under the Apache License, Version 2.0 (the - - "License"); you may not use this file except in compliance - - with the License. You may obtain a copy of the License at - - - - http://www.apache.org/licenses/LICENSE-2.0 - - - - Unless required by applicable law or agreed to in writing, - - software distributed under the License is distributed on an - - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - - KIND, either express or implied. See the License for the - - specific language governing permissions and limitations - - under the License. - - +template_identifier,sender_email,subject,message,url +test_sample,DEFAULT,Test Sample,This is a test message,template diff --cc component-test/src/main/resources/templates/template.html index d6a4d1c,0000000..745db88 mode 100644,000000..100644 --- a/component-test/src/main/resources/templates/template.html +++ b/component-test/src/main/resources/templates/template.html @@@ -1,457 -1,0 +1,457 @@@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<!doctype html> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:th="http://www.thymeleaf.org"> +<head> + <meta name="viewport" content="width=device-width"/> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + <title>Simple Email</title> + <link href="https://fonts.googleapis.com/css?family=helvatica" rel="stylesheet"/> + <style> + /* ------------------------------------- + GLOBAL RESETS + ------------------------------------- */ + + /*All the styling goes here*/ + + img { + border: none; + -ms-interpolation-mode: bicubic; + max-width: 100%; + } + + body { + background-color: #f6f6f6; + font-family: sans-serif; + -webkit-font-smoothing: antialiased; + font-size: 14px; + line-height: 1.4; + margin: 0; + padding: 0; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + } + + table { + border-collapse: separate; + mso-table-lspace: 0pt; + mso-table-rspace: 0pt; + width: 100%; + } + + table td { + font-family: sans-serif; + font-size: 14px; + vertical-align: top; + } + + /* ------------------------------------- + CONTAINER + ------------------------------------- */ + + .body { + background-color: #f6f6f6; + width: 100%; + } + + /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */ + .container { + display: block; + margin: 0 auto !important; + /* makes it centered */ + max-width: 580px; + padding: 10px; + width: 580px; + } + + /* This should also be a block element, so that it will fill 100% of the .container */ + .content { + box-sizing: border-box; + display: block; + margin: 0 auto; + max-width: 580px; + padding: 10px; + } + + /* ------------------------------------- + HEADER, FOOTER, MAIN + ------------------------------------- */ + .main { + background: #ffffff; + border-radius: 3px; + width: 100%; + } + + .wrapper { + box-sizing: border-box; + padding: 20px; + } + + .content-block { + padding-bottom: 10px; + padding-top: 10px; + } + + .footer { + clear: both; + margin-top: 10px; + text-align: center; + width: 100%; + } + + .footer td, + .footer p, + .footer span, + .footer a { + color: #999999; + font-size: 12px; + text-align: center; + } + + /* ------------------------------------- + TYPOGRAPHY + ------------------------------------- */ + h1, + h2, + h3, + h4 { + color: #000000; + font-family: sans-serif; + font-weight: 400; + line-height: 1.4; + margin: 0; + margin-bottom: 30px; + } + + h1 { + font-size: 35px; + font-weight: 300; + text-align: center; + text-transform: capitalize; + } + + p, + ul, + ol { + font-family: sans-serif; + font-size: 14px; + font-weight: normal; + margin: 0; + margin-bottom: 15px; + } + + p li, + ul li, + ol li { + list-style-position: inside; + margin-left: 5px; + } + + a { + color: #a92334; + text-decoration: underline; + } + + /* ------------------------------------- + BUTTONS + ------------------------------------- */ + .btn { + box-sizing: border-box; + width: 100%; + } + + .btn > tbody > tr > td { + padding-bottom: 15px; + } + + .btn table { + width: auto; + } + + .btn table td { + background-color: #ffffff; + border-radius: 5px; + text-align: center; + } + + .btn a { + background-color: #ffffff; + border: solid 1px #a92334; + border-radius: 5px; + box-sizing: border-box; + color: #a92334; + cursor: pointer; + display: inline-block; + font-size: 14px; + font-weight: bold; + margin: 0; + padding: 12px 25px; + text-decoration: none; + text-transform: capitalize; + } + + .btn-primary table td { + background-color: #a92334; + } + + .btn-primary a { + background-color: #a92334; + border-color: #a92334; + color: #ffffff; + } + + /* ------------------------------------- + OTHER STYLES THAT MIGHT BE USEFUL + ------------------------------------- */ + .last { + margin-bottom: 0; + } + + .first { + margin-top: 0; + } + + .align-center { + text-align: center; + } + + .align-right { + text-align: right; + } + + .align-left { + text-align: left; + } + + .clear { + clear: both; + } + + .mt0 { + margin-top: 0; + } + + .mb0 { + margin-bottom: 0; + } + + .preheader { + color: transparent; + display: none; + height: 0; + max-height: 0; + max-width: 0; + opacity: 0; + overflow: hidden; + mso-hide: all; + visibility: hidden; + width: 0; + } + + .powered-by a { + text-decoration: none; + } + + hr { + border: 0; + border-bottom: 1px solid #f6f6f6; + margin: 20px 0; + } + + /* ------------------------------------- + RESPONSIVE AND MOBILE FRIENDLY STYLES + ------------------------------------- */ + @media only screen and (max-width: 620px) { + table[class=body] h1 { + font-size: 28px !important; + margin-bottom: 10px !important; + } + + table[class=body] p, + table[class=body] ul, + table[class=body] ol, + table[class=body] td, + table[class=body] span, + table[class=body] a { + font-size: 16px !important; + } + + table[class=body] .wrapper, + table[class=body] .article { + padding: 10px !important; + } + + table[class=body] .content { + padding: 0 !important; + } + + table[class=body] .container { + padding: 0 !important; + width: 100% !important; + } + + table[class=body] .main { + border-left-width: 0 !important; + border-radius: 0 !important; + border-right-width: 0 !important; + } + + table[class=body] .btn table { + width: 100% !important; + } + + table[class=body] .btn a { + width: 100% !important; + } + + table[class=body] .img-responsive { + height: auto !important; + max-width: 100% !important; + width: auto !important; + } + } + + /* ------------------------------------- + PRESERVE THESE STYLES IN THE HEAD + ------------------------------------- */ + @media all { + .headTab{ + height: 60px; + width: auto; + max-width: 540px; + padding: 10px; + margin: 0 auto; + background-color: #ffffff; + /*-webkit-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69); + -moz-box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69); + box-shadow: 0px -1px 139px -25px rgba(0,0,0,0.69);*/ + } + .ExternalClass { + width: 100%; + } + + .ExternalClass, + .ExternalClass p, + .ExternalClass span, + .ExternalClass font, + .ExternalClass td, + .ExternalClass div { + line-height: 100%; + } + + .apple-link a { + color: inherit !important; + font-family: inherit !important; + font-size: inherit !important; + font-weight: inherit !important; + line-height: inherit !important; + text-decoration: none !important; + } + + .btn-primary table td:hover { + background-color: #a92334 !important; + } + + .btn-primary a:hover { + background-color: #a92334 !important; + border-color: #a92334 !important; + } + } + + </style> +</head> +<body> +<span class="preheader">Header Message</span> +<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body"> + + <tr> + <td> </td> + + <td class="container"> - <div class="headTab"><img style="height:40px; margin:10px;" class="img-responsive" src="http://fineract.apache.org/images/apache-fineract-logo.png" alt="Logo"></div> ++ <div class="headTab"><img style="height:40px; margin:10px;" class="img-responsive" src="http://fineract.apache.org/images/apache-fineract-logo.png" alt="Logo"/></div> + + <div class="content"> + + <!-- START CENTERED WHITE CONTAINER --> + <table role="presentation" class="main"> + + <!-- START MAIN CONTENT AREA --> + <tr> + <td class="wrapper"> + <table role="presentation" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <p>Dear Valued Customer,</p> + + <p>This is a sample message an account update</p> + <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary"> + <tbody> + <tr> + <td align="left"> + <table role="presentation" border="0" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td> <a href="http://fineract.apache.org" target="_blank">Call To Action</a> </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> + </table> + <p>No reply required. This is a computer generated mail.</p> + <p>Best Regards,</p> + <p>MFI</p> + </td> + </tr> + </table> + </td> + </tr> + + <!-- END MAIN CONTENT AREA --> + </table> + <!-- END CENTERED WHITE CONTAINER --> + + <!-- START FOOTER --> + <div class="footer"> + <table role="presentation" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td class="content-block"> + <span class="apple-link">Apache Software Foundation, Forest Hill, Maryland, United States</span> + <p> Don't like these emails? <a href="">Unsubscribe</a>.</p> + </td> + </tr> + <tr> + <td class="content-block powered-by"> + Powered by <a href="http://fineract.apache.org">Apache Fineract</a>. + </td> + </tr> + </table> + </div> + <!-- END FOOTER --> + + </div> + </td> + <td> </td> + </tr> +</table> +</body> +</html> diff --cc service/src/main/java/org/apache/fineract/cn/notification/service/internal/service/EmailService.java index f1f24ed,6a6a78f..e77563a --- 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 @@@ -115,8 -150,8 +115,8 @@@ public class EmailService @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO) @Transactional - @EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION) + @EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.SEND_EMAIL_NOTIFICATION) - public String sendEmail(String from, String to, String subject, String message) { + public String sendPlainEmail(String to, String subject, String message) { SimpleMailMessage mail = new SimpleMailMessage(); try { @@@ -128,29 -164,6 +128,29 @@@ } catch (MailException exception) { logger.debug("Caused by:" + exception.getCause().toString()); } - return null; + return to; } + + @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO) + @Transactional - @EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.POST_SEND_EMAIL_NOTIFICATION) ++ @EventEmitter(selectorName = NotificationEventConstants.SELECTOR_NAME, selectorValue = NotificationEventConstants.SEND_EMAIL_NOTIFICATION) + public String sendFormattedEmail(String to, + String subject, + Map<String, Object> message, + String emailTemplate) { + MimeMessagePreparator messagePreparator = mimeMessage -> { + MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage); + messageHelper.setTo(to); + messageHelper.setSubject(subject); + String content = mailBuilder.build(message, emailTemplate); + messageHelper.setText(content, true); + }; + try { + this.mailSender.send(messagePreparator); + return to; + } catch (MailException e) { + logger.error("Failed to send Formatted email{}", e.getMessage()); + } + return null; + } } diff --cc service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql index 19f43bd,9e1aba3..81fc5bf --- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql +++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql @@@ -57,6 -55,16 +57,19 @@@ CREATE TABLE wada_templates url VARCHAR(255) NOT NULL, PRIMARY KEY (id)); --- ----------------------------------------------------- --- Table wada_data_source_application --- ----------------------------------------------------- - CREATE TABLE wada_data_source_application ( - id BIGINT NOT NULL AUTO_INCREMENT, - tenant_identifier VARCHAR(32) NOT NULL, - application_identifier VARCHAR(32) NOT NULL, - permittable_identifier VARCHAR(32) NOT NULL, - PRIMARY KEY (id) -); -INSERT INTO wada_sms_gateway_configurations VALUES ('1', 'Twilio', 'ACdc00866577a42133e16d98456ad15592', '0b2f78b1c083eb71599d014d1af5748e', '+12055486680', 'ACTIVE'); -INSERT INTO wada_email_gateway_configurations VALUES ('1', 'Gmail', 'smtp.gmail.com', '587','[email protected]', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE'); +INSERT INTO wada_sms_gateway_configurations VALUES ('1', 'DEFAULT', 'ACdc00866577a42133e16d98456ad15592', '0b2f78b1c083eb71599d014d1af5748e', '+12055486680', 'ACTIVE'); +INSERT INTO wada_email_gateway_configurations VALUES ('1', 'DEFAULT', 'smtp.gmail.com', '587','[email protected]', 'pnuugpwmcibipdpw', 'smtp', 'true', 'true', 'ACTIVE'); ++ ++/*Insert default template for supported events*/ ++INSERT INTO wada_templates VALUES ('1','customerCreatedEvent','DEFAULT','Account created','Your account has been created','template'); ++INSERT INTO wada_templates VALUES ('2','customerUpdatedEvents','DEFAULT','Account updated','Your account has been Updated','template'); ++INSERT INTO wada_templates VALUES ('3','customerActivatedEvent','DEFAULT','Account Activated','Your account has been Activated','template'); ++INSERT INTO wada_templates VALUES ('4','customerLockedEvent','DEFAULT','Account Locked','Your account has been Locked','template'); ++INSERT INTO wada_templates VALUES ('5','customerUnlockedEvent','DEFAULT','Account unlocked','Your account has been Unlocked','template'); ++INSERT INTO wada_templates VALUES ('6','customerClosedEvent','DEFAULT','Account closed successfully','Your account has been Closed','template'); ++INSERT INTO wada_templates VALUES ('7','customerReopenedEvent','DEFAULT','Account Reopened','Your account has been reopened','template'); ++INSERT INTO wada_templates VALUES ('8','contactDetailsChangedEvent','DEFAULT','Contact details has been updated','Your contact has been changed successfully','template'); ++INSERT INTO wada_templates VALUES ('9','addressChangedEvent','DEFAULT','Residence address has been changed','Your address has been changed successfully','template'); ++ ++INSERT INTO wada_templates VALUES ('10','sample','DEFAULT','Test Subject','Talk is cheap! Show me the code','template'); diff --cc service/src/main/resources/templatedetails/templates.csv index ddc76ef,0000000..ed60944 mode 100644,000000..100644 --- a/service/src/main/resources/templatedetails/templates.csv +++ b/service/src/main/resources/templatedetails/templates.csv @@@ -1,28 -1,0 +1,10 @@@ - - - - Licensed to the Apache Software Foundation (ASF) under one - - or more contributor license agreements. See the NOTICE file - - distributed with this work for additional information - - regarding copyright ownership. The ASF licenses this file - - to you under the Apache License, Version 2.0 (the - - "License"); you may not use this file except in compliance - - with the License. You may obtain a copy of the License at - - - - http://www.apache.org/licenses/LICENSE-2.0 - - - - Unless required by applicable law or agreed to in writing, - - software distributed under the License is distributed on an - - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - - KIND, either express or implied. See the License for the - - specific language governing permissions and limitations - - under the License. - - +template_identifier,sender_email,subject,message,url +customerCreatedEvent,DEFAULT,Account created,"Your account has been created",template +customerUpdatedEvents,DEFAULT,Account updated,Your account has been Updated,template +customerActivatedEvent,DEFAULT,Account Activated,Your account has been Activated,template +customerLockedEvent,DEFAULT,Account Locked,Your account has been Locked,template +customerUnlockedEvent,DEFAULT,Account unlocked,Your account has been Unlocked,template +customerClosedEvent,DEFAULT,Account closed successfully,Your account has been Closed,template +customerReopenedEvent,DEFAULT,Account Reopened,Your account has been reopened,template +contactDetailsChangedEvent,DEFAULT,Contact details has been updated,Your contact has been changed successfully,template +addressChangedEvent,DEFAULT,Residence address has been changed,Your address has been changed successfully,template diff --cc shared.gradle index 7ecfdc6,45b090e..3162af1 --- a/shared.gradle +++ b/shared.gradle @@@ -126,8 -123,8 +125,10 @@@ rat "gradlew", "gradlew.bat", "README.md", - "**/.dockerignore/**" - - ".dockerignore" ++ ".dockerignore", ++ "component-test/src/main/resources/importdata/*.csv", ++ "service/src/main/resources/templatedetails/*.csv", ] + plainOutput = true }
