package com.fdkankan.contro.mq.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.fdkankan.common.constant.CommonSuccessStatus;
import com.fdkankan.contro.entity.ScenePlus;
import com.fdkankan.contro.entity.ScenePlusExt;
import com.fdkankan.contro.mq.service.IBuildSceneService;
import com.fdkankan.contro.service.*;
import com.fdkankan.fyun.config.FYunFileConfig;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.model.constants.ConstantFilePath;
import com.fdkankan.model.constants.UploadFilePath;
import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* TODO
*
*
* @author dengsixing
* @since 2022/4/20
**/
@Slf4j
@Service
@RefreshScope
public class BuildE57SceneServiceImpl implements IBuildSceneService {
public static final String logUrlFormat = "**algorithm-log**: [%sbuild_log/%s/e57/console.log](%sbuild_log/%s/e57/console.log)";
@Value("${queue.modeling.e57.modeling-post}")
private String queueModelingPost;
@Value("${model.type:#{null}}")
private String modelType;
@Value("${env:gn}")
private String env;
@Value("#{'${build.scene.post.not-delete-nas-nums:}'.split(',')}")
private List notDeleteNasNumList;
@Value("${queue.application.laser.e57-modeling-done:e57-modeling-done}")
private String queueE57ModelingDone;
@Autowired
private RabbitMqProducer mqProducer;
@Resource
private FYunFileServiceInterface fYunFileService;
@Autowired
private FYunFileConfig fYunFileConfig;
@Autowired
private IScenePlusService scenePlusService;
@Autowired
private IScenePlusExtService scenePlusExtService;
@Autowired
private IBuildSceneDTService buildSceneDTService;
@Autowired
private ICommonService commonService;
@Autowired
private ISceneColdStorageService sceneColdStorageService;
@Autowired
private IntermitSceneService intermitSceneService;
@Override
public void buildScenePre(BuildSceneCallMessage message) throws Exception{
String num = message.getSceneNum();
try {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String dataSource = scenePlusExt.getDataSource();
String path = dataSource + "_e57";
message.setPath(dataSource);
//根据相机类型,组装资源路径
//下载资源到本地
this.downLoadSource(message, path);
//发送mq,就进行计算
message.setPath(path);
message.setResultReceiverMqName(queueModelingPost);
message.setBizType("e57");
log.info("e57计算资源准备结束,场景码:{}", message.getSceneNum());
}catch (Exception e){
log.error("e57计算前置处理出错,num"+num, e);
buildSceneDTService.handBaseFail("e57计算资源准备异常!", message.getPath(), message.getSceneNum(), "计算控制服务器");
throw e;
}
}
private String getOssPath(String path) {
String ossPath = ConstantFilePath.OSS_PREFIX
+ path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
.replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
if (!ossPath.endsWith("/")) {
ossPath = ossPath.concat("/");
}
return ossPath;
}
@Override
public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
String ossPath = getOssPath(buildSceneMqMessage.getPath());
fYunFileService.downloadFileByCommand(path + "/capture", ossPath);
//下载点位校准文件
//上传点位校准相关文件(小)
String localExtraPath = path + "/extras/vision_edit.txt";
String ossExtras = String.format(UploadFilePath.scene_result_data_path, buildSceneMqMessage.getSceneNum()) + "extras";
List extras = fYunFileService.listRemoteFiles(ossExtras);
log.info("key:{}, list:{}", ossExtras, JSON.toJSONString(extras));
if(CollUtil.isNotEmpty(extras)){
extras.parallelStream().forEach(key->{
fYunFileService.downloadFile(key, localExtraPath);
});
}
}
@Override
public void buildScenePost(BuildSceneResultMqMessage message) throws Exception {
String num = message.getBuildContext().get("sceneNum").toString();
String path = message.getPath();
String bucket = (String)message.getExt().get("bucket");
String bizId = (String)message.getExt().get("bizId");
String ossKeyFormat = (String)message.getExt().get("ossKey");
try {
// 上传计算日志
//如果是重复计算,没有走到计算逻辑,不需要上传日志文件
log.info("开始上传计算日志");
String buildLogPath = String.format(UploadFilePath.BUILD_LOG_PATH, num) + "e57/";
fYunFileService.uploadFile(path + File.separator + "console.log", buildLogPath + "console.log");
log.info("计算日志上传完成");
Map laserMqContent = new HashMap<>();
laserMqContent.put("num", num);
laserMqContent.put("bizId", bizId);
if (!message.getBuildSuccess()) {
//发送mq通知激光系统
laserMqContent.put("status", CommonSuccessStatus.FAIL.code());
mqProducer.sendByWorkQueue(queueE57ModelingDone, laserMqContent);
// 发送钉钉消息,计算失败
String logUrl = String.format(logUrlFormat,fYunFileConfig.getHost(),num,fYunFileConfig.getHost(),num);
buildSceneDTService.handModelFail("计算失败", message.getPath(), num, message.getHostName(), logUrl);
return;
}
//压缩e57
String localPath = path + "/results/laserData/laser.e57";
String zipPath = path + "/results/laserData/laser-e57.zip";
String ossKey = String.format(ossKeyFormat, num, num);
ZipUtil.zip(localPath, zipPath);
fYunFileService.uploadFileByCommand(bucket,zipPath, ossKey);
//发送mq通知激光系统
laserMqContent.put("status", CommonSuccessStatus.SUCCESS.code());
mqProducer.sendByWorkQueue(queueE57ModelingDone, laserMqContent);
try {
FileUtil.del(path);
}catch (Exception e){
log.error("删除计算目录失败,path:{}", path);
}
log.info("e57场景计算结果处理结束,场景码:{}", num);
}catch (Exception e){
log.error("e57场景计算结果处理出错,num"+num, e);
buildSceneDTService.handBaseFail("e57场景计算结果处理出错!", message.getPath(), num, "计算控制服务器");
throw e;
}
}
}