package com.product.patch.service;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.google.common.collect.Lists;
|
import com.product.common.io.FileUtils;
|
import com.product.common.lang.StringUtils;
|
import com.product.core.config.Global;
|
import com.product.core.dao.BaseDao;
|
import com.product.core.entity.DataTableEntity;
|
import com.product.core.entity.FieldSetEntity;
|
import com.product.core.exception.BaseException;
|
import com.product.core.service.support.AbstractBaseService;
|
import com.product.patch.config.CmnConst;
|
import com.product.patch.config.ErrorCode;
|
import com.product.patch.service.idel.IPatchExtractService;
|
import com.product.patch.util.RSAUtil;
|
import com.product.util.BaseUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.io.File;
|
import java.text.SimpleDateFormat;
|
import java.util.Arrays;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* Copyright © 6c
|
*
|
* @Date: 2022-04-02 16:59
|
* @Author: 6c
|
* @Description: 补丁抽取
|
*/
|
@Service
|
public class PatchExtractService extends AbstractBaseService implements IPatchExtractService {
|
@Autowired
|
private BaseDao baseDao;
|
|
public void testExtract() {
|
FieldSetEntity fse = new FieldSetEntity();
|
fse.setTableName("temp_table");
|
fse.setValue(CmnConst.FIELD_CLIENT_UUID, "a34f8818-d36d-4d82-b1b0-dbc0d2e70a03");
|
fse.setValue("deploy_date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
fse.setValue("operator", "admin");
|
|
JSONObject paramObj = new JSONObject();
|
|
// 表数据
|
JSONObject tableReportObj = new JSONObject();
|
tableReportObj.put("6c_test_contract", "id<5");
|
tableReportObj.put("6c_test_renewal", "id<3");
|
paramObj.put(CmnConst.PARAM_TABLE_REPORT, tableReportObj.toJSONString());
|
|
// 表结构
|
JSONArray tableStructureArray = new JSONArray();
|
JSONObject tableStructureObj = new JSONObject();
|
tableStructureObj.put("table_name", "6c_test_contract");
|
tableStructureObj.put("field", "title,money");
|
tableStructureObj.put("index", "id,uuid");
|
tableStructureArray.add(tableStructureObj);
|
paramObj.put(CmnConst.PARAM_TABLE_REPORT, tableStructureArray.toJSONString());
|
|
// 功能建模
|
JSONObject functionObj = new JSONObject();
|
functionObj.put("c4abd684-0788-4a39-9422-3c24bc73d2bc", "1,2,3");
|
functionObj.put("d0edf393-db19-44b1-87aa-95d28751b0d8", "1,2");
|
tableStructureArray.add(functionObj);
|
paramObj.put(CmnConst.PARAM_FUNCTION, functionObj.toJSONString());
|
|
// 流程建模
|
JSONObject flowObj = new JSONObject();
|
flowObj.put("7c93182a-d091-4a07-b223-56b9bb9fcde8", "1,2,3");
|
tableStructureArray.add(functionObj);
|
paramObj.put(CmnConst.PARAM_FLOW, flowObj.toJSONString());
|
|
fse.setValue(CmnConst.DATA, paramObj);
|
extract(fse);
|
}
|
|
/**
|
* 获取表、视图、索引信息
|
* @return
|
*/
|
public JSONObject listTableInfo() {
|
String dataBaseName = baseDao.getDataBaseName();
|
JSONObject resultObj = new JSONObject();
|
|
StringBuilder sql = new StringBuilder(512);
|
sql.append("\nselect table_name");
|
sql.append("\nfrom information_schema.`TABLES`");
|
sql.append("\nwhere table_schema=?");
|
sql.append("\nand table_type='BASE TABLE'");
|
sql.append("\norder by table_name");
|
DataTableEntity dte = baseDao.listTable(sql.toString(), new Object[]{dataBaseName});
|
resultObj.put(CmnConst.PARAM_TABLE_REPORT, BaseUtil.dataTableEntityToJson(dte));
|
|
sql.setLength(0);
|
sql.append("\nselect *");
|
sql.append("\nfrom (");
|
sql.append("\n select table_name,1 table_type,1 operate_type,column_name name");
|
sql.append("\n from information_schema.`COLUMNS`");
|
sql.append("\n where table_schema=?");
|
sql.append("\n and table_name in (");
|
sql.append("\n select table_name");
|
sql.append("\n from information_schema.`TABLES`");
|
sql.append("\n where table_schema=?");
|
sql.append("\n and table_type='BASE TABLE'");
|
sql.append("\n )");
|
sql.append("\n union all");
|
sql.append("\n select table_name,1 table_type,2 operate_type,column_name name");
|
sql.append("\n from information_schema.`STATISTICS`");
|
sql.append("\n where table_schema=?");
|
sql.append("\n and table_name in (");
|
sql.append("\n select table_name");
|
sql.append("\n from information_schema.`TABLES`");
|
sql.append("\n where table_schema=?");
|
sql.append("\n and table_type='BASE TABLE'");
|
sql.append("\n )");
|
sql.append("\n union all");
|
sql.append("\n select table_name,2 table_type,null,null");
|
sql.append("\n from information_schema.`VIEWS`");
|
sql.append("\n where table_schema=?");
|
sql.append("\n order by table_name");
|
sql.append("\n) t");
|
sql.append("\norder by table_type,table_name,operate_type,name");
|
dte = baseDao.listTable(sql.toString(), new Object[]{dataBaseName, dataBaseName, dataBaseName, dataBaseName, dataBaseName});
|
resultObj.put(CmnConst.PARAM_TABLE_STRUCTURE, BaseUtil.dataTableEntityToJson(dte));
|
|
sql.setLength(0);
|
sql.append("\nselect uuid,tricode,function_name,t.*");
|
sql.append("\nfrom product_sys_functions f,(");
|
sql.append("\n select \"按钮\" type union all select \"页面\" union all select \"连线\"");
|
sql.append("\n) t");
|
sql.append("\nwhere data_type=1");
|
sql.append("\norder by tricode");
|
dte = baseDao.listTable(sql.toString(), new Object[]{});
|
resultObj.put(CmnConst.PARAM_FUNCTION, BaseUtil.dataTableEntityToJson(dte));
|
|
sql.setLength(0);
|
sql.append("\nselect uuid,title,t.*");
|
sql.append("\nfrom product_sys_flow_model f,(");
|
sql.append("\n select \"节点\" type union all select \"处理器\" union all select \"连线\"");
|
sql.append("\n) t");
|
sql.append("\nwhere length(type_code)>0");
|
sql.append("\norder by title");
|
dte = baseDao.listTable(sql.toString(), new Object[]{});
|
resultObj.put(CmnConst.PARAM_FLOW, BaseUtil.dataTableEntityToJson(dte));
|
|
return resultObj;
|
}
|
|
/**
|
* 补丁抽取
|
* @param fse
|
*/
|
public void extract(FieldSetEntity fse) {
|
String aimClientUUID = fse.getString(CmnConst.FIELD_CLIENT_UUID);
|
if (StringUtils.isEmpty(aimClientUUID)) {
|
throw new BaseException(ErrorCode.EXTRACT_NO_AIM_CLIENT_UUID);
|
}
|
JSONObject paramObj = JSON.parseObject(fse.getString(CmnConst.DATA));
|
JSONArray resultArray = new JSONArray();
|
// 表数据
|
resultArray.addAll(extractTableRecord(paramObj.getJSONObject(CmnConst.PARAM_TABLE_REPORT)));
|
// 表结构
|
resultArray.addAll(extractTableStructure(paramObj.getJSONArray(CmnConst.PARAM_TABLE_STRUCTURE)));
|
// 功能建模
|
resultArray.addAll(extractFunction(paramObj.getJSONArray(CmnConst.PARAM_FUNCTION)));
|
// 流程建模
|
resultArray.addAll(extractTableStructure(paramObj.getJSONArray(CmnConst.PARAM_FLOW)));
|
|
Date deployDate = fse.getDate(CmnConst.PARAM_DEPLOY_DATE);
|
String operator = fse.getString(CmnConst.PARAM_OPERATOR);
|
writeToFile(resultArray.toString(), deployDate, operator, aimClientUUID);
|
}
|
|
/**
|
* 表数据
|
* @param paramObj
|
*/
|
private JSONArray extractTableRecord(JSONObject paramObj) {
|
DataTableEntity dte;
|
JSONArray resultArray = new JSONArray();
|
for (Map.Entry<String, Object> entry : paramObj.entrySet()) {
|
dte = baseDao.listTable(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString(), new Object[]{});
|
resultArray.addAll(dte.toJson());
|
}
|
return resultArray;
|
}
|
|
/**
|
* 表结构
|
* @param paramArr
|
*/
|
private JSONArray extractTableStructure(JSONArray paramArr) {
|
JSONArray resultArray = new JSONArray();
|
JSONObject resultObj;
|
JSONObject tempObj;
|
for (Object obj : paramArr) {
|
tempObj = (JSONObject) obj;
|
if ("1".equals(tempObj.getString(CmnConst.TABLE_TYPE))) {
|
// 表
|
if ("1".equals(tempObj.getString(CmnConst.OPERATE_TYPE))) {
|
// 字段
|
resultObj = getTable(tempObj);
|
} else if ("2".equals(tempObj.getString(CmnConst.OPERATE_TYPE))) {
|
// 索引
|
resultObj = getIndex(tempObj);
|
} else {
|
throw new BaseException(ErrorCode.EXTRACT_INVALID_OPERATE_TYPE);
|
}
|
} else if ("2".equals(tempObj.getString(CmnConst.TABLE_TYPE))) {
|
// 视图
|
resultObj = getView(tempObj);
|
} else {
|
throw new BaseException(ErrorCode.EXTRACT_INVALID_TABLE_TYPE);
|
}
|
if (resultObj != null && !resultObj.isEmpty()) {
|
resultArray.add(resultObj);
|
}
|
}
|
return resultArray;
|
}
|
|
/**
|
* 表结构-字段
|
* @param jsonObject
|
* @return
|
*/
|
private JSONObject getTable(JSONObject jsonObject) {
|
String name = jsonObject.getString(CmnConst.NAME);
|
if (StringUtils.isEmpty(name)) {
|
return new JSONObject();
|
}
|
String[] nameArr = name.split(",");
|
String dataBaseName = baseDao.getDataBaseName();
|
List<String> paramList = Lists.newArrayList();
|
paramList.add(dataBaseName);
|
paramList.add(jsonObject.getString(CmnConst.TABLE_NAME));
|
paramList.addAll(Arrays.asList(nameArr));
|
String filter = String.format("%s=? and %s='%s' and %s=? and %s", CmnConst.DATABASE_COLUMN, CmnConst.TABLE_TYPE_COLUMN, CmnConst.TABLE_TYPE_TABLE, CmnConst.TABLE_NAME, BaseUtil.buildQuestionMarkFilter(CmnConst.COLUMNS_NAME_COLUMN, nameArr.length, true));
|
String tableName = String.format("%s.`%s`", CmnConst.DATABASE, CmnConst.TABLE);
|
FieldSetEntity fse = baseDao.getFieldSetByFilter(tableName, filter, paramList.toArray(), false);
|
return BaseUtil.fieldSetEntityToJson(fse);
|
}
|
|
/**
|
* 表结构-索引
|
* @param jsonObject
|
* @return
|
*/
|
private JSONObject getIndex(JSONObject jsonObject) {
|
String name = jsonObject.getString(CmnConst.NAME);
|
if (StringUtils.isEmpty(name)) {
|
return new JSONObject();
|
}
|
String[] nameArr = name.split(",");
|
String dataBaseName = baseDao.getDataBaseName();
|
List<String> paramList = Lists.newArrayList();
|
paramList.add(dataBaseName);
|
paramList.add(jsonObject.getString(CmnConst.TABLE_NAME));
|
paramList.addAll(Arrays.asList(nameArr));
|
String filter = String.format("%s=? and %s=? and %s=?", CmnConst.DATABASE_COLUMN, CmnConst.TABLE_NAME, BaseUtil.buildQuestionMarkFilter(CmnConst.INDEX_NAME_COLUMN, nameArr.length, true));
|
String tableName = String.format("%s.`%s`", CmnConst.DATABASE, CmnConst.INDEX);
|
FieldSetEntity fse = baseDao.getFieldSetByFilter(tableName, filter, paramList.toArray(), false);
|
return BaseUtil.fieldSetEntityToJson(fse);
|
}
|
|
/**
|
* 表结构-视图
|
* @param jsonObject
|
* @return
|
*/
|
private JSONObject getView(JSONObject jsonObject) {
|
String name = jsonObject.getString(CmnConst.NAME);
|
if (StringUtils.isEmpty(name)) {
|
return new JSONObject();
|
}
|
String[] nameArr = name.split(",");
|
String dataBaseName = baseDao.getDataBaseName();
|
List<String> paramList = Lists.newArrayList();
|
paramList.add(dataBaseName);
|
paramList.add(jsonObject.getString(CmnConst.TABLE_NAME));
|
paramList.addAll(Arrays.asList(nameArr));
|
String filter = String.format("%s=? and %s=? and %s=?", CmnConst.DATABASE_COLUMN, CmnConst.TABLE_NAME, BaseUtil.buildQuestionMarkFilter(CmnConst.INDEX_NAME_COLUMN, nameArr.length, true));
|
String tableName = String.format("%s.`%s`", CmnConst.DATABASE, CmnConst.VIEWS);
|
FieldSetEntity fse = baseDao.getFieldSetByFilter(tableName, filter, paramList.toArray(), false);
|
return BaseUtil.fieldSetEntityToJson(fse);
|
}
|
|
/**
|
* 功能建模
|
* @param paramArr
|
* @return
|
*/
|
private JSONArray extractFunction(JSONArray paramArr) {
|
JSONArray resultArray = new JSONArray();
|
JSONObject paramObj;
|
for (int i = 0;i < paramArr.size();i++) {
|
paramObj = paramArr.getJSONObject(i);
|
// todo
|
// resultArray.add();
|
}
|
return resultArray;
|
}
|
|
/**
|
* 补丁输出到文件
|
* @param patchContent
|
* @param deployDate
|
* @param operator
|
* @param clientUUID
|
*/
|
private void writeToFile(String patchContent, Date deployDate, String operator, String clientUUID) {
|
deployDate = deployDate == null ? new Date() : deployDate;
|
operator = StringUtils.isEmpty(operator) ? "admin" : operator;
|
String patchDir = Global.getSystemConfig("patch.extract.dir","");
|
File dir = new File(patchDir);
|
dir.mkdirs();
|
String deployDateStr = new SimpleDateFormat(CmnConst.DATE_FORMAT_1).format(deployDate);
|
String fileName = patchDir + File.separator + deployDateStr + "-" + operator + ".patch";
|
File file = new File(fileName);
|
boolean appendFlag = false;
|
if (file.exists()) {
|
appendFlag = true;
|
} else {
|
try {
|
file.createNewFile();
|
} catch (Exception e) {
|
throw new BaseException(ErrorCode.EXTRACT_CREATE_FILE_FAIL);
|
}
|
}
|
StringBuilder content = new StringBuilder(1024);
|
content.append(deployDateStr).append("-").append(operator).append(";\n")
|
.append(patchContent);
|
String encodedData = content.toString();
|
|
// 加密
|
FieldSetEntity mainFse = baseDao.getFieldSetEntityByFilter(CmnConst.TABLE_PRODUCT_SYS_ORG_LEVELS, "org_level_id=1", new Object[]{}, false);
|
FieldSetEntity mainCryptFse = baseDao.getFieldSetEntityByFilter(CmnConst.TABLE_PRODUCT_SYS_PATCH_KEY, "org_level_uuid=?", new Object[]{mainFse.getUUID()}, false);
|
String mainPrivateKey = mainCryptFse.getString(CmnConst.FIELD_PIRVATE_KEY);
|
FieldSetEntity clientCryptFse = baseDao.getFieldSetEntityByFilter(CmnConst.TABLE_PRODUCT_SYS_PATCH_KEY, "org_level_uuid=?", new Object[]{clientUUID}, false);
|
String clientPublicKey = clientCryptFse.getString(CmnConst.FIELD_PUBLIC_KEY);
|
try {
|
encodedData = RSAUtil.privateEncrypt(encodedData, RSAUtil.getPrivateKey(mainPrivateKey));
|
encodedData = RSAUtil.publicEncrypt(encodedData, RSAUtil.getPublicKey(clientPublicKey));
|
} catch (Exception e) {
|
e.printStackTrace();
|
throw new BaseException(ErrorCode.EXTRACT_ENCODE_FAIL);
|
}
|
|
FileUtils.writeToFile(fileName, encodedData, "utf-8", appendFlag);
|
}
|
}
|