package rfx.server.configs;
import java.io.IOException;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import rfx.server.util.FileUtils;
import rfx.server.util.StringPool;
import rfx.server.util.StringUtil;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
public class SqlDbConfigs implements Serializable {
private static final long serialVersionUID = 6185084071488833500L;
public static final int MAX_CONNECTIONS = 100;
public static final int MIN_CONNECTIONS = 2;
public static final long MAX_WAIT = 15000;
public final static String MY_SQL = "mysql";
public final static String SQL_SERVER = "sqlserver";
public final static String ORACLE = "oracle";
public static class SqlDbConfigsMap {
private HashMap<String, SqlDbConfigs> map;
public SqlDbConfigsMap() {}
public HashMap<String, SqlDbConfigs> getMap() {
if(map == null){
map = new HashMap<String, SqlDbConfigs>(0);
}
return map;
}
public void setMap(HashMap<String, SqlDbConfigs> map) {
this.map = map;
}
}
String dbId = StringPool.BLANK;
private String username;
private String password;
private String database;
private String host;
private int port;
private String dbdriver;
private String dbdriverclasspath;
static final Map<String,SqlDbConfigs> sqlDbConfigsCache = new HashMap<String,SqlDbConfigs>(6);
static final Map<String,Driver> driversCache = new HashMap<String, Driver>();
static String sqlDbConfigsJson = null;
public static SqlDbConfigs load(String dbId){
return loadFromFile(ConfigManager.SQL_DB_CONFIG_FILE,dbId);
}
public static SqlDbConfigs loadConfigs(String sqlDbConfigsJson, String dbId){
String k = dbId;
if( ! sqlDbConfigsCache.containsKey(k) ){
SqlDbConfigs configs = null;
try {
SqlDbConfigsMap map = new Gson().fromJson(sqlDbConfigsJson, SqlDbConfigsMap.class);
configs = map.getMap().get(dbId);
} catch (Exception e) {
e.printStackTrace();
}
if(configs == null){
throw new IllegalArgumentException("CAN NOT LOAD SqlDbConfigs from JSON: " + sqlDbConfigsJson);
}
configs.setDbId(dbId);
sqlDbConfigsCache.put(k, configs);
}
return sqlDbConfigsCache.get(k);
}
public static SqlDbConfigs loadFromFile(String filePath, String dbId){
String k = dbId;
if(sqlDbConfigsJson == null){
try {
sqlDbConfigsJson = FileUtils.readFileAsString(filePath);
} catch (IOException e) {
throw new IllegalArgumentException("File is not found at " + filePath);
}
}
if( ! sqlDbConfigsCache.containsKey(k) ){
SqlDbConfigs configs = null;
try {
SqlDbConfigsMap map = new Gson().fromJson(sqlDbConfigsJson, SqlDbConfigsMap.class);
configs = map.getMap().get(dbId);
} catch (Exception e) {
if(e instanceof JsonSyntaxException){
System.err.println("Wrong JSON syntax in file " + filePath );
}else {
e.printStackTrace();
}
}
if(configs == null){
throw new IllegalArgumentException("CAN NOT LOAD SqlDbConfigs dbId " + dbId + " from " + filePath );
}
configs.setDbId(dbId);
sqlDbConfigsCache.put(k, configs);
}
return sqlDbConfigsCache.get(k);
}
public String getConnectionUrl(){
StringBuilder s = new StringBuilder();
if(MY_SQL.equals(this.getDbdriver())){
s.append("jdbc:").append(MY_SQL).append("://");
s.append(this.getHost());
s.append(":").append(getPort()).append("/");
s.append(this.getDatabase());
s.append("?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true");
} else if(SQL_SERVER.equals(this.getDbdriver())){
s.append("jdbc:").append(SQL_SERVER).append("://");
s.append(this.getHost());
s.append(";databaseName=");
s.append(this.getDatabase());
} else if(ORACLE.equals(this.getDbdriver())){
System.setProperty("java.security.egd", "file:///dev/urandom");
//"jdbc:oracle:thin:@10.254.53.220:1521:ORADEV1"
s.append("jdbc:").append(ORACLE).append(":thin:@");
s.append(this.getHost());
s.append(":").append(this.getPort()).append(":");
s.append(this.getDatabase());
} else {
throw new IllegalArgumentException("Currently, only support JDBC driver for MySQL, MSSQL Server and Oracle!");
}
return s.toString();
}
public Connection getConnection() throws SQLException{
Connection dbConnection = null;
try {
Driver driver = driversCache.get(getDbdriverclasspath());
String connectionUrl = getConnectionUrl();
if(driver == null){
driver = (Driver) Class.forName(getDbdriverclasspath()).newInstance();
driversCache.put(getDbdriverclasspath(), driver);
DriverManager.registerDriver(driver);
}
dbConnection = DriverManager.getConnection(connectionUrl, getUsername(), getPassword());
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Missing JDBC driver jar for " + this.getDbdriverclasspath());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return dbConnection;
}
public SqlDbConfigs() {
}
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 getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getDbdriver() {
return dbdriver;
}
public void setDbdriver(String dbdriver) {
this.dbdriver = dbdriver;
}
public String getDbdriverclasspath() {
return dbdriverclasspath;
}
public void setDbdriverclasspath(String dbdriverclasspath) {
this.dbdriverclasspath = dbdriverclasspath;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDbId() {
return dbId;
}
public void setDbId(String dbId) {
this.dbId = dbId;
}
public DataSource getDataSource() throws IllegalArgumentException{
String connectionUrl = getConnectionUrl();
if(StringUtil.isEmpty(dbdriverclasspath)
|| getPort() == 0
|| StringUtil.isEmpty(database)
|| StringUtil.isEmpty(username)
|| StringUtil.isEmpty(connectionUrl)){
throw new IllegalArgumentException("Some of sql config is not valid, can not create DataSource for dbId: " + dbId);
}
DriverManager.setLoginTimeout(30);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setInitialSize(SqlDbConfigs.MIN_CONNECTIONS);
dataSource.setDriverClassName(getDbdriverclasspath());
dataSource.setUsername(getUsername());
dataSource.setPassword(getPassword());
dataSource.setUrl(connectionUrl);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTestWhileIdle(true);
dataSource.setMaxActive(SqlDbConfigs.MAX_CONNECTIONS);
dataSource.setMinIdle(SqlDbConfigs.MIN_CONNECTIONS);
dataSource.setMaxWait(SqlDbConfigs.MAX_WAIT);
dataSource.setDefaultAutoCommit(true);
return dataSource;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
s.append(" ,Dbdriver: ").append(getDbdriver());
s.append(" ,Dbdriverclasspath: ").append(getDbdriverclasspath());
s.append(" ,Host: ").append(getHost());
s.append(" ,Database: ").append(getDatabase());
s.append(" ,Username: ").append(getUsername());
s.append(" ,Password.length: ").append(getPassword().length());
s.append(" ,ConnectionUrl: ").append(getConnectionUrl());
return s.toString();
}
}