You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2023/02/17 15:31:23 UTC

[fineract] branch develop updated: FINERACT-1724: Ability to run Fineract in Liquibase only mode for scaled environments

This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 6c86e15eb FINERACT-1724: Ability to run Fineract in Liquibase only mode for scaled environments
6c86e15eb is described below

commit 6c86e15eb7d5c10b591320bb19f866507504b20a
Author: Arnold Galovics <ga...@gmail.com>
AuthorDate: Wed Feb 15 12:04:21 2023 +0100

    FINERACT-1724: Ability to run Fineract in Liquibase only mode for scaled environments
---
 .../note/starter/TestDefaultConfiguration.java     |  4 +-
 .../note/starter/TestOverrideConfiguration.java    |  4 +-
 .../en/chapters/appendix/properties-database.adoc  |  5 +++
 .../docs/en/chapters/deployment/kubernetes.adoc    | 10 ++++-
 .../org/apache/fineract/ServerApplication.java     | 10 +++--
 .../UpdateTrialBalanceDetailsConfig.java           |  2 +-
 .../UpdateTrialBalanceDetailsTasklet.java          |  2 +-
 .../service/BulkImportEventListener.java           |  2 +-
 ...eractLiquibaseOnlyApplicationConfiguration.java | 45 ++++++++++++++++++++++
 .../FineractProfiles.java}                         | 11 ++----
 ...va => FineractWebApplicationConfiguration.java} | 13 ++++++-
 ...FineractLiquibaseOnlyApplicationCondition.java} | 13 ++++---
 .../FineractWebApplicationCondition.java}          | 13 ++++---
 .../condition/ProfileCondition.java}               | 17 +++++---
 .../infrastructure/core/config/HikariCpConfig.java |  3 +-
 .../infrastructure/core/config/JdbcConfig.java     |  2 +-
 .../infrastructure/core/config/jpa/JPAConfig.java  |  2 +-
 .../DataSourcePerTenantServiceFactory.java         |  2 +-
 .../{ => database}/HikariDataSourceFactory.java    |  2 +-
 .../service/{ => database}/RoutingDataSource.java  |  2 +-
 .../{ => database}/RoutingDataSourceService.java   |  2 +-
 .../RoutingDataSourceServiceFactory.java           |  3 +-
 .../TomcatJdbcDataSourcePerTenantService.java      |  3 +-
 .../migration/TenantDatabaseStateVerifier.java     |  3 --
 .../migration/TenantDatabaseUpgradeService.java    | 40 +++++++++----------
 .../service/tenant}/JdbcTenantDetailsService.java  |  2 +-
 .../service/tenant}/TenantDetailsService.java      |  2 +-
 .../service/tenant}/TenantMapper.java              |  4 +-
 .../service/GenericDataServiceImpl.java            |  2 +-
 ...xternalEventConfigurationValidationService.java |  2 +-
 .../jobs/ScheduledJobRunnerConfig.java             |  2 +-
 .../jobs/service/JobSchedulerServiceImpl.java      |  2 +-
 .../jobs/service/SchedulerTriggerListener.java     |  2 +-
 .../jobs/service/StuckJobListener.java             |  2 +-
 .../jobs/service/updatenpa/UpdateNpaConfig.java    |  2 +-
 .../jobs/service/updatenpa/UpdateNpaTasklet.java   |  2 +-
 .../service/BasicAuthTenantDetailsServiceJdbc.java |  1 +
 .../GenerateRdScheduleConfig.java                  |  2 +-
 .../GenerateRdScheduleTasklet.java                 |  2 +-
 .../application-liquibase-only.properties          | 20 ++++++++++
 .../src/main/resources/application.properties      |  2 +-
 .../org/apache/fineract/TestConfiguration.java     | 11 +++---
 .../DataSourcePerTenantServiceFactoryTest.java     |  4 +-
 .../core/LiquibaseStepDefinitions.java             |  8 +++-
 ...nalEventConfigurationValidationServiceTest.java |  2 +-
 45 files changed, 196 insertions(+), 95 deletions(-)

