minor additions to Flyway support...ability to optionally upgrade databases on application startup
This commit is contained in:
@@ -36,6 +36,7 @@ CREATE TABLE `tenants` (
|
|||||||
`schema_server_port` varchar(10) NOT NULL DEFAULT '3306',
|
`schema_server_port` varchar(10) NOT NULL DEFAULT '3306',
|
||||||
`schema_username` varchar(100) NOT NULL DEFAULT 'root',
|
`schema_username` varchar(100) NOT NULL DEFAULT 'root',
|
||||||
`schema_password` varchar(100) NOT NULL DEFAULT 'mysql',
|
`schema_password` varchar(100) NOT NULL DEFAULT 'mysql',
|
||||||
|
`auto_update` tinyint(1) NOT NULL DEFAULT '1',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|||||||
@@ -191,6 +191,9 @@ task deployPentahoReports() {
|
|||||||
|
|
||||||
war {
|
war {
|
||||||
it.dependsOn deployPentahoReports
|
it.dependsOn deployPentahoReports
|
||||||
|
from ('../mifosng-db/migrations') {
|
||||||
|
into "WEB-INF/classes/sql"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
license {
|
license {
|
||||||
|
|||||||
+18
-14
@@ -15,10 +15,11 @@ public class MifosPlatformTenant {
|
|||||||
private final String schemaUsername;
|
private final String schemaUsername;
|
||||||
private final String schemaPassword;
|
private final String schemaPassword;
|
||||||
private final String timezoneId;
|
private final String timezoneId;
|
||||||
|
private final boolean autoUpdateEnabled;
|
||||||
|
|
||||||
public MifosPlatformTenant(final Long id, final String name, final String schemaName, final String schemaServer,
|
public MifosPlatformTenant(final Long id, final String name, final String schemaName, final String schemaServer,
|
||||||
final String schemaServerPort, final String schemaUsername, final String schemaPassword, String timezoneId) {
|
final String schemaServerPort, final String schemaUsername, final String schemaPassword, String timezoneId,
|
||||||
|
final boolean autoUpdateEnabled) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.schemaName = schemaName;
|
this.schemaName = schemaName;
|
||||||
@@ -27,7 +28,14 @@ public class MifosPlatformTenant {
|
|||||||
this.schemaUsername = schemaUsername;
|
this.schemaUsername = schemaUsername;
|
||||||
this.schemaPassword = schemaPassword;
|
this.schemaPassword = schemaPassword;
|
||||||
this.timezoneId = timezoneId;
|
this.timezoneId = timezoneId;
|
||||||
|
this.autoUpdateEnabled = autoUpdateEnabled;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String databaseURL() {
|
||||||
|
String url = new StringBuilder("jdbc:mysql://").append(schemaServer).append(':').append(schemaServerPort).append('/')
|
||||||
|
.append(schemaName).toString();
|
||||||
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -39,15 +47,7 @@ public class MifosPlatformTenant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getSchemaName() {
|
public String getSchemaName() {
|
||||||
return schemaName;
|
return this.schemaName;
|
||||||
}
|
|
||||||
|
|
||||||
public String getSchemaServer() {
|
|
||||||
return schemaServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSchemaServerPort() {
|
|
||||||
return schemaServerPort;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSchemaUsername() {
|
public String getSchemaUsername() {
|
||||||
@@ -57,9 +57,13 @@ public class MifosPlatformTenant {
|
|||||||
public String getSchemaPassword() {
|
public String getSchemaPassword() {
|
||||||
return schemaPassword;
|
return schemaPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTimezoneId() {
|
public String getTimezoneId() {
|
||||||
return timezoneId;
|
return timezoneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAutoUpdateEnabled() {
|
||||||
|
return this.autoUpdateEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.infrastructure.core.domain;
|
||||||
|
|
||||||
|
public class Tenant {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final String name;
|
||||||
|
private final String schemaName;
|
||||||
|
private final String schemaServer;
|
||||||
|
private final String schemaServerPort;
|
||||||
|
private final String schemaUsername;
|
||||||
|
private final String schemaPassword;
|
||||||
|
private final String timezoneId;
|
||||||
|
|
||||||
|
|
||||||
|
public Tenant(final Long id, final String name, final String schemaName, final String schemaServer,
|
||||||
|
final String schemaServerPort, final String schemaUsername, final String schemaPassword, String timezoneId) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.schemaName = schemaName;
|
||||||
|
this.schemaServer = schemaServer;
|
||||||
|
this.schemaServerPort = schemaServerPort;
|
||||||
|
this.schemaUsername = schemaUsername;
|
||||||
|
this.schemaPassword = schemaPassword;
|
||||||
|
this.timezoneId = timezoneId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaName() {
|
||||||
|
return schemaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaServer() {
|
||||||
|
return schemaServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaServerPort() {
|
||||||
|
return schemaServerPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaUsername() {
|
||||||
|
return schemaUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaPassword() {
|
||||||
|
return schemaPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimezoneId() {
|
||||||
|
return timezoneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.infrastructure.core.service;
|
||||||
|
|
||||||
|
|
||||||
|
public interface ITenantUpgradeService {
|
||||||
|
|
||||||
|
void upgradeAllTenants();
|
||||||
|
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.infrastructure.core.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
||||||
|
import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.googlecode.flyway.core.Flyway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JDBC implementation of {@link TenantDetailsService} for loading a tenants
|
||||||
|
* details by a <code>tenantIdentifier</code>.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TenantUpgradeService implements ITenantUpgradeService {
|
||||||
|
|
||||||
|
private final TenantDetailsService tenantDetailsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public TenantUpgradeService(TenantDetailsService detailsService) {
|
||||||
|
this.tenantDetailsService = detailsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PostConstruct
|
||||||
|
public void upgradeAllTenants() {
|
||||||
|
List<MifosPlatformTenant> tenants = tenantDetailsService.findAllTenants();
|
||||||
|
for (MifosPlatformTenant tenant : tenants) {
|
||||||
|
if (tenant.isAutoUpdateEnabled()) {
|
||||||
|
Flyway flyway = new Flyway();
|
||||||
|
flyway.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword());
|
||||||
|
flyway.setLocations("sql");
|
||||||
|
flyway.migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-10
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService {
|
public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService {
|
||||||
|
|
||||||
private final Map<Long, DataSource> tenantToDataSourceMap = new ConcurrentHashMap<Long, DataSource>(1);
|
private final Map<Long, DataSource> tenantToDataSourceMap = new ConcurrentHashMap<Long, DataSource>(1);
|
||||||
private final DataSource tenantDataSource;
|
private final DataSource tenantDataSource;
|
||||||
|
|
||||||
@@ -61,24 +61,23 @@ public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenant
|
|||||||
// see
|
// see
|
||||||
// http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency
|
// http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency
|
||||||
|
|
||||||
StringBuilder jdbcUrlBuilder = new StringBuilder("jdbc:mysql://").append(tenant.getSchemaServer()).append(':')
|
String jdbcUrl = tenant.databaseURL();
|
||||||
.append(tenant.getSchemaServerPort()).append('/').append(tenant.getSchemaName());
|
|
||||||
|
|
||||||
PoolConfiguration poolConfiguration = new PoolProperties();
|
PoolConfiguration poolConfiguration = new PoolProperties();
|
||||||
poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver");
|
poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver");
|
||||||
poolConfiguration.setName(tenant.getSchemaName() + "_pool");
|
poolConfiguration.setName(tenant.getSchemaName() + "_pool");
|
||||||
poolConfiguration.setUrl(jdbcUrlBuilder.toString());
|
poolConfiguration.setUrl(jdbcUrl);
|
||||||
poolConfiguration.setUsername(tenant.getSchemaUsername());
|
poolConfiguration.setUsername(tenant.getSchemaUsername());
|
||||||
poolConfiguration.setPassword(tenant.getSchemaPassword());
|
poolConfiguration.setPassword(tenant.getSchemaPassword());
|
||||||
|
|
||||||
poolConfiguration.setInitialSize(5);
|
poolConfiguration.setInitialSize(5);
|
||||||
//poolConfiguration.setMaxActive(5);
|
// poolConfiguration.setMaxActive(5);
|
||||||
//poolConfiguration.setMinIdle(1);
|
// poolConfiguration.setMinIdle(1);
|
||||||
//poolConfiguration.setMaxIdle(4);
|
// poolConfiguration.setMaxIdle(4);
|
||||||
|
|
||||||
//poolConfiguration.setSuspectTimeout(60);
|
// poolConfiguration.setSuspectTimeout(60);
|
||||||
//poolConfiguration.setTimeBetweenEvictionRunsMillis(30000);
|
// poolConfiguration.setTimeBetweenEvictionRunsMillis(30000);
|
||||||
//poolConfiguration.setMinEvictableIdleTimeMillis(60000);
|
// poolConfiguration.setMinEvictableIdleTimeMillis(60000);
|
||||||
|
|
||||||
poolConfiguration.setTestOnBorrow(true);
|
poolConfiguration.setTestOnBorrow(true);
|
||||||
poolConfiguration.setValidationQuery("SELECT 1");
|
poolConfiguration.setValidationQuery("SELECT 1");
|
||||||
|
|||||||
+37
-18
@@ -7,6 +7,7 @@ package org.mifosplatform.infrastructure.security.service;
|
|||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@@ -33,23 +34,17 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
|
|||||||
this.jdbcTemplate = new JdbcTemplate(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, schema_server as schemaServer, schema_server_port as schemaServerPort, "
|
|
||||||
+ " schema_username as schemaUsername, schema_password as schemaPassword , timezone_id as timezoneId "
|
|
||||||
+ " 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<MifosPlatformTenant> {
|
private static final class TenantMapper implements RowMapper<MifosPlatformTenant> {
|
||||||
|
|
||||||
|
private StringBuilder sqlBuilder = new StringBuilder(
|
||||||
|
"id, name, schema_name as schemaName, schema_server as schemaServer, schema_server_port as schemaServerPort, auto_update as autoUpdate, ")//
|
||||||
|
.append(" schema_username as schemaUsername, schema_password as schemaPassword , timezone_id as timezoneId ")//
|
||||||
|
.append(" from tenants t");//
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MifosPlatformTenant mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
public MifosPlatformTenant mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
@@ -60,9 +55,33 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
|
|||||||
String schemaServerPort = rs.getString("schemaServerPort");
|
String schemaServerPort = rs.getString("schemaServerPort");
|
||||||
String schemaUsername = rs.getString("schemaUsername");
|
String schemaUsername = rs.getString("schemaUsername");
|
||||||
String schemaPassword = rs.getString("schemaPassword");
|
String schemaPassword = rs.getString("schemaPassword");
|
||||||
String timezoneId =rs.getString("timezoneId");
|
String timezoneId = rs.getString("timezoneId");
|
||||||
|
boolean autoUpdateEnabled = rs.getBoolean("autoUpdate");
|
||||||
return new MifosPlatformTenant(id, name, schemaName, schemaServer, schemaServerPort, schemaUsername, schemaPassword ,timezoneId);
|
|
||||||
|
return new MifosPlatformTenant(id, name, schemaName, schemaServer, schemaServerPort, schemaUsername, schemaPassword,
|
||||||
|
timezoneId, autoUpdateEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MifosPlatformTenant loadTenantById(final String tenantIdentifier) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
TenantMapper rm = new TenantMapper();
|
||||||
|
String sql = "select " + rm.schema() + " 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MifosPlatformTenant> findAllTenants() {
|
||||||
|
TenantMapper rm = new TenantMapper();
|
||||||
|
String sql = "select " + rm.schema();
|
||||||
|
|
||||||
|
List<MifosPlatformTenant> mifosPlatformTenants = jdbcTemplate.query(sql, rm, new Object[] {});
|
||||||
|
return mifosPlatformTenants;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+4
@@ -5,10 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.security.service;
|
package org.mifosplatform.infrastructure.security.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
||||||
|
|
||||||
public interface TenantDetailsService {
|
public interface TenantDetailsService {
|
||||||
|
|
||||||
MifosPlatformTenant loadTenantById(String tenantId);
|
MifosPlatformTenant loadTenantById(String tenantId);
|
||||||
|
|
||||||
|
List<MifosPlatformTenant> findAllTenants();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
|
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
|
||||||
|
|
||||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="tenantUpgradeService">
|
||||||
<property name="dataSource" ref="tenantAwareDataSource" />
|
<property name="dataSource" ref="tenantAwareDataSource" />
|
||||||
<property name="persistenceUnitName" value="jpa-pu" />
|
<property name="persistenceUnitName" value="jpa-pu" />
|
||||||
<property name="jpaVendorAdapter">
|
<property name="jpaVendorAdapter">
|
||||||
|
|||||||
Reference in New Issue
Block a user