
com.github.javaclub.cdl.client.matrix.rule.DynamicRouterStrategy Maven / Gradle / Ivy
The newest version!
package com.github.javaclub.cdl.client.matrix.rule;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.javaclub.cdl.client.config.DbConfigManager;
/**
* 库表动态路由
*/
public class DynamicRouterStrategy implements RouterStrategy {
private DbConfigManager dbConfigManager;
private volatile DynamicRouterInfo routerInfo;
private HashFunction hashFunction;
private AtomicBoolean inited = new AtomicBoolean(false);
public void init() {
if(inited.compareAndSet(false,true)){
updateRouter(dbConfigManager.getShardDynamicRouter(this));
}
}
public void setDbConfigManager(DbConfigManager dbConfigManager) {
this.dbConfigManager = dbConfigManager;
}
public void updateRouter(String newCfg) {
if (StringUtils.isNotBlank(newCfg)) {
DynamicRouterCfg dynamicRouterCfg = JSONObject.parseObject(newCfg, DynamicRouterCfg.class);
DynamicRouterInfo dynamicRouterInfo = new DynamicRouterInfo();
dynamicRouterInfo.setDefaultDbGroup(dynamicRouterCfg.getDefaultDbGroup());
dynamicRouterInfo.setShardingColumn(dynamicRouterCfg.getShardingColumn());
for (String table : dynamicRouterCfg.getShardRouterMap().keySet()) {
Map map = new HashMap<>();
Map shards = dynamicRouterCfg.getShardRouterMap().get(table);
for (String group : shards.keySet()) {
String[] ss = shards.get(group).split(",");
for (String s : ss) {
String[] aa = s.split("-");
int startIndex = Integer.parseInt(aa[0]);
int endIndex = Integer.parseInt(aa[1]);
for (int i = startIndex; i <= endIndex; i++) {
String actualTable = dynamicRouterCfg.getTablePrefix().get(table)
+ SuffixParse.getTableSuffix(i, aa[0].length());
map.put(actualTable, group);
}
}
}
List sortedActualTable = new ArrayList<>();
sortedActualTable.addAll(map.keySet());
Collections.sort(sortedActualTable);
dynamicRouterInfo.getRouterMap().put(table, new HashMap());
for (int i = 0; i < sortedActualTable.size(); i++) {
RouterNode routerNode = new RouterNode();
routerNode.setActualTable(sortedActualTable.get(i));
routerNode.setGroupName(map.get(sortedActualTable.get(i)));
dynamicRouterInfo.getRouterMap().get(table).put(i, routerNode);
}
}
this.routerInfo = dynamicRouterInfo;
}
}
@Override
public Map getShardingColumn() {
if(!inited.get()){
throw new RuntimeException("init method not be invoked at first, check your spring bean");
}
return routerInfo.getShardingColumn();
}
@Override
public Map getActualTable(String table, Object shardColumnValue) {
if(!inited.get()){
throw new RuntimeException("init method not be invoked at first, check your spring bean");
}
if (routerInfo.getRouterMap().get(table) == null) {
throw new RuntimeException("not found route map for table:" + table);
}
int tableIndex = -1;
if(hashFunction != null){
tableIndex = hashFunction.doHash(table, shardColumnValue);
}
if(tableIndex == -1){
if (shardColumnValue instanceof Number) {
Number number = (Number) shardColumnValue;
long value = number.longValue();
long mod = value % routerInfo.getRouterMap().get(table).size();
tableIndex = (int) mod;
} else {
tableIndex = shardColumnValue.hashCode() % routerInfo.getRouterMap().get(table).size();
}
}
RouterNode routerNode = routerInfo.getRouterMap().get(table).get(tableIndex);
Map map = new HashMap<>();
map.put(routerNode.getGroupName(), routerNode.getActualTable());
return map;
}
@Override
public Map> getAllActualTable(String table) {
if(!inited.get()){
throw new RuntimeException("init method not be invoked at first, check your spring bean");
}
Map> map = new HashMap<>();
if (routerInfo.getShardingColumn().get(table) == null) {
map.put(routerInfo.getDefaultDbGroup(), Arrays.asList(new String[] { table }));
return map;
}
Map routerMap = routerInfo.getRouterMap().get(table);
if (routerMap == null) {
throw new RuntimeException("not found route map for table:" + table);
}
for (RouterNode routerNode : routerMap.values()) {
String groupName = routerNode.getGroupName();
if (map.get(groupName) == null) {
map.put(groupName, new ArrayList());
}
if (!map.get(groupName).contains(routerNode.getActualTable())) {
map.get(groupName).add(routerNode.getActualTable());
}
}
return map;
}
@Override
public void setHashFunction(HashFunction hashFunction) {
this.hashFunction = hashFunction;
}
class DynamicRouterInfo {
private String defaultDbGroup; // 非sharding表走默认库
private Map> routerMap = new HashMap<>();
private Map shardingColumn = new HashMap<>();
public String getDefaultDbGroup() {
return defaultDbGroup;
}
public void setDefaultDbGroup(String defaultDbGroup) {
this.defaultDbGroup = defaultDbGroup;
}
public Map> getRouterMap() {
return routerMap;
}
public void setRouterMap(Map> routerMap) {
this.routerMap = routerMap;
}
public Map getShardingColumn() {
return shardingColumn;
}
public void setShardingColumn(Map shardingColumn) {
this.shardingColumn = shardingColumn;
}
}
@Override
public String getDefaultGroup() {
return routerInfo.getDefaultDbGroup();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy