/*
* Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software;Designed and Developed mainly by many Chinese
* opensource volunteers. you can redistribute it and/or modify it under the
* terms of the GNU General Public License version 2 only, as published by the
* Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Any questions about this component can be directed to it's project Web address
* https://code.google.com/p/opencloudb/.
*
*/
package io.mycat.server.config.loader;
import io.mycat.backend.MySQLDataSource;
import io.mycat.backend.PhysicalDBNode;
import io.mycat.backend.PhysicalDBPool;
import io.mycat.backend.PhysicalDatasource;
import io.mycat.backend.jdbc.JDBCDatasource;
import io.mycat.backend.postgresql.PostgreSQLDataSource;
import io.mycat.server.config.ConfigException;
import io.mycat.server.config.cluster.MycatClusterConfig;
import io.mycat.server.config.node.CharsetConfig;
import io.mycat.server.config.node.DBHostConfig;
import io.mycat.server.config.node.DataHostConfig;
import io.mycat.server.config.node.DataNodeConfig;
import io.mycat.server.config.node.HostIndexConfig;
import io.mycat.server.config.node.QuarantineConfig;
import io.mycat.server.config.node.RuleConfig;
import io.mycat.server.config.node.SchemaConfig;
import io.mycat.server.config.node.SequenceConfig;
import io.mycat.server.config.node.SystemConfig;
import io.mycat.server.config.node.UserConfig;
import io.mycat.server.packet.util.CharsetUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author mycat
*/
public class ConfigInitializer {
private volatile SystemConfig system;
private volatile MycatClusterConfig cluster;
private volatile QuarantineConfig quarantine;
private volatile Map<String, UserConfig> users;
private volatile Map<String, SchemaConfig> schemas;
private volatile Map<String, PhysicalDBNode> dataNodes;
private volatile Map<String, PhysicalDBPool> dataHosts;
private volatile Map<String, RuleConfig> tableRules;
private volatile SequenceConfig sequenceConfig;
private volatile CharsetConfig charsetConfig;
public ConfigInitializer(boolean loadDataHost) {
ConfigLoader configLoader = ConfigFactory.instanceLoader();
this.system = configLoader.getSystemConfig();
this.users = configLoader.getUserConfigs();
if (loadDataHost) {
this.dataHosts = initDataHosts(configLoader);
this.dataNodes = initDataNodes(configLoader);
}
this.initCharsetConfig(configLoader); // 需要放在 initDataHosts 后面
this.tableRules = configLoader.getTableRuleConfigs();
this.schemas = configLoader.getSchemaConfigs();
this.quarantine = configLoader.getQuarantineConfigs();
this.cluster = configLoader.getClusterConfigs();
this.sequenceConfig = configLoader.getSequenceConfig();
this.charsetConfig = new CharsetConfig();
this.checkConfig();
}
private void checkConfig() throws ConfigException {
if (users == null || users.isEmpty())
return;
for (UserConfig uc : users.values()) {
if (uc == null) {
continue;
}
Set<String> authSchemas = uc.getSchemas();
if (authSchemas == null) {
continue;
}
for (String schema : authSchemas) {
if (!schemas.containsKey(schema)) {
String errMsg = "schema " + schema + " refered by user "
+ uc.getName() + " is not exist!";
throw new ConfigException(errMsg);
}
}
}
for (SchemaConfig sc : schemas.values()) {
if (null == sc) {
continue;
}
}
}
public SystemConfig getSystem() {
return system;
}
public MycatClusterConfig getCluster() {
return cluster;
}
public QuarantineConfig getQuarantine() {
return quarantine;
}
public Map<String, UserConfig> getUsers() {
return users;
}
public Map<String, SchemaConfig> getSchemas() {
return schemas;
}
public Map<String, PhysicalDBNode> getDataNodes() {
return dataNodes;
}
public Map<String, PhysicalDBPool> getDataHosts() {
return this.dataHosts;
}
public CharsetConfig getCharsetConfig() {
return this.charsetConfig;
}
public SequenceConfig getSequenceConfig() {
return this.sequenceConfig;
}
/*
* private MycatCluster initCobarCluster(ConfigLoader configLoader) { return
* new MycatCluster(configLoader.getClusterConfigs()); }
*/
public Map<String, RuleConfig> getTableRules() {
return tableRules;
}
public void setTableRules(Map<String, RuleConfig> tableRules) {
this.tableRules = tableRules;
}
private Map<String, PhysicalDBPool> initDataHosts(ConfigLoader configLoader) {
Map<String, DataHostConfig> nodeConfs = configLoader
.getDataHostConfigs();
Map<String, PhysicalDBPool> nodes = new HashMap<String, PhysicalDBPool>(
nodeConfs.size());
for (DataHostConfig conf : nodeConfs.values()) {
PhysicalDBPool pool = getPhysicalDBPool(conf, configLoader);
nodes.put(pool.getHostName(), pool);
}
return nodes;
}
private PhysicalDatasource[] createDataSource(DataHostConfig conf,
String hostName, String dbType, String dbDriver,
DBHostConfig[] nodes, boolean isRead) {
PhysicalDatasource[] dataSources = new PhysicalDatasource[nodes.length];
if (dbType.equals("mysql") && dbDriver.equals("native")) {
for (int i = 0; i < nodes.length; i++) {
nodes[i].setIdleTimeout(system.getIdleTimeout());
MySQLDataSource ds = new MySQLDataSource(nodes[i], conf, isRead);
dataSources[i] = ds;
}
} else if (dbDriver.equals("jdbc")) {
for (int i = 0; i < nodes.length; i++) {
nodes[i].setIdleTimeout(system.getIdleTimeout());
JDBCDatasource ds = new JDBCDatasource(nodes[i], conf, isRead);
dataSources[i] = ds;
}
} else if ("PostgreSQL".equalsIgnoreCase(dbType)
&& "native".equals(dbDriver)) {
for (int i = 0; i < nodes.length; i++) {
nodes[i].setIdleTimeout(system.getIdleTimeout());
PostgreSQLDataSource ds = new PostgreSQLDataSource(nodes[i],
conf, isRead);
dataSources[i] = ds;
}
} else {
throw new ConfigException("not supported yet !" + hostName);
}
return dataSources;
}
private PhysicalDBPool getPhysicalDBPool(DataHostConfig conf,
ConfigLoader configLoader) {
String name = conf.getName();
String dbType = conf.getDbType();
String dbDriver = conf.getDbDriver();
PhysicalDatasource[] writeSources = createDataSource(conf, name,
dbType, dbDriver, conf.getWriteHosts(), false);
Map<Integer, DBHostConfig[]> readHostsMap = conf.getReadHosts();
Map<Integer, PhysicalDatasource[]> readSourcesMap = new HashMap<Integer, PhysicalDatasource[]>(
readHostsMap.size());
for (Map.Entry<Integer, DBHostConfig[]> entry : readHostsMap.entrySet()) {
PhysicalDatasource[] readSources = createDataSource(conf, name,
dbType, dbDriver, entry.getValue(), true);
readSourcesMap.put(entry.getKey(), readSources);
}
return new PhysicalDBPool(conf.getName(), conf,
writeSources, readSourcesMap, conf.getBalance(),
conf.getWriteType());
}
private Map<String, PhysicalDBNode> initDataNodes(ConfigLoader configLoader) {
Map<String, DataNodeConfig> nodeConfs = configLoader
.getDataNodeConfigs();
Map<String, PhysicalDBNode> nodes = new HashMap<String, PhysicalDBNode>(
nodeConfs.size());
for (DataNodeConfig conf : nodeConfs.values()) {
PhysicalDBPool pool = this.dataHosts.get(conf.getDataHost());
if (pool == null) {
throw new ConfigException("dataHost not exists "
+ conf.getDataHost());
}
PhysicalDBNode dataNode = new PhysicalDBNode(conf.getName(),
conf.getDatabase(), pool);
nodes.put(dataNode.getName(), dataNode);
}
return nodes;
}
private void initCharsetConfig(ConfigLoader configLoader) {
this.charsetConfig = configLoader.getCharsetConfigs();
CharsetUtil.load(this.dataHosts, charsetConfig.getProps());
// CharsetUtil.asynLoad(this.dataHosts, charsetConfig.getProps());
}
public HostIndexConfig getHostIndexs() {
ConfigLoader configLoader = ConfigFactory.instanceLoader();
return configLoader.getHostIndexConfig();
}
}