diff --git a/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestDefaultConfiguration.java b/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestDefaultConfiguration.java
index da74531f2..8a2395af1 100644
--- a/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestDefaultConfiguration.java
+++ b/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestDefaultConfiguration.java
@@ -22,8 +22,8 @@ import static org.mockito.Mockito.mock;
 
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
 import org.apache.fineract.portfolio.group.domain.GroupRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
diff --git a/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestOverrideConfiguration.java b/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestOverrideConfiguration.java
index 173671a0b..10f8d6cce 100644
--- a/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestOverrideConfiguration.java
+++ b/custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestOverrideConfiguration.java
@@ -21,8 +21,8 @@ package com.acme.fineract.portfolio.note.starter;
 import static org.mockito.Mockito.mock;
 
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
 import org.apache.fineract.portfolio.group.domain.GroupRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
diff --git a/fineract-doc/src/docs/en/chapters/appendix/properties-database.adoc b/fineract-doc/src/docs/en/chapters/appendix/properties-database.adoc
index cb3ce2bc6..834bec705 100644
--- a/fineract-doc/src/docs/en/chapters/appendix/properties-database.adoc
+++ b/fineract-doc/src/docs/en/chapters/appendix/properties-database.adoc
@@ -48,4 +48,9 @@
 |FINERACT_DEFAULT_TENANTDB_DESCRIPTION
 |Default Demo Tenant
 |TBD
+
+|spring.liquibase.enabled
+|FINERACT_LIQUIBASE_ENABLED
+|true
+|TBD
 |===
diff --git a/fineract-doc/src/docs/en/chapters/deployment/kubernetes.adoc b/fineract-doc/src/docs/en/chapters/deployment/kubernetes.adoc
index d69ba2f74..8cf75957f 100644
--- a/fineract-doc/src/docs/en/chapters/deployment/kubernetes.adoc
+++ b/fineract-doc/src/docs/en/chapters/deployment/kubernetes.adoc
@@ -1,3 +1,11 @@
 = Kubernetes
 
-TBD
+In a scaled Kubernetes environment where multiple Fineract instances are deployed, doing the database migrations properly is essential.
+
+Fineract provides a way to run only the Liquibase migrations instead of starting up the whole application server so that you can easily do the migrations before actually upgrading a Fineract instance.
+
+The `FINERACT_LIQUIBASE_ENABLED` flag controls whether Liquibase is enabled or not. For regular read/write/batch manager/batch worker instances this should be disabled.
+
+There's a special Spring profile that should be enabled for running Liquibase only. In can be done via `SPRING_PROFILES_ACTIVE` environment variable. The profile name is `liquibase-only`. At the end of the migration process, the application will exit.
+
+For the instance running the Liquibase migrations, the profile should be activated.
\ No newline at end of file
diff --git a/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java b/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
index 87ce9053d..2bbe662e9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
@@ -19,10 +19,12 @@
 package org.apache.fineract;
 
 import java.io.IOException;
