diff --git a/mifosng-db/multi-tenant-demo-backups/0001-mifos-platform-shared-tenants.sql b/mifosng-db/multi-tenant-demo-backups/0001-mifos-platform-shared-tenants.sql
index 5b7c74955..e4d2afdb0 100644
--- a/mifosng-db/multi-tenant-demo-backups/0001-mifos-platform-shared-tenants.sql
+++ b/mifosng-db/multi-tenant-demo-backups/0001-mifos-platform-shared-tenants.sql
@@ -36,6 +36,7 @@ CREATE TABLE `tenants` (
`schema_server_port` varchar(10) NOT NULL DEFAULT '3306',
`schema_username` varchar(100) NOT NULL DEFAULT 'root',
`schema_password` varchar(100) NOT NULL DEFAULT 'mysql',
+ `auto_update` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle
index 70849d76e..afbb8c6c1 100644
--- a/mifosng-provider/build.gradle
+++ b/mifosng-provider/build.gradle
@@ -191,6 +191,9 @@ task deployPentahoReports() {
war {
it.dependsOn deployPentahoReports
+ from ('../mifosng-db/migrations') {
+ into "WEB-INF/classes/sql"
+ }
}
license {
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/MifosPlatformTenant.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/MifosPlatformTenant.java
index 23e87d727..83ff28d20 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/MifosPlatformTenant.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/MifosPlatformTenant.java
@@ -15,10 +15,11 @@ public class MifosPlatformTenant {
private final String schemaUsername;
private final String schemaPassword;
private final String timezoneId;
-
+ private final boolean autoUpdateEnabled;
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.name = name;
this.schemaName = schemaName;
@@ -27,7 +28,14 @@ public class MifosPlatformTenant {
this.schemaUsername = schemaUsername;
this.schemaPassword = schemaPassword;
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() {
@@ -39,15 +47,7 @@ public class MifosPlatformTenant {
}
public String getSchemaName() {
- return schemaName;
- }
-
- public String getSchemaServer() {
- return schemaServer;
- }
-
- public String getSchemaServerPort() {
- return schemaServerPort;
+ return this.schemaName;
}
public String getSchemaUsername() {
@@ -57,9 +57,13 @@ public class MifosPlatformTenant {
public String getSchemaPassword() {
return schemaPassword;
}
-
+
public String getTimezoneId() {
return timezoneId;
}
-
+
+ public boolean isAutoUpdateEnabled() {
+ return this.autoUpdateEnabled;
+ }
+
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/Tenant.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/Tenant.java
new file mode 100755
index 000000000..79c8c3189
--- /dev/null
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/domain/Tenant.java
@@ -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;
+ }
+
+}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/ITenantUpgradeService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/ITenantUpgradeService.java
new file mode 100755
index 000000000..6b186e3bf
--- /dev/null
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/ITenantUpgradeService.java
@@ -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();
+
+}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantUpgradeService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantUpgradeService.java
new file mode 100755
index 000000000..4ee3ab336
--- /dev/null
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantUpgradeService.java
@@ -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 tenantIdentifier.
+ */
+@Service
+public class TenantUpgradeService implements ITenantUpgradeService {
+
+ private final TenantDetailsService tenantDetailsService;
+
+ @Autowired
+ public TenantUpgradeService(TenantDetailsService detailsService) {
+ this.tenantDetailsService = detailsService;
+ }
+
+ @Override
+ @PostConstruct
+ public void upgradeAllTenants() {
+ List 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();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java
index 9a79839a9..d7290548a 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service;
*/
@Service
public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService {
-
+
private final Map tenantToDataSourceMap = new ConcurrentHashMap(1);
private final DataSource tenantDataSource;
@@ -61,24 +61,23 @@ public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenant
// see
// http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency
- StringBuilder jdbcUrlBuilder = new StringBuilder("jdbc:mysql://").append(tenant.getSchemaServer()).append(':')
- .append(tenant.getSchemaServerPort()).append('/').append(tenant.getSchemaName());
+ String jdbcUrl = tenant.databaseURL();
PoolConfiguration poolConfiguration = new PoolProperties();
poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver");
poolConfiguration.setName(tenant.getSchemaName() + "_pool");
- poolConfiguration.setUrl(jdbcUrlBuilder.toString());
+ poolConfiguration.setUrl(jdbcUrl);
poolConfiguration.setUsername(tenant.getSchemaUsername());
poolConfiguration.setPassword(tenant.getSchemaPassword());
poolConfiguration.setInitialSize(5);
- //poolConfiguration.setMaxActive(5);
- //poolConfiguration.setMinIdle(1);
- //poolConfiguration.setMaxIdle(4);
+ // poolConfiguration.setMaxActive(5);
+ // poolConfiguration.setMinIdle(1);
+ // poolConfiguration.setMaxIdle(4);
- //poolConfiguration.setSuspectTimeout(60);
- //poolConfiguration.setTimeBetweenEvictionRunsMillis(30000);
- //poolConfiguration.setMinEvictableIdleTimeMillis(60000);
+ // poolConfiguration.setSuspectTimeout(60);
+ // poolConfiguration.setTimeBetweenEvictionRunsMillis(30000);
+ // poolConfiguration.setMinEvictableIdleTimeMillis(60000);
poolConfiguration.setTestOnBorrow(true);
poolConfiguration.setValidationQuery("SELECT 1");
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java
index 28a5f9b98..c286e7c2b 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java
@@ -7,6 +7,7 @@ package org.mifosplatform.infrastructure.security.service;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.List;
import javax.sql.DataSource;
@@ -33,23 +34,17 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
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 {
+ 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
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 schemaUsername = rs.getString("schemaUsername");
String schemaPassword = rs.getString("schemaPassword");
- String timezoneId =rs.getString("timezoneId");
-
- return new MifosPlatformTenant(id, name, schemaName, schemaServer, schemaServerPort, schemaUsername, schemaPassword ,timezoneId);
+ String timezoneId = rs.getString("timezoneId");
+ boolean autoUpdateEnabled = rs.getBoolean("autoUpdate");
+
+ 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 findAllTenants() {
+ TenantMapper rm = new TenantMapper();
+ String sql = "select " + rm.schema();
+
+ List mifosPlatformTenants = jdbcTemplate.query(sql, rm, new Object[] {});
+ return mifosPlatformTenants;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java
index 4a6f554bf..cb58b8870 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java
@@ -5,10 +5,14 @@
*/
package org.mifosplatform.infrastructure.security.service;
+import java.util.List;
+
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
public interface TenantDetailsService {
MifosPlatformTenant loadTenantById(String tenantId);
+ List findAllTenants();
+
}
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 1cc49c00f..f009fcb2c 100644
--- a/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml
+++ b/mifosng-provider/src/main/resources/META-INF/spring/infrastructure.xml
@@ -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/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
-
+