李春阳 1 year ago
parent
commit
0082d3a5f5
12 changed files with 415 additions and 247 deletions
  1. 1 0
      api-common/src/main/java/api/common/pojo/param/scene/SceneEvaluationComputeParam.java
  2. 2 0
      api-common/src/main/java/api/common/pojo/po/scene/SceneEvaluationRulePO.java
  3. 11 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/adapter/controller/scene_library/score_rule/ScoreRuleController.java
  4. 22 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/ApplicationContextAwareImpl.java
  5. 1 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneAccidentService.java
  6. 65 247
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneEvaluationRuleService.java
  7. 1 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneNaturalService.java
  8. 1 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneReferenceLibService.java
  9. 1 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneStandardsService.java
  10. 278 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/runnable/SceneEvaluationComputeRunnable.java
  11. 8 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/runnable/SceneEvaluationUploadRunnable.java
  12. 24 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/threadpool/ThreadPool.java

+ 1 - 0
api-common/src/main/java/api/common/pojo/param/scene/SceneEvaluationComputeParam.java

@@ -28,4 +28,5 @@ public class SceneEvaluationComputeParam implements Serializable {
     private String evaluationPath;
     private String vehicleId;
     private String algorithmId;
+    private String createUserId;
 }

+ 2 - 0
api-common/src/main/java/api/common/pojo/po/scene/SceneEvaluationRulePO.java

@@ -45,4 +45,6 @@ public class SceneEvaluationRulePO implements Serializable {
     // 修改人
     public String modifyUserId;
 
+    public String localPath;
+
 }

+ 11 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/adapter/controller/scene_library/score_rule/ScoreRuleController.java

@@ -197,6 +197,17 @@ public class ScoreRuleController {
     }
 
 
+    /**
+     * 新增场景评价规则支持传入路径
+     */
+    @PostMapping("/saveSceneEvaluationRuleByPath")
+    public ResponseBodyVO<String> saveSceneEvaluationRule(@RequestBody SceneEvaluationRulePO sceneEvaluationRulePO) {
+        if (ObjectUtil.isNull(sceneEvaluationRulePO.getRuleName())) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "参数 RulesName 不能为空,请检查");
+        }
+        return sceneEvaluationRuleService.uploadPyScriptAndSaveRuleByPath(sceneEvaluationRulePO);
+    }
+
     /**
      * 查询场景评分规则列表
      */

+ 22 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/ApplicationContextAwareImpl.java

@@ -0,0 +1,22 @@
+package com.css.simulation.resource.server.app.impl;
+
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationContextAwareImpl implements ApplicationContextAware {
+    @Getter
+    private static ApplicationContext applicationContext = null;
+
+    @Override
+    @Autowired
+    public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
+        ApplicationContextAwareImpl.applicationContext = applicationContext;
+    }
+
+}

+ 1 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneAccidentService.java