-import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
+import org.apache.fineract.infrastructure.core.boot.FineractLiquibaseOnlyApplicationConfiguration;
+import org.apache.fineract.infrastructure.core.boot.FineractWebApplicationConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Import;
 
 /**
  * Fineract main() application which launches Fineract in an embedded Tomcat HTTP (using Spring Boot).
@@ -39,11 +41,12 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
 
 public class ServerApplication extends SpringBootServletInitializer {
 
-    private static class Configuration extends AbstractApplicationConfiguration {}
+    @Import({ FineractWebApplicationConfiguration.class, FineractLiquibaseOnlyApplicationConfiguration.class })
+    private static class Configuration {}
 
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
-        return builder.sources(Configuration.class);
+        return configureApplication(builder);
     }
 
     private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
@@ -52,6 +55,5 @@ public class ServerApplication extends SpringBootServletInitializer {
 
     public static void main(String[] args) throws IOException {
         configureApplication(new SpringApplicationBuilder(ServerApplication.class)).run(args);
-        // ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
index 2826e8423..05db8ccae 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
@@ -19,7 +19,7 @@
 package org.apache.fineract.accounting.glaccount.jobs.updatetrialbalancedetails;
 
 import org.apache.fineract.accounting.glaccount.domain.TrialBalanceRepositoryWrapper;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
 import org.springframework.batch.core.Job;
 import org.springframework.batch.core.Step;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
index bbefb7f41..d3cfee019 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
@@ -27,8 +27,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.accounting.glaccount.domain.TrialBalance;
 import org.apache.fineract.accounting.glaccount.domain.TrialBalanceRepositoryWrapper;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.springframework.batch.core.StepContribution;
 import org.springframework.batch.core.scope.context.ChunkContext;
 import org.springframework.batch.core.step.tasklet.Tasklet;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportEventListener.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportEventListener.java
index a82b7fedf..3c13f6afd 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportEventListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportEventListener.java
@@ -33,10 +33,10 @@ import org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler
 import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand;
 import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
 import org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService;
-import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractLiquibaseOnlyApplicationConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractLiquibaseOnlyApplicationConfiguration.java
new file mode 100644
index 000000000..78f5e7d45
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractLiquibaseOnlyApplicationConfiguration.java
@@ -0,0 +1,45 @@
+/**
+ * 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.boot;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.condition.FineractLiquibaseOnlyApplicationCondition;
+import org.apache.fineract.infrastructure.core.config.FineractProperties;
+import org.apache.fineract.infrastructure.core.config.HikariCpConfig;
+import org.apache.fineract.infrastructure.core.config.JdbcConfig;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Import;
+
+@Conditional(FineractLiquibaseOnlyApplicationCondition.class)
+@Slf4j
+@EnableConfigurationProperties({ FineractProperties.class, LiquibaseProperties.class })
+@Import({ HikariCpConfig.class, JdbcConfig.class })
+@ComponentScan(basePackages = { "org.apache.fineract.infrastructure.core.service.migration",
+        "org.apache.fineract.infrastructure.core.service.database", "org.apache.fineract.infrastructure.core.service.tenant" })
+public class FineractLiquibaseOnlyApplicationConfiguration implements InitializingBean {
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        log.warn("Fineract is running in Liquibase only mode");
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
similarity index 75%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java
copy to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
index 343ef1c81..e07173efc 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
@@ -16,14 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.boot;
 
-import javax.sql.DataSource;
+public final class FineractProfiles {
 
-/**
- * A service for getting hold of the appropriate {@link DataSource} connection pool.
- */
-public interface RoutingDataSourceService {
+    public static final String LIQUIBASE_ONLY = "liquibase-only";
 
-    DataSource retrieveDataSource();
+    private FineractProfiles() {}
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/AbstractApplicationConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractWebApplicationConfiguration.java
similarity index 81%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/AbstractApplicationConfiguration.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractWebApplicationConfiguration.java
index dcc5fe71d..73ec21230 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/AbstractApplicationConfiguration.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractWebApplicationConfiguration.java
@@ -18,7 +18,10 @@
  */
 package org.apache.fineract.infrastructure.core.boot;
 
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.condition.FineractWebApplicationCondition;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -29,6 +32,7 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.integration.annotation.IntegrationComponentScan;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -47,6 +51,13 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 @EnableConfigurationProperties({ FineractProperties.class, LiquibaseProperties.class })
 @ComponentScan(basePackages = "org.apache.fineract.**")
 @IntegrationComponentScan(basePackages = "org.apache.fineract.**")
-public abstract class AbstractApplicationConfiguration {
+@Conditional(FineractWebApplicationCondition.class)
+@Slf4j
+// The class needs to be abstract for some reason, otherwise the tests start to fail...
+public abstract class FineractWebApplicationConfiguration implements InitializingBean {
 
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        log.warn("Fineract is running in web application mode");
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
similarity index 69%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
copy to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
index df3123e50..1721c6dd1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
@@ -16,14 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.condition;
 
 import java.util.List;
-import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
 
-public interface TenantDetailsService {
+public class FineractLiquibaseOnlyApplicationCondition extends ProfileCondition {
 
-    FineractPlatformTenant loadTenantById(String tenantId);
-
-    List<FineractPlatformTenant> findAllTenants();
+    @Override
+    protected boolean matches(List<String> activeProfiles) {
+        return activeProfiles.contains(FineractProfiles.LIQUIBASE_ONLY);
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
similarity index 70%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
copy to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
index df3123e50..44cc02093 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
@@ -16,14 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.condition;
 
 import java.util.List;
-import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
 
-public interface TenantDetailsService {
+public class FineractWebApplicationCondition extends ProfileCondition {
 
-    FineractPlatformTenant loadTenantById(String tenantId);
-
-    List<FineractPlatformTenant> findAllTenants();
+    @Override
+    protected boolean matches(List<String> activeProfiles) {
+        return !activeProfiles.contains(FineractProfiles.LIQUIBASE_ONLY);
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
similarity index 56%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
copy to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
index df3123e50..4404abbce 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
@@ -16,14 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.condition;
 
+import java.util.Arrays;
 import java.util.List;
-import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
 
-public interface TenantDetailsService {
+public abstract class ProfileCondition implements Condition {
 
-    FineractPlatformTenant loadTenantById(String tenantId);
+    @Override
+    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+        String[] activeProfiles = context.getEnvironment().getActiveProfiles();
+        return matches(Arrays.asList(activeProfiles));
+    }
 
-    List<FineractPlatformTenant> findAllTenants();
+    protected abstract boolean matches(List<String> activeProfiles);
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/HikariCpConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/HikariCpConfig.java
index 8086e569c..90a7204e6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/HikariCpConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/HikariCpConfig.java
@@ -21,7 +21,6 @@ package org.apache.fineract.infrastructure.core.config;
 
 import com.zaxxer.hikari.HikariConfig;
 import com.zaxxer.hikari.HikariDataSource;
-import javax.sql.DataSource;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
@@ -41,7 +40,7 @@ public class HikariCpConfig {
     }
 
     @Bean(destroyMethod = "close")
-    public DataSource hikariTenantDataSource(HikariConfig hikariConfig) {
+    public HikariDataSource hikariTenantDataSource(HikariConfig hikariConfig) {
         return new HikariDataSource(hikariConfig);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JdbcConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JdbcConfig.java
index 87936e636..55e58c7c0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JdbcConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JdbcConfig.java
@@ -18,7 +18,7 @@
  */
 package org.apache.fineract.infrastructure.core.config;
 
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.jdbc.core.JdbcTemplate;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
index 77c1f7866..3cadc00e0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
@@ -27,8 +27,8 @@ import java.util.Set;
 import org.apache.fineract.infrastructure.core.auditing.JpaAuditingHandlerRegistrar;
 import org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl;
 import org.apache.fineract.infrastructure.core.persistence.DatabaseSelectingPersistenceUnitPostProcessor;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
 import org.eclipse.persistence.config.PersistenceUnitProperties;
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/DataSourcePerTenantServiceFactory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
similarity index 98%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/DataSourcePerTenantServiceFactory.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
index 2380f7d52..7ce120335 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/DataSourcePerTenantServiceFactory.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
 import static org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection.toJdbcUrl;
 import static org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection.toProtocol;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/HikariDataSourceFactory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
similarity index 94%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/HikariDataSourceFactory.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
index dc43d2541..162bf13df 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/HikariDataSourceFactory.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
 import com.zaxxer.hikari.HikariConfig;
 import com.zaxxer.hikari.HikariDataSource;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
similarity index 97%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSource.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
index abf9f892b..ab618bcd1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
 import java.sql.Connection;
 import java.sql.SQLException;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
similarity index 93%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
index 343ef1c81..b97e5eabd 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
 import javax.sql.DataSource;
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceServiceFactory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
similarity index 92%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceServiceFactory.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
index 112cd44e6..007a9b9d3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/RoutingDataSourceServiceFactory.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
@@ -16,8 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.stereotype.Component;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
similarity index 95%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
index fb85ebeee..b01d6999d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
@@ -16,13 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service;
+package org.apache.fineract.infrastructure.core.service.database;
 
 import java.util.HashMap;
 import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
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 3759c7fd9..248c57016 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
@@ -22,7 +22,6 @@ 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.boot.autoconfigure.liquibase.LiquibaseProperties;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@@ -42,8 +41,6 @@ public class TenantDatabaseStateVerifier {
     private final LiquibaseProperties liquibaseProperties;
     private final DatabaseIndependentQueryService dbQueryService;
 
-    private final FineractProperties fineractProperties;
-
     public boolean isFirstLiquibaseMigration(DataSource dataSource) {
         boolean databaseChangelogTableExists = dbQueryService.isTablePresent(dataSource, "DATABASECHANGELOG");
         return !databaseChangelogTableExists;
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 1faf5b7e2..aee562ba2 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
@@ -20,18 +20,21 @@ package org.apache.fineract.infrastructure.core.service.migration;
 
 import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.function.Function;
 import javax.sql.DataSource;
 import liquibase.exception.LiquibaseException;
 import liquibase.integration.spring.SpringLiquibase;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
 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.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 
 /**
@@ -39,6 +42,7 @@ import org.springframework.stereotype.Service;
  */
 @Service
 @Slf4j
+@RequiredArgsConstructor
 public class TenantDatabaseUpgradeService implements InitializingBean {
 
     private static final String TENANT_STORE_DB_CONTEXT = "tenant_store_db";
@@ -47,33 +51,24 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
     private static final String CUSTOM_CHANGELOG_CONTEXT = "custom_changelog";
 
     private final TenantDetailsService tenantDetailsService;
+    @Qualifier("hikariTenantDataSource")
     private final DataSource tenantDataSource;
     private final FineractProperties fineractProperties;
     private final TenantDatabaseStateVerifier databaseStateVerifier;
     private final ExtendedSpringLiquibaseFactory liquibaseFactory;
     private final TenantDataSourceFactory tenantDataSourceFactory;
-
-    @Autowired
-    public TenantDatabaseUpgradeService(final TenantDetailsService detailsService,
-            @Qualifier("hikariTenantDataSource") final DataSource tenantDataSource, final FineractProperties fineractProperties,
-            TenantDatabaseStateVerifier databaseStateVerifier, ExtendedSpringLiquibaseFactory liquibaseFactory,
-            TenantDataSourceFactory tenantDataSourceFactory) {
-        this.tenantDetailsService = detailsService;
-        this.tenantDataSource = tenantDataSource;
-        this.fineractProperties = fineractProperties;
-        this.databaseStateVerifier = databaseStateVerifier;
-        this.liquibaseFactory = liquibaseFactory;
-        this.tenantDataSourceFactory = tenantDataSourceFactory;
-    }
+    private final Environment environment;
 
     @Override
     public void afterPropertiesSet() throws Exception {
-        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");
+        if (notLiquibaseOnlyMode()) {
+            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;
             }
-            return;
         }
         try {
             upgradeTenantStore();
@@ -83,6 +78,11 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
         }
     }
 
+    private boolean notLiquibaseOnlyMode() {
+        List<String> activeProfiles = Arrays.asList(environment.getActiveProfiles());
+        return !activeProfiles.contains(FineractProfiles.LIQUIBASE_ONLY);
+    }
+
     private void upgradeTenantStore() throws LiquibaseException {
         log.warn("Upgrading tenant store DB at {}:{}", fineractProperties.getTenant().getHost(), fineractProperties.getTenant().getPort());
         logTenantStoreDetails();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
similarity index 97%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
index ee78901eb..6ff01e39f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.service.tenant;
 
 import java.util.List;
 import javax.sql.DataSource;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
similarity index 94%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
index df3123e50..51cde2469 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantDetailsService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.service.tenant;
 
 import java.util.List;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantMapper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
similarity index 98%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantMapper.java
rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
index 7a4f57a6a..979639d0b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TenantMapper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.fineract.infrastructure.security.service;
+package org.apache.fineract.infrastructure.core.service.tenant;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -44,7 +44,7 @@ public final class TenantMapper implements RowMapper<FineractPlatformTenant> {
             + " from tenants t left join tenant_server_connections ts ";
     private final StringBuilder sqlBuilder = new StringBuilder(TENANT_SERVER_CONNECTION_BUILDER);
 
-    TenantMapper(boolean isReport) {
+    public TenantMapper(boolean isReport) {
         this.isReport = isReport;
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
index d8d52ce82..2eb6cf6f6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
@@ -28,9 +28,9 @@ import java.util.List;
 import javax.sql.DataSource;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
 import org.apache.fineract.infrastructure.core.service.database.IndexDetail;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
 import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
 import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
 import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnValueData;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
index b3c7efc69..095dcb0db 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
@@ -29,11 +29,11 @@ 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.core.service.tenant.TenantDetailsService;
 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;
 import org.springframework.stereotype.Service;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/ScheduledJobRunnerConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/ScheduledJobRunnerConfig.java
index 1062c3c28..7c560535d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/ScheduledJobRunnerConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/ScheduledJobRunnerConfig.java
@@ -19,7 +19,7 @@
 package org.apache.fineract.infrastructure.jobs;
 
 import org.apache.fineract.infrastructure.core.persistence.ExtendedJpaTransactionManager;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
 import org.springframework.batch.core.configuration.JobRegistry;
 import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
 import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
index 17ec72343..6d7af7c66 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
@@ -29,9 +29,9 @@ import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
 import org.apache.fineract.infrastructure.jobs.domain.SchedulerDetail;
-import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.stereotype.Component;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
index 55b2db779..e0e9f920a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
@@ -27,7 +27,7 @@ import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadP
 import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
-import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobKey;
 import org.quartz.Trigger;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StuckJobListener.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StuckJobListener.java
index 353c5c914..cfbd98dab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StuckJobListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StuckJobListener.java
@@ -27,10 +27,10 @@ import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadP
 import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.apache.fineract.infrastructure.event.external.service.JdbcTemplateFactory;
 import org.apache.fineract.infrastructure.jobs.domain.JobExecutionRepository;
 import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameProvider;
-import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
 import org.springframework.batch.core.configuration.JobRegistry;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.ApplicationListener;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
index b0c72d164..8a3ab7466 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
@@ -18,9 +18,9 @@
  */
 package org.apache.fineract.infrastructure.jobs.service.updatenpa;
 
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.springframework.batch.core.Job;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
index 927864bf8..f969abe46 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
@@ -21,10 +21,10 @@ package org.apache.fineract.infrastructure.jobs.service.updatenpa;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.batch.core.StepContribution;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java
index fa32a618f..88256014b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.security.service;
 
 import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantMapper;
 import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentifierException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleConfig.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleConfig.java
index ab4b24c09..286b93716 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleConfig.java
@@ -18,7 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings.jobs.generaterdschedule;
 
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
 import org.apache.fineract.portfolio.savings.service.DepositAccountReadPlatformService;
 import org.springframework.batch.core.Job;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleTasklet.java
index f20e173a3..a555afd04 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/jobs/generaterdschedule/GenerateRdScheduleTasklet.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
 import org.apache.fineract.portfolio.savings.DepositAccountUtils;
 import org.apache.fineract.portfolio.savings.service.DepositAccountReadPlatformService;
 import org.springframework.batch.core.StepContribution;
diff --git a/fineract-provider/src/main/resources/application-liquibase-only.properties b/fineract-provider/src/main/resources/application-liquibase-only.properties
new file mode 100644
index 000000000..cf24eda91
--- /dev/null
+++ b/fineract-provider/src/main/resources/application-liquibase-only.properties
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+spring.main.web-application-type=none
diff --git a/fineract-provider/src/main/resources/application.properties b/fineract-provider/src/main/resources/application.properties
index 170ff1cee..d13c4c355 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -159,7 +159,7 @@ spring.datasource.hikari.dataSourceProperties['dumpQueriesOnException']=${FINERA
 spring.jpa.open-in-view=false
 
 # Liquibase configuration
-spring.liquibase.enabled=true
+spring.liquibase.enabled=${FINERACT_LIQUIBASE_ENABLED:true}
 spring.liquibase.changeLog=classpath:/db/changelog/db.changelog-master.xml
 
 spring.liquibase.parameters.fineract.tenant.identifier=${fineract.tenant.identifier}
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 3d30b193b..98a6ddad1 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java
@@ -30,9 +30,9 @@ import org.apache.fineract.infrastructure.core.service.migration.ExtendedSpringL
 import org.apache.fineract.infrastructure.core.service.migration.TenantDataSourceFactory;
 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.tenant.TenantDetailsService;
 import org.apache.fineract.infrastructure.jobs.ScheduledJobRunnerConfig;
 import org.apache.fineract.infrastructure.jobs.service.JobRegisterService;
-import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
@@ -59,6 +59,7 @@ import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.FilterType;
 import org.springframework.context.annotation.Primary;
+import org.springframework.core.env.Environment;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
@@ -138,8 +139,8 @@ public class TestConfiguration {
 
     @Bean
     public TenantDatabaseStateVerifier tenantDatabaseStateVerifier(DatabaseIndependentQueryService databaseIndependentQueryService,
-            LiquibaseProperties liquibaseProperties, FineractProperties fineractProperties) {
-        return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService, fineractProperties);
+            LiquibaseProperties liquibaseProperties) {
+        return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService);
     }
 
     /**
@@ -150,9 +151,9 @@ public class TestConfiguration {
     public TenantDatabaseUpgradeService tenantDatabaseUpgradeService(TenantDetailsService tenantDetailsService,
             HikariDataSource tenantDataSource, TenantDatabaseStateVerifier tenantDatabaseStateVerifier,
             ExtendedSpringLiquibaseFactory liquibaseFactory, TenantDataSourceFactory tenantDataSourceFactory,
-            FineractProperties fineractProperties) {
+            FineractProperties fineractProperties, Environment environment) {
         return new TenantDatabaseUpgradeService(tenantDetailsService, tenantDataSource, fineractProperties, tenantDatabaseStateVerifier,
-                liquibaseFactory, tenantDataSourceFactory);
+                liquibaseFactory, tenantDataSourceFactory, environment);
     }
 
     /**
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
index e34c8aa84..20d8df67c 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
@@ -37,8 +37,8 @@ import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
-import org.apache.fineract.infrastructure.core.service.DataSourcePerTenantServiceFactory;
-import org.apache.fineract.infrastructure.core.service.HikariDataSourceFactory;
+import org.apache.fineract.infrastructure.core.service.database.DataSourcePerTenantServiceFactory;
+import org.apache.fineract.infrastructure.core.service.database.HikariDataSourceFactory;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
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 be2143c33..27b64e415 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
@@ -39,8 +39,10 @@ import org.apache.fineract.infrastructure.core.service.migration.SchemaUpgradeNe
 import org.apache.fineract.infrastructure.core.service.migration.TenantDataSourceFactory;
 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.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.mock.env.MockEnvironment;
 
 public class LiquibaseStepDefinitions implements En {
 
@@ -61,6 +63,7 @@ public class LiquibaseStepDefinitions implements En {
     private List<FineractPlatformTenant> allTenants;
     private SchemaUpgradeNeededException executionException;
     private DataSource defaultTenantDataSource;
+    private Environment environment;
 
     public LiquibaseStepDefinitions() {
         Given("Liquibase is disabled with a default tenant", () -> {
@@ -148,6 +151,7 @@ public class LiquibaseStepDefinitions implements En {
         tenantDataSourceFactory = mock(TenantDataSourceFactory.class);
         tenantDetailsService = mock(TenantDetailsService.class);
         databaseStateVerifier = mock(TenantDatabaseStateVerifier.class);
+        environment = new MockEnvironment();
 
         liquibaseFactory = mock(ExtendedSpringLiquibaseFactory.class);
 
@@ -176,6 +180,6 @@ public class LiquibaseStepDefinitions implements En {
         given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "custom_changelog")).willReturn(customChangeLogLiquibase);
 
         tenantDatabaseUpgradeService = new TenantDatabaseUpgradeService(tenantDetailsService, tenantStoreDataSource, fineractProperties,
-                databaseStateVerifier, liquibaseFactory, tenantDataSourceFactory);
+                databaseStateVerifier, liquibaseFactory, tenantDataSourceFactory, environment);
     }
 }
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
index ed0d22ae4..441ff0f29 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
@@ -31,9 +31,9 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 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;
 import org.junit.jupiter.api.extension.ExtendWith;