/*
* Copyright 2015-2016 http://hsweb.me
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hsweb.web.datasource.dynamic;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.hsweb.web.core.datasource.DatabaseType;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosProperties;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author zhouhao
* @see com.atomikos.jdbc.AbstractDataSourceBean
* @since 2.1
*/
@ConfigurationProperties(prefix = "hsweb.dynamicDatasource")
public class DynamicDataSourceProperties
implements BeanClassLoaderAware, InitializingBean {
private String name = "core";
private DatabaseType type = null;
private String datasourceName = null;
private String username = "sa";
private String password = "";
private String url = "jdbc:h2:file:./data/h2db;DB_CLOSE_ON_EXIT=FALSE";
private String testQuery = null;
private int loginTimeout = 0;
private int maxLifetime = 0;
private int minPoolSize = 3;
private int maxPoolSize = 80;
private int borrowConnectionTimeout = 60;
private int reapTimeout = 0;
private int maxIdleTime = 60;
private int maintenanceInterval = 60;
private int defaultIsolationLevel = -1;
private int transactionTimeout = 300;
private Properties properties = null;
private ClassLoader classLoader = null;
private DatasourceTypeSupport datasourceTypeSupport = null;
private AtomikosProperties icatch = new AtomikosProperties();
public int getTransactionTimeout() {
return transactionTimeout;
}
public void setTransactionTimeout(int transactionTimeout) {
this.transactionTimeout = transactionTimeout;
}
public String getDatasourceName() {
return datasourceName;
}
public void setDatasourceName(String datasourceName) {
this.datasourceName = datasourceName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public DatabaseType getType() {
if (type == null) {
type = DatabaseType.fromJdbcUrl(getUrl());
}
return type;
}
public AtomikosProperties getIcatch() {
return icatch;
}
public void setIcatch(AtomikosProperties icatch) {
this.icatch = icatch;
}
public void setType(DatabaseType type) {
this.type = type;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTestQuery() {
return testQuery;
}
public void setTestQuery(String testQuery) {
this.testQuery = testQuery;
}
public int getLoginTimeout() {
return loginTimeout;
}
public void setLoginTimeout(int loginTimeout) {
this.loginTimeout = loginTimeout;
}
public int getMaxLifetime() {
return maxLifetime;
}
public void setMaxLifetime(int maxLifetime) {
this.maxLifetime = maxLifetime;
}
public int getMinPoolSize() {
return minPoolSize;
}
public void setMinPoolSize(int minPoolSize) {
this.minPoolSize = minPoolSize;
}
public int getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public int getBorrowConnectionTimeout() {
return borrowConnectionTimeout;
}
public void setBorrowConnectionTimeout(int borrowConnectionTimeout) {
this.borrowConnectionTimeout = borrowConnectionTimeout;
}
public int getReapTimeout() {
return reapTimeout;
}
public void setReapTimeout(int reapTimeout) {
this.reapTimeout = reapTimeout;
}
public int getMaxIdleTime() {
return maxIdleTime;
}
public void setMaxIdleTime(int maxIdleTime) {
this.maxIdleTime = maxIdleTime;
}
public int getMaintenanceInterval() {
return maintenanceInterval;
}
public void setMaintenanceInterval(int maintenanceInterval) {
this.maintenanceInterval = maintenanceInterval;
}
public int getDefaultIsolationLevel() {
return defaultIsolationLevel;
}
public void setDefaultIsolationLevel(int defaultIsolationLevel) {
this.defaultIsolationLevel = defaultIsolationLevel;
}
public Properties getProperties() {
if (properties == null) {
properties = new Properties();
}
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(url);
Assert.notNull(username);
if (datasourceName == null) {
datasourceName = lookupSupportDatasourceName();
}
if (type == null) {
type = DatabaseType.fromJdbcUrl(getUrl());
}
if (!StringUtils.hasText(testQuery)) testQuery = getType().getTestQuery();
getProperties().put(datasourceTypeSupport.usernameProperty, getUsername());
getProperties().put(datasourceTypeSupport.passwordProperty, getPassword());
getProperties().put(datasourceTypeSupport.urlProperty, getUrl());
initDefaultProperties();
}
public String lookupSupportDatasourceName() throws ClassNotFoundException {
for (DatasourceTypeSupport support : DatasourceTypeSupport.values()) {
try {
ClassUtils.forName(support.className, classLoader);
datasourceTypeSupport = support;
return support.className;
} catch (ClassNotFoundException e) {
}
}
return getType().getXaDataSourceClassName();
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public void putProperties(AtomikosDataSourceBean dataSourceBean) {
dataSourceBean.setXaProperties(this.getProperties());
dataSourceBean.setXaDataSourceClassName(this.getDatasourceName());
dataSourceBean.setUniqueResourceName(this.getName());
dataSourceBean.setMinPoolSize(this.getMinPoolSize());
dataSourceBean.setMaxPoolSize(this.getMaxPoolSize());
dataSourceBean.setTestQuery(this.getTestQuery());
dataSourceBean.setBorrowConnectionTimeout(this.getBorrowConnectionTimeout());
dataSourceBean.setMaintenanceInterval(this.getMaintenanceInterval());
dataSourceBean.setDefaultIsolationLevel(this.getDefaultIsolationLevel());
dataSourceBean.setMaxLifetime(this.getMaxLifetime());
dataSourceBean.setMaxIdleTime(this.getMaxIdleTime());
dataSourceBean.setReapTimeout(this.getReapTimeout());
try {
dataSourceBean.setLoginTimeout(this.getLoginTimeout());
} catch (SQLException e) {
}
}
public void initDefaultProperties() {
datasourceTypeSupport.putDefaultProperties(getProperties());
}
private enum DatasourceTypeSupport {
druid("com.alibaba.druid.pool.xa.DruidXADataSource", "username", "password", "url") {
@Override
public void putDefaultProperties(Properties properties) {
super.putDefaultProperties(properties);
properties.putIfAbsent("filters", "stat");
properties.putIfAbsent("maxActive", 200);
properties.putIfAbsent("initialSize", 3);
properties.putIfAbsent("minIdle", 3);
properties.putIfAbsent("maxWait", 5000);
properties.putIfAbsent("timeBetweenEvictionRunsMillis", 60000);
properties.putIfAbsent("minEvictableIdleTimeMillis", 1800000);
properties.putIfAbsent("testWhileIdle", true);
properties.putIfAbsent("testOnBorrow", false);
properties.putIfAbsent("testOnReturn", false);
properties.putIfAbsent("poolPreparedStatements", true);
properties.putIfAbsent("maxOpenPreparedStatements", 20);
}
};
DatasourceTypeSupport(String className, String usernameProperty, String passwordProperty, String urlProperty) {
this.className = className;
this.usernameProperty = usernameProperty;
this.passwordProperty = passwordProperty;
this.urlProperty = urlProperty;
}
final String className;
final String usernameProperty;
final String passwordProperty;
final String urlProperty;
public void putDefaultProperties(Properties properties) {
}
}
}