FINERACT-1734-Create-Custom-Business-Event

This commit is contained in:
Ruchi Dhamankar
2022-12-23 12:16:33 +01:00
committed by Arnold Gálovics
parent 0f41eb2c42
commit d3dcc760e2
19 changed files with 446 additions and 29 deletions
@@ -0,0 +1,25 @@
/**
* 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.
*/
description = 'ACME Corp.: Fineract external events'
group = 'com.acme.fineract.event'
archivesBaseName = 'acme-fineract-event-externalevent'
apply from: 'dependencies.gradle'
@@ -0,0 +1,23 @@
/**
* 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.
*/
dependencies {
implementation(project(':fineract-provider'))
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
}
@@ -0,0 +1,35 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.acme.fineract.event.externalevent;
import java.util.List;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventSourceData;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventSourceProvider;
import org.apache.fineract.infrastructure.event.external.service.validation.SimpleExternalEventSourceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AcmeExternalEventSourceProviderConfig {
@Bean
public ExternalEventSourceProvider acmeEventSourceProvider() {
return new SimpleExternalEventSourceProvider(List.of(new ExternalEventSourceData("com.acme.fineract.event.externalevent")));
}
}
@@ -0,0 +1,36 @@
/**
* 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 com.acme.fineract.event.externalevent;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
public class AcmeLoanExternalEvent extends LoanBusinessEvent {
private static final String TYPE = "AcmeLoanExternalEvent";
public AcmeLoanExternalEvent(Loan value) {
super(value);
}
@Override
public String getType() {
return TYPE;
}
}
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<changeSet author="acme" id="1">
<insert tableName="m_external_event_configuration">
<column name="type" value="AcmeLoanExternalEvent"/>
<column name="enabled" valueBoolean="false"/>
</insert>
</changeSet>
</databaseChangeLog>
+25
View File
@@ -0,0 +1,25 @@
/**
* 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.
*/
description = 'ACME Corp.: Fineract Event Starter'
group = 'com.acme.fineract.event'
archivesBaseName = 'acme-fineract-event-starter'
apply from: 'dependencies.gradle'
@@ -0,0 +1,23 @@
/**
* 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.
*/
dependencies {
implementation(project(':fineract-provider'))
implementation('org.springframework.boot:spring-boot-starter')
}
@@ -0,0 +1,27 @@
/**
* 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 com.acme.fineract.event.starter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
@AutoConfiguration
@ComponentScans({ @ComponentScan("com.acme.fineract.event.externalevent") })
public class AcmeEventAutoConfiguration {}
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.acme.fineract.event.starter.AcmeEventAutoConfiguration
@@ -25,11 +25,10 @@ import java.util.function.Function;
import javax.sql.DataSource;
import liquibase.exception.LiquibaseException;
import liquibase.integration.spring.SpringLiquibase;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.config.FineractProperties;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -39,12 +38,13 @@ import org.springframework.stereotype.Service;
* A service that picks up on tenants that are configured to auto-update their specific schema on application startup.
*/
@Service
@Slf4j
public class TenantDatabaseUpgradeService implements InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(TenantDatabaseUpgradeService.class);
private static final String TENANT_STORE_DB_CONTEXT = "tenant_store_db";
private static final String INITIAL_SWITCH_CONTEXT = "initial_switch";
private static final String TENANT_DB_CONTEXT = "tenant_db";
private static final String CUSTOM_CHANGELOG_CONTEXT = "custom_changelog";
private final TenantDetailsService tenantDetailsService;
private final DataSource tenantDataSource;
@@ -69,9 +69,9 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
if (databaseStateVerifier.isLiquibaseDisabled() || !fineractProperties.getMode().isWriteEnabled()) {
LOG.warn("Liquibase is disabled. Not upgrading any database.");
log.warn("Liquibase is disabled. Not upgrading any database.");
if (!fineractProperties.getMode().isWriteEnabled()) {
LOG.warn("Liquibase is disabled because the current instance is configured as a non-write Fineract instance");
log.warn("Liquibase is disabled because the current instance is configured as a non-write Fineract instance");
}
return;
}
@@ -84,7 +84,7 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
}
private void upgradeTenantStore() throws LiquibaseException {
LOG.warn("Upgrading tenant store DB at {}:{}", fineractProperties.getTenant().getHost(), fineractProperties.getTenant().getPort());
log.warn("Upgrading tenant store DB at {}:{}", fineractProperties.getTenant().getHost(), fineractProperties.getTenant().getPort());
logTenantStoreDetails();
if (databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)) {
ExtendedSpringLiquibase liquibase = liquibaseFactory.create(tenantDataSource, TENANT_STORE_DB_CONTEXT, INITIAL_SWITCH_CONTEXT);
@@ -93,32 +93,32 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
}
SpringLiquibase liquibase = liquibaseFactory.create(tenantDataSource, TENANT_STORE_DB_CONTEXT);
liquibase.afterPropertiesSet();
LOG.warn("Tenant store upgrade finished");
log.warn("Tenant store upgrade finished");
}
private void logTenantStoreDetails() {
LOG.info("- fineract.tenant.username: {}", fineractProperties.getTenant().getUsername());
LOG.info("- fineract.tenant.password: ****");
LOG.info("- fineract.tenant.parameters: {}", fineractProperties.getTenant().getParameters());
LOG.info("- fineract.tenant.timezone: {}", fineractProperties.getTenant().getTimezone());
LOG.info("- fineract.tenant.description: {}", fineractProperties.getTenant().getDescription());
LOG.info("- fineract.tenant.identifier: {}", fineractProperties.getTenant().getIdentifier());
LOG.info("- fineract.tenant.name: {}", fineractProperties.getTenant().getName());
log.info("- fineract.tenant.username: {}", fineractProperties.getTenant().getUsername());
log.info("- fineract.tenant.password: ****");
log.info("- fineract.tenant.parameters: {}", fineractProperties.getTenant().getParameters());
log.info("- fineract.tenant.timezone: {}", fineractProperties.getTenant().getTimezone());
log.info("- fineract.tenant.description: {}", fineractProperties.getTenant().getDescription());
log.info("- fineract.tenant.identifier: {}", fineractProperties.getTenant().getIdentifier());
log.info("- fineract.tenant.name: {}", fineractProperties.getTenant().getName());
}
private void upgradeIndividualTenants() throws LiquibaseException {
LOG.warn("Upgrading all tenants");
log.warn("Upgrading all tenants");
List<FineractPlatformTenant> tenants = tenantDetailsService.findAllTenants();
if (isNotEmpty(tenants)) {
for (FineractPlatformTenant tenant : tenants) {
upgradeIndividualTenant(tenant);
}
}
LOG.warn("Tenant upgrades have finished");
log.warn("Tenant upgrades have finished");
}
private void upgradeIndividualTenant(FineractPlatformTenant tenant) throws LiquibaseException {
LOG.info("Upgrade for tenant {} has started", tenant.getTenantIdentifier());
log.info("Upgrade for tenant {} has started", tenant.getTenantIdentifier());
DataSource tenantDataSource = tenantDataSourceFactory.create(tenant);
if (databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)) {
ExtendedSpringLiquibase liquibase = liquibaseFactory.create(tenantDataSource, TENANT_DB_CONTEXT, INITIAL_SWITCH_CONTEXT);
@@ -127,20 +127,22 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
}
SpringLiquibase tenantLiquibase = liquibaseFactory.create(tenantDataSource, TENANT_DB_CONTEXT);
tenantLiquibase.afterPropertiesSet();
LOG.info("Upgrade for tenant {} has finished", tenant.getTenantIdentifier());
SpringLiquibase customChangelogLiquibase = liquibaseFactory.create(tenantDataSource, TENANT_DB_CONTEXT, CUSTOM_CHANGELOG_CONTEXT);
customChangelogLiquibase.afterPropertiesSet();
log.info("Upgrade for tenant {} has finished", tenant.getTenantIdentifier());
}
private void applyInitialLiquibase(DataSource dataSource, ExtendedSpringLiquibase liquibase, String id,
Function<DataSource, Boolean> isUpgradableFn) throws LiquibaseException {
if (databaseStateVerifier.isFlywayPresent(dataSource)) {
if (isUpgradableFn.apply(dataSource)) {
LOG.warn("Cannot proceed with upgrading database {}", id);
LOG.warn("It seems the database doesn't have the latest schema changes applied until the 1.6 release");
log.warn("Cannot proceed with upgrading database {}", id);
log.warn("It seems the database doesn't have the latest schema changes applied until the 1.6 release");
throw new SchemaUpgradeNeededException("Make sure to upgrade to Fineract 1.6 first and then to a newer version");
}
LOG.warn("This is the first Liquibase migration for {}. We'll sync the changelog for you and then apply everything else", id);
log.warn("This is the first Liquibase migration for {}. We'll sync the changelog for you and then apply everything else", id);
liquibase.changeLogSync();
LOG.warn("Liquibase changelog sync is complete");
log.warn("Liquibase changelog sync is complete");
} else {
liquibase.afterPropertiesSet();
}
@@ -27,10 +27,12 @@ import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.event.business.domain.BulkBusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
import org.apache.fineract.infrastructure.event.external.exception.ExternalEventConfigurationNotFoundException;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventSourceService;
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -41,11 +43,11 @@ import org.springframework.stereotype.Service;
@Service
public class ExternalEventConfigurationValidationService implements InitializingBean {
private static final String EXTERNAL_EVENT_CLASSES_BASE_PACKAGE = "org.apache.fineract.infrastructure.event.business.domain";
private static final String EXTERNAL_EVENT_BUSINESS_INTERFACE = BusinessEvent.class.getName();
private static final String BULK_BUSINESS_EVENT = BulkBusinessEvent.class.getName();
private final TenantDetailsService tenantDetailsService;
private final JdbcTemplateFactory jdbcTemplateFactory;
private final ExternalEventSourceService externalEventSourceService;
@Override
public void afterPropertiesSet() throws Exception {
@@ -67,6 +69,10 @@ public class ExternalEventConfigurationValidationService implements Initializing
throws ExternalEventConfigurationNotFoundException {
log.info("Validating external event configuration for {}", tenant.getTenantIdentifier());
List<String> eventConfigurations = getExternalEventConfigurationsForTenant(tenant);
if (log.isDebugEnabled()) {
log.debug("Missing from eventClasses: {}", CollectionUtils.subtract(eventClasses, eventConfigurations));
log.debug("Missing from eventConfigurations: {}", CollectionUtils.subtract(eventConfigurations, eventClasses));
}
if (eventClasses.size() != eventConfigurations.size()) {
throw new ExternalEventConfigurationNotFoundException();
@@ -88,7 +94,13 @@ public class ExternalEventConfigurationValidationService implements Initializing
}
private List<String> getAllEventClasses() {
try (ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages(EXTERNAL_EVENT_CLASSES_BASE_PACKAGE).scan()) {
List<String> sourcePackages = externalEventSourceService.getSourcePackages();
if (log.isDebugEnabled()) {
log.debug("Packages {}", sourcePackages);
}
String[] sourcePackagesForScan = new String[sourcePackages.size()];
try (ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages(sourcePackages.toArray(sourcePackagesForScan))
.scan()) {
ClassInfoList businessEventClasses = scanResult.getClassesImplementing(EXTERNAL_EVENT_BUSINESS_INTERFACE)
.filter(classInfo -> (!classInfo.isInterface() && !classInfo.isAbstract()
&& !classInfo.getName().equalsIgnoreCase(BULK_BUSINESS_EVENT)));
@@ -0,0 +1,29 @@
/**
* 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.infrastructure.event.external.service.validation;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class ExternalEventSourceData {
private final String sourcePackage;
}
@@ -0,0 +1,26 @@
/**
* 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.infrastructure.event.external.service.validation;
import java.util.Set;
public interface ExternalEventSourceProvider {
Set<ExternalEventSourceData> provide();
}
@@ -0,0 +1,36 @@
/**
* 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.infrastructure.event.external.service.validation;
import java.util.Arrays;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ExternalEventSourceProviderConfig {
private static final String EXTERNAL_EVENT_CLASSES_BASE_PACKAGE = "org.apache.fineract.infrastructure.event.business.domain";
@Bean
public ExternalEventSourceProvider fineractExternalEventSourceProvider() {
List<ExternalEventSourceData> sourcePackages = Arrays.asList(new ExternalEventSourceData(EXTERNAL_EVENT_CLASSES_BASE_PACKAGE));
return new SimpleExternalEventSourceProvider(sourcePackages);
}
}
@@ -0,0 +1,39 @@
/**
* 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.infrastructure.event.external.service.validation;
import static java.util.stream.Collectors.toList;
import java.util.Collection;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ExternalEventSourceService {
private final Collection<ExternalEventSourceProvider> providers;
public List<String> getSourcePackages() {
return providers.stream().map(ExternalEventSourceProvider::provide).flatMap(Collection::stream)
.map(source -> source.getSourcePackage()).collect(toList());
}
}
@@ -0,0 +1,36 @@
/**
* 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.infrastructure.event.external.service.validation;
import java.util.Collection;
import java.util.Set;
public class SimpleExternalEventSourceProvider implements ExternalEventSourceProvider {
private final Set<ExternalEventSourceData> sourcePackages;
public SimpleExternalEventSourceProvider(Collection<ExternalEventSourceData> sourcePackages) {
this.sourcePackages = Set.copyOf(sourcePackages);
}
@Override
public Set<ExternalEventSourceData> provide() {
return sourcePackages;
}
}
@@ -31,5 +31,5 @@
<include file="tenant-store/changelog-tenant-store.xml" relativeToChangelogFile="true" context="tenant_store_db AND !initial_switch"/>
<include file="tenant/initial-switch-changelog-tenant.xml" relativeToChangelogFile="true" context="tenant_db AND initial_switch"/>
<include file="tenant/changelog-tenant.xml" relativeToChangelogFile="true" context="tenant_db AND !initial_switch"/>
<includeAll path="db/custom-changelog" errorIfMissingOrEmpty="false" context="tenant_db" />
<includeAll path="db/custom-changelog" errorIfMissingOrEmpty="false" context="tenant_db AND custom_changelog" />
</databaseChangeLog>
@@ -54,6 +54,7 @@ public class LiquibaseStepDefinitions implements En {
private ExtendedSpringLiquibase tenantStoreLiquibase;
private ExtendedSpringLiquibase initialTenantLiquibase;
private ExtendedSpringLiquibase tenantLiquibase;
private ExtendedSpringLiquibase customChangeLogLiquibase;
private FineractPlatformTenant defaultTenant;
private DataSource tenantStoreDataSource;
private TenantDatabaseUpgradeService tenantDatabaseUpgradeService;
@@ -158,6 +159,7 @@ public class LiquibaseStepDefinitions implements En {
initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
tenantLiquibase = mock(ExtendedSpringLiquibase.class);
customChangeLogLiquibase = mock(ExtendedSpringLiquibase.class);
initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
@@ -171,6 +173,7 @@ public class LiquibaseStepDefinitions implements En {
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "custom_changelog")).willReturn(customChangeLogLiquibase);
tenantDatabaseUpgradeService = new TenantDatabaseUpgradeService(tenantDetailsService, tenantStoreDataSource, fineractProperties,
databaseStateVerifier, liquibaseFactory, tenantDataSourceFactory);
@@ -32,6 +32,7 @@ import java.util.Arrays;
import java.util.List;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.event.external.exception.ExternalEventConfigurationNotFoundException;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventSourceService;
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -50,11 +51,14 @@ public class ExternalEventConfigurationValidationServiceTest {
@Mock
private TenantDetailsService tenantDetailsService;
@Mock
private ExternalEventSourceService externalEventSourceService;
private ExternalEventConfigurationValidationService underTest;
@BeforeEach
public void setUp() {
underTest = new ExternalEventConfigurationValidationService(tenantDetailsService, jdbcTemplateFactory);
underTest = new ExternalEventConfigurationValidationService(tenantDetailsService, jdbcTemplateFactory, externalEventSourceService);
}
@Test
@@ -98,7 +102,8 @@ public class ExternalEventConfigurationValidationServiceTest {
when(tenantDetailsService.findAllTenants()).thenReturn(tenants);
when(jdbcTemplateFactory.create(any())).thenReturn(jdbcTemplate);
when(jdbcTemplate.queryForList(anyString(), eq(String.class))).thenReturn(configurations);
List<String> sourcePackage = Arrays.asList("org.apache.fineract.infrastructure.event.business.domain");
when(externalEventSourceService.getSourcePackages()).thenReturn(sourcePackage);
// when
underTest.afterPropertiesSet();
@@ -117,7 +122,8 @@ public class ExternalEventConfigurationValidationServiceTest {
when(tenantDetailsService.findAllTenants()).thenReturn(tenants);
when(jdbcTemplateFactory.create(any())).thenReturn(jdbcTemplate);
when(jdbcTemplate.queryForList(anyString(), eq(String.class))).thenReturn(new ArrayList<>());
List<String> sourcePackage = Arrays.asList("org.apache.fineract.infrastructure.event.business.domain");
when(externalEventSourceService.getSourcePackages()).thenReturn(sourcePackage);
// when
ExternalEventConfigurationNotFoundException exceptionThrown = assertThrows(ExternalEventConfigurationNotFoundException.class,
() -> underTest.afterPropertiesSet());
@@ -171,7 +177,8 @@ public class ExternalEventConfigurationValidationServiceTest {
when(tenantDetailsService.findAllTenants()).thenReturn(tenants);
when(jdbcTemplateFactory.create(any())).thenReturn(jdbcTemplate);
when(jdbcTemplate.queryForList(anyString(), eq(String.class))).thenReturn(configurationWithMissingCentersCreateBusinessEvent);
List<String> sourcePackage = Arrays.asList("org.apache.fineract.infrastructure.event.business.domain");
when(externalEventSourceService.getSourcePackages()).thenReturn(sourcePackage);
// when
ExternalEventConfigurationNotFoundException exceptionThrown = assertThrows(ExternalEventConfigurationNotFoundException.class,
() -> underTest.afterPropertiesSet());