Merge pull request #1466 from rajuan/MIFOSX-2153

MIFOSX-2153:Added support to use seperate DB server instance for reports
This commit is contained in:
Vishwas Babu A J
2015-08-24 17:40:25 +05:30
14 changed files with 457 additions and 233 deletions
@@ -74,8 +74,8 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
CommandProcessingResult result = null; CommandProcessingResult result = null;
JsonCommand command = null; JsonCommand command = null;
Integer numberOfRetries = 0; Integer numberOfRetries = 0;
Integer maxNumberOfRetries = ThreadLocalContextUtil.getTenant().getMaxRetriesOnDeadlock(); Integer maxNumberOfRetries = ThreadLocalContextUtil.getTenant().getConnection().getMaxRetriesOnDeadlock();
Integer maxIntervalBetweenRetries = ThreadLocalContextUtil.getTenant().getMaxIntervalBetweenRetries(); Integer maxIntervalBetweenRetries = ThreadLocalContextUtil.getTenant().getConnection().getMaxIntervalBetweenRetries();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(), command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(),
wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getSavingsId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getSavingsId(),
@@ -60,23 +60,23 @@ public class TenantDataSourcePortFixService {
public void fixUpTenantsSchemaServerPort() { public void fixUpTenantsSchemaServerPort() {
if (!enabled) { if (!enabled) {
logger.info("No schema_server_port UPDATE made to tenants table of the mifosplatform-tenants schema, because " + ENABLED + " = false"); logger.info("No schema_server_port UPDATE made to tenant_server_connections table of the mifosplatform-tenants schema, because " + ENABLED + " = false");
return; return;
} }
if (dsp == null) { if (dsp == null) {
// we don't have any generic mechanism to know the DB port, given just a tenant DataSource // we don't have any generic mechanism to know the DB port, given just a tenant DataSource
logger.debug("No schema_server_port UPDATE made to tenants table of the mifosplatform-tenants schema (because neither MariaDB4j nor our own Spring Boot DataSourceConfiguration is used in a traditional WAR)"); logger.debug("No schema_server_port UPDATE made to tenant_server_connections table of the mifosplatform-tenants schema (because neither MariaDB4j nor our own Spring Boot DataSourceConfiguration is used in a traditional WAR)");
return; return;
} }
int r = jdbcTemplate int r = jdbcTemplate
.update("UPDATE tenants SET schema_server = ?, schema_server_port = ?, schema_username = ?, schema_password = ?", .update("UPDATE tenant_server_connections SET schema_server = ?, schema_server_port = ?, schema_username = ?, schema_password = ?",
dsp.getHost(), dsp.getPort(), dsp.getUsername(), dsp.getPassword()); dsp.getHost(), dsp.getPort(), dsp.getUsername(), dsp.getPassword());
if ( r == 0 ) if ( r == 0 )
logger.warn("UPDATE tenants SET ... did not update ANY rows - something is probably wrong"); logger.warn("UPDATE tenant_server_connections SET ... did not update ANY rows - something is probably wrong");
else else
logger.info("Upated " logger.info("Upated "
+ r + r
+ " rows in the tenants table of the mifosplatform-tenants schema to the real current host: " + " rows in the tenant_server_connections table of the mifosplatform-tenants schema to the real current host: "
+ dsp.getHost() + ", port: " + dsp.getPort()); + dsp.getHost() + ", port: " + dsp.getPort());
} }
@@ -10,115 +10,16 @@ public class MifosPlatformTenant {
private final Long id; private final Long id;
private final String tenantIdentifier; private final String tenantIdentifier;
private final String name; 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; private final String timezoneId;
private final boolean autoUpdateEnabled; private final MifosPlatformTenantConnection connection;
private final int initialSize;
private final boolean testOnBorrow;
private final long validationInterval;
private final boolean removeAbandoned;
private final int removeAbandonedTimeout;
private final boolean logAbandoned;
private final int abandonWhenPercentageFull;
private final int maxActive;
private final int minIdle;
private final int maxIdle;
private final int suspectTimeout;
private final int timeBetweenEvictionRunsMillis;
private final int minEvictableIdleTimeMillis;
private final int maxRetriesOnDeadlock;
private final int maxIntervalBetweenRetries;
public MifosPlatformTenant(final Long id, final String tenantIdentifier, final String name, final String schemaName, public MifosPlatformTenant(final Long id, final String tenantIdentifier, final String name,
final String schemaServer, final String schemaServerPort, final String schemaUsername, final String schemaPassword, final String timezoneId, final MifosPlatformTenantConnection connection) {
final String timezoneId, final boolean autoUpdateEnabled, final int initialSize, final boolean testOnBorrow,
final long validationInterval, final boolean removeAbandoned, final int removeAbandonedTimeout, final boolean logAbandoned,
final int abandonWhenPercentageFull, final int maxActive, final int minIdle, final int maxIdle, final int suspectTimeout,
final int timeBetweenEvictionRunsMillis, final int minEvictableIdleTimeMillis, final int maxRetriesOnDeadlock,
final int maxIntervalBetweenRetries) {
this.id = id; this.id = id;
this.tenantIdentifier = tenantIdentifier; this.tenantIdentifier = tenantIdentifier;
this.name = name; this.name = name;
this.schemaName = schemaName;
this.schemaServer = schemaServer;
this.schemaServerPort = schemaServerPort;
this.schemaUsername = schemaUsername;
this.schemaPassword = schemaPassword;
this.timezoneId = timezoneId; this.timezoneId = timezoneId;
this.autoUpdateEnabled = autoUpdateEnabled; this.connection = connection;
this.initialSize = initialSize;
this.testOnBorrow = testOnBorrow;
this.validationInterval = validationInterval;
this.removeAbandoned = removeAbandoned;
this.removeAbandonedTimeout = removeAbandonedTimeout;
this.logAbandoned = logAbandoned;
this.abandonWhenPercentageFull = abandonWhenPercentageFull;
this.maxActive = maxActive;
this.minIdle = minIdle;
this.maxIdle = maxIdle;
this.suspectTimeout = suspectTimeout;
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
this.maxIntervalBetweenRetries = maxIntervalBetweenRetries;
this.maxRetriesOnDeadlock = maxRetriesOnDeadlock;
}
public String databaseURL() {
final String url = new StringBuilder("jdbc:mysql://").append(this.schemaServer).append(':').append(this.schemaServerPort)
.append('/').append(this.schemaName).toString();
return url;
}
public int getMaxActive() {
return this.maxActive;
}
public int getMinIdle() {
return this.minIdle;
}
public int getMaxIdle() {
return this.maxIdle;
}
public int getTimeBetweenEvictionRunsMillis() {
return this.timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return this.minEvictableIdleTimeMillis;
}
public int getInitialSize() {
return initialSize;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public long getValidationInterval() {
return validationInterval;
}
public boolean isRemoveAbandoned() {
return removeAbandoned;
}
public int getRemoveAbandonedTimeout() {
return removeAbandonedTimeout;
}
public boolean isLogAbandoned() {
return logAbandoned;
}
public int getAbandonWhenPercentageFull() {
return abandonWhenPercentageFull;
} }
public Long getId() { public Long getId() {
@@ -133,36 +34,12 @@ public class MifosPlatformTenant {
return this.name; return this.name;
} }
public String getSchemaName() {
return this.schemaName;
}
public String getSchemaUsername() {
return this.schemaUsername;
}
public String getSchemaPassword() {
return this.schemaPassword;
}
public String getTimezoneId() { public String getTimezoneId() {
return this.timezoneId; return this.timezoneId;
} }
public boolean isAutoUpdateEnabled() { public MifosPlatformTenantConnection getConnection() {
return this.autoUpdateEnabled; return connection;
}
public int getSuspectTimeout() {
return this.suspectTimeout;
}
public int getMaxRetriesOnDeadlock() {
return maxRetriesOnDeadlock;
}
public int getMaxIntervalBetweenRetries() {
return maxIntervalBetweenRetries;
} }
} }
@@ -0,0 +1,242 @@
/**
* 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;
/**
* Holds DB server connection details.
*
*/
public class MifosPlatformTenantConnection {
private final Long connectionId;
private final String schemaServer;
private final String schemaServerPort;
private final String schemaUsername;
private final String schemaPassword;
private final String schemaName;
private final boolean autoUpdateEnabled;
private final int initialSize;
private final long validationInterval;
private final boolean removeAbandoned;
private final int removeAbandonedTimeout;
private final boolean logAbandoned;
private final int abandonWhenPercentageFull;
private final int maxActive;
private final int minIdle;
private final int maxIdle;
private final int suspectTimeout;
private final int timeBetweenEvictionRunsMillis;
private final int minEvictableIdleTimeMillis;
private final int maxRetriesOnDeadlock;
private final int maxIntervalBetweenRetries;
private final boolean testOnBorrow;
public MifosPlatformTenantConnection(final Long connectionId,final String schemaName, String schemaServer,final String schemaServerPort,final String schemaUsername,final String schemaPassword,
final boolean autoUpdateEnabled,final int initialSize,final long validationInterval,final boolean removeAbandoned,final int removeAbandonedTimeout,
final boolean logAbandoned,final int abandonWhenPercentageFull,final int maxActive,final int minIdle,final int maxIdle,final int suspectTimeout,
final int timeBetweenEvictionRunsMillis,final int minEvictableIdleTimeMillis,final int maxRetriesOnDeadlock,final int maxIntervalBetweenRetries,final boolean tesOnBorrow) {
this.connectionId = connectionId;
this.schemaName =schemaName;
this.schemaServer = schemaServer;
this.schemaServerPort = schemaServerPort;
this.schemaUsername = schemaUsername;
this.schemaPassword = schemaPassword;
this.autoUpdateEnabled = autoUpdateEnabled;
this.initialSize = initialSize;
this.validationInterval = validationInterval;
this.removeAbandoned = removeAbandoned;
this.removeAbandonedTimeout = removeAbandonedTimeout;
this.logAbandoned = logAbandoned;
this.abandonWhenPercentageFull = abandonWhenPercentageFull;
this.maxActive = maxActive;
this.minIdle = minIdle;
this.maxIdle = maxIdle;
this.suspectTimeout = suspectTimeout;
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
this.maxRetriesOnDeadlock = maxRetriesOnDeadlock;
this.maxIntervalBetweenRetries = maxIntervalBetweenRetries;
this.testOnBorrow=tesOnBorrow;
}
public String databaseURL() {
final String url = new StringBuilder("jdbc:mysql://").append(this.schemaServer).append(':').append(this.schemaServerPort)
.append('/').append(this.schemaName).toString();
return url;
}
/**
* @return the schemaServer
*/
public String getSchemaServer() {
return this.schemaServer;
}
/**
* @return the schemaServerPort
*/
public String getSchemaServerPort() {
return this.schemaServerPort;
}
/**
* @return the schemaUsername
*/
public String getSchemaUsername() {
return this.schemaUsername;
}
/**
* @return the schemaPassword
*/
public String getSchemaPassword() {
return this.schemaPassword;
}
/**
* @return the autoUpdateEnabled
*/
public boolean isAutoUpdateEnabled() {
return this.autoUpdateEnabled;
}
/**
* @return the initialSize
*/
public int getInitialSize() {
return this.initialSize;
}
/**
* @return the validationInterval
*/
public long getValidationInterval() {
return this.validationInterval;
}
/**
* @return the removeAbandoned
*/
public boolean isRemoveAbandoned() {
return this.removeAbandoned;
}
/**
* @return the removeAbandonedTimeout
*/
public int getRemoveAbandonedTimeout() {
return this.removeAbandonedTimeout;
}
/**
* @return the logAbandoned
*/
public boolean isLogAbandoned() {
return this.logAbandoned;
}
/**
* @return the abandonWhenPercentageFull
*/
public int getAbandonWhenPercentageFull() {
return this.abandonWhenPercentageFull;
}
/**
* @return the maxActive
*/
public int getMaxActive() {
return this.maxActive;
}
/**
* @return the minIdle
*/
public int getMinIdle() {
return this.minIdle;
}
/**
* @return the maxIdle
*/
public int getMaxIdle() {
return this.maxIdle;
}
/**
* @return the suspectTimeout
*/
public int getSuspectTimeout() {
return this.suspectTimeout;
}
/**
* @return the timeBetweenEvictionRunsMillis
*/
public int getTimeBetweenEvictionRunsMillis() {
return this.timeBetweenEvictionRunsMillis;
}
/**
* @return the minEvictableIdleTimeMillis
*/
public int getMinEvictableIdleTimeMillis() {
return this.minEvictableIdleTimeMillis;
}
/**
* @return the maxRetriesOnDeadlock
*/
public int getMaxRetriesOnDeadlock() {
return this.maxRetriesOnDeadlock;
}
/**
* @return the maxIntervalBetweenRetries
*/
public int getMaxIntervalBetweenRetries() {
return this.maxIntervalBetweenRetries;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public Long getConnectionId() {
return connectionId;
}
public String getSchemaName() {
return schemaName;
}
@Override
public String toString() {
return this.schemaName+":"+this.schemaServer+":"+this.schemaServerPort;
}
}
@@ -12,6 +12,7 @@ import javax.sql.DataSource;
import org.mifosplatform.infrastructure.core.boot.db.TenantDataSourcePortFixService; import org.mifosplatform.infrastructure.core.boot.db.TenantDataSourcePortFixService;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant; import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenantConnection;
import org.mifosplatform.infrastructure.security.service.TenantDetailsService; import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -32,11 +33,8 @@ public class TenantDatabaseUpgradeService {
protected final TenantDataSourcePortFixService tenantDataSourcePortFixService; protected final TenantDataSourcePortFixService tenantDataSourcePortFixService;
@Autowired @Autowired
public TenantDatabaseUpgradeService( public TenantDatabaseUpgradeService(final TenantDetailsService detailsService,
final TenantDetailsService detailsService, @Qualifier("tenantDataSourceJndi") final DataSource dataSource, TenantDataSourcePortFixService tenantDataSourcePortFixService) {
@Qualifier("tenantDataSourceJndi") final DataSource dataSource,
TenantDataSourcePortFixService tenantDataSourcePortFixService)
{
this.tenantDetailsService = detailsService; this.tenantDetailsService = detailsService;
this.tenantDataSource = dataSource; this.tenantDataSource = dataSource;
this.tenantDataSourcePortFixService = tenantDataSourcePortFixService; this.tenantDataSourcePortFixService = tenantDataSourcePortFixService;
@@ -44,36 +42,37 @@ public class TenantDatabaseUpgradeService {
@PostConstruct @PostConstruct
public void upgradeAllTenants() { public void upgradeAllTenants() {
upgradeTenantDB(); upgradeTenantDB();
final List<MifosPlatformTenant> tenants = this.tenantDetailsService.findAllTenants(); final List<MifosPlatformTenant> tenants = this.tenantDetailsService.findAllTenants();
for (final MifosPlatformTenant tenant : tenants) { for (final MifosPlatformTenant tenant : tenants) {
if (tenant.isAutoUpdateEnabled()) { final MifosPlatformTenantConnection connection = tenant.getConnection();
if (connection.isAutoUpdateEnabled()) {
final Flyway flyway = new Flyway(); final Flyway flyway = new Flyway();
flyway.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword()); flyway.setDataSource(connection.databaseURL(), connection.getSchemaUsername(), connection.getSchemaPassword());
flyway.setLocations("sql/migrations/core_db"); flyway.setLocations("sql/migrations/core_db");
flyway.setOutOfOrder(true); flyway.setOutOfOrder(true);
try { try {
flyway.migrate(); flyway.migrate();
} catch (FlywayException e) { } catch (FlywayException e) {
String betterMessage = e.getMessage() String betterMessage = e.getMessage() + "; for Tenant DB URL: " + connection.databaseURL() + ", username: "
+ "; for Tenant DB URL: " + tenant.databaseURL() + connection.getSchemaPassword();
+ ", username: " + tenant.getSchemaUsername(); throw new FlywayException(betterMessage, e.getCause());
throw new FlywayException(betterMessage, e.getCause());
} }
} }
} }
} }
/** /**
* Initializes, and if required upgrades (using Flyway) the Tenant DB itself. * Initializes, and if required upgrades (using Flyway) the Tenant DB
*/ * itself.
private void upgradeTenantDB() { */
final Flyway flyway = new Flyway(); private void upgradeTenantDB() {
flyway.setDataSource(tenantDataSource); final Flyway flyway = new Flyway();
flyway.setLocations("sql/migrations/list_db"); flyway.setDataSource(tenantDataSource);
flyway.setOutOfOrder(true); flyway.setLocations("sql/migrations/list_db");
flyway.migrate(); flyway.setOutOfOrder(true);
flyway.migrate();
tenantDataSourcePortFixService.fixUpTenantsSchemaServerPort(); tenantDataSourcePortFixService.fixUpTenantsSchemaServerPort();
} }
} }
@@ -20,7 +20,7 @@ public class ThreadLocalContextUtil {
private static final ThreadLocal<MifosPlatformTenant> tenantcontext = new ThreadLocal<>(); private static final ThreadLocal<MifosPlatformTenant> tenantcontext = new ThreadLocal<>();
private static final ThreadLocal<String> authTokenContext = new ThreadLocal<>(); private static final ThreadLocal<String> authTokenContext = new ThreadLocal<>();
public static void setTenant(final MifosPlatformTenant tenant) { public static void setTenant(final MifosPlatformTenant tenant) {
Assert.notNull(tenant, "tenant cannot be null"); Assert.notNull(tenant, "tenant cannot be null");
tenantcontext.set(tenant); tenantcontext.set(tenant);
@@ -13,6 +13,7 @@ import javax.sql.DataSource;
import org.apache.tomcat.jdbc.pool.PoolConfiguration; import org.apache.tomcat.jdbc.pool.PoolConfiguration;
import org.apache.tomcat.jdbc.pool.PoolProperties; import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant; import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenantConnection;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -42,17 +43,20 @@ public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceSe
// default to tenant database datasource // default to tenant database datasource
DataSource tenantDataSource = this.tenantDataSource; DataSource tenantDataSource = this.tenantDataSource;
final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
if (tenant != null) { if (tenant != null) {
final MifosPlatformTenantConnection tenantConnection = tenant.getConnection();
synchronized (this.tenantToDataSourceMap) { synchronized (this.tenantToDataSourceMap) {
// if tenant information available switch to appropriate // if tenantConnection information available switch to
// appropriate
// datasource // datasource
// for that tenant. // for that tenant.
if (this.tenantToDataSourceMap.containsKey(tenant.getId())) { if (this.tenantToDataSourceMap.containsKey(tenantConnection.getConnectionId())) {
tenantDataSource = this.tenantToDataSourceMap.get(tenant.getId()); tenantDataSource = this.tenantToDataSourceMap.get(tenantConnection.getConnectionId());
} else { } else {
tenantDataSource = createNewDataSourceFor(tenant); tenantDataSource = createNewDataSourceFor(tenantConnection);
this.tenantToDataSourceMap.put(tenant.getId(), tenantDataSource); this.tenantToDataSourceMap.put(tenantConnection.getConnectionId(), tenantDataSource);
} }
} }
} }
@@ -60,31 +64,31 @@ public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceSe
return tenantDataSource; return tenantDataSource;
} }
private DataSource createNewDataSourceFor(final MifosPlatformTenant tenant) { // creates the data source oltp and report databases
private DataSource createNewDataSourceFor(final MifosPlatformTenantConnection tenantConnectionObj) {
// 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
// see also org.mifosplatform.DataSourceProperties.setMifosDefaults() // see also org.mifosplatform.DataSourceProperties.setMifosDefaults()
final String jdbcUrl = tenant.databaseURL();
final String jdbcUrl = tenantConnectionObj.databaseURL();
final PoolConfiguration poolConfiguration = new PoolProperties(); final PoolConfiguration poolConfiguration = new PoolProperties();
poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver"); poolConfiguration.setDriverClassName("com.mysql.jdbc.Driver");
poolConfiguration.setName(tenant.getSchemaName() + "_pool"); poolConfiguration.setName(tenantConnectionObj.getSchemaName() + "_pool");
poolConfiguration.setUrl(jdbcUrl); poolConfiguration.setUrl(jdbcUrl);
poolConfiguration.setUsername(tenant.getSchemaUsername()); poolConfiguration.setUsername(tenantConnectionObj.getSchemaUsername());
poolConfiguration.setPassword(tenant.getSchemaPassword()); poolConfiguration.setPassword(tenantConnectionObj.getSchemaPassword());
poolConfiguration.setInitialSize(tenant.getInitialSize()); poolConfiguration.setInitialSize(tenantConnectionObj.getInitialSize());
poolConfiguration.setTestOnBorrow(tenant.isTestOnBorrow()); poolConfiguration.setTestOnBorrow(tenantConnectionObj.isTestOnBorrow());
poolConfiguration.setValidationQuery("SELECT 1"); poolConfiguration.setValidationQuery("SELECT 1");
poolConfiguration.setValidationInterval(tenant.getValidationInterval()); poolConfiguration.setValidationInterval(tenantConnectionObj.getValidationInterval());
poolConfiguration.setRemoveAbandoned(tenant.isRemoveAbandoned()); poolConfiguration.setRemoveAbandoned(tenantConnectionObj.isRemoveAbandoned());
poolConfiguration.setRemoveAbandonedTimeout(tenant.getRemoveAbandonedTimeout()); poolConfiguration.setRemoveAbandonedTimeout(tenantConnectionObj.getRemoveAbandonedTimeout());
poolConfiguration.setLogAbandoned(tenant.isLogAbandoned()); poolConfiguration.setLogAbandoned(tenantConnectionObj.isLogAbandoned());
poolConfiguration.setAbandonWhenPercentageFull(tenant.getAbandonWhenPercentageFull()); poolConfiguration.setAbandonWhenPercentageFull(tenantConnectionObj.getAbandonWhenPercentageFull());
/** /**
* Vishwas- Do we need to enable the below properties and add * Vishwas- Do we need to enable the below properties and add
@@ -30,6 +30,7 @@ import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant; import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenantConnection;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil; import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
@@ -248,9 +249,9 @@ public class ReadReportingServiceImpl implements ReadReportingService {
outputType = outputTypeParam; outputType = outputTypeParam;
} }
if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS") || outputType.equalsIgnoreCase("XLSX") || outputType if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS")
.equalsIgnoreCase("CSV"))) { throw new PlatformDataIntegrityException("error.msg.invalid.outputType", || outputType.equalsIgnoreCase("XLSX") || outputType.equalsIgnoreCase("CSV"))) { throw new PlatformDataIntegrityException(
"No matching Output Type: " + outputType); } "error.msg.invalid.outputType", "No matching Output Type: " + outputType); }
if (this.noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled", if (this.noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled",
"Pentaho is not enabled"); } "Pentaho is not enabled"); }
@@ -279,7 +280,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
PdfReportUtil.createPDF(masterReport, baos); PdfReportUtil.createPDF(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/pdf").build(); return Response.ok().entity(baos.toByteArray()).type("application/pdf").build();
} }
if ("XLS".equalsIgnoreCase(outputType)) { if ("XLS".equalsIgnoreCase(outputType)) {
ExcelReportUtil.createXLS(masterReport, baos); ExcelReportUtil.createXLS(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel") return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel")
@@ -367,16 +368,17 @@ public class ReadReportingServiceImpl implements ReadReportingService {
final String userhierarchy = currentUser.getOffice().getHierarchy(); final String userhierarchy = currentUser.getOffice().getHierarchy();
logger.info("db URL:" + tenantUrl + " userhierarchy:" + userhierarchy); logger.info("db URL:" + tenantUrl + " userhierarchy:" + userhierarchy);
rptParamValues.put("userhierarchy", userhierarchy); rptParamValues.put("userhierarchy", userhierarchy);
final Long userid = currentUser.getId(); final Long userid = currentUser.getId();
logger.info("db URL:" + tenantUrl + " userid:" + userid); logger.info("db URL:" + tenantUrl + " userid:" + userid);
rptParamValues.put("userid", userid); rptParamValues.put("userid", userid);
final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
final MifosPlatformTenantConnection tenantConnection = tenant.getConnection();
rptParamValues.put("tenantUrl", tenantUrl); rptParamValues.put("tenantUrl", tenantUrl);
rptParamValues.put("username", tenant.getSchemaUsername()); rptParamValues.put("username", tenantConnection.getSchemaUsername());
rptParamValues.put("password", tenant.getSchemaPassword()); rptParamValues.put("password", tenantConnection.getSchemaPassword());
} catch (final Exception e) { } catch (final Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage()); logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
@@ -53,7 +53,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
private static boolean firstRequestProcessed = false; private static boolean firstRequestProcessed = false;
private final static Logger logger = LoggerFactory.getLogger(TenantAwareBasicAuthenticationFilter.class); private final static Logger logger = LoggerFactory.getLogger(TenantAwareBasicAuthenticationFilter.class);
private final BasicAuthTenantDetailsService basicAuthTenantDetailsService; private final BasicAuthTenantDetailsService basicAuthTenantDetailsService;
private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer; private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
@@ -91,6 +91,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
} else { } else {
String tenantIdentifier = request.getHeader(this.tenantRequestHeader); String tenantIdentifier = request.getHeader(this.tenantRequestHeader);
if (org.apache.commons.lang.StringUtils.isBlank(tenantIdentifier)) { if (org.apache.commons.lang.StringUtils.isBlank(tenantIdentifier)) {
tenantIdentifier = request.getParameter("tenantIdentifier"); tenantIdentifier = request.getParameter("tenantIdentifier");
} }
@@ -99,8 +100,12 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
"No tenant identifier found: Add request header of '" + this.tenantRequestHeader "No tenant identifier found: Add request header of '" + this.tenantRequestHeader
+ "' or add the parameter 'tenantIdentifier' to query string of request URL."); } + "' or add the parameter 'tenantIdentifier' to query string of request URL."); }
// check tenants database for tenantId String pathInfo = request.getRequestURI();
final MifosPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier); boolean isReportRequest = false;
if (pathInfo != null && pathInfo.contains("report")) {
isReportRequest = true;
}
final MifosPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier, isReportRequest);
ThreadLocalContextUtil.setTenant(tenant); ThreadLocalContextUtil.setTenant(tenant);
String authToken = request.getHeader("Authorization"); String authToken = request.getHeader("Authorization");
@@ -110,9 +115,9 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
} }
if (!firstRequestProcessed) { if (!firstRequestProcessed) {
final String baseUrl = request.getRequestURL().toString().replace(request.getPathInfo(), "/"); final String baseUrl = request.getRequestURL().toString().replace(request.getPathInfo(), "/");
System.setProperty("baseUrl", baseUrl); System.setProperty("baseUrl", baseUrl);
final boolean ehcacheEnabled = this.configurationDomainService.isEhcacheEnabled(); final boolean ehcacheEnabled = this.configurationDomainService.isEhcacheEnabled();
if (ehcacheEnabled) { if (ehcacheEnabled) {
this.cacheWritePlatformService.switchToCache(CacheType.SINGLE_NODE); this.cacheWritePlatformService.switchToCache(CacheType.SINGLE_NODE);
@@ -122,7 +127,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
TenantAwareBasicAuthenticationFilter.firstRequestProcessed = true; TenantAwareBasicAuthenticationFilter.firstRequestProcessed = true;
} }
} }
super.doFilter(req, res, chain); super.doFilter(req, res, chain);
} catch (final InvalidTenantIdentiferException e) { } catch (final InvalidTenantIdentiferException e) {
// deal with exception at low level // deal with exception at low level
@@ -9,5 +9,5 @@ import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
public interface BasicAuthTenantDetailsService { public interface BasicAuthTenantDetailsService {
MifosPlatformTenant loadTenantById(String tenantId); MifosPlatformTenant loadTenantById(String tenantId, boolean isReport);
} }
@@ -11,6 +11,7 @@ import java.sql.SQLException;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant; import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenantConnection;
import org.mifosplatform.infrastructure.security.exception.InvalidTenantIdentiferException; import org.mifosplatform.infrastructure.security.exception.InvalidTenantIdentiferException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -36,34 +37,52 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails
private static final class TenantMapper implements RowMapper<MifosPlatformTenant> { private static final class TenantMapper implements RowMapper<MifosPlatformTenant> {
private final StringBuilder sqlBuilder = new StringBuilder( private final boolean isReport;
"id, name,identifier, schema_name as schemaName, schema_server as schemaServer, schema_server_port as schemaServerPort, auto_update as autoUpdate, ")// private final StringBuilder sqlBuilder = new StringBuilder(" t.id, ts.id as connectionId , ")//
.append(" schema_username as schemaUsername, schema_password as schemaPassword , timezone_id as timezoneId , pool_initial_size as initialSize, ") // .append(" t.timezone_id as timezoneId , t.name,t.identifier, ts.schema_name as schemaName, ts.schema_server as schemaServer,")//
.append(" pool_validation_interval as validationInterval, pool_remove_abandoned as removeAbandoned, pool_remove_abandoned_timeout as removeAbandonedTimeout, ")// .append(" ts.schema_server_port as schemaServerPort, ts.auto_update as autoUpdate,")//
.append(" pool_log_abandoned as logAbandoned, pool_abandon_when_percentage_full as abandonedWhenPercentageFull, pool_test_on_borrow as testOnBorrow, ")// .append(" ts.schema_username as schemaUsername, ts.schema_password as schemaPassword , ts.pool_initial_size as initialSize,")//
.append(" pool_max_active as poolMaxActive, pool_min_idle as poolMinIdle, pool_max_idle as poolMaxIdle, ")// .append(" ts.pool_validation_interval as validationInterval, ts.pool_remove_abandoned as removeAbandoned, ts.pool_remove_abandoned_timeout as removeAbandonedTimeout,")//
.append(" pool_suspect_timeout as poolSuspectTimeout, pool_time_between_eviction_runs_millis as poolTimeBetweenEvictionRunsMillis, ")// .append(" ts.pool_log_abandoned as logAbandoned, ts.pool_abandon_when_percentage_full as abandonedWhenPercentageFull, ts.pool_test_on_borrow as testOnBorrow,")//
.append(" pool_min_evictable_idle_time_millis as poolMinEvictableIdleTimeMillis, ")// .append(" ts.pool_max_active as poolMaxActive, ts.pool_min_idle as poolMinIdle, ts.pool_max_idle as poolMaxIdle,")//
.append(" deadlock_max_retries as maxRetriesOnDeadlock, ")// .append(" ts.pool_suspect_timeout as poolSuspectTimeout, ts.pool_time_between_eviction_runs_millis as poolTimeBetweenEvictionRunsMillis,")//
.append(" deadlock_max_retry_interval as maxIntervalBetweenRetries ")// .append(" ts.pool_min_evictable_idle_time_millis as poolMinEvictableIdleTimeMillis,")//
.append(" from tenants t");// .append(" ts.deadlock_max_retries as maxRetriesOnDeadlock,")//
.append(" ts.deadlock_max_retry_interval as maxIntervalBetweenRetries ")//
.append(" from tenants t left join tenant_server_connections ts ");
public TenantMapper(boolean isReport) {
this.isReport = isReport;
}
public String schema() { public String schema() {
if(this.isReport){
this.sqlBuilder.append(" on t.report_Id = ts.id");
}else{
this.sqlBuilder.append(" on t.oltp_Id = ts.id");
}
return this.sqlBuilder.toString(); return this.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 {
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String tenantIdentifier = rs.getString("identifier"); final String tenantIdentifier = rs.getString("identifier");
final String name = rs.getString("name"); final String name = rs.getString("name");
final String timezoneId = rs.getString("timezoneId");
final MifosPlatformTenantConnection connection = getDBConnection(rs);
return new MifosPlatformTenant(id, tenantIdentifier, name, timezoneId, connection);
}
// gets the DB connection
private MifosPlatformTenantConnection getDBConnection(ResultSet rs) throws SQLException {
final Long connectionId = rs.getLong("connectionId");
final String schemaName = rs.getString("schemaName"); final String schemaName = rs.getString("schemaName");
final String schemaServer = rs.getString("schemaServer"); final String schemaServer = rs.getString("schemaServer");
final String schemaServerPort = rs.getString("schemaServerPort"); final String schemaServerPort = rs.getString("schemaServerPort");
final String schemaUsername = rs.getString("schemaUsername"); final String schemaUsername = rs.getString("schemaUsername");
final String schemaPassword = rs.getString("schemaPassword"); final String schemaPassword = rs.getString("schemaPassword");
final String timezoneId = rs.getString("timezoneId");
final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate"); final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate");
final int initialSize = rs.getInt("initialSize"); final int initialSize = rs.getInt("initialSize");
final boolean testOnBorrow = rs.getBoolean("testOnBorrow"); final boolean testOnBorrow = rs.getBoolean("testOnBorrow");
@@ -84,10 +103,10 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails
maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15); maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15);
maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15); maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15);
return new MifosPlatformTenant(id, tenantIdentifier, name, schemaName, schemaServer, schemaServerPort, schemaUsername, return new MifosPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, schemaUsername,
schemaPassword, timezoneId, autoUpdateEnabled, initialSize, testOnBorrow, validationInterval, removeAbandoned, schemaPassword, autoUpdateEnabled, initialSize, validationInterval, removeAbandoned, removeAbandonedTimeout,
removeAbandonedTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, timeBetweenEvictionRunsMillis,
timeBetweenEvictionRunsMillis, minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries); minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries, testOnBorrow);
} }
private int bindValueInMinMaxRange(final int value, int min, int max) { private int bindValueInMinMaxRange(final int value, int min, int max) {
@@ -100,10 +119,10 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails
@Override @Override
@Cacheable(value = "tenantsById") @Cacheable(value = "tenantsById")
public MifosPlatformTenant loadTenantById(final String tenantIdentifier) { public MifosPlatformTenant loadTenantById(final String tenantIdentifier, final boolean isReport) {
try { try {
final TenantMapper rm = new TenantMapper(); final TenantMapper rm = new TenantMapper(isReport);
final String sql = "select " + rm.schema() + " where t.identifier like ?"; final String sql = "select " + rm.schema() + " where t.identifier like ?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { tenantIdentifier }); return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { tenantIdentifier });
@@ -12,6 +12,7 @@ import java.util.List;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant; import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenantConnection;
import org.mifosplatform.infrastructure.security.exception.InvalidTenantIdentiferException; import org.mifosplatform.infrastructure.security.exception.InvalidTenantIdentiferException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -37,17 +38,18 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
private static final class TenantMapper implements RowMapper<MifosPlatformTenant> { private static final class TenantMapper implements RowMapper<MifosPlatformTenant> {
private final StringBuilder sqlBuilder = new StringBuilder( private final StringBuilder sqlBuilder = new StringBuilder("t.id, ts.id as connectionId , ")//
"id, name,identifier, schema_name as schemaName, schema_server as schemaServer, schema_server_port as schemaServerPort, auto_update as autoUpdate, ")// .append(" t.timezone_id as timezoneId , t.name,t.identifier, ts.schema_name as schemaName, ts.schema_server as schemaServer,")//
.append(" schema_username as schemaUsername, schema_password as schemaPassword , timezone_id as timezoneId , pool_initial_size as initialSize, ") // .append(" ts.schema_server_port as schemaServerPort, ts.auto_update as autoUpdate,")//
.append(" pool_validation_interval as validationInterval, pool_remove_abandoned as removeAbandoned, pool_remove_abandoned_timeout as removeAbandonedTimeout, ")// .append(" ts.schema_username as schemaUsername, ts.schema_password as schemaPassword , ts.pool_initial_size as initialSize,")//
.append(" pool_log_abandoned as logAbandoned, pool_abandon_when_percentage_full as abandonedWhenPercentageFull, pool_test_on_borrow as testOnBorrow, ")// .append(" ts.pool_validation_interval as validationInterval, ts.pool_remove_abandoned as removeAbandoned, ts.pool_remove_abandoned_timeout as removeAbandonedTimeout,")//
.append(" pool_max_active as poolMaxActive, pool_min_idle as poolMinIdle, pool_max_idle as poolMaxIdle, ")// .append(" ts.pool_log_abandoned as logAbandoned, ts.pool_abandon_when_percentage_full as abandonedWhenPercentageFull, ts.pool_test_on_borrow as testOnBorrow,")//
.append(" pool_suspect_timeout as poolSuspectTimeout, pool_time_between_eviction_runs_millis as poolTimeBetweenEvictionRunsMillis, ")// .append(" ts.pool_max_active as poolMaxActive, ts.pool_min_idle as poolMinIdle, ts.pool_max_idle as poolMaxIdle,")//
.append(" pool_min_evictable_idle_time_millis as poolMinEvictableIdleTimeMillis, ")// .append(" ts.pool_suspect_timeout as poolSuspectTimeout, ts.pool_time_between_eviction_runs_millis as poolTimeBetweenEvictionRunsMillis,")//
.append(" deadlock_max_retries as maxRetriesOnDeadlock, ")// .append(" ts.pool_min_evictable_idle_time_millis as poolMinEvictableIdleTimeMillis,")//
.append(" deadlock_max_retry_interval as maxIntervalBetweenRetries ")// .append(" ts.deadlock_max_retries as maxRetriesOnDeadlock,")//
.append(" from tenants t");// .append(" ts.deadlock_max_retry_interval as maxIntervalBetweenRetries ")//
.append(" from tenants t left join tenant_server_connections ts on t.oltp_Id=ts.id ");
public String schema() { public String schema() {
return this.sqlBuilder.toString(); return this.sqlBuilder.toString();
@@ -55,16 +57,24 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
@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 {
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String tenantIdentifier = rs.getString("identifier"); final String tenantIdentifier = rs.getString("identifier");
final String name = rs.getString("name"); final String name = rs.getString("name");
final String timezoneId = rs.getString("timezoneId");
final MifosPlatformTenantConnection connection = getDBConnection(rs);
return new MifosPlatformTenant(id, tenantIdentifier, name, timezoneId, connection);
}
// gets the DB connection
private MifosPlatformTenantConnection getDBConnection(ResultSet rs) throws SQLException {
final Long connectionId = rs.getLong("connectionId");
final String schemaName = rs.getString("schemaName"); final String schemaName = rs.getString("schemaName");
final String schemaServer = rs.getString("schemaServer"); final String schemaServer = rs.getString("schemaServer");
final String schemaServerPort = rs.getString("schemaServerPort"); final String schemaServerPort = rs.getString("schemaServerPort");
final String schemaUsername = rs.getString("schemaUsername"); final String schemaUsername = rs.getString("schemaUsername");
final String schemaPassword = rs.getString("schemaPassword"); final String schemaPassword = rs.getString("schemaPassword");
final String timezoneId = rs.getString("timezoneId");
final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate"); final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate");
final int initialSize = rs.getInt("initialSize"); final int initialSize = rs.getInt("initialSize");
final boolean testOnBorrow = rs.getBoolean("testOnBorrow"); final boolean testOnBorrow = rs.getBoolean("testOnBorrow");
@@ -85,10 +95,11 @@ public class JdbcTenantDetailsService implements TenantDetailsService {
maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15); maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15);
maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15); maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15);
return new MifosPlatformTenant(id, tenantIdentifier, name, schemaName, schemaServer, schemaServerPort, schemaUsername, return new MifosPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, schemaUsername,
schemaPassword, timezoneId, autoUpdateEnabled, initialSize, testOnBorrow, validationInterval, removeAbandoned, schemaPassword, autoUpdateEnabled, initialSize, validationInterval, removeAbandoned, removeAbandonedTimeout,
removeAbandonedTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, timeBetweenEvictionRunsMillis,
timeBetweenEvictionRunsMillis, minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries); minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries, testOnBorrow);
} }
private int bindValueInMinMaxRange(final int value, int min, int max) { private int bindValueInMinMaxRange(final int value, int min, int max) {
@@ -34,12 +34,12 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.Page; import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.accountdetails.data.AccountSummaryCollectionData; import org.mifosplatform.portfolio.accountdetails.data.AccountSummaryCollectionData;
import org.mifosplatform.portfolio.accountdetails.service.AccountDetailsReadPlatformService; import org.mifosplatform.portfolio.accountdetails.service.AccountDetailsReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.portfolio.savings.data.SavingsAccountData; import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService; import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -0,0 +1,65 @@
START TRANSACTION;
RENAME TABLE tenants to temp_tenants;
create table tenant_server_connections(`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`schema_server` VARCHAR(100) NOT NULL DEFAULT 'localhost',
`schema_name` VARCHAR(100) NOT NULL,
`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',
`pool_initial_size` INT(5) NULL DEFAULT '5',
`pool_validation_interval` INT(11) NULL DEFAULT '30000',
`pool_remove_abandoned` TINYINT(1) NULL DEFAULT '1',
`pool_remove_abandoned_timeout` INT(5) NULL DEFAULT '60',
`pool_log_abandoned` TINYINT(1) NULL DEFAULT '1',
`pool_abandon_when_percentage_full` INT(5) NULL DEFAULT '50',
`pool_test_on_borrow` TINYINT(1) NULL DEFAULT '1',
`pool_max_active` INT(5) NULL DEFAULT '40',
`pool_min_idle` INT(5) NULL DEFAULT '20',
`pool_max_idle` INT(5) NULL DEFAULT '10',
`pool_suspect_timeout` INT(5) NULL DEFAULT '60',
`pool_time_between_eviction_runs_millis` INT(11) NULL DEFAULT '34000',
`pool_min_evictable_idle_time_millis` INT(11) NULL DEFAULT '60000',
`deadlock_max_retries` INT(5) NULL DEFAULT '0',
`deadlock_max_retry_interval` INT(5) NULL DEFAULT '1',
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2;
INSERT INTO `tenant_server_connections` (`id`,`schema_name`,`schema_server`, `schema_server_port`, `schema_username`, `schema_password`, `auto_update`, `pool_initial_size`, `pool_validation_interval`, `pool_remove_abandoned`, `pool_remove_abandoned_timeout`, `pool_log_abandoned`, `pool_abandon_when_percentage_full`, `pool_test_on_borrow`, `pool_max_active`, `pool_min_idle`, `pool_max_idle`, `pool_suspect_timeout`, `pool_time_between_eviction_runs_millis`, `pool_min_evictable_idle_time_millis`, `deadlock_max_retries`, `deadlock_max_retry_interval`)
SELECT `id`,`schema_name`,`schema_server`, `schema_server_port`, `schema_username`, `schema_password`, `auto_update`, `pool_initial_size`, `pool_validation_interval`, `pool_remove_abandoned`, `pool_remove_abandoned_timeout`, `pool_log_abandoned`, `pool_abandon_when_percentage_full`, `pool_test_on_borrow`, `pool_max_active`, `pool_min_idle`, `pool_max_idle`, `pool_suspect_timeout`, `pool_time_between_eviction_runs_millis`, `pool_min_evictable_idle_time_millis`, `deadlock_max_retries`, `deadlock_max_retry_interval` from temp_tenants;
CREATE TABLE tenants(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`identifier` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`timezone_id` VARCHAR(100) NOT NULL,
`country_id` INT(11) NULL DEFAULT NULL,
`joined_date` DATE NULL DEFAULT NULL,
`created_date` DATETIME NULL DEFAULT NULL,
`lastmodified_date` DATETIME NULL DEFAULT NULL,
`oltp_id` BIGINT(20) NOT NULL,
`report_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_oltp_id` (`oltp_id`),
INDEX `fk_report_id` (`report_id`),
CONSTRAINT `fk_oltp_id` FOREIGN KEY (`oltp_id`) REFERENCES `tenant_server_connections` (`id`),
CONSTRAINT `fk_report_id` FOREIGN KEY (`report_id`) REFERENCES `tenant_server_connections` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=6;
INSERT INTO tenants(`id`,`identifier`,`name`,`timezone_id`,`country_id`,`joined_date`,`created_date`,`lastmodified_date`,`oltp_id`, `report_id`)
SELECT `id`,`identifier`,`name`,`timezone_id`,`country_id`,`joined_date`,`created_date`,`lastmodified_date`,`id`, `id` from temp_tenants ;
DROP TABLE temp_tenants;
COMMIT;