123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- package com.fdkankan.modeling.service.impl;
- import cn.hutool.core.util.StrUtil;
- import com.alibaba.fastjson.JSONObject;
- import com.fdkankan.common.constant.CommonStatus;
- import com.fdkankan.common.constant.ModelingBuildStatus;
- import com.fdkankan.common.util.FileUtils;
- import com.fdkankan.model.enums.ModelTypeEnums;
- import com.fdkankan.model.utils.ComputerUtil;
- import com.fdkankan.modeling.bean.BuildSceneResultBean;
- import com.fdkankan.modeling.constants.SysConstants;
- import com.fdkankan.modeling.entity.BuildLog;
- import com.fdkankan.modeling.exception.BuildException;
- import com.fdkankan.modeling.service.IBuildLogService;
- import com.fdkankan.modeling.service.IReverseE57Service;
- import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
- import com.fdkankan.rabbitmq.bean.BuildSceneProcessLogMessage;
- import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
- import com.fdkankan.rabbitmq.util.RabbitMqProducer;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.time.StopWatch;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import org.springframework.util.ObjectUtils;
- import javax.annotation.Resource;
- import javax.print.DocFlavor;
- import java.io.File;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
- import java.util.concurrent.Future;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.TimeoutException;
- @Slf4j
- @Service
- public class ReverseE57ServiceImpl implements IReverseE57Service {
- @Value("${queue.modeling.modeling-call}")
- private String queueModelingCall;
- @Value("${queue.modeling.modeling-process-log}")
- private String queueModelingProcessLog;
- @Value("${queue.modeling.modeling-post}")
- private String queueModelingPost;
- @Autowired
- private IBuildLogService buildLogService;
- @Resource
- private RabbitMqProducer rabbitMqProducer;
- @Value("${model.type:#{null}}")
- private String modelType;
- @Override
- public void build(BuildSceneCallMessage message, BuildLog buildLog) {
- //开始计时
- StopWatch watch = new StopWatch();
- watch.start();
- //发送记录计算状态为计算中
- rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
- BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(ModelingBuildStatus.CALCULATING.code()).queueName(queueModelingCall).build());
- final BuildSceneResultBean buildSceneResult = new BuildSceneResultBean();
- String resultQueueName = StrUtil.isNotBlank(message.getResultReceiverMqName()) ?
- message.getResultReceiverMqName() : queueModelingPost;
- buildSceneResult.setResultQueueName(resultQueueName);
- ModelingBuildStatus status = null;
- Future<ModelingBuildStatus> future = null;
- try {
- Map<String,Object> buildContext = new HashMap<>();
- buildContext.put("num", message.getSceneNum());
- buildLog.setHostName(SysConstants.hostName);
- buildLog.setQueueName(queueModelingCall);
- buildLog.setSceneNum(message.getSceneNum());
- buildLog.setDataSource(message.getPath());
- buildLog.setCreateTime(new Date());
- buildLog.setUpdateTime(new Date());
- buildLog.setBuildType(0);
- buildLog.setStatus(0);
- buildLogService.save(buildLog);
- future = SysConstants.executorService.submit(() -> {
- try {
- return buildScene(buildContext,message, buildSceneResult,buildLog);
- } catch (Exception e) {
- log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
- e.printStackTrace();
- return ModelingBuildStatus.FAILED;
- }
- });
- status = future.get(SysConstants.modelTimeOut, TimeUnit.HOURS);
- //结束计时
- watch.stop();
- buildLog.setDuration(watch.getTime(TimeUnit.SECONDS));
- } catch (TimeoutException ex) {
- log.error("服务实例:{} 构建异常:",SysConstants.hostName,ex);
- status = ModelingBuildStatus.OVERTIME;
- log.info("释放线程");
- //场景计算超时,需要中断当前执行任务,释放线程池中的任务线程,否则下个场景计算获取不到线程进行计算
- future.cancel(true);
- } catch (BuildException e){
- status = e.getBuildStatus();
- } catch(Exception e) {
- log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
- if (e.getCause() instanceof BuildException) {
- status = ((BuildException) e.getCause()).getBuildStatus();
- buildLog.setStatus(((BuildException) e.getCause()).getBuildStatus().code());
- } else {
- status = ModelingBuildStatus.FAILED;
- }
- }
- buildLog.setStatus(status.code());
- buildSceneResult.setCameraType(message.getCameraType());
- buildSceneResult.setBuildStatus(status);
- //计算后处理
- ModelingBuildStatus buildStatus = null;
- try {
- buildStatus = buildSceneResult.getBuildStatus();
- log.info("服务{} 计算结束:{},计算状态:{}", SysConstants.hostName, buildLog.getSceneNum(),buildStatus.message());
- buildLog.setUpdateTime(new Date());
- buildLog.setResultQuequeName(buildSceneResult.getResultQueueName());
- buildLogService.updateById(buildLog);
- } catch (Exception e) {
- log.error("计算后业务处理出错!", e);
- }finally {
- buildSceneResult.setDuration(buildLog.getDuration());
- this.sendCallResult(message, buildSceneResult);
- rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
- BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(buildStatus.code()).queueName(queueModelingCall).build());
- }
- }
- /**
- * 发送计算结果
- * @param message
- * @param buildSceneResult
- */
- private void sendCallResult(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult){
- ModelingBuildStatus buildStatus = buildSceneResult.getBuildStatus();
- //重复计算不需要发送mq做后置处理
- if(buildStatus.equals(ModelingBuildStatus.REPEAT)){
- return;
- }
- BuildSceneResultMqMessage buildResult = BuildSceneResultMqMessage.builder()
- .buildSuccess(buildStatus.equals(ModelingBuildStatus.SUCCESS))
- .computeTime(buildSceneResult.getDuration())
- .path(buildSceneResult.getPath())
- .hostName(SysConstants.hostName)
- .build();
- buildResult.setBuildContext(message.getBuildContext());
- rabbitMqProducer.sendByWorkQueue(buildSceneResult.getResultQueueName(),buildResult);
- }
- private ModelingBuildStatus buildScene(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult,BuildLog logRecord) throws Exception{
- //如果mq生产者在消息体中设置了结算结果mq队列名,就发到这个队列,否则就发送到默认队列
- String path = message.getPath();
- String num = message.getSceneNum();
- //不同的相机不同的方法
- String cameraType = message.getCameraType();
- //0表示有4k图,1表示没有
- //判断调用V2还是V3版本的算法
- String buildType = ObjectUtils.isEmpty(message.getBuildType()) ? "V2" : message.getBuildType();
- buildSceneResult.setCameraType(cameraType);
- buildSceneResult.setNum(num);
- buildSceneResult.setPath(path);
- String splitType = "SPLIT_V29";
- String skyboxType = "SKYBOX_V11";
- String otherType = (String)message.getExt().get("otherType");
- Integer isObj = (Integer) message.getExt().get("isObj");
- if(StrUtil.isNotEmpty(modelType) && ModelTypeEnums.TILE_CODE.equals(modelType)){
- skyboxType = "SKYBOX_V15";
- }
- if(Objects.nonNull(isObj) && isObj == CommonStatus.YES.code().intValue()){
- splitType = "SPLIT_V30";
- }
- this.createProjectAndDataFile(path,num, splitType, skyboxType,otherType,null,null);
- //计算模型并返回需要上传oss的文件集合
- ComputerUtil.computer(num, path, buildType);
- // 检测计算结果文件是否有生成
- String resultsPath = path + File.separator + "results" + File.separator;
- if (!new File(resultsPath + "upload.json").exists()) {
- log.error("未检测到计算结果文件:upload.json");
- return ModelingBuildStatus.FAILED;
- }
- log.info("八目上完oss结束修改数据:"+num);
- return ModelingBuildStatus.SUCCESS;
- }
- public void createProjectAndDataFile(String path, String sceneNum, String splitType, String skyboxType, String otherType, Map<String, Object> projectExtras, Map<String, Object> dataExtras) {
- JSONObject projectJson = new JSONObject();
- if (!org.apache.commons.lang3.ObjectUtils.isEmpty(projectExtras)) {
- projectJson.putAll(projectExtras);
- }
- projectJson.put("sceneNum", sceneNum);
- FileUtils.writeFile(path + File.separator + "project.json", projectJson.toString());
- JSONObject dataJson = new JSONObject();
- if (!org.apache.commons.lang3.ObjectUtils.isEmpty(dataExtras)) {
- dataJson.putAll(dataExtras);
- }
- dataJson.put("split_type", splitType);
- dataJson.put("skybox_type", skyboxType);
- dataJson.put("extras", (Object)null);
- dataJson.put("other_type", otherType);
- FileUtils.writeFile(path + File.separator + "data.json", dataJson.toString());
- }
- }
|