ObjectRelationMigration.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. package com.persagy.proxy.migration.handler;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.fasterxml.jackson.databind.node.JsonNodeFactory;
  5. import com.fasterxml.jackson.databind.node.ObjectNode;
  6. import com.persagy.dmp.basic.model.QueryCriteria;
  7. import com.persagy.dmp.basic.utils.JsonNodeUtils;
  8. import com.persagy.dmp.common.constant.ResponseCode;
  9. import com.persagy.dmp.common.model.entity.BaseEntity;
  10. import com.persagy.dmp.digital.client.DigitalRelationFacade;
  11. import com.persagy.dmp.digital.entity.ObjectRelation;
  12. import com.persagy.dmp.rwd.migrate.entity.SyncData;
  13. import com.persagy.proxy.adm.request.AdmResponse;
  14. import com.persagy.proxy.common.entity.InstanceUrlParam;
  15. import com.persagy.proxy.migration.constant.MiGrationRelCode;
  16. import com.persagy.proxy.migration.constant.MigrationConstant;
  17. import com.persagy.proxy.migration.constant.MigrationTable;
  18. import com.persagy.proxy.migration.constant.MigrationType;
  19. import com.persagy.proxy.migration.model.DataMigrationExcel;
  20. import com.persagy.proxy.migration.model.DataMigrationResponse;
  21. import com.persagy.proxy.migration.model.MigrationInfo;
  22. import com.persagy.proxy.migration.service.Impl.MigrationAbstractServiceImpl;
  23. import lombok.extern.slf4j.Slf4j;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. /**
  27. * @author lvxianyun
  28. * @title: RelationMigration
  29. * @projectName adm-middleware
  30. * @description: 迁移adm交付的数据到现场,覆盖现场数据,提供增加、删除、修改 记录放入excel; dt_relation 数据迁移 adm -> target project
  31. * @date 2021/12/8 19:51
  32. */
  33. @Slf4j
  34. public class ObjectRelationMigration extends MigrationAbstractServiceImpl<ObjectRelation> implements IDataMigration, IDataMigrationProcess<ObjectRelation> {
  35. private static ObjectRelationMigration instance;
  36. private ObjectRelationMigration() {}
  37. // 静态方法返回该实例
  38. public static ObjectRelationMigration getInstance() {
  39. if(instance == null) {
  40. synchronized (ObjectRelationMigration.class) {
  41. if (instance == null) {
  42. instance = new ObjectRelationMigration();
  43. }
  44. }
  45. }
  46. return instance;
  47. }
  48. /**
  49. * 数据迁移
  50. *
  51. * @param context
  52. * @param migrationInfo
  53. * @return
  54. */
  55. @Override
  56. public List<DataMigrationExcel> migrateForExcel(InstanceUrlParam context, MigrationInfo migrationInfo) {
  57. log.info("######################### dt_relation 数据迁移内容获取开始 #########################");
  58. long start = System.currentTimeMillis();
  59. List<DataMigrationExcel> dataMigrationExcels = new ArrayList<>();
  60. for (MiGrationRelCode miGrationRelCode: MiGrationRelCode.values()){
  61. log.info("######################### dt_relation "+miGrationRelCode.getCode()+"数据迁移内容获取开始 #########################");
  62. QueryCriteria queryCriteria = getQueryCriteria(miGrationRelCode.getCode());
  63. dataMigrationExcels.addAll(startMigrateForExcel(context, migrationInfo, queryCriteria));
  64. log.info("######################### dt_relation "+miGrationRelCode.getCode()+"数据迁移内容获取结束 #########################");
  65. }
  66. long end = System.currentTimeMillis();
  67. log.info("######################### dt_relation 数据迁移内容获取结束 "+(end-start)+"#########################");
  68. return dataMigrationExcels;
  69. }
  70. @Override
  71. public AdmResponse migrateForLog(InstanceUrlParam context, MigrationInfo migrationInfo) {
  72. log.info("######################### dt_relation 同步开始 #########################");
  73. long start = System.currentTimeMillis();
  74. for (MiGrationRelCode miGrationRelCode: MiGrationRelCode.values()){
  75. log.info("######################### dt_relation "+miGrationRelCode.getCode()+"同步开始 #########################");
  76. QueryCriteria queryCriteria = getQueryCriteria(miGrationRelCode.getCode());
  77. List<SyncData> syncDataList = startMigrateForLog(context, migrationInfo, queryCriteria);
  78. log.info("######################### dt_relation "+miGrationRelCode.getCode()+"同步结束 共计:"+syncDataList.size()+"条 #########################");
  79. }
  80. long end = System.currentTimeMillis();
  81. log.info("######################### dt_relation 同步结束 "+(end-start)+"#########################");
  82. return AdmResponse.success();
  83. }
  84. private QueryCriteria getQueryCriteria(String typeCode){
  85. QueryCriteria queryCriteria = new QueryCriteria();
  86. ObjectNode criteria = JsonNodeFactory.instance.objectNode();
  87. criteria.put("valid", 1);
  88. criteria.put("relCode", typeCode);
  89. return queryCriteria;
  90. }
  91. private List<DataMigrationExcel> startMigrateForExcel(InstanceUrlParam context, MigrationInfo migrationInfo, QueryCriteria queryCriteria){
  92. List<DataMigrationExcel> dataMigrationExcels = new ArrayList<>();
  93. List<ObjectRelation> admRelations = getAdmData(context, queryCriteria);
  94. String queryUrl = requestUrl(context, migrationInfo, MigrationType.QUERY.getCode());
  95. List<ObjectRelation> projectRelations = getProjectData(queryCriteria, ObjectRelation.class, queryUrl);
  96. if(CollUtil.isEmpty(admRelations)){
  97. log.error(" ######################### dt_relation adm已交付:"+ ResponseCode.C0320.getDesc() +" 数据迁移内容获取结束 #########################");
  98. return dataMigrationExcels;
  99. }
  100. //String insertUrl = requestUrl(context, migrationInfo, MigrationType.INSERT.getCode());
  101. if(CollUtil.isEmpty(projectRelations)){
  102. //DataMigrationResponse dataMigrationResponse = insertBatch(admRelations, ObjectRelation.class, insertUrl);
  103. dataMigrationExcels.addAll(processDataForExcel(admRelations, MigrationType.CREATE.getCode()));
  104. return dataMigrationExcels;
  105. }
  106. List<ObjectNode> objectNodeListPro = JsonNodeUtils.toListNode(projectRelations, null, null);
  107. Map<String,Object> projectDefineMap = toEntityMap(objectNodeListPro, ObjectRelation.class);
  108. List<ObjectNode> objectNodeListAdm = JsonNodeUtils.toListNode(admRelations, null, null);
  109. Map<String,Object> admDefineMap = toEntityMap(objectNodeListAdm, ObjectRelation.class);
  110. //差集 新增
  111. Map<String,Object> doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap);
  112. if(!CollUtil.isEmpty(doSubtractFromInsert)){
  113. List<ObjectRelation> insertData = toList(doSubtractFromInsert, admRelations);
  114. //DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl);
  115. dataMigrationExcels.addAll(processDataForExcel(insertData, MigrationType.CREATE.getCode()));
  116. }
  117. //差集 删除
  118. Map<String,Object> doSubtractFromDelete = doSubtractDel(admDefineMap, projectDefineMap);
  119. if(!CollUtil.isEmpty(doSubtractFromDelete)){
  120. List<String> deleteIds = doSubtractFromDelete.entrySet().stream().map(en -> en.getKey()).collect(Collectors.toList());
  121. List<ObjectRelation> deleteData = toListByIds(deleteIds, projectRelations);
  122. // String delUrl = requestUrl(context, migrationInfo, MigrationType.DELETE.getCode());
  123. // DataMigrationResponse dataMigrationResponse = deleteBatch(deleteIds, ObjectRelation.class, delUrl);
  124. dataMigrationExcels.addAll(processDataForExcel(deleteData, MigrationType.DELETE.getCode()));
  125. }
  126. //交集更新
  127. Map<String,Object> intersectionUpdateFrom = doIntersectionGetFrom(admDefineMap, projectDefineMap);
  128. Map<String,Object> intersectionUpdateTo = doIntersectionGetTo(admDefineMap, projectDefineMap);
  129. if(!CollUtil.isEmpty(intersectionUpdateFrom) && !CollUtil.isEmpty(intersectionUpdateTo)){
  130. Map<String, Object> compareData = compareData(intersectionUpdateFrom, intersectionUpdateTo);
  131. if(CollUtil.isNotEmpty(compareData) && compareData.size() > 0){
  132. List<ObjectRelation> updateData = toList(compareData, admRelations);
  133. //String updateUrl = requestUrl(context, migrationInfo, MigrationType.UPDATE.getCode());
  134. //DataMigrationResponse dataMigrationResponse = updateBatch(updateData, ObjectRelation.class, updateUrl);
  135. dataMigrationExcels.addAll(processDataForExcel(updateData, MigrationType.UPDATE.getCode()));
  136. }
  137. }
  138. return dataMigrationExcels;
  139. }
  140. private List<SyncData> startMigrateForLog(InstanceUrlParam context, MigrationInfo migrationInfo, QueryCriteria queryCriteria){
  141. List<SyncData> syncDataList = new ArrayList<>();
  142. List<ObjectRelation> admRelations = getAdmData(context, queryCriteria);
  143. String queryUrl = requestUrl(context, migrationInfo, MigrationType.QUERY.getCode());
  144. List<ObjectRelation> projectRelations = getProjectData(queryCriteria, ObjectRelation.class, queryUrl);
  145. if(CollUtil.isEmpty(admRelations)){
  146. log.error(" ######################### dt_relation adm已交付:"+ ResponseCode.C0320.getDesc() +" 同步结束 #########################");
  147. }
  148. String insertUrl = requestUrl(context, migrationInfo, MigrationType.CREATE.getCode());
  149. if(CollUtil.isEmpty(projectRelations)){
  150. DataMigrationResponse dataMigrationResponse = insertBatch(admRelations, ObjectRelation.class, insertUrl);
  151. syncDataList = processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode());
  152. }
  153. List<ObjectNode> objectNodeListPro = JsonNodeUtils.toListNode(projectRelations, null, null);
  154. Map<String,Object> projectDefineMap = toEntityMap(objectNodeListPro, ObjectRelation.class);
  155. List<ObjectNode> objectNodeListAdm = JsonNodeUtils.toListNode(admRelations, null, null);
  156. Map<String,Object> admDefineMap = toEntityMap(objectNodeListAdm, ObjectRelation.class);
  157. //差集 新增
  158. Map<String,Object> doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap);
  159. if(!CollUtil.isEmpty(doSubtractFromInsert)){
  160. List<ObjectRelation> insertData = toList(doSubtractFromInsert, admRelations);
  161. DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl);
  162. syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode()));
  163. }
  164. //差集 删除
  165. Map<String,Object> doSubtractFromDelete = doSubtractDel(admDefineMap, projectDefineMap);
  166. if(!CollUtil.isEmpty(doSubtractFromDelete)){
  167. List<String> deleteIds = doSubtractFromDelete.entrySet().stream().map(en -> en.getKey()).collect(Collectors.toList());
  168. String delUrl = requestUrl(context, migrationInfo, MigrationType.DELETE.getCode());
  169. //处理删除的数据
  170. DataMigrationResponse dataMigrationResponse = deleteBatch(deleteIds, ObjectRelation.class, delUrl);
  171. List<String> successIds = (List<String>) dataMigrationResponse.getData();
  172. List<ObjectRelation> delObjs = toListByIds(successIds, projectRelations);
  173. dataMigrationResponse.setData(delObjs);
  174. syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.DELETE.getCode()));
  175. }
  176. //交集更新
  177. Map<String,Object> intersectionUpdateFrom = doIntersectionGetFrom(admDefineMap, projectDefineMap);
  178. Map<String,Object> intersectionUpdateTo = doIntersectionGetTo(admDefineMap, projectDefineMap);
  179. if(!CollUtil.isEmpty(intersectionUpdateFrom) && !CollUtil.isEmpty(intersectionUpdateTo)){
  180. Map<String, Object> compareData = compareData(intersectionUpdateFrom, intersectionUpdateTo);
  181. if(CollUtil.isNotEmpty(compareData) && compareData.size() > 0){
  182. List<ObjectRelation> updateData = toList(compareData, admRelations);
  183. String updateUrl = requestUrl(context, migrationInfo, MigrationType.UPDATE.getCode());
  184. DataMigrationResponse dataMigrationResponse = updateBatch(updateData, ObjectRelation.class, updateUrl);
  185. syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.UPDATE.getCode()));
  186. }
  187. }
  188. return super.addSynLog(context, syncDataList);
  189. }
  190. /**
  191. * 获取adm交付的数据,默认获取有效数据
  192. *
  193. * @param context
  194. * @return
  195. */
  196. @Override
  197. public List<ObjectRelation> getAdmData(InstanceUrlParam context, QueryCriteria queryCriteria) {
  198. List<ObjectRelation> relations = DigitalRelationFacade.query(context.getGroupCode(),context.getProjectId(),context.getUserId(),context.getUserId(),queryCriteria);
  199. return relations;
  200. }
  201. /**
  202. * 根据map转为需要处理的对象集合
  203. * 使用 MigrationConstant.spliter 作为拼接符
  204. * @param fromMap
  205. * @param fromList
  206. * @return
  207. */
  208. public List<ObjectRelation> toList(Map<String, Object> fromMap, List<ObjectRelation> fromList) {
  209. if(CollUtil.isEmpty(fromMap) || CollUtil.isEmpty(fromList)){
  210. return Collections.emptyList();
  211. }
  212. return toListByIds(fromMap.keySet(), fromList);
  213. }
  214. public List<ObjectRelation> toListByIds(Collection<String> ids, List<ObjectRelation> fromList) {
  215. if(CollUtil.isEmpty(ids) || CollUtil.isEmpty(fromList)){
  216. return Collections.emptyList();
  217. }
  218. List<ObjectRelation> results = new ArrayList<>(ids.size());
  219. Map<String, ObjectRelation> objectRelationMap = CollUtil.fieldValueMap(fromList, BaseEntity.PROP_ID);
  220. for(String key : ids){
  221. results.add(objectRelationMap.get(key));
  222. }
  223. return results;
  224. }
  225. /**
  226. * 拼接访问链接
  227. *
  228. * @param context
  229. * @param migrationInfo
  230. * @param type
  231. * @return
  232. */
  233. @Override
  234. public String requestUrl(InstanceUrlParam context, MigrationInfo migrationInfo, String type) {
  235. if(StrUtil.isBlank(migrationInfo.getTargetUrl())){
  236. return null;
  237. }
  238. StringBuilder url = new StringBuilder(migrationInfo.getTargetUrl());
  239. if(type.equals(MigrationType.QUERY.getCode())) {
  240. url.append(MigrationConstant.DT_RELATION);
  241. }else if(type.equals(MigrationType.CREATE.getCode())){
  242. url.append(MigrationConstant.DT_RELATION_INSERT);
  243. }else if(type.equals(MigrationType.UPDATE.getCode())){
  244. url.append(MigrationConstant.DT_RELATION_UPDATE);
  245. }else{
  246. url.append(MigrationConstant.DT_RELATION_DELETE);
  247. }
  248. return commonUrl(context, url.toString(), migrationInfo);
  249. }
  250. /**
  251. * 将目标集合处理成excel格式的集合 使用与insert/delete
  252. *
  253. * @param list
  254. * @return
  255. */
  256. @Override
  257. public List<DataMigrationExcel> processDataForExcel(Collection list, String type) {
  258. if(CollUtil.isEmpty(list)){
  259. return Collections.emptyList();
  260. }
  261. List<DataMigrationExcel> dataMigrationExcels = new ArrayList<>();
  262. for(Object obj : list){
  263. if(obj == null){
  264. continue;
  265. }
  266. ObjectRelation objectRelation = (ObjectRelation) obj;
  267. DataMigrationExcel excel = new DataMigrationExcel();
  268. excel.setId(objectRelation.getId());
  269. excel.setName(String.join(StrUtil.DASHED, objectRelation.getRelCode(), objectRelation.getGraphCode()));
  270. excel.setObjFrom(objectRelation.getObjFrom());
  271. excel.setTargetProject(objectRelation.getObjTo());
  272. excel.setType(type);
  273. dataMigrationExcels.add(excel);
  274. }
  275. return dataMigrationExcels;
  276. }
  277. /**
  278. * 将目标集合处理成SyncData(日志)格式的集合 入库
  279. *
  280. * @param dataMigrationResponse
  281. * @param type insert/delete
  282. * @return
  283. */
  284. @Override
  285. public List<SyncData> processDataForLog(DataMigrationResponse dataMigrationResponse, String type) {
  286. if(CollUtil.isEmpty(dataMigrationResponse.getData()) && CollUtil.isEmpty(dataMigrationResponse.getErrorMsg())){
  287. return Collections.emptyList();
  288. }
  289. List<SyncData> syncDataList = new ArrayList<>();
  290. if(CollUtil.isNotEmpty(dataMigrationResponse.getData())){
  291. for(Object obj : dataMigrationResponse.getData()){
  292. ObjectRelation relation = (ObjectRelation) obj;
  293. SyncData syncData = new SyncData();
  294. syncData.setTableName(MigrationTable.DTRELATION.getCode());
  295. syncData.setType(type);//操作
  296. syncData.setTargetId(relation.getId());
  297. syncData.setName(String.join(StrUtil.DASHED, relation.getRelCode(), relation.getGraphCode()));
  298. syncData.setFromId(relation.getObjFrom());
  299. syncData.setToId(relation.getObjTo());
  300. syncDataList.add(syncData);
  301. }
  302. }
  303. if(CollUtil.isNotEmpty(dataMigrationResponse.getErrorMsg())){
  304. syncDataList.addAll(addErrorInfoForLog(dataMigrationResponse.getErrorMsg(),MigrationTable.DTRELATION.getCode()));
  305. }
  306. return syncDataList;
  307. }
  308. }