ReverseE57ServiceImpl.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package com.fdkankan.modeling.service.impl;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.fdkankan.common.constant.CommonStatus;
  5. import com.fdkankan.common.constant.ModelingBuildStatus;
  6. import com.fdkankan.common.util.FileUtils;
  7. import com.fdkankan.model.enums.ModelTypeEnums;
  8. import com.fdkankan.model.utils.ComputerUtil;
  9. import com.fdkankan.modeling.bean.BuildSceneResultBean;
  10. import com.fdkankan.modeling.constants.SysConstants;
  11. import com.fdkankan.modeling.entity.BuildLog;
  12. import com.fdkankan.modeling.exception.BuildException;
  13. import com.fdkankan.modeling.service.IBuildLogService;
  14. import com.fdkankan.modeling.service.IReverseE57Service;
  15. import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
  16. import com.fdkankan.rabbitmq.bean.BuildSceneProcessLogMessage;
  17. import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
  18. import com.fdkankan.rabbitmq.util.RabbitMqProducer;
  19. import lombok.extern.slf4j.Slf4j;
  20. import org.apache.commons.lang3.StringUtils;
  21. import org.apache.commons.lang3.time.StopWatch;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.beans.factory.annotation.Value;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.util.ObjectUtils;
  26. import javax.annotation.Resource;
  27. import javax.print.DocFlavor;
  28. import java.io.File;
  29. import java.util.Date;
  30. import java.util.HashMap;
  31. import java.util.Map;
  32. import java.util.Objects;
  33. import java.util.concurrent.Future;
  34. import java.util.concurrent.TimeUnit;
  35. import java.util.concurrent.TimeoutException;
  36. @Slf4j
  37. @Service
  38. public class ReverseE57ServiceImpl implements IReverseE57Service {
  39. @Value("${queue.modeling.modeling-call}")
  40. private String queueModelingCall;
  41. @Value("${queue.modeling.modeling-process-log}")
  42. private String queueModelingProcessLog;
  43. @Value("${queue.modeling.modeling-post}")
  44. private String queueModelingPost;
  45. @Autowired
  46. private IBuildLogService buildLogService;
  47. @Resource
  48. private RabbitMqProducer rabbitMqProducer;
  49. @Value("${model.type:#{null}}")
  50. private String modelType;
  51. @Override
  52. public void build(BuildSceneCallMessage message, BuildLog buildLog) {
  53. //开始计时
  54. StopWatch watch = new StopWatch();
  55. watch.start();
  56. //发送记录计算状态为计算中
  57. rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
  58. BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(ModelingBuildStatus.CALCULATING.code()).queueName(queueModelingCall).build());
  59. final BuildSceneResultBean buildSceneResult = new BuildSceneResultBean();
  60. String resultQueueName = StrUtil.isNotBlank(message.getResultReceiverMqName()) ?
  61. message.getResultReceiverMqName() : queueModelingPost;
  62. buildSceneResult.setResultQueueName(resultQueueName);
  63. ModelingBuildStatus status = null;
  64. Future<ModelingBuildStatus> future = null;
  65. try {
  66. Map<String,Object> buildContext = new HashMap<>();
  67. buildContext.put("num", message.getSceneNum());
  68. buildLog.setHostName(SysConstants.hostName);
  69. buildLog.setQueueName(queueModelingCall);
  70. buildLog.setSceneNum(message.getSceneNum());
  71. buildLog.setDataSource(message.getPath());
  72. buildLog.setCreateTime(new Date());
  73. buildLog.setUpdateTime(new Date());
  74. buildLog.setBuildType(0);
  75. buildLog.setStatus(0);
  76. buildLogService.save(buildLog);
  77. future = SysConstants.executorService.submit(() -> {
  78. try {
  79. return buildScene(buildContext,message, buildSceneResult,buildLog);
  80. } catch (Exception e) {
  81. log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
  82. e.printStackTrace();
  83. return ModelingBuildStatus.FAILED;
  84. }
  85. });
  86. status = future.get(SysConstants.modelTimeOut, TimeUnit.HOURS);
  87. //结束计时
  88. watch.stop();
  89. buildLog.setDuration(watch.getTime(TimeUnit.SECONDS));
  90. } catch (TimeoutException ex) {
  91. log.error("服务实例:{} 构建异常:",SysConstants.hostName,ex);
  92. status = ModelingBuildStatus.OVERTIME;
  93. log.info("释放线程");
  94. //场景计算超时,需要中断当前执行任务,释放线程池中的任务线程,否则下个场景计算获取不到线程进行计算
  95. future.cancel(true);
  96. } catch (BuildException e){
  97. status = e.getBuildStatus();
  98. } catch(Exception e) {
  99. log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
  100. if (e.getCause() instanceof BuildException) {
  101. status = ((BuildException) e.getCause()).getBuildStatus();
  102. buildLog.setStatus(((BuildException) e.getCause()).getBuildStatus().code());
  103. } else {
  104. status = ModelingBuildStatus.FAILED;
  105. }
  106. }
  107. buildLog.setStatus(status.code());
  108. buildSceneResult.setCameraType(message.getCameraType());
  109. buildSceneResult.setBuildStatus(status);
  110. //计算后处理
  111. ModelingBuildStatus buildStatus = null;
  112. try {
  113. buildStatus = buildSceneResult.getBuildStatus();
  114. log.info("服务{} 计算结束:{},计算状态:{}", SysConstants.hostName, buildLog.getSceneNum(),buildStatus.message());
  115. buildLog.setUpdateTime(new Date());
  116. buildLog.setResultQuequeName(buildSceneResult.getResultQueueName());
  117. buildLogService.updateById(buildLog);
  118. } catch (Exception e) {
  119. log.error("计算后业务处理出错!", e);
  120. }finally {
  121. buildSceneResult.setDuration(buildLog.getDuration());
  122. this.sendCallResult(message, buildSceneResult);
  123. rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
  124. BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(buildStatus.code()).queueName(queueModelingCall).build());
  125. }
  126. }
  127. /**
  128. * 发送计算结果
  129. * @param message
  130. * @param buildSceneResult
  131. */
  132. private void sendCallResult(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult){
  133. ModelingBuildStatus buildStatus = buildSceneResult.getBuildStatus();
  134. //重复计算不需要发送mq做后置处理
  135. if(buildStatus.equals(ModelingBuildStatus.REPEAT)){
  136. return;
  137. }
  138. BuildSceneResultMqMessage buildResult = BuildSceneResultMqMessage.builder()
  139. .buildSuccess(buildStatus.equals(ModelingBuildStatus.SUCCESS))
  140. .computeTime(buildSceneResult.getDuration())
  141. .path(buildSceneResult.getPath())
  142. .hostName(SysConstants.hostName)
  143. .build();
  144. buildResult.setBuildContext(message.getBuildContext());
  145. rabbitMqProducer.sendByWorkQueue(buildSceneResult.getResultQueueName(),buildResult);
  146. }
  147. private ModelingBuildStatus buildScene(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult,BuildLog logRecord) throws Exception{
  148. //如果mq生产者在消息体中设置了结算结果mq队列名,就发到这个队列,否则就发送到默认队列
  149. String path = message.getPath();
  150. String num = message.getSceneNum();
  151. //不同的相机不同的方法
  152. String cameraType = message.getCameraType();
  153. //0表示有4k图,1表示没有
  154. //判断调用V2还是V3版本的算法
  155. String buildType = ObjectUtils.isEmpty(message.getBuildType()) ? "V2" : message.getBuildType();
  156. buildSceneResult.setCameraType(cameraType);
  157. buildSceneResult.setNum(num);
  158. buildSceneResult.setPath(path);
  159. //计算模型并返回需要上传oss的文件集合
  160. ComputerUtil.computer(num, path, buildType);
  161. // 检测计算结果文件是否有生成
  162. String resultsPath = path + File.separator + "results" + File.separator;
  163. if (!new File(resultsPath + "upload.json").exists()) {
  164. log.error("未检测到计算结果文件:upload.json");
  165. return ModelingBuildStatus.FAILED;
  166. }
  167. log.info("八目上完oss结束修改数据:"+num);
  168. return ModelingBuildStatus.SUCCESS;
  169. }
  170. }