package com.persagy.proxy.migration.handler; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.persagy.dmp.basic.model.QueryCriteria; import com.persagy.dmp.basic.utils.JsonNodeUtils; import com.persagy.dmp.common.constant.ResponseCode; import com.persagy.dmp.common.model.entity.BaseEntity; import com.persagy.dmp.digital.client.DigitalRelationFacade; import com.persagy.dmp.digital.entity.ObjectRelation; import com.persagy.dmp.rwd.migrate.entity.SyncData; import com.persagy.proxy.adm.request.AdmResponse; import com.persagy.proxy.common.entity.InstanceUrlParam; import com.persagy.proxy.migration.constant.MiGrationRelCode; import com.persagy.proxy.migration.constant.MigrationConstant; import com.persagy.proxy.migration.constant.MigrationTable; import com.persagy.proxy.migration.constant.MigrationType; import com.persagy.proxy.migration.model.DataMigrationExcel; import com.persagy.proxy.migration.model.DataMigrationResponse; import com.persagy.proxy.migration.model.MigrationInfo; import com.persagy.proxy.migration.service.Impl.MigrationAbstractServiceImpl; import lombok.extern.slf4j.Slf4j; import java.util.*; import java.util.stream.Collectors; /** * @author lvxianyun * @title: RelationMigration * @projectName adm-middleware * @description: 迁移adm交付的数据到现场,覆盖现场数据,提供增加、删除、修改 记录放入excel; dt_relation 数据迁移 adm -> target project * @date 2021/12/8 19:51 */ @Slf4j public class ObjectRelationMigration extends MigrationAbstractServiceImpl implements IDataMigration, IDataMigrationProcess { private static ObjectRelationMigration instance; private ObjectRelationMigration() {} // 静态方法返回该实例 public static ObjectRelationMigration getInstance() { if(instance == null) { synchronized (ObjectRelationMigration.class) { if (instance == null) { instance = new ObjectRelationMigration(); } } } return instance; } /** * 数据迁移 * * @param context * @param migrationInfo * @return */ @Override public List migrateForExcel(InstanceUrlParam context, MigrationInfo migrationInfo) { log.info("######################### dt_relation 数据迁移内容获取开始 #########################"); long start = System.currentTimeMillis(); List dataMigrationExcels = new ArrayList<>(); for (MiGrationRelCode miGrationRelCode: MiGrationRelCode.values()){ log.info("######################### dt_relation "+miGrationRelCode.getCode()+"数据迁移内容获取开始 #########################"); QueryCriteria queryCriteria = getQueryCriteria(miGrationRelCode.getCode()); dataMigrationExcels.addAll(startMigrateForExcel(context, migrationInfo, queryCriteria)); log.info("######################### dt_relation "+miGrationRelCode.getCode()+"数据迁移内容获取结束 #########################"); } long end = System.currentTimeMillis(); log.info("######################### dt_relation 数据迁移内容获取结束 "+(end-start)+"#########################"); return dataMigrationExcels; } @Override public AdmResponse migrateForLog(InstanceUrlParam context, MigrationInfo migrationInfo) { log.info("######################### dt_relation 同步开始 #########################"); long start = System.currentTimeMillis(); for (MiGrationRelCode miGrationRelCode: MiGrationRelCode.values()){ log.info("######################### dt_relation "+miGrationRelCode.getCode()+"同步开始 #########################"); QueryCriteria queryCriteria = getQueryCriteria(miGrationRelCode.getCode()); List syncDataList = startMigrateForLog(context, migrationInfo, queryCriteria); log.info("######################### dt_relation "+miGrationRelCode.getCode()+"同步结束 共计:"+syncDataList.size()+"条 #########################"); } long end = System.currentTimeMillis(); log.info("######################### dt_relation 同步结束 "+(end-start)+"#########################"); return AdmResponse.success(); } private QueryCriteria getQueryCriteria(String typeCode){ QueryCriteria queryCriteria = new QueryCriteria(); ObjectNode criteria = JsonNodeFactory.instance.objectNode(); criteria.put("valid", 1); criteria.put("relCode", typeCode); return queryCriteria; } private List startMigrateForExcel(InstanceUrlParam context, MigrationInfo migrationInfo, QueryCriteria queryCriteria){ List dataMigrationExcels = new ArrayList<>(); List admRelations = getAdmData(context, queryCriteria); String queryUrl = requestUrl(context, migrationInfo, MigrationType.QUERY.getCode()); List projectRelations = getProjectData(queryCriteria, ObjectRelation.class, queryUrl); if(CollUtil.isEmpty(admRelations)){ log.error(" ######################### dt_relation adm已交付:"+ ResponseCode.C0320.getDesc() +" 数据迁移内容获取结束 #########################"); return dataMigrationExcels; } //String insertUrl = requestUrl(context, migrationInfo, MigrationType.INSERT.getCode()); if(CollUtil.isEmpty(projectRelations)){ //DataMigrationResponse dataMigrationResponse = insertBatch(admRelations, ObjectRelation.class, insertUrl); dataMigrationExcels.addAll(processDataForExcel(admRelations, MigrationType.CREATE.getCode())); return dataMigrationExcels; } List objectNodeListPro = JsonNodeUtils.toListNode(projectRelations, null, null); Map projectDefineMap = toEntityMap(objectNodeListPro, ObjectRelation.class); List objectNodeListAdm = JsonNodeUtils.toListNode(admRelations, null, null); Map admDefineMap = toEntityMap(objectNodeListAdm, ObjectRelation.class); //差集 新增 Map doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(doSubtractFromInsert)){ List insertData = toList(doSubtractFromInsert, admRelations); //DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl); dataMigrationExcels.addAll(processDataForExcel(insertData, MigrationType.CREATE.getCode())); } //差集 删除 Map doSubtractFromDelete = doSubtractDel(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(doSubtractFromDelete)){ List deleteIds = doSubtractFromDelete.entrySet().stream().map(en -> en.getKey()).collect(Collectors.toList()); List deleteData = toListByIds(deleteIds, projectRelations); // String delUrl = requestUrl(context, migrationInfo, MigrationType.DELETE.getCode()); // DataMigrationResponse dataMigrationResponse = deleteBatch(deleteIds, ObjectRelation.class, delUrl); dataMigrationExcels.addAll(processDataForExcel(deleteData, MigrationType.DELETE.getCode())); } //交集更新 Map intersectionUpdateFrom = doIntersectionGetFrom(admDefineMap, projectDefineMap); Map intersectionUpdateTo = doIntersectionGetTo(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(intersectionUpdateFrom) && !CollUtil.isEmpty(intersectionUpdateTo)){ Map compareData = compareData(intersectionUpdateFrom, intersectionUpdateTo); if(CollUtil.isNotEmpty(compareData) && compareData.size() > 0){ List updateData = toList(compareData, admRelations); //String updateUrl = requestUrl(context, migrationInfo, MigrationType.UPDATE.getCode()); //DataMigrationResponse dataMigrationResponse = updateBatch(updateData, ObjectRelation.class, updateUrl); dataMigrationExcels.addAll(processDataForExcel(updateData, MigrationType.UPDATE.getCode())); } } return dataMigrationExcels; } private List startMigrateForLog(InstanceUrlParam context, MigrationInfo migrationInfo, QueryCriteria queryCriteria){ List syncDataList = new ArrayList<>(); List admRelations = getAdmData(context, queryCriteria); String queryUrl = requestUrl(context, migrationInfo, MigrationType.QUERY.getCode()); List projectRelations = getProjectData(queryCriteria, ObjectRelation.class, queryUrl); if(CollUtil.isEmpty(admRelations)){ log.error(" ######################### dt_relation adm已交付:"+ ResponseCode.C0320.getDesc() +" 同步结束 #########################"); } String insertUrl = requestUrl(context, migrationInfo, MigrationType.CREATE.getCode()); if(CollUtil.isEmpty(projectRelations)){ DataMigrationResponse dataMigrationResponse = insertBatch(admRelations, ObjectRelation.class, insertUrl); syncDataList = processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode()); } List objectNodeListPro = JsonNodeUtils.toListNode(projectRelations, null, null); Map projectDefineMap = toEntityMap(objectNodeListPro, ObjectRelation.class); List objectNodeListAdm = JsonNodeUtils.toListNode(admRelations, null, null); Map admDefineMap = toEntityMap(objectNodeListAdm, ObjectRelation.class); //差集 新增 Map doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(doSubtractFromInsert)){ List insertData = toList(doSubtractFromInsert, admRelations); DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl); syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode())); } //差集 删除 Map doSubtractFromDelete = doSubtractDel(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(doSubtractFromDelete)){ List deleteIds = doSubtractFromDelete.entrySet().stream().map(en -> en.getKey()).collect(Collectors.toList()); String delUrl = requestUrl(context, migrationInfo, MigrationType.DELETE.getCode()); //处理删除的数据 DataMigrationResponse dataMigrationResponse = deleteBatch(deleteIds, ObjectRelation.class, delUrl); List successIds = (List) dataMigrationResponse.getData(); List delObjs = toListByIds(successIds, projectRelations); dataMigrationResponse.setData(delObjs); syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.DELETE.getCode())); } //交集更新 Map intersectionUpdateFrom = doIntersectionGetFrom(admDefineMap, projectDefineMap); Map intersectionUpdateTo = doIntersectionGetTo(admDefineMap, projectDefineMap); if(!CollUtil.isEmpty(intersectionUpdateFrom) && !CollUtil.isEmpty(intersectionUpdateTo)){ Map compareData = compareData(intersectionUpdateFrom, intersectionUpdateTo); if(CollUtil.isNotEmpty(compareData) && compareData.size() > 0){ List updateData = toList(compareData, admRelations); String updateUrl = requestUrl(context, migrationInfo, MigrationType.UPDATE.getCode()); DataMigrationResponse dataMigrationResponse = updateBatch(updateData, ObjectRelation.class, updateUrl); syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.UPDATE.getCode())); } } return super.addSynLog(context, syncDataList); } /** * 获取adm交付的数据,默认获取有效数据 * * @param context * @return */ @Override public List getAdmData(InstanceUrlParam context, QueryCriteria queryCriteria) { List relations = DigitalRelationFacade.query(context.getGroupCode(),context.getProjectId(),context.getUserId(),context.getUserId(),queryCriteria); return relations; } /** * 根据map转为需要处理的对象集合 * 使用 MigrationConstant.spliter 作为拼接符 * @param fromMap * @param fromList * @return */ public List toList(Map fromMap, List fromList) { if(CollUtil.isEmpty(fromMap) || CollUtil.isEmpty(fromList)){ return Collections.emptyList(); } return toListByIds(fromMap.keySet(), fromList); } public List toListByIds(Collection ids, List fromList) { if(CollUtil.isEmpty(ids) || CollUtil.isEmpty(fromList)){ return Collections.emptyList(); } List results = new ArrayList<>(ids.size()); Map objectRelationMap = CollUtil.fieldValueMap(fromList, BaseEntity.PROP_ID); for(String key : ids){ results.add(objectRelationMap.get(key)); } return results; } /** * 拼接访问链接 * * @param context * @param migrationInfo * @param type * @return */ @Override public String requestUrl(InstanceUrlParam context, MigrationInfo migrationInfo, String type) { if(StrUtil.isBlank(migrationInfo.getTargetUrl())){ return null; } StringBuilder url = new StringBuilder(migrationInfo.getTargetUrl()); if(type.equals(MigrationType.QUERY.getCode())) { url.append(MigrationConstant.DT_RELATION); }else if(type.equals(MigrationType.CREATE.getCode())){ url.append(MigrationConstant.DT_RELATION_INSERT); }else if(type.equals(MigrationType.UPDATE.getCode())){ url.append(MigrationConstant.DT_RELATION_UPDATE); }else{ url.append(MigrationConstant.DT_RELATION_DELETE); } return commonUrl(context, url.toString(), migrationInfo); } /** * 将目标集合处理成excel格式的集合 使用与insert/delete * * @param list * @return */ @Override public List processDataForExcel(Collection list, String type) { if(CollUtil.isEmpty(list)){ return Collections.emptyList(); } List dataMigrationExcels = new ArrayList<>(); for(Object obj : list){ if(obj == null){ continue; } ObjectRelation objectRelation = (ObjectRelation) obj; DataMigrationExcel excel = new DataMigrationExcel(); excel.setId(objectRelation.getId()); excel.setName(String.join(StrUtil.DASHED, objectRelation.getRelCode(), objectRelation.getGraphCode())); excel.setObjFrom(objectRelation.getObjFrom()); excel.setTargetProject(objectRelation.getObjTo()); excel.setType(type); dataMigrationExcels.add(excel); } return dataMigrationExcels; } /** * 将目标集合处理成SyncData(日志)格式的集合 入库 * * @param dataMigrationResponse * @param type insert/delete * @return */ @Override public List processDataForLog(DataMigrationResponse dataMigrationResponse, String type) { if(CollUtil.isEmpty(dataMigrationResponse.getData()) && CollUtil.isEmpty(dataMigrationResponse.getErrorMsg())){ return Collections.emptyList(); } List syncDataList = new ArrayList<>(); if(CollUtil.isNotEmpty(dataMigrationResponse.getData())){ for(Object obj : dataMigrationResponse.getData()){ ObjectRelation relation = (ObjectRelation) obj; SyncData syncData = new SyncData(); syncData.setTableName(MigrationTable.DTRELATION.getCode()); syncData.setType(type);//操作 syncData.setTargetId(relation.getId()); syncData.setName(String.join(StrUtil.DASHED, relation.getRelCode(), relation.getGraphCode())); syncData.setFromId(relation.getObjFrom()); syncData.setToId(relation.getObjTo()); syncDataList.add(syncData); } } if(CollUtil.isNotEmpty(dataMigrationResponse.getErrorMsg())){ syncDataList.addAll(addErrorInfoForLog(dataMigrationResponse.getErrorMsg(),MigrationTable.DTRELATION.getCode())); } return syncDataList; } }