@@ -887,6 +887,7 @@ public class SceneAccidentService {
                                 sceneEvaluationComputeParam.setSceneType(DictConstants.SCENE_ACCIDENT);
                                 sceneEvaluationComputeParam.setTaskId(taskId);
                                 sceneEvaluationComputeParam.setComputeType(DictConstants.COMPLEXITY);
+                                sceneEvaluationComputeParam.setCreateUserId(AuthUtil.getCurrentUserId());
                                 if (isupdate.equals("1")) {
                                     String tempSceneId = scenes.get(0).getAccidentId();
                                     sceneEvaluationComputeParam.setCopySceneId(scenes.stream().map(SceneAccidentPO::getAccidentId).filter(sceneId -> !StringUtils.equals(tempSceneId, sceneId)).collect(Collectors.toList()));

+ 65 - 247
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneEvaluationRuleService.java

@@ -3,43 +3,36 @@ package com.css.simulation.resource.server.app.service;
 import api.common.pojo.common.ResponseBodyVO;
 import api.common.pojo.constants.DictConstants;
 import api.common.pojo.enums.SceneEvaluationEnum;
-import api.common.pojo.param.MinioParameter;
 import api.common.pojo.param.scene.*;
 import api.common.pojo.po.scene.SceneComplexityPO;
 import api.common.pojo.po.scene.SceneEvaluationOperatePO;
 import api.common.pojo.po.scene.SceneEvaluationRulePO;
 import api.common.pojo.po.scene.SceneRiskPO;
-import api.common.util.*;
+import api.common.util.LogUtil;
+import api.common.util.StringUtil;
+import api.common.util.TimeUtil;
 import com.alibaba.druid.util.StringUtils;
 import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneComplexityMapper;
 import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneEvaluationRuleMapper;
 import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageMapper;
 import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneRiskMapper;
 import com.css.simulation.resource.server.infra.feign.service.FileDownService;
+import com.css.simulation.resource.server.infra.runnable.SceneEvaluationComputeRunnable;
+import com.css.simulation.resource.server.infra.threadpool.ThreadPool;
 import com.css.simulation.resource.server.infra.util.AuthUtil;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import feign.Response;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import static api.common.pojo.enums.SceneEvaluationEnum.matchLevelEnumByLevel;
-
 @Slf4j
 @Service
 public class SceneEvaluationRuleService {
@@ -120,6 +113,61 @@ public class SceneEvaluationRuleService {
         return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
     }
 
+
+    @SneakyThrows
+    public ResponseBodyVO<String> uploadPyScriptAndSaveRuleByPath(SceneEvaluationRulePO sceneEvaluationRulePO) {
+
+        boolean hasRuleId = StringUtil.isEmpty(sceneEvaluationRulePO.getRuleId());
+
+        // 检查是否存在同名场景评价规则
+        int repeatPyScriptAndSaveRuleCount = querySceneEvaluationRuleOnly(sceneEvaluationRulePO.getRuleName(),
+                hasRuleId ? null : sceneEvaluationRulePO.getRuleId());
+        if (repeatPyScriptAndSaveRuleCount > 0) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "场景规则 " + sceneEvaluationRulePO.getRuleName() + " 已存在,请重新命名。");
+        }
+        // 新建或者是编辑时重新上传文件
+        if ((hasRuleId) || sceneEvaluationRulePO.getUploadNewFile()) {
+            String roleCode = AuthUtil.getCurrentUserRoleCode();
+            if (!DictConstants.ROLE_CODE_ADMIN.equals(roleCode) && !DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) {
+                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "非管理员禁止上传文件");
+            }
+            // 检查文件内容是否合规
+//            String pyStr = new String(file.getBytes(), StandardCharsets.UTF_8);
+//            //1 校验 python 语法错误
+//            String pylint = PythonUtil.pylint(pyStr, PythonUtil.C, PythonUtil.R, PythonUtil.W, PythonUtil.E0401, PythonUtil.E0601);
+//            if (!pylint.contains(PythonUtil.PASS)) {
+//                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "代码格式错误,请检查。");
+//            }
+//            // 获取文件原本的名字
+//            String originName = file.getOriginalFilename();
+//            if (null == originName) {
+//                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "文件名为空,请检查!");
+//            }
+//            Integer nowTime = TimeUtil.getRq(new Date(), 0);
+//            String randomCode = StringUtil.getRandomCode();
+//            String fileName = "/" + DictConstants.SCENE_EVALUATION_RULE_PY_FILE + "/" + nowTime + "/" + randomCode + "/" + originName;
+//            ResponseBodyVO<String> response = fileDownService.upload(file, fileName);
+//            if (response.isStatus()) {
+//                sceneEvaluationRulePO.setScriptName(originName);
+//                sceneEvaluationRulePO.setScriptPath(fileName);
+//            } else {
+//                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "上传失败!");
+//            }
+//        }
+//
+//        // 判断 ruleId 是否为空
+//        if (StringUtil.isEmpty(sceneEvaluationRulePO.getRuleId())) {
+//            // 创建
+//            saveSceneEvaluationRule(sceneEvaluationRulePO);
+//        } else {
+//            // 修改
+//            updateSceneEvaluationRule(sceneEvaluationRulePO);
+//        }
+        }
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
+    }
+
+
     @SneakyThrows
     public void deleteSceneEvaluationRule(SceneEvaluationRulePO params) {
         // todo 如果是复杂度脚本需要校验是否有自然/交通等模板有引用
@@ -217,238 +265,8 @@ public class SceneEvaluationRuleService {
     }
 
 
-    /**
-     * 场景上传计算复杂度,计算复杂度需要用到 osc 和 odr 路径,计算危险度用 evaluationPath
-     *
-     * @param param
-     */
-    public boolean computeSceneReference(SceneImportParam param, List<SceneEvaluationComputeParam> sceneEvaluationComputeParams) {
-        String ruleId = param.getSceneEvaluationRuleId();
-        // 获取场景评价规则
-        SceneEvaluationRulePO sceneEvaluationRulePO = sceneEvaluationRuleMapper.querySceneEvaluationPyById(ruleId);
-        if (sceneEvaluationRulePO == null) {
-            log.error(ruleId + " 的场景评价规则已删除");
-            return false;
-        }
-        // 1 判断有没有用户目录,没有则复制
-        String evaluationDirectoryOfUser = linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId() + "/";
-        String scriptsPath = evaluationDirectoryOfUser + "scripts";
-        if (!new File(evaluationDirectoryOfUser).exists()) {
-            // 1 将场景评价规则脚本保存到 script 目录
-            FileUtil.createDirectory(scriptsPath);
-//            final ArrayList<String> scriptFilePath = CollectionUtil.createArrayList(
-//                    "/data_preprocessing.py",
-//                    "/elevation.py",
-//                    "/scenario_evaluation_utils52.py"
-//            );
-//            for (String pyFilePath : scriptFilePath) {
-//                try {
-//                    downloadDependFile(sceneEvaluationScript + pyFilePath, scriptsPath + pyFilePath);
-//                } catch (IOException e) {
-//                    log.error("下载 py 依赖文件失败: " + sceneEvaluationScript + pyFilePath, e);
-//                    return false;
-//                }
-//            }
-        }
-
-        // 下载场景评价脚本到脚本目录
-        if (sceneEvaluationRulePO.getScriptPath() == null) {
-            return false;
-        }
-        String pyMainPath = scriptsPath + "/" + sceneEvaluationRulePO.getRuleId();
-        if (!new File(pyMainPath).exists()) {
-            try {
-                downloadDependFile(sceneEvaluationRulePO.getScriptPath(), pyMainPath);
-                Path path = Paths.get(pyMainPath);
-                Set<PosixFilePermission> permissions = new HashSet<>();
-                permissions.add(PosixFilePermission.OWNER_READ);
-                permissions.add(PosixFilePermission.OWNER_WRITE);
-                permissions.add(PosixFilePermission.OWNER_EXECUTE);
-                permissions.add(PosixFilePermission.GROUP_READ);
-                permissions.add(PosixFilePermission.GROUP_WRITE);
-                permissions.add(PosixFilePermission.GROUP_EXECUTE);
-                permissions.add(PosixFilePermission.OTHERS_READ);
-                permissions.add(PosixFilePermission.OTHERS_WRITE);
-                permissions.add(PosixFilePermission.OTHERS_EXECUTE);
-                Files.setPosixFilePermissions(path, permissions);
-            } catch (IOException e) {
-                log.error("下载执行文件失败: " + sceneEvaluationRulePO.getScriptPath(), e);
-                return false;
-            }
-        }
-        String scenePathFather = evaluationDirectoryOfUser + "scene/";
-        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
-            // 创建场景路径
-            String scenePath = scenePathFather + sceneEvaluationComputeParam.getSceneId();
-            if (!new File(scenePath).exists()) {
-                FileUtil.createDirectory(scenePath);
-            } else {
-                // 一个场景只计算一次
-                return false;
-            }
-            try {
-                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
-                    if (StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXODRPath())
-                            || StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXOSCPath())) {
-                        continue;
-                    }
-                    // 计算复杂度,根据场景 id 获取场景信息,下载 osc odr
-                    String scenarioOsc = sceneEvaluationComputeParam.getSceneXOSCPath();
-                    String[] splitXosc = scenarioOsc.split("/");
-                    String xoscName = splitXosc[splitXosc.length - 1];
-                    downloadDependFile(sceneEvaluationComputeParam.getSceneXOSCPath(), scenePath + "/" + xoscName);
-
-                    String scenarioOdr = sceneEvaluationComputeParam.getSceneXODRPath();
-                    String[] splitXodr = scenarioOdr.split("/");
-                    String xodrName = splitXodr[splitXodr.length - 1];
-                    downloadDependFile(sceneEvaluationComputeParam.getSceneXODRPath(), scenePath + "/" + xodrName);
-                } else if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.RISK)) {
-                    if (StringUtil.isEmpty(sceneEvaluationComputeParam.getEvaluationPath())) {
-                        continue;
-                    }
-                    // 计算危险度 从 minio path 下载 csv (ego 和 sensors)
-                    downloadDependFile(sceneEvaluationComputeParam.getEvaluationPath() + "/Ego.csv", scenePath + "/Ego.csv");
-                    downloadDependFile(sceneEvaluationComputeParam.getEvaluationPath() + "/evaluation.csv", scenePath + "/evaluation.csv");
-                } else {
-                    return false;
-                }
-            } catch (IOException e) {
-                log.error("文件下载失败", e);
-                FileUtil.deleteFolder(scenePath);   // 删除临时文件
-            }
-        }
-        String sceneEvaluationCommand;
-        if (StringUtils.equals(sceneEvaluationComputeParams.get(0).getComputeType(), DictConstants.COMPLEXITY)) {
-            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " complexity";
-        } else {
-            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " criticality";
-        }
-        String sceneEvaluationResult;
-        log.info("开始执行场景评价命令:" + sceneEvaluationCommand);
-        Runtime r = Runtime.getRuntime();
-        Process p;
-        try {
-            p = r.exec(sceneEvaluationCommand);
-        } catch (IOException e) {
-            log.error("执行场景评价脚本失败,脚本命令为: " + sceneEvaluationCommand, e);
-            return false;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        try {
-            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
-            String inline;
-            while ((inline = br.readLine()) != null) {
-                sb.append(inline).append("\n");
-            }
-            br.close();
-        } catch (IOException e) {
-            log.error("获取场景评价脚本返回内容失败", e);
-            return false;
-        }
-        sceneEvaluationResult = sb.toString();
-        log.info("场景评价结束,结果为:" + sceneEvaluationResult);
-        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
-            // 读文件
-            StringBuilder result = new StringBuilder();
-            try {
-                FileInputStream fileInputStream = new FileInputStream(scenePathFather + sceneEvaluationComputeParam.getSceneId() + "/scenario_evaluation.json");
-                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
-
-                String line;
-                while ((line = bufferedReader.readLine()) != null) {
-                    result.append(line).append("\n");
-                }
-                bufferedReader.close();
-            } catch (IOException e) {
-                log.error("读取场景评价结果失败", e);
-                continue;
-            }
-            String resultStr = result.toString();
-            String replace = StringUtil.replace(resultStr, "'", "\"");
-            JsonNode rootNode;
-            try {
-                ObjectMapper mapper = new ObjectMapper();
-                //JSON ----> JsonNode
-                rootNode = mapper.readTree(replace);
-
-                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
-                    String complexity = rootNode.path("复杂度").asText();
-                    String complexityLevel = rootNode.path("复杂度等级").asText();
-                    SceneComplexityPO sceneComplexityPO = new SceneComplexityPO();
-                    sceneComplexityPO.setSceneId(sceneEvaluationComputeParam.getSceneId());
-                    sceneComplexityPO.setComplexityId(StringUtil.getRandomUUID());
-                    sceneComplexityPO.setSceneType(sceneEvaluationComputeParam.getSceneType());
-                    sceneComplexityPO.setRuleId(ruleId);
-                    sceneComplexityPO.setTaskId(sceneEvaluationComputeParam.getTaskId());
-                    sceneComplexityPO.setComplexity(complexity);
-                    sceneComplexityPO.setComplexityLevel(matchLevelEnumByLevel(complexityLevel));
-                    sceneComplexityPO.setIsDeleted(DictConstants.IS_NOT_DELETED);
-                    sceneComplexityPO.setCreateUserId(AuthUtil.getCurrentUserId());
-                    sceneComplexityPO.setCreateTime(TimeUtil.getNowForMysql());
-                    sceneComplexityMapper.saveSceneComplexity(sceneComplexityPO);
-                    if (CollectionUtil.isNotEmpty(sceneEvaluationComputeParam.getCopySceneId())) {
-                        copySceneComplexityResult(sceneEvaluationComputeParam.getTaskId(), sceneEvaluationComputeParam.getSceneId(), sceneEvaluationComputeParam.getCopySceneId());
-                    }
-                } else {
-                    String risk = rootNode.path("危险度").asText();
-                    String riskLevel = rootNode.path("危险度等级").asText();
-                    SceneRiskPO sceneRiskPO = new SceneRiskPO();
-                    sceneRiskPO.setSceneId(sceneEvaluationComputeParam.getSceneId());
-                    sceneRiskPO.setRuleId(StringUtil.getRandomUUID());
-                    sceneRiskPO.setSceneType(sceneEvaluationComputeParam.getSceneType());
-                    sceneRiskPO.setRuleId(ruleId);
-                    sceneRiskPO.setTaskId(sceneEvaluationComputeParam.getTaskId());
-                    sceneRiskPO.setRisk(risk);
-                    sceneRiskPO.setRiskLevel(matchLevelEnumByLevel(riskLevel));
-                    sceneRiskPO.setIsDeleted(DictConstants.IS_NOT_DELETED);
-                    sceneRiskPO.setCreateUserId(AuthUtil.getCurrentUserId());
-                    sceneRiskPO.setCreateTime(TimeUtil.getNowForMysql());
-                    sceneRiskMapper.saveSceneRisk(sceneRiskPO);
-                }
-            } catch (Exception e) {
-                log.error("场景" + sceneEvaluationComputeParam.getSceneId() + " 的场景评价失败:", e);
-            }
-        }
-        // 删除临时文件
-//        FileUtil.deleteFolder(linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId());   // 删除临时文件
-        return true;
-    }
-
-    private void downloadDependFile(String minioPath, String localPath) throws IOException {
-        Response download = fileDownService.download(MinioParameter.builder().objectName(minioPath).build());
-        Response.Body body = download.body();
-        InputStream inputStream;
-        inputStream = body.asInputStream();
-        File file = new File(localPath);
-        OutputStream outputStream = Files.newOutputStream(file.toPath());
-        byte[] buffer = new byte[1024];
-        int bytesRead;
-        while ((bytesRead = inputStream.read(buffer)) != -1) {
-            outputStream.write(buffer, 0, bytesRead);
-        }
-        inputStream.close();
-        outputStream.close();
-        download.close();
-    }
-
-    public void copySceneComplexityResult(String taskId, String tempSceneId, List<String> copySceneIds) {
-        List<SceneComplexityPO> sceneComplexityPOS = sceneComplexityMapper.selectSceneComplexityEvaluation(taskId, tempSceneId);
-        List<SceneComplexityPO> saveList = new ArrayList<>();
-        if (CollectionUtil.isNotEmpty(sceneComplexityPOS)) {
-            for (SceneComplexityPO sceneComplexityPO : sceneComplexityPOS) {
-                for (String copySceneId : copySceneIds) {
-                    SceneComplexityPO tempComplexityPO = new SceneComplexityPO();
-                    BeanUtils.copyProperties(sceneComplexityPO, tempComplexityPO);
-                    tempComplexityPO.setSceneId(copySceneId);
-                    tempComplexityPO.setComplexityId(StringUtil.getRandomUUID());
-                    saveList.add(tempComplexityPO);
-                }
-            }
-            if (CollectionUtil.isNotEmpty(saveList)) {
-                sceneComplexityMapper.saveSceneComplexityS(saveList);
-            }
-        }
+    public void computeSceneReference(SceneImportParam param, List<SceneEvaluationComputeParam> sceneEvaluationComputeParams) {
+        ThreadPool.sceneEvaluationComputePool.execute(new SceneEvaluationComputeRunnable(param, sceneEvaluationComputeParams, linuxTempPath));
     }
 
     public boolean checkSelectReferenceComplexity(String sceneId, SceneEvaluationForListParam sceneEvaluationForListParam, Map<String, SceneComplexityPO> complexityPOMap) {

+ 1 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneNaturalService.java

@@ -711,6 +711,7 @@ public class SceneNaturalService {
                                 sceneEvaluationComputeParam.setSceneType(DictConstants.SCENE_NATURAL);
                                 sceneEvaluationComputeParam.setTaskId(taskId);
                                 sceneEvaluationComputeParam.setComputeType(DictConstants.COMPLEXITY);
+                                sceneEvaluationComputeParam.setCreateUserId(AuthUtil.getCurrentUserId());
                                 if (update) {
                                     String tempSceneId = scenes.get(0).getNaturalId();
                                     sceneEvaluationComputeParam.setCopySceneId(scenes.stream().map(SceneNaturalPO::getNaturalId).filter(sceneId -> !StringUtils.equals(tempSceneId, sceneId)).collect(Collectors.toList()));

+ 1 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneReferenceLibService.java

@@ -339,6 +339,7 @@ public class SceneReferenceLibService {
                                 sceneEvaluationComputeParam.setSceneType(DictConstants.SCENE_REFERENCE_LIB);
                                 sceneEvaluationComputeParam.setTaskId(taskId);
                                 sceneEvaluationComputeParam.setComputeType(DictConstants.COMPLEXITY);
+                                sceneEvaluationComputeParam.setCreateUserId(AuthUtil.getCurrentUserId());
                                 if (isUpdate) {
                                     String tempSceneId = scenes.get(0).getSceneId();
                                     sceneEvaluationComputeParam.setCopySceneId(scenes.stream().map(SceneReferenceLibPO::getSceneId).filter(sceneId -> !StringUtils.equals(tempSceneId, sceneId)).collect(Collectors.toList()));

+ 1 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/SceneStandardsService.java

@@ -442,6 +442,7 @@ public class SceneStandardsService {
                                 sceneEvaluationComputeParam.setSceneType(DictConstants.SCENE_STANDARD);
                                 sceneEvaluationComputeParam.setTaskId(taskId);
                                 sceneEvaluationComputeParam.setComputeType(DictConstants.COMPLEXITY);
+                                sceneEvaluationComputeParam.setCreateUserId(AuthUtil.getCurrentUserId());
                                 if (isupdate.equals("1")) {
                                     String tempSceneId = scenes.get(0).getRegulationsId();
                                     sceneEvaluationComputeParam.setCopySceneId(scenes.stream().map(StandardsRegulationsPO::getRegulationsId).filter(sceneId -> !StringUtils.equals(tempSceneId, sceneId)).collect(Collectors.toList()));

+ 278 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/runnable/SceneEvaluationComputeRunnable.java

@@ -0,0 +1,278 @@
+package com.css.simulation.resource.server.infra.runnable;
+
+import api.common.pojo.constants.DictConstants;
+import api.common.pojo.param.MinioParameter;
+import api.common.pojo.param.scene.SceneEvaluationComputeParam;
+import api.common.pojo.param.scene.SceneImportParam;
+import api.common.pojo.po.scene.SceneComplexityPO;
+import api.common.pojo.po.scene.SceneEvaluationRulePO;
+import api.common.pojo.po.scene.SceneRiskPO;
+import api.common.util.CollectionUtil;
+import api.common.util.FileUtil;
+import api.common.util.StringUtil;
+import api.common.util.TimeUtil;
+import com.alibaba.druid.util.StringUtils;
+import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneComplexityMapper;
+import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneEvaluationRuleMapper;
+import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneRiskMapper;
+import com.css.simulation.resource.server.infra.feign.service.FileDownService;
+import com.css.simulation.resource.server.app.impl.ApplicationContextAwareImpl;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import feign.Response;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static api.common.pojo.enums.SceneEvaluationEnum.matchLevelEnumByLevel;
+
+/**
+ * @author 15765
+ * @date 2024/4/10 22:22
+ */
+@Slf4j
+public class SceneEvaluationComputeRunnable implements Runnable {
+
+    private final String linuxTempPath;
+    private final SceneImportParam param;
+    private final List<SceneEvaluationComputeParam> sceneEvaluationComputeParams;
+
+    public SceneEvaluationComputeRunnable(SceneImportParam param, List<SceneEvaluationComputeParam> sceneEvaluationComputeParams, String linuxTempPath) {
+        this.param = param;
+        this.sceneEvaluationComputeParams = sceneEvaluationComputeParams;
+        this.linuxTempPath = linuxTempPath;
+    }
+
+    @Override
+    public void run() {
+        String ruleId = param.getSceneEvaluationRuleId();
+        log.info("开始执行线程:" + ruleId);
+        SceneEvaluationRuleMapper sceneEvaluationRuleMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneEvaluationRuleMapper.class);
+        SceneComplexityMapper sceneComplexityMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneComplexityMapper.class);
+        SceneRiskMapper sceneRiskMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneRiskMapper.class);
+        // 获取场景评价规则
+        SceneEvaluationRulePO sceneEvaluationRulePO = sceneEvaluationRuleMapper.querySceneEvaluationPyById(ruleId);
+        if (sceneEvaluationRulePO == null) {
+            log.error(ruleId + " 的场景评价规则已删除");
+            return;
+        }
+        log.info("场景评价规则为:" + sceneEvaluationRulePO);
+        // 1 判断有没有用户目录,没有则复制
+        String evaluationDirectoryOfUser = linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId() + "/";
+        String scriptsPath = evaluationDirectoryOfUser + "scripts";
+        if (!new File(evaluationDirectoryOfUser).exists()) {
+            // 1 将场景评价规则脚本保存到 script 目录
+            FileUtil.createDirectory(scriptsPath);
+        }
+
+        // 下载场景评价脚本到脚本目录
+        if (sceneEvaluationRulePO.getScriptPath() == null) {
+            return;
+        }
+        String pyMainPath = scriptsPath + "/" + sceneEvaluationRulePO.getRuleId();
+        if (!new File(pyMainPath).exists()) {
+            try {
+                downloadDependFile(sceneEvaluationRulePO.getScriptPath(), pyMainPath);
+                Path path = Paths.get(pyMainPath);
+                Set<PosixFilePermission> permissions = new HashSet<>();
+                permissions.add(PosixFilePermission.OWNER_READ);
+                permissions.add(PosixFilePermission.OWNER_WRITE);
+                permissions.add(PosixFilePermission.OWNER_EXECUTE);
+                permissions.add(PosixFilePermission.GROUP_READ);
+                permissions.add(PosixFilePermission.GROUP_WRITE);
+                permissions.add(PosixFilePermission.GROUP_EXECUTE);
+                permissions.add(PosixFilePermission.OTHERS_READ);
+                permissions.add(PosixFilePermission.OTHERS_WRITE);
+                permissions.add(PosixFilePermission.OTHERS_EXECUTE);
+                Files.setPosixFilePermissions(path, permissions);
+            } catch (IOException e) {
+                log.error("下载执行文件失败: " + sceneEvaluationRulePO.getScriptPath(), e);
+                return;
+            }
+        }
+        String scenePathFather = evaluationDirectoryOfUser + "scene/";
+        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
+            // 创建场景路径
+            String scenePath = scenePathFather + sceneEvaluationComputeParam.getSceneId();
+            if (!new File(scenePath).exists()) {
+                FileUtil.createDirectory(scenePath);
+            } else {
+                // 一个场景只计算一次
+                return;
+            }
+            try {
+                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
+                    if (StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXODRPath())
+                            || StringUtil.isEmpty(sceneEvaluationComputeParam.getSceneXOSCPath())) {
+                        continue;
+                    }
+                    // 计算复杂度,根据场景 id 获取场景信息,下载 osc odr
+                    String scenarioOsc = sceneEvaluationComputeParam.getSceneXOSCPath();
+                    String[] splitXosc = scenarioOsc.split("/");
+                    String xoscName = splitXosc[splitXosc.length - 1];
+                    downloadDependFile(sceneEvaluationComputeParam.getSceneXOSCPath(), scenePath + "/" + xoscName);
+
+                    String scenarioOdr = sceneEvaluationComputeParam.getSceneXODRPath();
+                    String[] splitXodr = scenarioOdr.split("/");
+                    String xodrName = splitXodr[splitXodr.length - 1];
+                    downloadDependFile(sceneEvaluationComputeParam.getSceneXODRPath(), scenePath + "/" + xodrName);
+                } else if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.RISK)) {
+                    if (StringUtil.isEmpty(sceneEvaluationComputeParam.getEvaluationPath())) {
+                        continue;
+                    }
+                    // 计算危险度 从 minio path 下载 csv (ego 和 sensors)
+                    downloadDependFile(sceneEvaluationComputeParam.getEvaluationPath() + "/Ego.csv", scenePath + "/Ego.csv");
+                    downloadDependFile(sceneEvaluationComputeParam.getEvaluationPath() + "/evaluation.csv", scenePath + "/evaluation.csv");
+                } else {
+                    return;
+                }
+            } catch (IOException e) {
+                log.error("文件下载失败", e);
+                FileUtil.deleteFolder(scenePath);   // 删除临时文件
+            }
+        }
+        String sceneEvaluationCommand;
+        if (StringUtils.equals(sceneEvaluationComputeParams.get(0).getComputeType(), DictConstants.COMPLEXITY)) {
+            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " complexity";
+        } else {
+            sceneEvaluationCommand = pyMainPath + " " + scenePathFather + " criticality";
+        }
+        String sceneEvaluationResult;
+        log.info("开始执行场景评价命令:" + sceneEvaluationCommand);
+        Runtime r = Runtime.getRuntime();
+        Process p;
+        try {
+            p = r.exec(sceneEvaluationCommand);
+        } catch (IOException e) {
+            log.error("执行场景评价脚本失败,脚本命令为: " + sceneEvaluationCommand, e);
+            return;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        try {
+            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String inline;
+            while ((inline = br.readLine()) != null) {
+                sb.append(inline).append("\n");
+            }
+            br.close();
+        } catch (IOException e) {
+            log.error("获取场景评价脚本返回内容失败", e);
+            return;
+        }
+        sceneEvaluationResult = sb.toString();
+        log.info("场景评价结束,结果为:" + sceneEvaluationResult);
+        for (SceneEvaluationComputeParam sceneEvaluationComputeParam : sceneEvaluationComputeParams) {
+            // 读文件
+            StringBuilder result = new StringBuilder();
+            try {
+                FileInputStream fileInputStream = new FileInputStream(scenePathFather + sceneEvaluationComputeParam.getSceneId() + "/scenario_evaluation.json");
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
+
+                String line;
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line).append("\n");
+                }
+                bufferedReader.close();
+            } catch (IOException e) {
+                log.error("读取场景评价结果失败", e);
+                continue;
+            }
+            String resultStr = result.toString();
+            String replace = StringUtil.replace(resultStr, "'", "\"");
+            JsonNode rootNode;
+            try {
+                ObjectMapper mapper = new ObjectMapper();
+                //JSON ----> JsonNode
+                rootNode = mapper.readTree(replace);
+
+                if (StringUtils.equals(sceneEvaluationComputeParam.getComputeType(), DictConstants.COMPLEXITY)) {
+                    String complexity = rootNode.path("复杂度").asText();
+                    String complexityLevel = rootNode.path("复杂度等级").asText();
+                    SceneComplexityPO sceneComplexityPO = new SceneComplexityPO();
+                    sceneComplexityPO.setSceneId(sceneEvaluationComputeParam.getSceneId());
+                    sceneComplexityPO.setComplexityId(StringUtil.getRandomUUID());
+                    sceneComplexityPO.setSceneType(sceneEvaluationComputeParam.getSceneType());
+                    sceneComplexityPO.setRuleId(ruleId);
+                    sceneComplexityPO.setTaskId(sceneEvaluationComputeParam.getTaskId());
+                    sceneComplexityPO.setComplexity(complexity);
+                    sceneComplexityPO.setComplexityLevel(matchLevelEnumByLevel(complexityLevel));
+                    sceneComplexityPO.setIsDeleted(DictConstants.IS_NOT_DELETED);
+                    sceneComplexityPO.setCreateUserId(sceneEvaluationComputeParam.getCreateUserId());
+                    sceneComplexityPO.setCreateTime(TimeUtil.getNowForMysql());
+                    sceneComplexityMapper.saveSceneComplexity(sceneComplexityPO);
+                    if (CollectionUtil.isNotEmpty(sceneEvaluationComputeParam.getCopySceneId())) {
+                        copySceneComplexityResult(sceneEvaluationComputeParam.getTaskId(), sceneEvaluationComputeParam.getSceneId(), sceneEvaluationComputeParam.getCopySceneId());
+                    }
+                } else {
+                    String risk = rootNode.path("危险度").asText();
+                    String riskLevel = rootNode.path("危险度等级").asText();
+                    SceneRiskPO sceneRiskPO = new SceneRiskPO();
+                    sceneRiskPO.setSceneId(sceneEvaluationComputeParam.getSceneId());
+                    sceneRiskPO.setRuleId(StringUtil.getRandomUUID());
+                    sceneRiskPO.setSceneType(sceneEvaluationComputeParam.getSceneType());
+                    sceneRiskPO.setRuleId(ruleId);
+                    sceneRiskPO.setTaskId(sceneEvaluationComputeParam.getTaskId());
+                    sceneRiskPO.setRisk(risk);
+                    sceneRiskPO.setRiskLevel(matchLevelEnumByLevel(riskLevel));
+                    sceneRiskPO.setIsDeleted(DictConstants.IS_NOT_DELETED);
+                    sceneRiskPO.setCreateUserId(sceneEvaluationComputeParam.getCreateUserId());
+                    sceneRiskPO.setCreateTime(TimeUtil.getNowForMysql());
+                    sceneRiskMapper.saveSceneRisk(sceneRiskPO);
+                }
+            } catch (Exception e) {
+                log.error("场景" + sceneEvaluationComputeParam.getSceneId() + " 的场景评价失败:", e);
+            }
+        }
+        // 删除临时文件
+//        FileUtil.deleteFolder(linuxTempPath + "scene/evaluation/" + sceneEvaluationComputeParams.get(0).getTaskId());   // 删除临时文件
+    }
+
+
+    private void downloadDependFile(String minioPath, String localPath) throws IOException {
+        FileDownService fileDownService = ApplicationContextAwareImpl.getApplicationContext().getBean(FileDownService.class);
+        Response download = fileDownService.download(MinioParameter.builder().objectName(minioPath).build());
+        Response.Body body = download.body();
+        InputStream inputStream;
+        inputStream = body.asInputStream();
+        File file = new File(localPath);
+        OutputStream outputStream = Files.newOutputStream(file.toPath());
+        byte[] buffer = new byte[1024];
+        int bytesRead;
+        while ((bytesRead = inputStream.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        inputStream.close();
+        outputStream.close();
+        download.close();
+    }
+
+    public void copySceneComplexityResult(String taskId, String tempSceneId, List<String> copySceneIds) {
+        SceneComplexityMapper sceneComplexityMapper = ApplicationContextAwareImpl.getApplicationContext().getBean(SceneComplexityMapper.class);
+        List<SceneComplexityPO> sceneComplexityPOS = sceneComplexityMapper.selectSceneComplexityEvaluation(taskId, tempSceneId);
+        List<SceneComplexityPO> saveList = new ArrayList<>();
+        if (CollectionUtil.isNotEmpty(sceneComplexityPOS)) {
+            for (SceneComplexityPO sceneComplexityPO : sceneComplexityPOS) {
+                for (String copySceneId : copySceneIds) {
+                    SceneComplexityPO tempComplexityPO = new SceneComplexityPO();
+                    BeanUtils.copyProperties(sceneComplexityPO, tempComplexityPO);
+                    tempComplexityPO.setSceneId(copySceneId);
+                    tempComplexityPO.setComplexityId(StringUtil.getRandomUUID());
+                    saveList.add(tempComplexityPO);
+                }
+            }
+            if (CollectionUtil.isNotEmpty(saveList)) {
+                sceneComplexityMapper.saveSceneComplexityS(saveList);
+            }
+        }
+    }
+}

+ 8 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/runnable/SceneEvaluationUploadRunnable.java

@@ -0,0 +1,8 @@
+package com.css.simulation.resource.server.infra.runnable;
+
+/**
+ * @author 15765
+ * @date 2024/4/10 22:22
+ */
+public class SceneEvaluationUploadRunnable {
+}

+ 24 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/threadpool/ThreadPool.java

@@ -0,0 +1,24 @@
+package com.css.simulation.resource.server.infra.threadpool;
+
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+
+import java.util.concurrent.*;
+
+/**
+ * @author lcy
+ * @date 2024/4/10 21:01
+ */
+public class ThreadPool {
+    private static final ThreadFactory sceneEvaluationComputeFactory = new ThreadFactoryBuilder()
+            .setNameFormat("scene-evaluation-compute-pool-%d").build();
+
+    private static final ThreadFactory sceneEvaluationUploadFactory = new ThreadFactoryBuilder()
+            .setNameFormat("scene-evaluation-upload-pool-%d").build();
+    public static ExecutorService sceneEvaluationComputePool = new ThreadPoolExecutor(5, 200,
+            0L, TimeUnit.MILLISECONDS,
+            new LinkedBlockingQueue<>(1024), sceneEvaluationComputeFactory, new ThreadPoolExecutor.AbortPolicy());
+
+    public static ExecutorService sceneEvaluationUploadPool = new ThreadPoolExecutor(5, 20,
+            0L, TimeUnit.MILLISECONDS,
+            new LinkedBlockingQueue<>(1024), sceneEvaluationUploadFactory, new ThreadPoolExecutor.AbortPolicy());
+}