From 15f0fc46774de58e094b68cc57dcb6b81fc2db2a Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Fri, 13 Jul 2012 18:05:14 +0100 Subject: [PATCH] support schema per tenant multi-tenancy. basic auth security filter is extended to detect tenant-id header on request, verify tenant id is valid and then use provided credentials to authenticate user details against users on the tenant specific schema. --- .../WIPdbchanges.sql | 8 +- ...atch-0001-fund-and-loanproduct-changes.sql | 6 +- .../patch-0002-fund-and-loan-changes.sql | 4 +- .../patch-0005-branch-transfer-of-funds.sql | 2 +- .../patch-0006-office-transactions.sql | 4 +- mifosng-provider/build.gradle | 28 +++---- .../ReadExtraDataAndReportingServiceImpl.java | 6 +- .../ClientReadPlatformServiceImpl.java | 11 ++- .../CurrencyReadPlatformServiceImpl.java | 11 ++- .../service/FundReadPlatformServiceImpl.java | 11 ++- .../DataSourcePerTenantService.java | 11 +++ .../InvalidTenantIdentiferException.java | 14 ++++ .../JdbcTenantDetailsService.java | 50 ++++++++++++ .../infrastructure/MifosPlatformTenant.java | 26 ++++++ .../TenantAwareBasicAuthenticationFilter.java | 49 ++++++++++++ .../TenantAwareRoutingDataSource.java | 34 ++++++++ .../infrastructure/TenantDetailsService.java | 7 ++ .../ThreadLocalContextUtil.java | 24 ++++++ .../TomcatJdbcDataSourcePerTenantService.java | 80 +++++++++++++++++++ .../LoanProductReadPlatformServiceImpl.java | 11 ++- .../OfficeReadPlatformServiceImpl.java | 12 ++- ...ntAwareJpaPlatformUserDetailsService.java} | 4 +- .../AppUserReadPlatformServiceImpl.java | 11 ++- .../PermissionReadPlatformServiceImpl.java | 11 ++- .../service/RoleReadPlatformServiceImpl.java | 11 ++- .../main/resources/META-INF/persistence.xml | 7 +- .../resources/META-INF/spring/appContext.xml | 6 +- .../META-INF/spring/infrastructure.xml | 13 +-- .../META-INF/spring/securityContext.xml | 28 ++++--- .../src/main/resources/logback.xml | 2 +- .../src/main/webapp/META-INF/context.xml | 2 +- .../webapp/WEB-INF/spring/webmvc-config.xml | 40 ---------- .../src/main/webapp/WEB-INF/web.xml | 46 +---------- .../src/test/resources/META-INF/context.xml | 4 +- 34 files changed, 399 insertions(+), 195 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DataSourcePerTenantService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/InvalidTenantIdentiferException.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareRoutingDataSource.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TomcatJdbcDataSourcePerTenantService.java rename mifosng-provider/src/main/java/org/mifosng/platform/security/{PlatformUserDetailsServiceImpl.java => TenantAwareJpaPlatformUserDetailsService.java} (85%) delete mode 100644 mifosng-provider/src/main/webapp/WEB-INF/spring/webmvc-config.xml diff --git a/mifosng-db/patches-beta-3-heavens-family/WIPdbchanges.sql b/mifosng-db/patches-beta-3-heavens-family/WIPdbchanges.sql index ef06a11ad..0977cfdad 100644 --- a/mifosng-db/patches-beta-3-heavens-family/WIPdbchanges.sql +++ b/mifosng-db/patches-beta-3-heavens-family/WIPdbchanges.sql @@ -1,3 +1,7 @@ - /* remove column org_id */ -ALTER TABLE `mifosngprovider`.`portfolio_client` DROP FOREIGN KEY `FKCE00CAB354DF2770` ;ALTER TABLE `mifosngprovider`.`portfolio_client` DROP COLUMN `org_id` , DROP INDEX `org_id` , ADD INDEX `external_id` (`external_id` ASC) , DROP INDEX `FKCE00CAB354DF2770` ; \ No newline at end of file +ALTER TABLE `portfolio_client` DROP FOREIGN KEY `FKCE00CAB354DF2770`; +ALTER TABLE `portfolio_client` + DROP COLUMN `org_id` , + DROP INDEX `org_id` , + ADD INDEX `external_id` (`external_id` ASC) , + DROP INDEX `FKCE00CAB354DF2770`; \ No newline at end of file diff --git a/mifosng-db/patches-beta-3-heavens-family/patch-0001-fund-and-loanproduct-changes.sql b/mifosng-db/patches-beta-3-heavens-family/patch-0001-fund-and-loanproduct-changes.sql index e034ad547..c97091a54 100644 --- a/mifosng-db/patches-beta-3-heavens-family/patch-0001-fund-and-loanproduct-changes.sql +++ b/mifosng-db/patches-beta-3-heavens-family/patch-0001-fund-and-loanproduct-changes.sql @@ -1,5 +1,5 @@ -- create fund table -DROP TABLE IF EXISTS `mifosngprovider`.`org_fund`; +DROP TABLE IF EXISTS `org_fund`; CREATE TABLE `org_fund` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `org_id` bigint(20) NOT NULL, @@ -21,13 +21,13 @@ CREATE TABLE `org_fund` ( ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -- example of dropping fund column/index/foreign key --- alter table `mifosngprovider`.`portfolio_product_loan` +-- alter table `portfolio_product_loan` -- DROP FOREIGN KEY `FKA6A8A7D77240145`, -- DROP INDEX `FKA6A8A7D77240145`, -- drop column `fund_id`; -- associate fund table with loan products making it fund optional at database level -alter table `mifosngprovider`.`portfolio_product_loan` +alter table `portfolio_product_loan` add column `fund_id` bigint(20) DEFAULT NULL, add KEY `FKA6A8A7D77240145` (`fund_id`), add CONSTRAINT `FKA6A8A7D77240145` FOREIGN KEY (`fund_id`) REFERENCES `org_fund` (`id`); \ No newline at end of file diff --git a/mifosng-db/patches-beta-3-heavens-family/patch-0002-fund-and-loan-changes.sql b/mifosng-db/patches-beta-3-heavens-family/patch-0002-fund-and-loan-changes.sql index c9de467bc..e2ad91e09 100644 --- a/mifosng-db/patches-beta-3-heavens-family/patch-0002-fund-and-loan-changes.sql +++ b/mifosng-db/patches-beta-3-heavens-family/patch-0002-fund-and-loan-changes.sql @@ -1,11 +1,11 @@ -- example of dropping fund column/index/foreign key --- alter table `mifosngprovider`.`portfolio_loan` +-- alter table `portfolio_loan` -- DROP FOREIGN KEY `FK7C885877240145`, -- DROP INDEX `FK7C885877240145`, -- drop column `fund_id`; -- associate fund table with loans making fund optional at database level -alter table `mifosngprovider`.`portfolio_loan` +alter table `portfolio_loan` add column `fund_id` bigint(20) DEFAULT NULL, add KEY `FK7C885877240145` (`fund_id`), add CONSTRAINT `FK7C885877240145` FOREIGN KEY (`fund_id`) REFERENCES `org_fund` (`id`); \ No newline at end of file diff --git a/mifosng-db/patches-beta-3-heavens-family/patch-0005-branch-transfer-of-funds.sql b/mifosng-db/patches-beta-3-heavens-family/patch-0005-branch-transfer-of-funds.sql index e7d98efbf..8c4e176fc 100644 --- a/mifosng-db/patches-beta-3-heavens-family/patch-0005-branch-transfer-of-funds.sql +++ b/mifosng-db/patches-beta-3-heavens-family/patch-0005-branch-transfer-of-funds.sql @@ -1,5 +1,5 @@ -- create fund table -DROP TABLE IF EXISTS `mifosngprovider`.`portfolio_office_monetary_transfers`; +DROP TABLE IF EXISTS `portfolio_office_monetary_transfers`; CREATE TABLE `portfolio_office_monetary_transfers` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `from_office_id` bigint(20) DEFAULT NULL, diff --git a/mifosng-db/patches-beta-3-heavens-family/patch-0006-office-transactions.sql b/mifosng-db/patches-beta-3-heavens-family/patch-0006-office-transactions.sql index 12bacb3d6..4b4a05717 100644 --- a/mifosng-db/patches-beta-3-heavens-family/patch-0006-office-transactions.sql +++ b/mifosng-db/patches-beta-3-heavens-family/patch-0006-office-transactions.sql @@ -1,6 +1,6 @@ -- create office transaction table -DROP TABLE IF EXISTS `mifosngprovider`.`portfolio_office_monetary_transfers`; -DROP TABLE IF EXISTS `mifosngprovider`.`portfolio_office_transaction`; +DROP TABLE IF EXISTS `portfolio_office_monetary_transfers`; +DROP TABLE IF EXISTS `portfolio_office_transaction`; CREATE TABLE `portfolio_office_transaction` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `from_office_id` bigint(20) DEFAULT NULL, diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index a4e3e1f2e..b201a1f98 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -14,19 +14,16 @@ buildscript { apply plugin: 'war' apply plugin: 'eclipse' apply plugin: 'tomcat' -//apply plugin: 'jdepend' sourceCompatibility = JavaVersion.VERSION_1_6 targetCompatibility = JavaVersion.VERSION_1_6 springVersion = '3.1.1.RELEASE' -springSecurityOauthVersion = '1.0.0.M6' springSecurityVersion = '3.1.0.RELEASE' -hibernateValidatorVersion = '4.2.0.Final' -hibernateCoreVersion = '4.1.0.Final' -jerseyVersion = '1.12' +hibernateValidatorVersion = '4.3.0.Final' +hibernateCoreVersion = '4.1.3.Final' +jerseyVersion = '1.13' springDataJpaVersion = '1.0.3.RELEASE' -springDatamongoDbVersion = '1.0.0.M4' repositories { mavenCentral() @@ -59,7 +56,7 @@ configurations { } dependencies { - def tomcatVersion = '7.0.27' + def tomcatVersion = '7.0.29' tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}", "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}" tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") { @@ -72,17 +69,13 @@ dependencies { ) compile( - [group: 'javax.servlet', name: 'jstl', version: '1.2'], - [group: 'org.springframework', name: 'spring-core', version: springVersion], [group: 'org.springframework', name: 'spring-aspects', version: springVersion], [group: 'org.springframework', name: 'spring-web', version: springVersion], - [group: 'org.springframework', name: 'spring-webmvc', version: springVersion], [group: 'org.springframework.security', name: 'spring-security-core', version: springSecurityVersion], [group: 'org.springframework.security', name: 'spring-security-web', version: springSecurityVersion], [group: 'org.springframework.security', name: 'spring-security-config', version: springSecurityVersion], - [group: 'org.springframework.security', name: 'spring-security-taglibs', version: springSecurityVersion], - [group: 'org.aspectj', name: 'aspectjrt', version: '1.6.11.RELEASE'], + [group: 'org.aspectj', name: 'aspectjrt', version: '1.6.12.RELEASE'], [group: 'javax.validation', name: 'validation-api', version: '1.0.0.GA'], [group: 'org.hibernate', name: 'hibernate-validator', version: hibernateValidatorVersion], @@ -105,13 +98,14 @@ dependencies { [group: 'org.apache.commons', name: 'commons-email', version: '1.2'], [group: 'commons-lang', name: 'commons-lang', version: '2.4'], - [group: 'org.slf4j', name: 'slf4j-api', version: '1.6.4'], - [group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.4'], + [group: 'org.slf4j', name: 'slf4j-api', version: '1.6.6'], + [group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.6'], - [group: 'ch.qos.logback', name: 'logback-core', version: '1.0.1'], - [group: 'ch.qos.logback', name: 'logback-classic', version: '1.0.0'], + [group: 'ch.qos.logback', name: 'logback-core', version: '1.0.6'], + [group: 'ch.qos.logback', name: 'logback-classic', version: '1.0.6'], - [group: 'mysql', name: 'mysql-connector-java', version: '5.1.18'], + [group: 'mysql', name: 'mysql-connector-java', version: '5.1.21'], + [group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '7.0.29'], [group: 'pentaho-reporting-engine', name: 'pentaho-reporting-engine-classic-core', version: '3.8.3-GA'], [group: 'pentaho-reporting-engine', name: 'pentaho-reporting-engine-classic-extensions', version: '3.8.3-GA'], diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/ReadExtraDataAndReportingServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/ReadExtraDataAndReportingServiceImpl.java index 379970924..b6b4a6b88 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/ReadExtraDataAndReportingServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/ReadExtraDataAndReportingServiceImpl.java @@ -27,6 +27,7 @@ import org.mifosng.platform.api.data.ResultsetDataRow; import org.mifosng.platform.exceptions.AdditionalFieldsNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.ReportNotFoundException; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.ReportProcessingException; @@ -46,15 +47,14 @@ import org.springframework.stereotype.Service; public class ReadExtraDataAndReportingServiceImpl implements ReadExtraDataAndReportingService { - private final static Logger logger = LoggerFactory - .getLogger(ReadExtraDataAndReportingServiceImpl.class); + private final static Logger logger = LoggerFactory.getLogger(ReadExtraDataAndReportingServiceImpl.class); private final DataSource dataSource; private final String reportingMetaDataDB; private Boolean noPentaho = false; @Autowired - public ReadExtraDataAndReportingServiceImpl(final DataSource dataSource) { + public ReadExtraDataAndReportingServiceImpl(final TenantAwareRoutingDataSource dataSource) { // kick off pentaho reports server ClassicEngineBoot.getInstance().start(); noPentaho = false; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java index 42ba352c8..c23ed69a4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java @@ -6,8 +6,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.sql.DataSource; - import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.joda.time.LocalDate; @@ -23,33 +21,34 @@ import org.mifosng.platform.client.domain.NoteEnumerations; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.NoteNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.organisation.service.OfficeReadPlatformService; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.service.AppUserReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class ClientReadPlatformServiceImpl implements ClientReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final OfficeReadPlatformService officeReadPlatformService; private final AppUserReadPlatformService appUserReadPlatformService; @Autowired public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, - final DataSource dataSource, + final TenantAwareRoutingDataSource dataSource, final OfficeReadPlatformService officeReadPlatformService, final AppUserReadPlatformService appUserReadPlatformService) { this.context = context; this.officeReadPlatformService = officeReadPlatformService; this.appUserReadPlatformService = appUserReadPlatformService; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } private String generateOfficeIdInClause(List offices) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java index 7595c8321..28f5abc5b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java @@ -4,27 +4,26 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import javax.sql.DataSource; - import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class CurrencyReadPlatformServiceImpl implements CurrencyReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; @Autowired - public CurrencyReadPlatformServiceImpl(final PlatformSecurityContext context, final DataSource dataSource) { + public CurrencyReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { this.context = context; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java index f6c7564fc..9d96369af 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java @@ -4,29 +4,28 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; -import javax.sql.DataSource; - import org.mifosng.platform.api.data.FundData; import org.mifosng.platform.exceptions.FundNotFoundException; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class FundReadPlatformServiceImpl implements FundReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; @Autowired public FundReadPlatformServiceImpl(final PlatformSecurityContext context, - final DataSource dataSource) { + final TenantAwareRoutingDataSource dataSource) { this.context = context; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } private static final class FundMapper implements RowMapper { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DataSourcePerTenantService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DataSourcePerTenantService.java new file mode 100644 index 000000000..381c36ea9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DataSourcePerTenantService.java @@ -0,0 +1,11 @@ +package org.mifosng.platform.infrastructure; + +import javax.sql.DataSource; + +/** + * A service for getting hold of the appropriate {@link DataSource} connection pool for the given tenant. + */ +public interface DataSourcePerTenantService { + + DataSource retrieveTenantAwareDataSource(); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/InvalidTenantIdentiferException.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/InvalidTenantIdentiferException.java new file mode 100644 index 000000000..c95487348 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/InvalidTenantIdentiferException.java @@ -0,0 +1,14 @@ +package org.mifosng.platform.infrastructure; + +/** + * {@link RuntimeException} thrown when an invalid tenant identifier is used in request to platform. + * + * @see CustomRequestHeaderAuthenticationFilter + */ +public class InvalidTenantIdentiferException extends RuntimeException { + + public InvalidTenantIdentiferException(final String message) { + super(message); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java new file mode 100644 index 000000000..9e59cffea --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java @@ -0,0 +1,50 @@ +package org.mifosng.platform.infrastructure; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class JdbcTenantDetailsService implements TenantDetailsService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public JdbcTenantDetailsService(@Qualifier("tenantDataSourceJndi") final DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public MifosPlatformTenant loadTenantById(final String tenantIdentifier) { + + try { + TenantMapper rm = new TenantMapper(); + String sql = "select id, name, schema_name as schemaName from tenants t where t.identifier like ?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {tenantIdentifier}); + } catch (EmptyResultDataAccessException e) { + throw new InvalidTenantIdentiferException("The tenant identifier: " + tenantIdentifier + " is not valid."); + } + } + + private static final class TenantMapper implements RowMapper { + + @Override + public MifosPlatformTenant mapRow(final ResultSet rs, final int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String name = rs.getString("name"); + String schemaName = rs.getString("schemaName"); + + return new MifosPlatformTenant(id, name, schemaName); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java new file mode 100644 index 000000000..d2306aa48 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java @@ -0,0 +1,26 @@ +package org.mifosng.platform.infrastructure; + +public class MifosPlatformTenant { + + private final Long id; + private final String name; + private final String schemaName; + + public MifosPlatformTenant(Long id, String name, String schemaName) { + this.id = id; + this.name = name; + this.schemaName = schemaName; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getSchemaName() { + return schemaName; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java new file mode 100644 index 000000000..04fb8522a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java @@ -0,0 +1,49 @@ +package org.mifosng.platform.infrastructure; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +/** + * + */ +public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFilter { + + @Autowired + private TenantDetailsService tenantDetailsService; + + private String tenantRequestHeader = "X-Mifos-Platform-TenantId"; + private boolean exceptionIfHeaderMissing = true; + + public TenantAwareBasicAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) { + super(authenticationManager, authenticationEntryPoint); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) req; + final String tenantId = request.getHeader(tenantRequestHeader); + + if (tenantId == null && exceptionIfHeaderMissing) { + throw new PreAuthenticatedCredentialsNotFoundException(tenantRequestHeader + " header not found in request."); + } + + // check tenants database for tenantId + MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId); + + ThreadLocalContextUtil.setTenant(tenant); + + super.doFilter(req, res, chain); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareRoutingDataSource.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareRoutingDataSource.java new file mode 100644 index 000000000..c15045ae3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareRoutingDataSource.java @@ -0,0 +1,34 @@ +package org.mifosng.platform.infrastructure; + +import java.sql.Connection; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.datasource.AbstractDataSource; +import org.springframework.stereotype.Service; + +/** + * + */ +@Service(value="tenantAwareDataSource") +public class TenantAwareRoutingDataSource extends AbstractDataSource { + + @Autowired + private DataSourcePerTenantService dataSourcePerTenantService; + + @Override + public Connection getConnection() throws SQLException { + return determineTargetDataSource().getConnection(); + } + + private DataSource determineTargetDataSource() { + return dataSourcePerTenantService.retrieveTenantAwareDataSource(); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return determineTargetDataSource().getConnection(username, password); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java new file mode 100644 index 000000000..8e5e0b500 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java @@ -0,0 +1,7 @@ +package org.mifosng.platform.infrastructure; + +public interface TenantDetailsService { + + MifosPlatformTenant loadTenantById(String tenantId); + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java new file mode 100644 index 000000000..cb9037bb2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java @@ -0,0 +1,24 @@ +package org.mifosng.platform.infrastructure; + +import org.springframework.util.Assert; + +/** + * + */ +public class ThreadLocalContextUtil { + + private static final ThreadLocal contextHolder = new ThreadLocal(); + + public static void setTenant(final MifosPlatformTenant tenant) { + Assert.notNull(tenant, "tenant cannot be null"); + contextHolder.set(tenant); + } + + public static MifosPlatformTenant getTenant() { + return contextHolder.get(); + } + + public static void clearTenant() { + contextHolder.remove(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TomcatJdbcDataSourcePerTenantService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TomcatJdbcDataSourcePerTenantService.java new file mode 100644 index 000000000..6dd05eeb3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TomcatJdbcDataSourcePerTenantService.java @@ -0,0 +1,80 @@ +package org.mifosng.platform.infrastructure; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.sql.DataSource; + +import org.apache.tomcat.jdbc.pool.PoolConfiguration; +import org.apache.tomcat.jdbc.pool.PoolProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +/** + * + */ +@Service +public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService { + + private final Map tenantToDataSourceMap = new ConcurrentHashMap(1); + private final DataSource tenantDataSource; + + @Autowired + public TomcatJdbcDataSourcePerTenantService(final @Qualifier("tenantDataSourceJndi") DataSource tenantDataSource) { + this.tenantDataSource = tenantDataSource; + } + + @Override + public DataSource retrieveTenantAwareDataSource() { + + // default to tenant database datasource + DataSource tenantDataSource = this.tenantDataSource; + + MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); + if (tenant != null) { + // if tenant information available switch to appropriate datasource for that tenant. + if (this.tenantToDataSourceMap.containsKey(tenant.getId())) { + tenantDataSource = this.tenantToDataSourceMap.get(tenant.getId()); + } else { + tenantDataSource = createNewDataSourceFor(tenant); + this.tenantToDataSourceMap.put(tenant.getId(), tenantDataSource); + } + } + + return tenantDataSource; + } + + private DataSource createNewDataSourceFor(final MifosPlatformTenant tenant) { + // see http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency + PoolConfiguration poolConfiguration = new PoolProperties(); + poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver"); + poolConfiguration.setName(tenant.getSchemaName() + "_pool"); + poolConfiguration.setUrl("jdbc:mysql://localhost:3306/" + tenant.getSchemaName()); + poolConfiguration.setUsername("root"); + poolConfiguration.setPassword("mysql"); + + poolConfiguration.setInitialSize(5); + poolConfiguration.setMaxActive(5); + poolConfiguration.setMinIdle(1); + poolConfiguration.setMaxIdle(4); + + poolConfiguration.setSuspectTimeout(60); + poolConfiguration.setTimeBetweenEvictionRunsMillis(30000); + poolConfiguration.setMinEvictableIdleTimeMillis(60000); + + poolConfiguration.setTestOnBorrow(true); + poolConfiguration.setValidationQuery("SELECT 1"); + poolConfiguration.setValidationInterval(30000); + + poolConfiguration.setRemoveAbandoned(true); + poolConfiguration.setRemoveAbandonedTimeout(60); + poolConfiguration.setLogAbandoned(true); + poolConfiguration.setAbandonWhenPercentageFull(50); + + poolConfiguration.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" + + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport"); + + return new org.apache.tomcat.jdbc.pool.DataSource(poolConfiguration); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java index a8da01dc5..17f38a938 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java @@ -6,8 +6,6 @@ import java.sql.SQLException; import java.util.Collection; import java.util.List; -import javax.sql.DataSource; - import org.joda.time.DateTime; import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; @@ -19,6 +17,7 @@ import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.fund.service.FundReadPlatformService; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.loan.domain.AmortizationMethod; import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; import org.mifosng.platform.loan.domain.InterestMethod; @@ -27,8 +26,8 @@ import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service @@ -37,7 +36,7 @@ public class LoanProductReadPlatformServiceImpl implements private final PlatformSecurityContext context; private final CurrencyReadPlatformService currencyReadPlatformService; - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final LoanDropdownReadPlatformService dropdownReadPlatformService; private final FundReadPlatformService fundReadPlatformService; @@ -47,12 +46,12 @@ public class LoanProductReadPlatformServiceImpl implements final CurrencyReadPlatformService currencyReadPlatformService, final FundReadPlatformService fundReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService, - final DataSource dataSource) { + final TenantAwareRoutingDataSource dataSource) { this.context = context; this.currencyReadPlatformService = currencyReadPlatformService; this.fundReadPlatformService = fundReadPlatformService; this.dropdownReadPlatformService = dropdownReadPlatformService; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java index 542cc3835..2c8a560b5 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java @@ -6,33 +6,31 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.sql.DataSource; - import org.joda.time.LocalDate; import org.mifosng.platform.api.data.OfficeData; import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final static String nameDecoratedBaseOnHierarchy = "concat(substring('........................................', 1, ((LENGTH(o.hierarchy) - LENGTH(REPLACE(o.hierarchy, '.', '')) - 1) * 4)), o.name)"; @Autowired - public OfficeReadPlatformServiceImpl(final PlatformSecurityContext context, - final DataSource dataSource) { + public OfficeReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { this.context = context; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } private static final class OfficeMapper implements RowMapper { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java similarity index 85% rename from mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java index 3cc5bb92a..1ee56b135 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java @@ -7,11 +7,13 @@ import org.springframework.dao.DataAccessException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; /** * Used in securityContext.xml as implementation of spring security's {@link UserDetailsService}. */ -public class PlatformUserDetailsServiceImpl implements PlatformUserDetailsService { +@Service(value="userDetailsService") +public class TenantAwareJpaPlatformUserDetailsService implements PlatformUserDetailsService { @Autowired private PlatformUserRepository platformUserRepository; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserReadPlatformServiceImpl.java index 32a7fc024..420167a27 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserReadPlatformServiceImpl.java @@ -9,42 +9,41 @@ import java.util.Collection; import java.util.List; import java.util.Set; -import javax.sql.DataSource; - import org.mifosng.platform.api.data.AppUserData; import org.mifosng.platform.api.data.OfficeData; import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.api.data.RoleData; import org.mifosng.platform.exceptions.UserNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.organisation.service.OfficeReadPlatformService; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUserRepository; import org.mifosng.platform.user.domain.Role; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final OfficeReadPlatformService officeReadPlatformService; private final RoleReadPlatformService roleReadPlatformService; private final AppUserRepository appUserRepository; @Autowired - public AppUserReadPlatformServiceImpl(final PlatformSecurityContext context, final DataSource dataSource, + public AppUserReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, final OfficeReadPlatformService officeReadPlatformService, final RoleReadPlatformService roleReadPlatformService, final AppUserRepository appUserRepository) { this.context = context; this.officeReadPlatformService = officeReadPlatformService; this.roleReadPlatformService = roleReadPlatformService; this.appUserRepository = appUserRepository; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java index caadb28b1..2002c60af 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java @@ -4,27 +4,26 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; -import javax.sql.DataSource; - import org.mifosng.platform.api.data.PermissionData; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class PermissionReadPlatformServiceImpl implements PermissionReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; @Autowired - public PermissionReadPlatformServiceImpl(final PlatformSecurityContext context, final DataSource dataSource) { + public PermissionReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { this.context = context; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleReadPlatformServiceImpl.java index 5d5977d46..5e600fb51 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleReadPlatformServiceImpl.java @@ -6,32 +6,31 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; -import javax.sql.DataSource; - import org.mifosng.platform.api.data.RoleData; import org.mifosng.platform.exceptions.RoleNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.Role; import org.mifosng.platform.user.domain.RoleRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.stereotype.Service; @Service public class RoleReadPlatformServiceImpl implements RoleReadPlatformService { - private final SimpleJdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final RoleRepository roleRepository; @Autowired - public RoleReadPlatformServiceImpl(final PlatformSecurityContext context, final DataSource dataSource, final RoleRepository roleRepository) { + public RoleReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, final RoleRepository roleRepository) { this.context = context; this.roleRepository = roleRepository; - this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override diff --git a/mifosng-provider/src/main/resources/META-INF/persistence.xml b/mifosng-provider/src/main/resources/META-INF/persistence.xml index dd30223a8..5e4e61fde 100644 --- a/mifosng-provider/src/main/resources/META-INF/persistence.xml +++ b/mifosng-provider/src/main/resources/META-INF/persistence.xml @@ -1,5 +1,8 @@ - + + org.hibernate.ejb.HibernatePersistence @@ -7,7 +10,7 @@ - + diff --git a/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml b/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml index f4691ee5a..25264fdae 100644 --- a/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml +++ b/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml @@ -3,12 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jpa="http://www.springframework.org/schema/data/jpa" - xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:sec="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd - http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> @@ -17,8 +15,8 @@ - + diff --git a/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml b/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml index ec498b0a3..9ef91d7c2 100644 --- a/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml +++ b/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml @@ -7,7 +7,7 @@ http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> - + @@ -23,14 +23,5 @@ - - - + \ No newline at end of file diff --git a/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml b/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml index 77723dec2..6631dd988 100644 --- a/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml +++ b/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml @@ -7,15 +7,25 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -25,8 +35,6 @@ - - diff --git a/mifosng-provider/src/main/resources/logback.xml b/mifosng-provider/src/main/resources/logback.xml index 831455bfa..e3e0c3473 100644 --- a/mifosng-provider/src/main/resources/logback.xml +++ b/mifosng-provider/src/main/resources/logback.xml @@ -7,7 +7,7 @@ - ${catalina.base}/logs/mifosng-provider.log + ${catalina.home}/logs/mifos-platform.log true diff --git a/mifosng-provider/src/main/webapp/META-INF/context.xml b/mifosng-provider/src/main/webapp/META-INF/context.xml index edab89f1e..e1be3d9f5 100644 --- a/mifosng-provider/src/main/webapp/META-INF/context.xml +++ b/mifosng-provider/src/main/webapp/META-INF/context.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/mifosng-provider/src/main/webapp/WEB-INF/spring/webmvc-config.xml b/mifosng-provider/src/main/webapp/WEB-INF/spring/webmvc-config.xml deleted file mode 100644 index 243d0716b..000000000 --- a/mifosng-provider/src/main/webapp/WEB-INF/spring/webmvc-config.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mifosng-provider/src/main/webapp/WEB-INF/web.xml b/mifosng-provider/src/main/webapp/WEB-INF/web.xml index 5c5caa845..c8e661683 100644 --- a/mifosng-provider/src/main/webapp/WEB-INF/web.xml +++ b/mifosng-provider/src/main/webapp/WEB-INF/web.xml @@ -5,12 +5,12 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="mifosng-platform-provider" version="2.5"> - MifosNg - Platform + Mifos Platform A provider of microfinance services which applications can consume once authenticated and authorized. webAppRootKey - mifosngserver.root + mifosplatform.root @@ -28,26 +28,10 @@ /* - - org.springframework.web.context.ContextLoaderListener - - org.springframework.security.web.session.HttpSessionEventPublisher - - jersey-serlvet com.sun.jersey.spi.spring.container.servlet.SpringServlet @@ -77,30 +61,4 @@ jersey-serlvet /api/v1/* - - - dispatcher - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - /WEB-INF/spring/webmvc-config.xml - - 1 - - - - dispatcher - / - - - - - *.jsp - true - - - - - 20 - \ No newline at end of file diff --git a/mifosng-provider/src/test/resources/META-INF/context.xml b/mifosng-provider/src/test/resources/META-INF/context.xml index b288db500..d9556190e 100644 --- a/mifosng-provider/src/test/resources/META-INF/context.xml +++ b/mifosng-provider/src/test/resources/META-INF/context.xml @@ -1,9 +1,9 @@