FINERACT-1571: Allow Liquibase data migration for write instances only

This commit is contained in:
taskain7
2022-04-27 16:18:29 +02:00
committed by Arnold Gálovics
parent e3e4dbeb8a
commit 56d14a1d69
7 changed files with 86 additions and 12 deletions
@@ -21,13 +21,15 @@ package org.apache.fineract.infrastructure.core.service.migration;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import javax.sql.DataSource; 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.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
@RequiredArgsConstructor
public class TenantDatabaseStateVerifier { public class TenantDatabaseStateVerifier {
private static final int TENANT_STORE_LATEST_FLYWAY_VERSION = 6; private static final int TENANT_STORE_LATEST_FLYWAY_VERSION = 6;
@@ -40,11 +42,7 @@ public class TenantDatabaseStateVerifier {
private final LiquibaseProperties liquibaseProperties; private final LiquibaseProperties liquibaseProperties;
private final DatabaseIndependentQueryService dbQueryService; private final DatabaseIndependentQueryService dbQueryService;
@Autowired private final FineractProperties fineractProperties;
public TenantDatabaseStateVerifier(LiquibaseProperties liquibaseProperties, DatabaseIndependentQueryService dbQueryService) {
this.liquibaseProperties = liquibaseProperties;
this.dbQueryService = dbQueryService;
}
public boolean isFirstLiquibaseMigration(DataSource dataSource) { public boolean isFirstLiquibaseMigration(DataSource dataSource) {
boolean databaseChangelogTableExists = dbQueryService.isTablePresent(dataSource, "DATABASECHANGELOG"); boolean databaseChangelogTableExists = dbQueryService.isTablePresent(dataSource, "DATABASECHANGELOG");
@@ -68,8 +68,11 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (databaseStateVerifier.isLiquibaseDisabled()) { 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");
}
return; return;
} }
try { try {
@@ -103,7 +103,7 @@ public class TestConfiguration {
@Bean @Bean
public TenantDatabaseStateVerifier tenantDatabaseStateVerifier(DatabaseIndependentQueryService databaseIndependentQueryService, public TenantDatabaseStateVerifier tenantDatabaseStateVerifier(DatabaseIndependentQueryService databaseIndependentQueryService,
LiquibaseProperties liquibaseProperties, FineractProperties fineractProperties) { LiquibaseProperties liquibaseProperties, FineractProperties fineractProperties) {
return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService); return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService, fineractProperties);
} }
/** /**
@@ -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);
});
}
}
@@ -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.TenantDatabaseStateVerifier;
import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseUpgradeService; import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseUpgradeService;
import org.apache.fineract.infrastructure.security.service.TenantDetailsService; import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
public class LiquibaseStepDefinitions implements En { public class LiquibaseStepDefinitions implements En {
private TenantDataSourceFactory tenantDataSourceFactory; private TenantDataSourceFactory tenantDataSourceFactory;
private TenantDetailsService tenantDetailsService; private TenantDetailsService tenantDetailsService;
private TenantDatabaseStateVerifier databaseStateVerifier; private TenantDatabaseStateVerifier databaseStateVerifier;
@Autowired
private FineractProperties fineractProperties; private FineractProperties fineractProperties;
private ExtendedSpringLiquibaseFactory liquibaseFactory; private ExtendedSpringLiquibaseFactory liquibaseFactory;
private ExtendedSpringLiquibase initialTenantStoreLiquibase; private ExtendedSpringLiquibase initialTenantStoreLiquibase;
@@ -100,8 +102,13 @@ public class LiquibaseStepDefinitions implements En {
Then("The database migration did not do anything", () -> { Then("The database migration did not do anything", () -> {
verify(databaseStateVerifier).isLiquibaseDisabled(); verify(databaseStateVerifier).isLiquibaseDisabled();
verifyNoMoreInteractions(databaseStateVerifier); verifyNoMoreInteractions(databaseStateVerifier);
verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, fineractProperties, liquibaseFactory, verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, liquibaseFactory, tenantDataSourceFactory);
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", () -> { Then("The tenant store upgrade fails with a schema upgrade needed", () -> {
@@ -140,7 +147,6 @@ public class LiquibaseStepDefinitions implements En {
tenantDataSourceFactory = mock(TenantDataSourceFactory.class); tenantDataSourceFactory = mock(TenantDataSourceFactory.class);
tenantDetailsService = mock(TenantDetailsService.class); tenantDetailsService = mock(TenantDetailsService.class);
databaseStateVerifier = mock(TenantDatabaseStateVerifier.class); databaseStateVerifier = mock(TenantDatabaseStateVerifier.class);
fineractProperties = mock(FineractProperties.class);
liquibaseFactory = mock(ExtendedSpringLiquibaseFactory.class); liquibaseFactory = mock(ExtendedSpringLiquibaseFactory.class);
@@ -158,7 +164,6 @@ public class LiquibaseStepDefinitions implements En {
defaultTenantDataSource = mock(DataSource.class); defaultTenantDataSource = mock(DataSource.class);
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(!liquibaseEnabled); 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", "initial_switch")).willReturn(initialTenantStoreLiquibase);
given(liquibaseFactory.create(tenantStoreDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase); given(liquibaseFactory.create(tenantStoreDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
@@ -33,6 +33,10 @@ fineract.tenant.identifier=default
fineract.tenant.name=fineract_default fineract.tenant.name=fineract_default
fineract.tenant.description=Default Demo Tenant 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 management.health.jms.enabled=false
# FINERACT 1296 # FINERACT 1296
@@ -6,8 +6,26 @@ Feature: Core Infrastructure
When The database migration process is executed When The database migration process is executed
Then The database migration did not do anything 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 @infrastructure
Scenario: Verify that schema migration works from scratch 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 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 tenant store
Given Liquibase runs the very first time for the default tenant Given Liquibase runs the very first time for the default tenant