From 56d14a1d69fcb1b2e1fe3425b246d12ea5c7dfdf Mon Sep 17 00:00:00 2001 From: taskain7 Date: Thu, 21 Apr 2022 13:29:09 +0200 Subject: [PATCH] FINERACT-1571: Allow Liquibase data migration for write instances only --- .../TenantDatabaseStateVerifier.java | 10 ++-- .../TenantDatabaseUpgradeService.java | 5 +- .../apache/fineract/TestConfiguration.java | 2 +- .../core/InstanceTypeStepDefinitions.java | 46 +++++++++++++++++++ .../core/LiquibaseStepDefinitions.java | 13 ++++-- .../resources/application-test.properties | 4 ++ .../infrastructure.core.feature | 18 ++++++++ 7 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/InstanceTypeStepDefinitions.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseStateVerifier.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseStateVerifier.java index 63e7e766b..3759c7fd9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseStateVerifier.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseStateVerifier.java @@ -21,13 +21,15 @@ package org.apache.fineract.infrastructure.core.service.migration; import java.util.Map; import java.util.Objects; import javax.sql.DataSource; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.infrastructure.core.config.FineractProperties; import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Component; @Component +@RequiredArgsConstructor public class TenantDatabaseStateVerifier { private static final int TENANT_STORE_LATEST_FLYWAY_VERSION = 6; @@ -40,11 +42,7 @@ public class TenantDatabaseStateVerifier { private final LiquibaseProperties liquibaseProperties; private final DatabaseIndependentQueryService dbQueryService; - @Autowired - public TenantDatabaseStateVerifier(LiquibaseProperties liquibaseProperties, DatabaseIndependentQueryService dbQueryService) { - this.liquibaseProperties = liquibaseProperties; - this.dbQueryService = dbQueryService; - } + private final FineractProperties fineractProperties; public boolean isFirstLiquibaseMigration(DataSource dataSource) { boolean databaseChangelogTableExists = dbQueryService.isTablePresent(dataSource, "DATABASECHANGELOG"); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java index e36e0c77e..dd3a974ce 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java @@ -68,8 +68,11 @@ public class TenantDatabaseUpgradeService implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { - if (databaseStateVerifier.isLiquibaseDisabled()) { + if (databaseStateVerifier.isLiquibaseDisabled() || !fineractProperties.getMode().isWriteEnabled()) { 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"); + } return; } try { diff --git a/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java b/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java index e14fcab7c..e287e331e 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java +++ b/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java @@ -103,7 +103,7 @@ public class TestConfiguration { @Bean public TenantDatabaseStateVerifier tenantDatabaseStateVerifier(DatabaseIndependentQueryService databaseIndependentQueryService, LiquibaseProperties liquibaseProperties, FineractProperties fineractProperties) { - return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService); + return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService, fineractProperties); } /** diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/InstanceTypeStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/InstanceTypeStepDefinitions.java new file mode 100644 index 000000000..a2715f368 --- /dev/null +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/InstanceTypeStepDefinitions.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.infrastructure.core; + +import io.cucumber.java8.En; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.beans.factory.annotation.Autowired; + +public class InstanceTypeStepDefinitions implements En { + + @Autowired + private FineractProperties fineractProperties; + + public InstanceTypeStepDefinitions() { + Given("Set every Fineract instance type to false", () -> { + fineractProperties.getMode().setWriteEnabled(false); + fineractProperties.getMode().setReadEnabled(false); + fineractProperties.getMode().setBatchEnabled(false); + }); + Given("Fineract instance is a write instance", () -> { + fineractProperties.getMode().setWriteEnabled(true); + }); + Given("Fineract instance is a read instance", () -> { + fineractProperties.getMode().setReadEnabled(true); + }); + Given("Fineract instance is a batch instance", () -> { + fineractProperties.getMode().setBatchEnabled(true); + }); + } +} diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java index 32b5394fa..b55fdc32f 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java @@ -40,12 +40,14 @@ import org.apache.fineract.infrastructure.core.service.migration.TenantDataSourc import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseStateVerifier; import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseUpgradeService; import org.apache.fineract.infrastructure.security.service.TenantDetailsService; +import org.springframework.beans.factory.annotation.Autowired; public class LiquibaseStepDefinitions implements En { private TenantDataSourceFactory tenantDataSourceFactory; private TenantDetailsService tenantDetailsService; private TenantDatabaseStateVerifier databaseStateVerifier; + @Autowired private FineractProperties fineractProperties; private ExtendedSpringLiquibaseFactory liquibaseFactory; private ExtendedSpringLiquibase initialTenantStoreLiquibase; @@ -100,8 +102,13 @@ public class LiquibaseStepDefinitions implements En { Then("The database migration did not do anything", () -> { verify(databaseStateVerifier).isLiquibaseDisabled(); verifyNoMoreInteractions(databaseStateVerifier); - verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, fineractProperties, liquibaseFactory, - tenantDataSourceFactory); + verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, liquibaseFactory, tenantDataSourceFactory); + }); + + Then("The database migration did not do anything, because it is not a write instance", () -> { + verify(databaseStateVerifier).isLiquibaseDisabled(); + verifyNoMoreInteractions(databaseStateVerifier); + verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, liquibaseFactory, tenantDataSourceFactory); }); Then("The tenant store upgrade fails with a schema upgrade needed", () -> { @@ -140,7 +147,6 @@ public class LiquibaseStepDefinitions implements En { tenantDataSourceFactory = mock(TenantDataSourceFactory.class); tenantDetailsService = mock(TenantDetailsService.class); databaseStateVerifier = mock(TenantDatabaseStateVerifier.class); - fineractProperties = mock(FineractProperties.class); liquibaseFactory = mock(ExtendedSpringLiquibaseFactory.class); @@ -158,7 +164,6 @@ public class LiquibaseStepDefinitions implements En { defaultTenantDataSource = mock(DataSource.class); given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(!liquibaseEnabled); - given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties()); given(liquibaseFactory.create(tenantStoreDataSource, "tenant_store_db", "initial_switch")).willReturn(initialTenantStoreLiquibase); given(liquibaseFactory.create(tenantStoreDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase); diff --git a/fineract-provider/src/test/resources/application-test.properties b/fineract-provider/src/test/resources/application-test.properties index c714f1384..58981db96 100644 --- a/fineract-provider/src/test/resources/application-test.properties +++ b/fineract-provider/src/test/resources/application-test.properties @@ -33,6 +33,10 @@ fineract.tenant.identifier=default fineract.tenant.name=fineract_default fineract.tenant.description=Default Demo Tenant +fineract.mode.read-enabled=true +fineract.mode.write-enabled=true +fineract.mode.batch-enabled=true + management.health.jms.enabled=false # FINERACT 1296 diff --git a/fineract-provider/src/test/resources/features/infrastructure/infrastructure.core.feature b/fineract-provider/src/test/resources/features/infrastructure/infrastructure.core.feature index a98edda3c..e78bd0e76 100644 --- a/fineract-provider/src/test/resources/features/infrastructure/infrastructure.core.feature +++ b/fineract-provider/src/test/resources/features/infrastructure/infrastructure.core.feature @@ -6,8 +6,26 @@ Feature: Core Infrastructure When The database migration process is executed Then The database migration did not do anything + @infrastructure + Scenario: Verify that schema migration is not executed when the Fineract instance is a read instance + Given Set every Fineract instance type to false + Given Fineract instance is a read instance + Given Liquibase is enabled with a default tenant + When The database migration process is executed + Then The database migration did not do anything, because it is not a write instance + + @infrastructure + Scenario: Verify that schema migration is not executed when the Fineract instance is a batch instance + Given Set every Fineract instance type to false + Given Fineract instance is a batch instance + Given Liquibase is enabled with a default tenant + When The database migration process is executed + Then The database migration did not do anything, because it is not a write instance + @infrastructure Scenario: Verify that schema migration works from scratch + Given Set every Fineract instance type to false + Given Fineract instance is a write instance Given Liquibase is enabled with a default tenant Given Liquibase runs the very first time for the tenant store Given Liquibase runs the very first time for the default tenant