Skip to content
Permalink
Browse files
Migrating MariaDB to PostgreSQL
  • Loading branch information
ebenezergraham committed Sep 4, 2019
1 parent 1359030 commit fb20e5d066565cb29bff644113f59d4e46449c38
Showing 20 changed files with 370 additions and 238 deletions.
@@ -50,11 +50,11 @@
public class AbstractNotificationTest extends SuiteTestEnvironment {

@ClassRule
public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, postgreSQLInitializer);
public static final String LOGGER_NAME = "test-logger";
public static final String TEST_USER = "homer";
public static final String TEST_ADDRESS = "egraham15@alustudent.com"; // Replace with developer's dummy testing email
public static final String TEST_TEMPLATE= "sample";
public static final String TEST_TEMPLATE= "test_sample";
public static final String SMS_TEST_NUMBER= "+23058409206"; // Replace with developers dummy testing number

@SuppressWarnings("WeakerAccess")
@@ -21,7 +21,7 @@
import org.apache.fineract.cn.test.env.TestEnvironment;
import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
import org.apache.fineract.cn.test.fixture.postgresql.PostgreSQLInitializer;
import org.junit.ClassRule;
import org.junit.rules.RuleChain;
import org.junit.rules.RunExternalResourceOnce;
@@ -39,12 +39,12 @@ public class SuiteTestEnvironment {

static final TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
static final CassandraInitializer cassandraInitializer = new CassandraInitializer();
static final MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
static final PostgreSQLInitializer postgreSQLInitializer = new PostgreSQLInitializer();
final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, postgreSQLInitializer);

@ClassRule
public static TestRule orderClassRules = RuleChain
.outerRule(new RunExternalResourceOnce(testEnvironment))
.around(new RunExternalResourceOnce(cassandraInitializer))
.around(new RunExternalResourceOnce(mariaDBInitializer));
.around(new RunExternalResourceOnce(postgreSQLInitializer));
}
@@ -85,7 +85,7 @@ public void checkIfConfigurationAlreadyExists() throws InterruptedException{
public void shouldSendAnSMS(){
this.logger.info("Send SMS Notification");
int to = this.notificationService.sendSMS(SMS_TEST_NUMBER,
"Dear Valued Customer\n\nTalk is cheap show me the code\n\nBest Regards\nYour MFI");
TEST_TEMPLATE);
Assert.assertNotNull(to);
}

@@ -18,14 +18,14 @@
*/
package org.apache.fineract.cn.notification;

import org.apache.fineract.cn.notification.importer.TestTemplateImport;
import org.apache.fineract.cn.notification.importer.TestImport;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({
TestTemplateImport.class,
TestImport.class,
TestEmailService.class,
TestSMSService.class,
EmailApiDocumentation.class,
@@ -21,17 +21,17 @@
import org.apache.fineract.cn.notification.AbstractNotificationTest;
import org.apache.fineract.cn.notification.api.v1.domain.Template;
import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
import org.apache.fineract.cn.notification.service.internal.importer.TemplateImporter;
import org.apache.fineract.cn.notification.service.internal.importer.Importer;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.net.URL;


public class TestTemplateImport extends AbstractNotificationTest {
public class TestImport extends AbstractNotificationTest {

public TestTemplateImport() {
public TestImport() {
super();
}

@@ -47,9 +47,26 @@ public void testTemplateImportHappyCase() throws IOException, InterruptedExcepti
notificationManager.createTemplate(template);
Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, template.getTemplateIdentifier()));

final TemplateImporter importer = new TemplateImporter(notificationManager, logger);
final Importer importer = new Importer(notificationManager, logger);
final URL uri = ClassLoader.getSystemResource("importdata/test-templates.csv");
importer.importCSV(uri);
importer.importTemplateCSV(uri);
Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_TEMPLATE, "test_sample"));
}

@Test
public void testSmsConfigImportHappyCase() throws IOException, InterruptedException {

final Importer importer = new Importer(notificationManager, logger);
final URL uri = ClassLoader.getSystemResource("importdata/test-sms-config.csv");
importer.importSmsConfigurationCSV(uri);
Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_SMS_CONFIGURATION, "DEFAULT"));
}

