JmgaServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. package com.fdkankan.contro.service.impl;
  2. import cn.hutool.core.codec.Base64;
  3. import cn.hutool.core.collection.CollUtil;
  4. import cn.hutool.core.io.FileUtil;
  5. import cn.hutool.core.lang.UUID;
  6. import cn.hutool.core.util.ZipUtil;
  7. import cn.hutool.http.HttpUtil;
  8. import com.alibaba.excel.EasyExcel;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.JSONArray;
  11. import com.alibaba.fastjson.JSONObject;
  12. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  13. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  14. import com.fdkankan.common.constant.ErrorCode;
  15. import com.fdkankan.common.constant.SceneStatus;
  16. import com.fdkankan.common.exception.BusinessException;
  17. import com.fdkankan.common.util.CmdUtils;
  18. import com.fdkankan.common.util.DateExtUtil;
  19. import com.fdkankan.contro.bean.SendCallAlgorithmDetail;
  20. import com.fdkankan.contro.constant.ZipConstant;
  21. import com.fdkankan.contro.entity.*;
  22. import com.fdkankan.contro.mq.service.IBuildLogService;
  23. import com.fdkankan.contro.service.*;
  24. import com.fdkankan.contro.vo.SendCallAlgorithmParam;
  25. import com.fdkankan.contro.vo.UploadSceneOrigParamVo;
  26. import com.fdkankan.fyun.face.FYunFileServiceInterface;
  27. import com.fdkankan.model.constants.ConstantFilePath;
  28. import com.fdkankan.rabbitmq.util.RabbitMqProducer;
  29. import com.fdkankan.web.util.RSAEncrypt;
  30. import lombok.extern.slf4j.Slf4j;
  31. import net.lingala.zip4j.core.ZipFile;
  32. import org.springframework.beans.factory.annotation.Autowired;
  33. import org.springframework.stereotype.Service;
  34. import javax.annotation.Resource;
  35. import java.io.File;
  36. import java.nio.charset.StandardCharsets;
  37. import java.util.*;
  38. import java.util.stream.Collectors;
  39. @Slf4j
  40. @Service
  41. public class JmgaServiceImpl implements IJmgaService {
  42. @Autowired
  43. private IOrigFileUploadBatchService origFileUploadBatchService;
  44. @Autowired
  45. private IOrigFileUploadService origFileUploadService;
  46. @Resource
  47. private FYunFileServiceInterface fileServiceInterface;
  48. @Resource
  49. private RabbitMqProducer mqProducer;
  50. @Resource
  51. private FYunFileServiceInterface fYunFileService;
  52. @Autowired
  53. private ISceneFileBuildService sceneFileBuildService;
  54. @Autowired
  55. private IUserService userService;
  56. @Autowired
  57. private IScenePlusService scenePlusService;
  58. @Autowired
  59. private IScenePlusExtService scenePlusExtService;
  60. @Autowired
  61. private ISceneBuildProcessLogService sceneBuildProcessLogService;
  62. @Autowired
  63. private IBuildLogService buildLogService;
  64. @Override
  65. public void checkFileWhole(String uuid, String dataSource, JSONObject fdageData) {
  66. int camType = fdageData.getJSONObject("cam").getIntValue("type");
  67. //从data.fdage中获取需要上传的文件列表
  68. JSONArray points = fdageData.getJSONArray("points");
  69. if(CollUtil.isEmpty(points)){
  70. return;
  71. }
  72. List<String> fileList = new ArrayList<>();
  73. for (Object point : points) {
  74. JSONObject pointJson = (JSONObject) point;
  75. if(camType == 5){//圆周率相机
  76. String name = pointJson.getString("name");
  77. fileList.add(name);
  78. }else{//四维相机
  79. JSONArray imgs = pointJson.getJSONArray("imgs");
  80. if(CollUtil.isEmpty(imgs)){
  81. continue;
  82. }
  83. for (Object img : imgs) {
  84. JSONObject imgJson = (JSONObject) img;
  85. String name = imgJson.getString("name");
  86. fileList.add(name);
  87. }
  88. }
  89. }
  90. //查询当前待通知计算批次文件是否存在
  91. List<OrigFileUploadBatch> batchList = origFileUploadBatchService.list(new LambdaQueryWrapper<OrigFileUploadBatch>().eq(OrigFileUploadBatch::getUuid, uuid));
  92. if(CollUtil.isNotEmpty(batchList)){
  93. Set<String> batchIds = batchList.stream().map(v -> v.getBatchId()).collect(Collectors.toSet());
  94. List<OrigFileUpload> origFileList = origFileUploadService.list(new LambdaQueryWrapper<OrigFileUpload>().in(OrigFileUpload::getBatchId, batchIds));
  95. //过滤出不存在的
  96. fileList = fileList.stream().filter(v -> origFileList.stream().noneMatch(k -> k.getFileName().equals(v))).collect(Collectors.toList());
  97. }
  98. if(CollUtil.isNotEmpty(fileList)){
  99. String args = JSON.toJSONString(fileList);
  100. if(fileList.size() > 5){
  101. args = fileList.size() + "个文件";
  102. }
  103. throw new BusinessException(ErrorCode.FAILURE_CODE_4001, args);
  104. }
  105. }
  106. @Override
  107. public void sendStatus(Map<String, Object> param) {
  108. mqProducer.sendByWorkQueue("jmga-event-notice", param);
  109. }
  110. @Override
  111. public void checkLackFile(String dataSource) {
  112. String dataFdagePath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat("data.fdage");
  113. if(!FileUtil.exist(dataFdagePath)){
  114. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("data.fdage"));
  115. }
  116. JSONObject fdageData = null;
  117. try {
  118. fdageData = JSON.parseObject(FileUtil.readUtf8String(dataFdagePath));
  119. }catch (Exception e){
  120. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("data.fdage"));
  121. }
  122. int camType = fdageData.getJSONObject("cam").getIntValue("type");
  123. if(camType == 1 || camType == 2 || camType == 9 || camType == 10 || camType == 11){
  124. Integer shootCount = fdageData.getJSONArray("points").size();
  125. if(shootCount > 0){//有点位代表架站式
  126. String parametersPath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat("parameters.json");
  127. if(!FileUtil.exist(parametersPath)){
  128. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("parameters.json"));
  129. }
  130. String sfmDataBinPath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat("sfm_data.bin");
  131. if(!FileUtil.exist(sfmDataBinPath)){
  132. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("sfm_data.bin"));
  133. }
  134. String upName = camType > 2 ? "Up.txt" : "Up.xml";
  135. String upTxtPath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat(upName);
  136. if(!FileUtil.exist(upTxtPath)){
  137. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage(upName));
  138. }
  139. }
  140. }
  141. if(camType == 5){
  142. String parametersPath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat("images/parameters.json");
  143. if(!FileUtil.exist(parametersPath)){
  144. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("parameters.json"));
  145. }
  146. String sfmDataBinPath = dataSource.concat(File.separator).concat("capture").concat(File.separator).concat("result/reconstruction/sfm_data.bin");
  147. if(!FileUtil.exist(sfmDataBinPath)){
  148. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage("sfm_data.bin"));
  149. }
  150. }
  151. //从data.fdage中获取需要上传的文件列表
  152. JSONArray points = fdageData.getJSONArray("points");
  153. if(CollUtil.isEmpty(points)){
  154. return;
  155. }
  156. for (Object point : points) {
  157. JSONObject pointJson = (JSONObject) point;
  158. if(camType == 5){//圆周率相机
  159. String name = pointJson.getString("name");
  160. this.checkFileAvailable(dataSource, name);
  161. }else{//四维相机
  162. JSONArray imgs = pointJson.getJSONArray("imgs");
  163. for (Object img : imgs) {
  164. JSONObject imgJson = (JSONObject) img;
  165. String name = imgJson.getString("name");
  166. this.checkFileAvailable(dataSource, name);
  167. }
  168. }
  169. }
  170. }
  171. private void checkFileAvailable(String dataSource, String fileName){
  172. List<File> fileList = FileUtil.loopFiles(dataSource.concat(File.separator).concat("capture"));
  173. if(CollUtil.isEmpty(fileList)){
  174. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage(fileName));
  175. }
  176. for (File file : fileList) {
  177. if(file.getName().equals(fileName) && file.length() > 0){
  178. return;
  179. }
  180. }
  181. throw new BusinessException(ErrorCode.FAILURE_CODE_4001.code(), ErrorCode.FAILURE_CODE_4001.formatMessage(fileName));
  182. }
  183. @Override
  184. public void uploadSceneOrig(UploadSceneOrigParamVo param) throws Exception {
  185. User user = userService.getById(param.getUserId());
  186. if(Objects.isNull(user)){
  187. throw new BusinessException(ErrorCode.USER_NOT_EXIST);
  188. }
  189. String uuid = UUID.randomUUID().toString();
  190. String zipName = uuid + ".zip";
  191. String zipDir = "/oss/4dkankan/bd_server/";
  192. fYunFileService.downloadFileByCommand(zipDir + zipName, param.getFilePath());
  193. // fYunFileService.deleteFile(param.getFilePath());
  194. //解压缩
  195. // String unzipCmd = "unzip -P " + ZipConstant.zipPassword + " " + zipDir + zipName + " -d " + zipDir + uuid;
  196. // CmdUtils.callLineSh(unzipCmd);
  197. ZipFile zipFile = new ZipFile(new File(zipDir + zipName));
  198. if (zipFile.isEncrypted()) {
  199. zipFile.setPassword(ZipConstant.zipPassword);
  200. zipFile.extractAll(zipDir + uuid);
  201. } else {
  202. ZipUtil.unzip(zipDir + zipName, zipDir + uuid);
  203. }
  204. // FileUtil.del(zipDir + zipName);
  205. //去读data.fdage
  206. File dataFdageFile = FileUtil.loopFiles(zipDir + uuid).stream().filter(v -> v.getName().equals("data.fdage")).findFirst().get();
  207. if(dataFdageFile == null){
  208. throw new BusinessException(ErrorCode.FAILURE_CODE_4002.code(), ErrorCode.FAILURE_CODE_4002.formatMessage("data.fdage"));
  209. }
  210. JSONObject dataFdageObj = JSONObject.parseObject(FileUtil.readUtf8String(dataFdageFile));
  211. int camType = dataFdageObj.getJSONObject("cam").getIntValue("type");
  212. String snCode = dataFdageObj.getJSONObject("cam").getString("uuid");
  213. String uuidTime = dataFdageObj.getString("uuidtime");
  214. String uniCode = snCode + "_" + uuidTime;
  215. String fileId = sceneFileBuildService.getFileId(snCode, uniCode);
  216. String homePath = "/oss/4dkankan/" + ConstantFilePath.OSS_PREFIX + snCode + "/" + fileId + "/" + uniCode;
  217. FileUtil.mkdir(homePath);
  218. String cpCmd = "cp -p -r " + zipDir + uuid + "/*/* " + homePath;
  219. CmdUtils.callLineSh(cpCmd);
  220. // FileUtil.del(zipDir + uuid);
  221. String params = snCode + "#" + fileId + "#" + uniCode;
  222. String encode = Base64.encode(RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile()), params.getBytes(StandardCharsets.UTF_8)));
  223. if(camType == 9 || camType == 10 || camType == 11){
  224. sceneFileBuildService.turntableUploadSuccess(encode, user);
  225. }else{
  226. sceneFileBuildService.uploadSuccessBuild(encode, user);
  227. }
  228. }
  229. @Override
  230. public void noticeBuildBd(String ossHost, String uuid, String dir) {
  231. String prefix = "http://" + ossHost + "/";
  232. String path = "/oss/4dkankan/bd_server/" + dir;
  233. List<File> files = FileUtil.loopFiles(path).stream().filter(file -> !file.getAbsolutePath().contains("backup")).collect(Collectors.toList());
  234. files.parallelStream().forEach(file ->{
  235. String url = prefix.concat(file.getAbsolutePath().substring(1).replace("/4dkankan",""));
  236. SendCallAlgorithmDetail detail = new SendCallAlgorithmDetail();
  237. detail.setFileName(FileUtil.getName(file.getAbsolutePath()));
  238. detail.setUuid(uuid);
  239. SendCallAlgorithmParam param = new SendCallAlgorithmParam();
  240. param.setFilepath(url);
  241. param.setDetails(detail);
  242. HttpUtil.post("http://127.0.0.1:8085/api/scene/file/sendCallAlgorithm", JSON.toJSONString(param));
  243. });
  244. }
  245. @Override
  246. public void updateSceneFailAndZipLog(String num, String failReason) {
  247. scenePlusService.update(new LambdaUpdateWrapper<ScenePlus>()
  248. .set(ScenePlus::getSceneStatus, SceneStatus.FAILD.code())
  249. .set(ScenePlus::getBuildFailReason, failReason)
  250. .eq(ScenePlus::getNum, num));
  251. String logBasePath = File.separator + "mnt" + File.separator + "logs" + File.separator;
  252. String tmpPath = logBasePath + "tmp" + File.separator;
  253. String logPath = tmpPath + num + "-" + Calendar.getInstance().getTimeInMillis() + File.separator;
  254. String zipPath = tmpPath + num + "-" + Calendar.getInstance().getTimeInMillis() + ".zip";
  255. FileUtil.mkdir(logPath);
  256. //打包服务端日志
  257. File[] ls = FileUtil.ls(logBasePath);
  258. for (File l : ls) {
  259. if(l.isFile() || !l.getName().startsWith("modeling-control")){
  260. continue;
  261. }
  262. this.copyLog(l.getAbsolutePath(), logPath, "info","sql","error");
  263. }
  264. //打包算法日志
  265. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  266. ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  267. String consoleLogPath = scenePlusExt.getDataSource() + "console.log";
  268. String consoleOldLogPath = scenePlusExt.getDataSource() + "console.old.log";
  269. if(FileUtil.exist(consoleLogPath)){
  270. FileUtil.copy(consoleLogPath, logPath,true);
  271. }
  272. if(FileUtil.exist(consoleOldLogPath)){
  273. FileUtil.copy(consoleOldLogPath, logPath,true);
  274. }
  275. //打包数据库记录
  276. String[] split = scenePlusExt.getDataSource().split("/");
  277. String uuid = split[split.length -1];
  278. List<OrigFileUploadBatch> batchList = origFileUploadBatchService.list(new LambdaQueryWrapper<OrigFileUploadBatch>().eq(OrigFileUploadBatch::getUuid, uuid));
  279. if(CollUtil.isNotEmpty(batchList)){
  280. EasyExcel.write(logPath.concat("origFileUploadBatch.xlsx"), OrigFileUploadBatch.class).sheet("origFileUploadBatch").doWrite(batchList);
  281. List<String> batchIdList = batchList.stream().map(v -> v.getBatchId()).collect(Collectors.toList());
  282. List<OrigFileUpload> uploadList = origFileUploadService.list(new LambdaQueryWrapper<OrigFileUpload>().in(OrigFileUpload::getBatchId, batchIdList));
  283. if(CollUtil.isNotEmpty(uploadList)){
  284. EasyExcel.write(logPath.concat("origFileUpload.xlsx"), OrigFileUpload.class).sheet("origFileUpload").doWrite(uploadList);
  285. }
  286. }
  287. List<SceneBuildProcessLog> processLogList = sceneBuildProcessLogService.listByNum(num);
  288. if(CollUtil.isNotEmpty(processLogList)){
  289. EasyExcel.write(logPath.concat("sceneBuildProcessLog.xlsx"), SceneBuildProcessLog.class).sheet("sceneBuildProcessLog").doWrite(processLogList);
  290. }
  291. List<BuildLog> buildLogList = buildLogService.list(new LambdaQueryWrapper<BuildLog>().eq(BuildLog::getSceneNum, num));
  292. if(CollUtil.isNotEmpty(buildLogList)){
  293. EasyExcel.write(logPath.concat("buildLog.xlsx"), BuildLog.class).sheet("buildLog").doWrite(buildLogList);
  294. }
  295. //上传日志,删除本地压缩包
  296. ZipUtil.zip(logPath, zipPath, false);
  297. String logName = "build_log/" + num + "/" + num + "-log.zip";
  298. if(fYunFileService.fileExist(logName)){
  299. fYunFileService.copyFileInBucket(logName, logName + "-bak-" + DateExtUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle11));
  300. }
  301. fYunFileService.uploadFile(zipPath, "build_log/" + num + "/" + num + "-log");
  302. }
  303. private void copyLog(String serverPath, String tmpPath, String... levels){
  304. level: for (String level : levels) {
  305. String infoPath = serverPath + File.separator + level + File.separator;
  306. List<File> fileList = FileUtil.loopFiles(infoPath);
  307. if(CollUtil.isEmpty(fileList)){
  308. continue;
  309. }
  310. CollUtil.reverse(fileList);
  311. for (File file : fileList) {
  312. int i = fileList.indexOf(file);
  313. if(i > 7){
  314. continue level;
  315. }
  316. FileUtil.copy(file.getAbsolutePath(), file.getAbsolutePath().replace(FileUtil.getParent(serverPath, 1), tmpPath), true);
  317. }
  318. }
  319. }
  320. }