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);
}
}