@Test
public void testEmailConfigImportHappyCase() throws IOException, InterruptedException {
final Importer importer = new Importer(notificationManager, logger);
final URL uri = ClassLoader.getSystemResource("importdata/test-email-config.csv");
importer.importEmailConfigurationCSV(uri);
Assert.assertTrue(eventRecorder.wait(NotificationEventConstants.POST_EMAIL_CONFIGURATION, "DEFAULT"));
}
}
@@ -0,0 +1,2 @@
identifier,host,port,username,app_password,protocol,smtp_auth,start_tls,state
DEFAULT,smtp.gmail.com,587,fineractcnnotificationdemo@gmail.com,pnuugpwmcibipdpw,smtp,true,true,ACTIVE
@@ -0,0 +1,2 @@
identifier,account_sid,auth_token,sender_number,state
DEFAULT,ACdc00866577a42133e16d98456ad15592,0b2f78b1c083eb71599d014d1af5748e,+12055486680,ACTIVE
@@ -64,7 +64,7 @@ dependencies {
[group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
[group: 'org.apache.fineract.cn', name: 'async', version: versions.frameworkasync],
[group: 'org.apache.fineract.cn', name: 'cassandra', version: versions.frameworkcassandra],
[group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
[group: 'org.apache.fineract.cn', name: 'postgresql', version: versions.frameworkpostgresql],
[group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
[group: 'org.apache.fineract.cn.permitted-feign-client', name: 'library', version: versions.frameworkpermittedfeignclient],
[group: 'org.hibernate', name: 'hibernate-validator', version: versions.validator],
@@ -23,7 +23,7 @@
import org.apache.fineract.cn.command.annotation.CommandLogLevel;
import org.apache.fineract.cn.command.annotation.EventEmitter;
import org.apache.fineract.cn.lang.ApplicationName;
import org.apache.fineract.cn.mariadb.domain.FlywayFactoryBean;
import org.apache.fineract.cn.postgresql.domain.FlywayFactoryBean;
import org.apache.fineract.cn.notification.api.v1.events.NotificationEventConstants;
import org.apache.fineract.cn.notification.service.ServiceConstants;
import org.apache.fineract.cn.notification.service.internal.command.InitializeServiceCommand;
@@ -30,7 +30,7 @@
import org.apache.fineract.cn.lang.ApplicationName;
import org.apache.fineract.cn.lang.config.EnableServiceException;
import org.apache.fineract.cn.lang.config.EnableTenantContext;
import org.apache.fineract.cn.mariadb.config.EnableMariaDB;
import org.apache.fineract.cn.postgresql.config.EnablePostgreSQL;
import org.apache.fineract.cn.notification.service.ServiceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,7 +63,7 @@
@EnableAsync
@EnableTenantContext
@EnableCassandra
@EnableMariaDB
@EnablePostgreSQL
@EnableCommandProcessing
@EnableAnubis
@EnableServiceException
@@ -0,0 +1,177 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.cn.notification.service.internal.importer;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.fineract.cn.notification.api.v1.client.NotificationManager;
import org.apache.fineract.cn.notification.api.v1.client.TemplateAlreadyExistException;
import org.apache.fineract.cn.notification.api.v1.domain.EmailConfiguration;
import org.apache.fineract.cn.notification.api.v1.domain.SMSConfiguration;
import org.apache.fineract.cn.notification.api.v1.domain.Template;
import org.slf4j.Logger;

import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
* @author Ebenezer Graham
*/
@SuppressWarnings("unused")
public class Importer {
private static final String TEMPLATE_IDENTIFIER_COLUMN = "template_identifier";
private static final String SENDER_EMAIL_COLUMN = "sender_email";
private static final String SUBJECT_COLUMN = "subject";
private static final String MESSAGE_COLUMN = "message";
private static final String URL_COLUMN = "url";

private static final String IDENTIFIER_COLUMN = "identifier";
private static final String ACCOUNT_SID_COLUMN = "account_sid";
private static final String AUTH_TOKEN_COLUMN = "auth_token";
private static final String SENDER_NUMBER_COLUMN = "sender_number";
private static final String STATE_COLUMN = "state";

private static final String HOST_EMAIL_COLUMN = "host";
private static final String PORT_COLUMN = "port";
private static final String USERNAME_COLUMN = "username";
private static final String APP_PASSWORD_COLUMN = "app_password";
private static final String PROTOCOL_COLUMN = "protocol";
private static final String SMTP_AUTH_COLUMN = "smtp_auth";
private static final String START_TLS_COLUMN = "start_tls";

private final NotificationManager notificationManager;
private final Logger logger;

public Importer(final NotificationManager notificationManager, final Logger logger) {
this.notificationManager = notificationManager;
this.logger = logger;
}

public void importTemplateCSV(final URL toImport) throws IOException {
final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
final List<Template>templatesList = StreamSupport.stream(parser.spliterator(), false)
.map(this::toTemplate)
.collect(Collectors.toList());
templatesList.forEach(this::createTemplate);
}

public void importSmsConfigurationCSV(final URL toImport) throws IOException {
final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
final List<SMSConfiguration>list = StreamSupport.stream(parser.spliterator(), false)
.map(this::toSmsConfiguration)
.collect(Collectors.toList());
list.forEach(this::createSmsConfiguration);
}

public void importEmailConfigurationCSV(final URL toImport) throws IOException {
final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader().withCommentMarker('-'));
final List<EmailConfiguration>list = StreamSupport.stream(parser.spliterator(), false)
.map(this::toEmailConfiguration)
.collect(Collectors.toList());
list.forEach(this::createEmailConfiguration);
}

private void createTemplate(final Template toCreate) {
try {
notificationManager.createTemplate(toCreate);
}
catch (final TemplateAlreadyExistException ignored) {
logger.error("Creation of template {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getTemplateIdentifier(),toCreate.toString());
}
}

private void createSmsConfiguration(final SMSConfiguration toCreate) {
try {
notificationManager.createSMSConfiguration(toCreate);
}
catch (final Exception ignored) {
logger.error("Creation of sms configuration {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getIdentifier(),toCreate.toString());
}
}

private void createEmailConfiguration(final EmailConfiguration toCreate) {
try {
notificationManager.createEmailConfiguration(toCreate);
}
catch (final Exception ignored) {
logger.error("Creation of email configuration {} failed, because a template with the same identifier but different properties already exists {}", toCreate.getIdentifier(),toCreate.toString());
}
}

private Template toTemplate(final CSVRecord csvRecord) {
try {
final String templateIdentifier = csvRecord.get(TEMPLATE_IDENTIFIER_COLUMN);
final String subject = csvRecord.get(SUBJECT_COLUMN);
final String senderEmail = csvRecord.get(SENDER_EMAIL_COLUMN);
final String url = csvRecord.get(URL_COLUMN);
String message;
try {
message = csvRecord.get(MESSAGE_COLUMN);
}
catch (final NullPointerException e) {
message = "Do not reply, This is a computer generate message.";
}
return new Template(templateIdentifier,senderEmail,subject,message,url);
}
catch (final IllegalArgumentException e) {
logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
throw e;
}
}

private EmailConfiguration toEmailConfiguration(final CSVRecord csvRecord) {
try {
final String identifier = csvRecord.get(IDENTIFIER_COLUMN);
final String host = csvRecord.get(HOST_EMAIL_COLUMN);
final String username = csvRecord.get(USERNAME_COLUMN);
final String port = csvRecord.get(PORT_COLUMN);
final String app_password = csvRecord.get(APP_PASSWORD_COLUMN);
final String protocol = csvRecord.get(PROTOCOL_COLUMN);
final String smtp_auth = csvRecord.get(SMTP_AUTH_COLUMN);
final String start_tls = csvRecord.get(START_TLS_COLUMN);
final String state = csvRecord.get(STATE_COLUMN);

return EmailConfiguration.create(identifier,host,port,protocol,username,app_password,smtp_auth,start_tls,state);
}
catch (final IllegalArgumentException e) {
logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
throw e;
}
}

private SMSConfiguration toSmsConfiguration(final CSVRecord csvRecord) {
try {
final String identifier = csvRecord.get(IDENTIFIER_COLUMN);
final String account_sid = csvRecord.get(ACCOUNT_SID_COLUMN);
final String auth_token = csvRecord.get(AUTH_TOKEN_COLUMN);
final String sender_number = csvRecord.get(SENDER_NUMBER_COLUMN);
final String state = csvRecord.get(STATE_COLUMN);
return SMSConfiguration.create(identifier,account_sid,auth_token,sender_number,state);
}
catch (final IllegalArgumentException e) {
logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber());
throw e;
}
}
}

0 comments on commit fb20e5d

Please sign in to comment.