use of org.sagacity.sqltoy.translate.model.TranslateConfigModel in project sagacity-sqltoy by chenrenfei.
the class TranslateConfigParse method parseTranslateConfig.
/**
* @todo 解析translate配置文件
* @param sqlToyContext
* @param translateMap 最终缓存配置,构建一个空map,在解析过程中填充
* @param checker 更新检测配置
* @param translateConfig 缓存配置文件
* @param charset
* @return
* @throws Exception
*/
public static DefaultConfig parseTranslateConfig(final SqlToyContext sqlToyContext, final IgnoreKeyCaseMap<String, TranslateConfigModel> translateMap, final List<CheckerConfigModel> checker, String translateConfig, String charset) throws Exception {
// 判断缓存翻译的配置文件是否存在
if (FileUtil.getFileInputStream(translateConfig) == null) {
logger.warn("缓存翻译配置文件:{}无法加载,请检查配路径正确性,如不使用缓存翻译可忽略此提示!", translateConfig);
return null;
}
return (DefaultConfig) XMLUtil.readXML(translateConfig, charset, false, new XMLCallbackHandler() {
@Override
public Object process(Document doc, Element root) throws Exception {
DefaultConfig defaultConfig = new DefaultConfig();
NodeList nodeList = root.getElementsByTagName("cache-translates");
if (nodeList.getLength() == 0) {
return defaultConfig;
}
// 解析缓存翻译配置
Element node = (Element) nodeList.item(0);
XMLUtil.setAttributes(node, defaultConfig);
NodeList elts;
Element elt;
NodeList sqlNode;
String sql;
String sqlId;
boolean isShowSql;
int index = 1;
for (String translateType : TRANSLATE_TYPES) {
elts = node.getElementsByTagName(translateType.concat(TRANSLATE_SUFFIX));
if (elts.getLength() > 0) {
for (int i = 0; i < elts.getLength(); i++) {
elt = (Element) elts.item(i);
TranslateConfigModel translateCacheModel = new TranslateConfigModel();
// 设置默认值
translateCacheModel.setHeap(defaultConfig.getDefaultHeap());
translateCacheModel.setOffHeap(defaultConfig.getDefaultOffHeap());
translateCacheModel.setDiskSize(defaultConfig.getDefaultDiskSize());
translateCacheModel.setKeepAlive(defaultConfig.getDefaultKeepAlive());
XMLUtil.setAttributes(elt, translateCacheModel);
translateCacheModel.setType(translateType);
// 非sqlId模式定义
if (translateType.equals("sql")) {
if (StringUtil.isBlank(translateCacheModel.getSql())) {
sqlNode = elt.getElementsByTagName("sql");
if (sqlNode.getLength() > 0) {
sql = StringUtil.trim(sqlNode.item(0).getTextContent());
} else {
sql = StringUtil.trim(elt.getTextContent());
}
sqlId = "s_trans_cache_0" + index;
isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, SqlUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyConfig.setParamsName(SqlConfigParseUtils.getSqlParamsName(sqlToyConfig.getSql(null), true));
sqlToyContext.putSqlToyConfig(sqlToyConfig);
translateCacheModel.setSql(sqlId);
index++;
}
}
// local模式是避免一些额外争议的产物,有部分开发者坚持缓存要应用自己管理
if (translateType.equals("local") && !elt.hasAttribute("keep-alive")) {
translateCacheModel.setKeepAlive(-1);
}
translateMap.put(translateCacheModel.getCache(), translateCacheModel);
logger.debug("已经加载缓存翻译:cache={},type={}", (translateCacheModel.getCache() == null) ? "[非增量]" : translateCacheModel.getCache(), translateType);
}
}
}
nodeList = root.getElementsByTagName("cache-update-checkers");
// 解析更新检测器
if (nodeList.getLength() == 0) {
return defaultConfig;
}
node = (Element) nodeList.item(0);
// 集群节点时间偏差(秒)
if (node.hasAttribute("cluster-time-deviation")) {
defaultConfig.setDeviationSeconds(Integer.parseInt(node.getAttribute("cluster-time-deviation")));
if (Math.abs(defaultConfig.getDeviationSeconds()) > 60) {
logger.debug("您设置的集群节点时间差异参数cluster-time-deviation={} 秒>60秒,将设置为60秒!", defaultConfig.getDeviationSeconds());
defaultConfig.setDeviationSeconds(-60);
} else {
defaultConfig.setDeviationSeconds(0 - Math.abs(defaultConfig.getDeviationSeconds()));
}
}
String nodeType;
index = 1;
// 缓存更新检测
for (String translateType : TRANSLATE_CHECKER_TYPES) {
nodeType = translateType.concat(CHECKER_SUFFIX);
elts = node.getElementsByTagName(nodeType);
if (elts.getLength() > 0) {
for (int i = 0; i < elts.getLength(); i++) {
elt = (Element) elts.item(i);
CheckerConfigModel checherConfigModel = new CheckerConfigModel();
XMLUtil.setAttributes(elt, checherConfigModel);
// 数据交互类型
checherConfigModel.setType(translateType.replace("-increment", ""));
// 增量方式更新
if (translateType.endsWith("-increment")) {
checherConfigModel.setIncrement(true);
// 增量方式必须要指定缓存名称
if (StringUtil.isBlank(checherConfigModel.getCache())) {
logger.error("translate update checker:{} must config with cache=\"xxx\"!", nodeType);
throw new IllegalArgumentException(nodeType + " must config with cache=\"xxx\"");
}
}
// sql模式且非sqlId模式定义
if (checherConfigModel.getType().equals("sql")) {
if (StringUtil.isBlank(checherConfigModel.getSql())) {
sqlId = (checherConfigModel.isIncrement() ? "s_trans_merge_chk_0" : "s_trans_chk_0") + index;
sqlNode = elt.getElementsByTagName("sql");
if (sqlNode.getLength() > 0) {
sql = StringUtil.trim(sqlNode.item(0).getTextContent());
} else {
sql = StringUtil.trim(elt.getTextContent());
}
isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, SqlUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyConfig.setParamsName(SqlConfigParseUtils.getSqlParamsName(sqlToyConfig.getSql(null), true));
// 增加条件参数检查,避免开发者手误然后找不到原因!有出现:lastUpdateTime 和 lastUpdateTimee 的找半天发现不了问题的!
if (sqlToyConfig.getParamsName() != null && sqlToyConfig.getParamsName().length > 1) {
throw new IllegalArgumentException("请检查缓存更新检测sql语句中的参数名称,所有参数名称要保持一致为lastUpdateTime!当前有:" + sqlToyConfig.getParamsName().length + " 个不同条件参数名!");
}
sqlToyContext.putSqlToyConfig(sqlToyConfig);
checherConfigModel.setSql(sqlId);
index++;
}
}
// 剔除tab\回车等特殊字符
String frequency = SqlUtil.clearMistyChars(checherConfigModel.getCheckFrequency(), "");
List<TimeSection> timeSections = new ArrayList<TimeSection>();
// frequency的格式 frequency="0..12?15,12..18:30?10,18:30..24?60"
if (StringUtil.isNotBlank(frequency)) {
// 统一格式,去除全角字符,去除空白
frequency = StringUtil.toDBC(frequency).replaceAll("\\;", ",").trim();
// 可以是单个频率值,表示0到24小时采用统一的频率
if (NumberUtil.isInteger(frequency)) {
TimeSection section = new TimeSection();
section.setStart(0);
section.setEnd(2400);
section.setIntervalSeconds(Integer.parseInt(frequency));
timeSections.add(section);
} else {
// 归整分割符号统一为逗号,将时间格式由HH:mm 转为HHmm格式
String[] sectionsStr = frequency.split("\\,");
for (int j = 0; j < sectionsStr.length; j++) {
TimeSection section = new TimeSection();
// 问号切割获取时间区间和时间间隔
String[] sectionPhase = sectionsStr[j].split("\\?");
// 获取开始和结束时间点
String[] startEnd = sectionPhase[0].split("\\.{2}");
section.setIntervalSeconds(Integer.parseInt(sectionPhase[1].trim()));
section.setStart(getHourMinute(startEnd[0].trim()));
section.setEnd(getHourMinute(startEnd[1].trim()));
timeSections.add(section);
}
}
}
checherConfigModel.setTimeSections(timeSections);
checker.add(checherConfigModel);
logger.debug("已经加载针对缓存:{} 更新的检测器,type={}", checherConfigModel.getCache(), translateType);
}
}
}
return defaultConfig;
}
});
}
use of org.sagacity.sqltoy.translate.model.TranslateConfigModel in project sagacity-sqltoy by chenrenfei.
the class TranslateConfigParse method parseTranslateConfig.
/**
* @todo 解析translate配置文件
* @param translateMap
* @param checker
* @param translateConfig
* @param charset
* @throws Exception
*/
public static DefaultConfig parseTranslateConfig(final SqlToyContext sqlToyContext, final HashMap<String, TranslateConfigModel> translateMap, final List<CheckerConfigModel> checker, String translateConfig, String charset) throws Exception {
return (DefaultConfig) XMLUtil.readXML(translateConfig, charset, false, new XMLCallbackHandler() {
@Override
public Object process(Document doc, Element root) throws Exception {
// 解析缓存翻译配置
Element node = root.element("cache-translates");
DefaultConfig defaultConfig = new DefaultConfig();
if (node.attribute("disk-store-path") != null)
defaultConfig.setDiskStorePath(node.attributeValue("disk-store-path"));
List<Element> elts;
for (String translateType : TRANSLATE_TYPES) {
elts = node.elements(translateType.concat(TRANSLATE_SUFFIX));
if (elts != null && !elts.isEmpty()) {
int index = 1;
for (Element elt : elts) {
TranslateConfigModel translateCacheModel = new TranslateConfigModel();
XMLUtil.setAttributes(elt, translateCacheModel);
translateCacheModel.setType(translateType);
if (translateType.equals("sql")) {
if (StringUtil.isBlank(translateCacheModel.getSql())) {
String sql = (elt.element("sql") != null) ? elt.elementText("sql") : elt.getText();
String sqlId = "SQLTOY_TRANSLATE_Cache_ID_00" + index;
boolean isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, StringUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyContext.putSqlToyConfig(sqlToyConfig);
translateCacheModel.setSql(sqlId);
}
index++;
}
// 过期时长
if (translateCacheModel.getKeepAlive() <= 0)
translateCacheModel.setKeepAlive(SqlToyConstants.getCacheExpireSeconds());
translateMap.put(translateCacheModel.getCache(), translateCacheModel);
}
}
}
// 解析更新检测器
node = root.element("cache-update-checkers");
if (node != null) {
for (String translateType : TRANSLATE_TYPES) {
elts = node.elements(translateType.concat(CHECKER_SUFFIX));
if (elts != null && !elts.isEmpty()) {
int index = 1;
for (Element elt : elts) {
CheckerConfigModel checherConfigModel = new CheckerConfigModel();
XMLUtil.setAttributes(elt, checherConfigModel);
checherConfigModel.setType(translateType);
if (translateType.equals("sql")) {
if (StringUtil.isBlank(checherConfigModel.getSql())) {
String sqlId = "SQLTOY_TRANSLATE_Check_ID_00" + index;
String sql = (elt.element("sql") != null) ? elt.elementText("sql") : elt.getText();
boolean isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, StringUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyContext.putSqlToyConfig(sqlToyConfig);
checherConfigModel.setSql(sqlId);
}
index++;
}
// 剔除tab\回车等特殊字符
String frequency = StringUtil.clearMistyChars(checherConfigModel.getCheckFrequency(), "");
List<TimeSection> timeSections = new ArrayList<TimeSection>();
// frequency的格式 frequency="0..12?15,12..18:30?10,18:30..24?60"
if (StringUtil.isNotBlank(frequency)) {
// 统一格式,去除全角字符,去除空白
frequency = frequency.replaceAll("\\;", ",").replaceAll("\\?", "?").replaceAll("\\.", ".").replaceAll("\\。", ".").replaceAll("\\,", ",").trim();
// 可以是单个频率值,表示0到24小时采用统一的频率
if (CommonUtils.isInteger(frequency)) {
TimeSection section = new TimeSection();
section.setStart(0);
section.setEnd(2400);
section.setIntervalSeconds(Integer.parseInt(frequency));
timeSections.add(section);
} else {
// 归整分割符号统一为逗号,将时间格式由HH:mm 转为HHmm格式
String[] sectionsStr = frequency.split("\\,");
for (int i = 0; i < sectionsStr.length; i++) {
TimeSection section = new TimeSection();
// 问号切割获取时间区间和时间间隔
String[] sectionPhase = sectionsStr[i].split("\\?");
// 获取开始和结束时间点
String[] startEnd = sectionPhase[0].split("\\.{2}");
section.setIntervalSeconds(Integer.parseInt(sectionPhase[1].trim()));
section.setStart(getHourMinute(startEnd[0].trim()));
section.setEnd(getHourMinute(startEnd[1].trim()));
timeSections.add(section);
}
}
}
checherConfigModel.setTimeSections(timeSections);
checker.add(checherConfigModel);
}
}
}
}
return defaultConfig;
}
});
}
use of org.sagacity.sqltoy.translate.model.TranslateConfigModel in project sagacity-sqltoy by chenrenfei.
the class TranslateManager method getTranslates.
/**
* @todo 根据sqltoy sql.xml中的翻译设置获取对应的缓存(多个translate对应的多个缓存结果)
* @param sqlToyContext
* @param conn
* @param translates
* @return
* @throws Exception
*/
public HashMap<String, HashMap<String, Object[]>> getTranslates(SqlToyContext sqlToyContext, Connection conn, HashMap<String, SqlTranslate> translates) throws Exception {
HashMap<String, HashMap<String, Object[]>> result = new HashMap<String, HashMap<String, Object[]>>();
SqlTranslate translate;
HashMap<String, Object[]> cache;
TranslateConfigModel cacheModel;
for (Map.Entry<String, SqlTranslate> entry : translates.entrySet()) {
translate = entry.getValue();
if (translateMap.containsKey(translate.getCache())) {
cacheModel = translateMap.get(translate.getCache());
cache = getCacheData(sqlToyContext, cacheModel, translate.getDictType());
if (cache != null)
result.put(translate.getColumn(), cache);
else {
result.put(translate.getColumn(), new HashMap<String, Object[]>());
logger.warn("sqltoy translate:cacheName={},cache-type={},column={}配置不正确,未获取对应cache数据!", cacheModel.getCache(), translate.getDictType(), translate.getColumn());
}
} else {
logger.error("cacheName:{} 没有配置,请检查sqltoy-translate.xml文件!", translate.getCache());
}
}
return result;
}
use of org.sagacity.sqltoy.translate.model.TranslateConfigModel in project sagacity-sqltoy by chenrenfei.
the class TranslateManager method getCacheData.
/**
* @todo 提供对外的访问(如要做增量更新可以对这里的数据进行修改即可达到缓存的更新作用)
* @param cacheName
* @param cacheType (一般为null,不为空时一般用于数据字典等同于dictType)
* @return
*/
public HashMap<String, Object[]> getCacheData(String cacheName, String cacheType) {
TranslateConfigModel cacheModel = translateMap.get(cacheName);
if (cacheModel == null) {
logger.error("cacheName:{} 没有配置,请检查sqltoy-translate.xml文件!", cacheName);
return null;
}
// 获得当前线程中的sql执行日志,后续缓存获取会覆盖掉日志
SqlExecuteTrace sqlTrace = SqlExecuteStat.get();
HashMap<String, Object[]> result = getCacheData(cacheModel, cacheType);
// 将调用获取缓存之前的日志放回线程中
if (sqlTrace != null) {
SqlExecuteStat.set(sqlTrace);
}
return result;
}
use of org.sagacity.sqltoy.translate.model.TranslateConfigModel in project sagacity-sqltoy by chenrenfei.
the class TranslateManager method getTranslates.
/**
* @todo 根据sqltoy sql.xml中的翻译设置获取对应的缓存(多个translate对应的多个缓存结果)
* @param translates
* @return
*/
public HashMap<String, HashMap<String, Object[]>> getTranslates(HashMap<String, Translate> translates) {
// 获得当前线程中的sql执行日志,后续缓存获取会覆盖掉日志
SqlExecuteTrace sqlTrace = SqlExecuteStat.get();
HashMap<String, HashMap<String, Object[]>> result = new HashMap<String, HashMap<String, Object[]>>();
HashMap<String, Object[]> cache;
TranslateConfigModel cacheModel;
TranslateExtend extend;
int cacheEltLength;
for (Map.Entry<String, Translate> entry : translates.entrySet()) {
extend = entry.getValue().getExtend();
if (translateMap.containsKey(extend.cache)) {
cacheModel = translateMap.get(extend.cache);
cache = getCacheData(cacheModel, extend.cacheType);
if (cache != null) {
// update 2022-1-4 增加缓存使用时cache-index 合法性校验
if (cache.size() > 0) {
cacheEltLength = cache.values().iterator().next().length;
if (extend.index >= cacheEltLength) {
throw new IllegalArgumentException("缓存取值数组越界:cacheName:" + extend.cache + ", column:" + extend.column + ",cache-indexs:(" + extend.index + ">=" + cacheEltLength + ")[缓存内容数组长度],请检查cache-indexs值确保跟缓存数据具体列保持一致!");
}
}
result.put(extend.column, cache);
} else {
result.put(extend.column, new HashMap<String, Object[]>());
if (logger.isWarnEnabled()) {
logger.warn("sqltoy translate:cacheName={},cache-type={},column={}配置不正确,未获取对应cache数据!", cacheModel.getCache(), extend.cacheType, extend.column);
} else {
System.err.println("sqltoy translate:cacheName=" + cacheModel.getCache() + ",cache-type=" + extend.cacheType + ",column=" + extend.column + " 配置不正确,未获取对应cache数据!");
}
}
} else {
logger.error("cacheName:{} 没有配置,请检查sqltoy-translate.xml文件!", extend.cache);
}
}
// 将调用获取缓存之前的日志放回线程中
if (sqlTrace != null) {
SqlExecuteStat.set(sqlTrace);
}
return result;
}
Aggregations