package com.product.data.center.service;
|
|
import cn.hutool.core.util.NumberUtil;
|
import com.product.common.lang.DateUtils;
|
import com.product.core.dao.BaseDao;
|
import com.product.core.entity.DataTableEntity;
|
import com.product.core.entity.FieldSetEntity;
|
import com.product.core.spring.context.SpringMVCContextHolder;
|
import com.product.data.center.config.CmnConst;
|
import com.product.datasource.dao.Dao;
|
import com.product.datasource.entity.DataBaseEntity;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @Author cheng
|
* @Date 2022/11/26 15:17
|
* @Desc 订单数据同步验证
|
*/
|
@Service
|
public class OrderDataValidationService {
|
|
@Resource
|
private BaseDao baseDao;
|
|
public synchronized void verificationEntryPoint() {
|
// FieldSetEntity fse = baseDao.getFieldSetBySQL("select * from product_sys_order_data_verification limit 1", new Object[]{}, true);
|
StringBuffer sql = new StringBuffer();
|
sql.append("\n SELECT ");
|
sql.append("\n m.uuid, ");
|
sql.append("\n m.data_source, ");
|
sql.append("\n s.uuid sub_uuid, ");
|
sql.append("\n table_name, ");
|
sql.append("\n auto_field,is_date ");
|
// sql.append("\n max_value, ");
|
// sql.append("\n result ");
|
sql.append("\n FROM ");
|
sql.append("\n product_sys_order_data_verification m ");
|
sql.append("\n INNER JOIN product_sys_order_data_verification_sub s ON s.master_uuid = m.uuid ");
|
sql.append("\n AND m.is_used = 1 ");
|
// sql.append("\n LEFT JOIN product_sys_order_data_verification_info i ON i.master_uuid = s.uuid ");
|
// sql.append("\n AND result =1 ");
|
DataTableEntity dte = baseDao.listTable(sql.toString(), (String[]) null);
|
if (DataTableEntity.isEmpty(dte)) {
|
return;
|
}
|
DataTableEntity sourceInfoDtb = baseDao.listTable("product_sys_order_data_verification_info", "id IN (select max(id) from product_sys_order_data_verification_info where length(max_value)>0 and result =1 GROUP BY data_source,table_name)", null, new Object[]{"max_value,data_source,table_name,master_uuid uuid,uuid m"});
|
// DataTableEntity subDt = fse.getSubDataTable("product_sys_order_data_verification_sub");
|
// if (DataTableEntity.isEmpty(subDt)) {
|
// return;
|
// }
|
String[] dataSource = dte.getString(0, "data_source").split(",");
|
if (dataSource.length <= 1) {
|
//不足2个数据源无法对比
|
return;
|
}
|
DataBaseEntity[] sourceDataBase = new DataBaseEntity[dataSource.length];
|
for (int i = 0; i < dataSource.length; i++) {
|
sourceDataBase[i] = new DataBaseEntity(dataSource[i]);
|
}
|
Map<String, List<ResultEntity>> map = new HashMap<>();
|
for (int i = 0; i < sourceDataBase.length; i++) {
|
sql.setLength(0);
|
DataBaseEntity dbe = sourceDataBase[i];
|
Dao dao = dbe.getDao();
|
try {
|
for (int k = 0; k < dte.getRows(); k++) {
|
if (k > 0) {
|
sql.append("\n UNION ALL \n");
|
}
|
FieldSetEntity fs = dte.getFieldSetEntity(k);
|
String subUuid = fs.getString("sub_uuid");
|
String autoField = fs.getString("auto_field");
|
String tableName = fs.getString("table_name");
|
Boolean isDate = fs.getBoolean("is_date");
|
sql.append(" SELECT COUNT(1) num,");
|
if (isDate) {
|
sql.append("to_char(MAX(").append(autoField).append("),'yyyy-mm-dd HH24:MI:SS') max");
|
sql.append(" ,to_char(MIN(").append(autoField).append("),'yyyy-mm-dd HH24:MI:SS') min ");
|
} else {
|
sql.append("to_char(MAX(").append(autoField).append(")) max");
|
sql.append(" ,to_char(MIN(").append(autoField).append(")) min ");
|
}
|
|
String maxValue = "";
|
if (!DataTableEntity.isEmpty(sourceInfoDtb) && sourceInfoDtb.getFieldSetEntity(subUuid) != null) {
|
FieldSetEntity f = sourceInfoDtb.getFieldSetEntity(subUuid).stream().filter(item -> item.getString("data_source").equals(dbe.getUuid()) && item.getString("table_name").equals(tableName)).findFirst().get();
|
maxValue = f.getString("max_value");
|
}
|
sql.append(",'" + (StringUtils.isEmpty(tableName) ? "" : tableName) + "' table_name,'" + maxValue + "' max_value");
|
sql.append(" FROM ").append(tableName);
|
fs.setValue("max_value", maxValue);
|
if (!StringUtils.isEmpty(maxValue)) {
|
sql.append(" WHERE ").append(autoField).append("> ");
|
if (isDate) {
|
sql.append(" to_date('" + fs.getDate("max_value", "yyyy-MM-dd HH:mm:ss") + "','yyyy-mm-dd HH24:MI:SS')");
|
} else {
|
sql.append("to_char('" + maxValue + "')");
|
}
|
}
|
}
|
DataTableEntity dt = dao.getList(sql.toString(), (Object[]) null);
|
for (int j = 0; j < dt.getRows(); j++) {
|
String tableName = dt.getString(j, "table_name");
|
List<ResultEntity> resultEntities = map.computeIfAbsent(tableName, k -> new ArrayList<>());
|
resultEntities.add(new ResultEntity(dt.getFieldSetEntity(j), dbe));
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
throw e;
|
} finally {
|
if (dao != null) {
|
dao.closeConnection();
|
}
|
}
|
}
|
|
DataTableEntity infoDte = new DataTableEntity();
|
map.forEach((k, v) -> {
|
StringBuilder message = new StringBuilder(64);
|
//获取最大的num结果
|
ResultEntity maxResult = v.stream().max(Comparator.comparingInt(ResultEntity::getNum)).get();
|
int totalCount = maxResult.getNum();
|
if (totalCount <= 0) {
|
//最大0条
|
return;
|
}
|
//过滤出小于num 或者 最大最小值不一致的
|
List<ResultEntity> collect = v.stream().filter(item -> item.getNum() < totalCount).collect(Collectors.toList());
|
boolean result = false;
|
if (collect != null && collect.size() > 0) {
|
//当前循环的表验证不通过,数量不一致
|
message.append("校验结果不一致!\n");
|
for (int i = 0; i < collect.size(); i++) {
|
ResultEntity resultEntity = collect.get(i);
|
DataBaseEntity dbe = resultEntity.getDbe();
|
message.append("\nERROR:" + (i + 1));
|
message.append("\n\t\t错误的连接名称:" + dbe.getConnectionName());
|
message.append("\n\t\t错误的表名:" + resultEntity.getTableName());
|
message.append("\n\t\t因总条数不一致判定为错误,本次最大总条数为:" + maxResult.getNum() + ",来自于连接名称:" + maxResult.getDbe().getConnectionName());
|
message.append("\n\t\t截止上一次成功的最大值:" + resultEntity.getLastMaxValue());
|
message.append("\n\t\t当前总条数:" + resultEntity.getNum());
|
}
|
} else {
|
//验证通过
|
message.append("校验成功,总条数一致 !");
|
result = true;
|
}
|
message.append("\n校验时间:" + DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
|
Date date = new Date();
|
for (int i = 0; i < v.size(); i++) {
|
FieldSetEntity infoFse = new FieldSetEntity();
|
infoFse.setTableName("product_sys_order_data_verification_info");
|
infoFse.setValue("result", result ? 1 : 0);
|
ResultEntity resultEntity = v.get(i);
|
infoFse.setValue("data_source", resultEntity.getDbe().getUuid());
|
infoFse.setValue("table_name", resultEntity.getTableName());
|
infoFse.setValue("max_value", resultEntity.getMaxValue());
|
FieldSetEntity filter = dte.getData().stream().filter(item -> resultEntity.getTableName().equals(item.getString("table_name"))).findFirst().get();
|
infoFse.setValue("master_uuid", filter.getString("sub_uuid"));
|
infoFse.setValue("message", message.toString());
|
System.out.println(message.length());
|
infoFse.setValue(CmnConst.CREATED_UTC_DATETIME, date);
|
infoDte.addFieldSetEntity(infoFse);
|
}
|
});
|
if (!DataTableEntity.isEmpty(infoDte)) {
|
try {
|
baseDao.add(infoDte);
|
} catch (Exception e) {
|
SpringMVCContextHolder.getSystemLogger().error(e);
|
e.printStackTrace();
|
}
|
}
|
|
}
|
|
class ResultEntity {
|
|
private int num;
|
|
private String minValue;
|
|
private String maxValue;
|
|
private String tableName;
|
|
private String lastMaxValue;
|
|
private DataBaseEntity dbe;
|
|
public ResultEntity(FieldSetEntity fse, DataBaseEntity dbe) {
|
this.num = NumberUtil.parseInt(fse.getString("num"));
|
this.minValue = fse.getString("min");
|
this.maxValue = fse.getString("max");
|
this.lastMaxValue = fse.getString("max_value");
|
this.tableName = fse.getString("table_name");
|
this.dbe = dbe;
|
}
|
|
public int getNum() {
|
return num;
|
}
|
|
public void setNum(int num) {
|
this.num = num;
|
}
|
|
public String getMinValue() {
|
return minValue;
|
}
|
|
public void setMinValue(String minValue) {
|
this.minValue = minValue;
|
}
|
|
public String getMaxValue() {
|
return maxValue;
|
}
|
|
public void setMaxValue(String maxValue) {
|
this.maxValue = maxValue;
|
}
|
|
public String getTableName() {
|
return tableName;
|
}
|
|
public void setTableName(String tableName) {
|
this.tableName = tableName;
|
}
|
|
public String getLastMaxValue() {
|
return lastMaxValue;
|
}
|
|
public void setLastMaxValue(String lastMaxValue) {
|
this.lastMaxValue = lastMaxValue;
|
}
|
|
public DataBaseEntity getDbe() {
|
return dbe;
|
}
|
|
public void setDbe(DataBaseEntity dbe) {
|
this.dbe = dbe;
|
}
|
|
}
|
|
}
|