|
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
import org.springframework.kafka.core.KafkaTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
import java.util.ArrayList;
|
|
@@ -34,9 +35,6 @@ import java.util.stream.Collectors;
|
|
|
@Slf4j
|
|
|
public class ManualProjectService {
|
|
|
|
|
|
-
|
|
|
- private static final String USER_ID = "simulation-resource-scheduler";
|
|
|
-
|
|
|
@Autowired
|
|
|
private SqlSessionFactory sqlSessionFactory;
|
|
|
@Autowired
|
|
@@ -56,70 +54,69 @@ public class ManualProjectService {
|
|
|
@Value("${minio.bucket-name}")
|
|
|
String bucketName;
|
|
|
|
|
|
- // -------------------------------- Comment --------------------------------
|
|
|
+ @Autowired
|
|
|
+ ManualProjectMapper manualProjectMapper;
|
|
|
+ @Autowired
|
|
|
+ TaskMapper taskMapper;
|
|
|
+ @Autowired
|
|
|
+ IndexTemplateMapper indexTemplateMapper;
|
|
|
+ @Autowired
|
|
|
+ SceneMapper sceneMapper;
|
|
|
+ @Autowired
|
|
|
+ AlgorithmMapper algorithmMapper;
|
|
|
|
|
|
- public void prepare(String manualProjectTopic, String projectId, String projectJson) {
|
|
|
+ // -------------------------------- Comment --------------------------------
|
|
|
|
|
|
+ @Transactional
|
|
|
+ public void prepare(String manualProjectTopic, String userId, String projectId, String projectJson) {
|
|
|
//1 redis 设置项目已完成任务为 0
|
|
|
Set<String> oldKeys = stringRedisTemplate.keys(manualProjectTopic + ":" + projectId + "*");
|
|
|
- assert oldKeys != null;
|
|
|
- stringRedisTemplate.delete(oldKeys);
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":completed", "0");
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":start", projectJson);
|
|
|
-
|
|
|
- try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
|
|
|
- ManualProjectMapper manualProjectMapper = sqlSession.getMapper(ManualProjectMapper.class);
|
|
|
- TaskMapper taskMapper = sqlSession.getMapper(TaskMapper.class);
|
|
|
- manualProjectMapper.resetProjectState(projectId, DictConstants.PROJECT_RUNNING); // 修改该 project 的状态为执行中,同时将已完成任务重置为 0 。
|
|
|
- taskMapper.deleteByProject(projectId); // 将该 project 下所有任务删除。
|
|
|
- sqlSession.commit();
|
|
|
+ if (CollectionUtil.isNotEmpty(oldKeys)) {
|
|
|
+ stringRedisTemplate.delete(oldKeys);
|
|
|
}
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":completed", "0");
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":start", projectJson);
|
|
|
+ manualProjectMapper.updateInit(projectId, DictConstants.PROJECT_RUNNING); // 修改该 project 的状态为执行中,同时将已完成任务重置为 0 。
|
|
|
+ taskMapper.deleteByProject(projectId); // 将该 project 下所有任务删除。
|
|
|
}
|
|
|
|
|
|
+ @SneakyThrows
|
|
|
+ @Transactional
|
|
|
+ public List<ScenePO> handlePackage(String manualProjectTopic, String userId, String projectId, String packageId) {
|
|
|
|
|
|
- public List<ScenePO> handlePackage(String manualProjectTopic, String projectId, String packageId) {
|
|
|
-
|
|
|
- try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
|
|
|
- IndexTemplateMapper indexTemplateMapper = sqlSession.getMapper(IndexTemplateMapper.class);
|
|
|
- SceneMapper sceneMapper = sqlSession.getMapper(SceneMapper.class);
|
|
|
- //1 查询该场景包的所有指标列表存入 redis
|
|
|
- List<IndexTemplatePO> allIndexList = indexTemplateMapper.selectByPackageIdIncludeDeleted(packageId);
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":" + packageId + ":all", JsonUtil.listToJson(allIndexList));
|
|
|
-
|
|
|
- //2 查询场景包叶子指标
|
|
|
- List<IndexTemplatePO> leafIndexList = allIndexList.stream().filter(index -> StringUtil.isNotEmpty(index.getRuleId())).collect(Collectors.toList());
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":" + packageId + ":leaf", JsonUtil.listToJson(leafIndexList));
|
|
|
- log.info("ManualProjectService--handlePackage 项目 " + projectId + " 的叶子指标为:" + leafIndexList);
|
|
|
- List<ScenePO> sceneList = new ArrayList<>();
|
|
|
- leafIndexList.forEach(leafIndex -> {
|
|
|
- String naturalIds = leafIndex.getSceneNaturalIds();
|
|
|
- String standardIds = leafIndex.getSceneStatueIds();
|
|
|
- String accidentIds = leafIndex.getSceneTrafficIds();
|
|
|
- if (StringUtil.isNotEmpty(naturalIds)) {
|
|
|
- List<String> naturalIdList = new ArrayList<>(Arrays.asList(naturalIds.split(",")));
|
|
|
- sceneList.addAll(sceneMapper.selectNaturalByIdList(naturalIdList));
|
|
|
- }
|
|
|
- if (StringUtil.isNotEmpty(standardIds)) {
|
|
|
- List<String> standardIdList = new ArrayList<>(Arrays.asList(standardIds.split(",")));
|
|
|
- sceneList.addAll(sceneMapper.selectStandardByIdList(standardIdList));
|
|
|
- }
|
|
|
- if (StringUtil.isNotEmpty(accidentIds)) {
|
|
|
- List<String> accidentIdList = new ArrayList<>(Arrays.asList(accidentIds.split(",")));
|
|
|
- sceneList.addAll(sceneMapper.selectAccidentByIdList(accidentIdList));
|
|
|
- }
|
|
|
- });
|
|
|
- sqlSession.commit();
|
|
|
- return sceneList;
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("ManualProjectService--handlePackage 场景包处理出错:" + e.getMessage());
|
|
|
- }
|
|
|
-
|
|
|
+ //1 查询该场景包的所有指标列表存入 redis
|
|
|
+ List<IndexTemplatePO> allIndexList = indexTemplateMapper.selectByPackageIdIncludeDeleted(packageId);
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":package:" + packageId + ":all", JsonUtil.listToJson(allIndexList));
|
|
|
|
|
|
+ //2 查询场景包叶子指标
|
|
|
+ List<IndexTemplatePO> leafIndexList = allIndexList.stream().filter(index -> StringUtil.isNotEmpty(index.getRuleId())).collect(Collectors.toList());
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":package:" + packageId + ":leaf", JsonUtil.listToJson(leafIndexList));
|
|
|
+ log.info("ManualProjectService--handlePackage 项目 " + projectId + " 的叶子指标为:" + leafIndexList);
|
|
|
+ List<ScenePO> sceneList = new ArrayList<>();
|
|
|
+ leafIndexList.forEach(leafIndex -> {
|
|
|
+ String naturalIds = leafIndex.getSceneNaturalIds();
|
|
|
+ String standardIds = leafIndex.getSceneStatueIds();
|
|
|
+ String accidentIds = leafIndex.getSceneTrafficIds();
|
|
|
+ if (StringUtil.isNotEmpty(naturalIds)) {
|
|
|
+ List<String> naturalIdList = new ArrayList<>(Arrays.asList(naturalIds.split(",")));
|
|
|
+ sceneList.addAll(sceneMapper.selectNaturalByIdList(naturalIdList));
|
|
|
+ }
|
|
|
+ if (StringUtil.isNotEmpty(standardIds)) {
|
|
|
+ List<String> standardIdList = new ArrayList<>(Arrays.asList(standardIds.split(",")));
|
|
|
+ sceneList.addAll(sceneMapper.selectStandardByIdList(standardIdList));
|
|
|
+ }
|
|
|
+ if (StringUtil.isNotEmpty(accidentIds)) {
|
|
|
+ List<String> accidentIdList = new ArrayList<>(Arrays.asList(accidentIds.split(",")));
|
|
|
+ sceneList.addAll(sceneMapper.selectAccidentByIdList(accidentIdList));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ manualProjectMapper.updateTaskNumber(projectId, sceneList.size());
|
|
|
+ log.info("ManualProjectService--handlePackage 项目" + projectId + " 共有 " + sceneList.size() + " 个任务,对应 " + sceneList.size() + " 个场景!");
|
|
|
+ return sceneList;
|
|
|
}
|
|
|
|
|
|
|
|
|
- public void sendTaskMessage(String manualProjectTopic, String projectId, int maxSimulationTime, Set<ScenePO> scenePOSet, VehiclePO vehiclePO, List<CameraPO> cameraPOList, List<OgtPO> ogtPOList) {
|
|
|
+ public void sendTaskMessage(String manualProjectTopic, String userId, String projectId, int maxSimulationTime, Set<ScenePO> scenePOSet, VehiclePO vehiclePO, List<CameraPO> cameraPOList, List<OgtPO> ogtPOList) {
|
|
|
|
|
|
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
|
|
|
IndexMapper indexMapper = sqlSession.getMapper(IndexMapper.class);
|
|
@@ -133,7 +130,7 @@ public class ManualProjectService {
|
|
|
lastTargetIdList.forEach(lastTargetId -> {
|
|
|
String taskId = StringUtil.getRandomUUID();
|
|
|
// 设置任务重试次数为 0,方便任务进行最大3次的重试。
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":" + taskId + ":retry", "0");
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":task:" + taskId + ":retry", "0");
|
|
|
// 保存任务信息
|
|
|
TaskPO taskPO = TaskPO.builder() // run_start_time 和 run_end_time 不填
|
|
|
.id(taskId)
|
|
@@ -146,9 +143,9 @@ public class ManualProjectService {
|
|
|
.runResultFilePath(resultPathMinio + projectId + "/" + taskId)
|
|
|
.build();
|
|
|
taskPO.setCreateTime(TimeUtil.getNowForMysql());
|
|
|
- taskPO.setCreateUserId(USER_ID);
|
|
|
+ taskPO.setCreateUserId(userId);
|
|
|
taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
- taskPO.setModifyUserId(USER_ID);
|
|
|
+ taskPO.setModifyUserId(userId);
|
|
|
taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
taskPO.setIsDeleted("0");
|
|
|
taskMapper.insert(taskPO);
|
|
@@ -222,7 +219,7 @@ public class ManualProjectService {
|
|
|
log.error("------- 发送消息失败:" + failure.getMessage());
|
|
|
});
|
|
|
messageNumber[0] = messageNumber[0] + 1;
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + projectId + ":" + taskId + ":message", taskJson);
|
|
|
+ stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":task:" + taskId + ":message", taskJson);
|
|
|
});
|
|
|
});
|
|
|
log.info("------- ManualProjectConsumer 共发送了" + messageNumber[0] + " 条消息!");
|
|
@@ -236,27 +233,25 @@ public class ManualProjectService {
|
|
|
|
|
|
|
|
|
@SneakyThrows
|
|
|
- public String handleAlgorithm(String manualProjectTopic, String projectId, String algorithmId) {
|
|
|
+ @Transactional
|
|
|
+ public String handleAlgorithm(String projectId, String algorithmId) {
|
|
|
String dockerImage;
|
|
|
- try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
|
|
|
- AlgorithmMapper algorithmMapper = sqlSession.getMapper(AlgorithmMapper.class);
|
|
|
- TaskMapper taskMapper = sqlSession.getMapper(TaskMapper.class);
|
|
|
- //4-1 根据算法 id 获取算法文件地址、是否已导入成镜像。
|
|
|
- AlgorithmPO algorithmPO = algorithmMapper.selectById(algorithmId);
|
|
|
- String algorithmTarLinuxTempPath = linuxTempPath + "algorithm/" + algorithmId + ".tar";
|
|
|
- dockerImage = "algorithm_" + algorithmId + ":latest";
|
|
|
- if (algorithmPO == null) {
|
|
|
- // 访问索为远程接口
|
|
|
- String tokenUri = "http://open-api.zoogooy.com/cgi-bin/token/token?grant_type=client_credential";
|
|
|
- String appid = "3e64be4a29e5478f9717d53c11ab26ad";
|
|
|
- String secret = "f183079f97ac9ed81a864619a83fc17a";
|
|
|
- String tokenUrl = tokenUri + "&appid=" + appid + "&secret=" + secret;
|
|
|
- String result = HttpUtil.get(closeableHttpClient, requestConfig, tokenUrl);
|
|
|
- ObjectMapper objectMapper = new ObjectMapper();
|
|
|
- JsonNode jsonNode = objectMapper.readTree(result);
|
|
|
- JsonNode dataNode = jsonNode.path("data");
|
|
|
+ //4-1 根据算法 id 获取算法文件地址、是否已导入成镜像。
|
|
|
+ AlgorithmPO algorithmPO = algorithmMapper.selectById(algorithmId);
|
|
|
+ String algorithmTarLinuxTempPath = linuxTempPath + "algorithm/" + algorithmId + ".tar";
|
|
|
+ dockerImage = "algorithm_" + algorithmId + ":latest";
|
|
|
+ if (algorithmPO == null) {
|
|
|
+ // 访问索为远程接口
|
|
|
+ String tokenUri = "http://open-api.zoogooy.com/cgi-bin/token/token?grant_type=client_credential";
|
|
|
+ String appid = "3e64be4a29e5478f9717d53c11ab26ad";
|
|
|
+ String secret = "f183079f97ac9ed81a864619a83fc17a";
|
|
|
+ String tokenUrl = tokenUri + "&appid=" + appid + "&secret=" + secret;
|
|
|
+ String result = HttpUtil.get(closeableHttpClient, requestConfig, tokenUrl);
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ JsonNode jsonNode = objectMapper.readTree(result);
|
|
|
+ JsonNode dataNode = jsonNode.path("data");
|
|
|
|
|
|
- String token = dataNode.path("access_token").asText();
|
|
|
+ String token = dataNode.path("access_token").asText();
|
|
|
|
|
|
/*
|
|
|
{
|
|
@@ -287,31 +282,29 @@ public class ManualProjectService {
|
|
|
"nowTime" : "2022-04-22 10:14:40"
|
|
|
}
|
|
|
*/
|
|
|
- String downloadUrl = "http://open-api.zoogooy.com/cgi-bin/api/icv-algorithm-agg/simulation/download"
|
|
|
- + "?access_token=" + token
|
|
|
- + "&id=" + algorithmId;
|
|
|
- String tempDownloadUrl = HttpUtil.get(closeableHttpClient, requestConfig, downloadUrl);
|
|
|
- InputStream inputStream = HttpUtil.getInputStream(closeableHttpClient, requestConfig, tempDownloadUrl);
|
|
|
- FileUtil.writeInputStreamToLocalFile(inputStream, algorithmTarLinuxTempPath);
|
|
|
+ String downloadUrl = "http://open-api.zoogooy.com/cgi-bin/api/icv-algorithm-agg/simulation/download"
|
|
|
+ + "?access_token=" + token
|
|
|
+ + "&id=" + algorithmId;
|
|
|
+ String tempDownloadUrl = HttpUtil.get(closeableHttpClient, requestConfig, downloadUrl);
|
|
|
+ InputStream inputStream = HttpUtil.getInputStream(closeableHttpClient, requestConfig, tempDownloadUrl);
|
|
|
+ FileUtil.writeInputStreamToLocalFile(inputStream, algorithmTarLinuxTempPath);
|
|
|
+ LinuxUtil.execute("docker import " + algorithmTarLinuxTempPath + " " + dockerImage);
|
|
|
+ } else {
|
|
|
+ String minioPath = algorithmPO.getMinioPath();
|
|
|
+ if ("0".equals(algorithmPO.getDockerImport()) || algorithmPO.getDockerImport() == null) {
|
|
|
+ // 下载算法文件到本地( 2 到仓库服务器)
|
|
|
+ MinioUtil.downloadToFile(minioClient, bucketName, minioPath, algorithmTarLinuxTempPath);
|
|
|
+ //4-2 本地执行 docker load 算法文件成镜像(集群版可改成用 docker-java 操作仓库)
|
|
|
LinuxUtil.execute("docker import " + algorithmTarLinuxTempPath + " " + dockerImage);
|
|
|
+ algorithmMapper.updateDockerImportAndDockerImageById("1", dockerImage, algorithmId);
|
|
|
+ } else if ("1".equals(algorithmPO.getDockerImport()) && StringUtil.isNotEmpty(algorithmPO.getDockerImage())) {
|
|
|
+ dockerImage = algorithmPO.getDockerImage();
|
|
|
} else {
|
|
|
- String minioPath = algorithmPO.getMinioPath();
|
|
|
- if ("0".equals(algorithmPO.getDockerImport()) || algorithmPO.getDockerImport() == null) {
|
|
|
- // 下载算法文件到本地( 2 到仓库服务器)
|
|
|
- MinioUtil.downloadToFile(minioClient, bucketName, minioPath, algorithmTarLinuxTempPath);
|
|
|
- //4-2 本地执行 docker load 算法文件成镜像(集群版可改成用 docker-java 操作仓库)
|
|
|
- LinuxUtil.execute("docker import " + algorithmTarLinuxTempPath + " " + dockerImage);
|
|
|
- algorithmMapper.updateDockerImportAndDockerImageById("1", dockerImage, algorithmId);
|
|
|
- } else if ("1".equals(algorithmPO.getDockerImport()) && StringUtil.isNotEmpty(algorithmPO.getDockerImage())) {
|
|
|
- dockerImage = algorithmPO.getDockerImage();
|
|
|
- } else {
|
|
|
- throw new RuntimeException("算法 " + algorithmId + " 的 mysql 数据有误!");
|
|
|
- }
|
|
|
+ throw new RuntimeException("算法 " + algorithmId + " 的 mysql 数据有误!");
|
|
|
}
|
|
|
- sqlSession.commit();
|
|
|
}
|
|
|
- return dockerImage;
|
|
|
-
|
|
|
|
|
|
+ log.info("ManualProjectService--handleAlgorithm 项目 " + projectId + " 使用的算法镜像为:" + dockerImage);
|
|
|
+ return dockerImage;
|
|
|
}
|
|
|
}
|