|
@@ -14,8 +14,6 @@ import lombok.SneakyThrows;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.http.client.config.RequestConfig;
|
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
-import org.apache.ibatis.session.ExecutorType;
|
|
|
-import org.apache.ibatis.session.SqlSession;
|
|
|
import org.apache.ibatis.session.SqlSessionFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
@@ -57,6 +55,8 @@ public class ManualProjectService {
|
|
|
@Autowired
|
|
|
ManualProjectMapper manualProjectMapper;
|
|
|
@Autowired
|
|
|
+ AutoSubProjectMapper autoSubProjectMapper;
|
|
|
+ @Autowired
|
|
|
TaskMapper taskMapper;
|
|
|
@Autowired
|
|
|
IndexTemplateMapper indexTemplateMapper;
|
|
@@ -77,16 +77,24 @@ public class ManualProjectService {
|
|
|
// -------------------------------- Comment --------------------------------
|
|
|
|
|
|
@Transactional
|
|
|
- public void prepare(String manualProjectTopic, String userId, String projectId, String projectJson) {
|
|
|
- //1 redis 设置项目已完成任务为 0
|
|
|
- Set<String> oldKeys = stringRedisTemplate.keys(manualProjectTopic + ":" + projectId + "*");
|
|
|
+ public void prepare(String clusterPrefix, String projectId, String projectType) {
|
|
|
+ //1 如果集群中有该项目旧的信息则直接删除
|
|
|
+ Set<String> oldKeys = stringRedisTemplate.keys(clusterPrefix + "*");
|
|
|
if (CollectionUtil.isNotEmpty(oldKeys)) {
|
|
|
- stringRedisTemplate.delete(oldKeys);
|
|
|
+ for (String oldKey : oldKeys) {
|
|
|
+ if (oldKey.contains(projectId)) {
|
|
|
+ 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 。
|
|
|
- // 将该 project 下所有旧的任务和指标得分删除。
|
|
|
+ //2 将项目状态修改为执行中
|
|
|
+ if (DictConstants.PROJECT_TYPE_MANUAL.equals(projectType)) {
|
|
|
+ manualProjectMapper.updateNowRunStateById(DictConstants.PROJECT_RUNNING, projectId); // 修改该 project 的状态为执行中,同时将已完成任务重置为 0 。
|
|
|
+ } else if (DictConstants.PROJECT_TYPE_AUTO_SUB.equals(projectType)) {
|
|
|
+ autoSubProjectMapper.updateNowRunStateById(DictConstants.PROJECT_RUNNING, projectId);
|
|
|
+ }
|
|
|
+
|
|
|
+ //3 将该 project 下所有旧的任务和指标得分删除。
|
|
|
taskMapper.deleteByProject(projectId);
|
|
|
indexMapper.deleteFirstTargetScoreByProjectId(projectId);
|
|
|
indexMapper.deleteLastTargetScoreByProjectId(projectId);
|
|
@@ -94,15 +102,17 @@ public class ManualProjectService {
|
|
|
|
|
|
@SneakyThrows
|
|
|
@Transactional
|
|
|
- public List<ScenePO> handlePackage(String manualProjectTopic, String userId, String projectId, String packageId) {
|
|
|
+ public List<ScenePO> handlePackage(String projectRunningPrefix, String projectId, String packageId) {
|
|
|
+ String allIndexPrefix = projectRunningPrefix + ":package:" + packageId + ":all";
|
|
|
+ String leafIndexPrefix = projectRunningPrefix + ":package:" + packageId + ":leaf";
|
|
|
|
|
|
//1 查询该场景包的所有指标列表存入 redis,包删了无所谓,但要过滤删掉的指标
|
|
|
List<IndexTemplatePO> allIndexList = indexTemplateMapper.selectByPackageIdIncludeDeleted(packageId);
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":package:" + packageId + ":all", JsonUtil.listToJson(allIndexList));
|
|
|
+ stringRedisTemplate.opsForValue().set(allIndexPrefix, 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));
|
|
|
+ stringRedisTemplate.opsForValue().set(leafIndexPrefix, JsonUtil.listToJson(leafIndexList));
|
|
|
log.info("ManualProjectService--handlePackage 项目 " + projectId + " 的叶子指标为:" + leafIndexList);
|
|
|
List<ScenePO> sceneList = new ArrayList<>();
|
|
|
leafIndexList.forEach(leafIndex -> {
|
|
@@ -122,125 +132,115 @@ public class ManualProjectService {
|
|
|
sceneList.addAll(sceneMapper.selectAccidentByIdList(accidentIdList));
|
|
|
}
|
|
|
});
|
|
|
- manualProjectMapper.updateTaskNumber(projectId, sceneList.size());
|
|
|
- log.info("ManualProjectService--handlePackage 项目" + projectId + " 共有 " + sceneList.size() + " 个任务,对应 " + sceneList.size() + " 个场景!");
|
|
|
+ log.info("ManualProjectService--handlePackage 项目" + projectId + " 共有 " + sceneList.size() + " 个任务!");
|
|
|
return sceneList;
|
|
|
}
|
|
|
|
|
|
|
|
|
- public void sendTaskMessage(String manualProjectTopic, String userId, String projectId, int maxSimulationTime, Set<ScenePO> scenePOSet, VehiclePO vehiclePO, List<CameraPO> cameraPOList, List<OgtPO> ogtPOList) {
|
|
|
+ public void sendTaskMessage(String projectRunningPrefix, String userId, String projectId, Long maxSimulationTime, Set<ScenePO> scenePOSet, VehiclePO vehiclePO, List<CameraPO> cameraPOList, List<OgtPO> ogtPOList) {
|
|
|
+ final int[] messageNumber = {0};
|
|
|
+ for (ScenePO scenePO : scenePOSet) {
|
|
|
+ String sceneId = scenePO.getId();
|
|
|
+ //3-1 可能会存在多个指标下有同样的场景,所以会查出多个指标,多个指标的场景需要发送多次
|
|
|
+ List<String> lastTargetIdList = indexMapper.selectLeafIndexIdByProjectAndSceneId(projectId, "%" + sceneId + "%");
|
|
|
+ lastTargetIdList.forEach(lastTargetId -> {
|
|
|
+ String taskId = StringUtil.getRandomUUID();
|
|
|
+ String taskRetryPrefix = projectRunningPrefix + ":task:" + taskId + ":retry";
|
|
|
+ String taskMessagePrefix = projectRunningPrefix + ":task:" + taskId + ":message";
|
|
|
+ // 设置任务重试次数为 0,方便任务进行最大3次的重试。
|
|
|
+ stringRedisTemplate.opsForValue().set(taskRetryPrefix, "0");
|
|
|
+ // 保存任务信息
|
|
|
+ TaskPO taskPO = TaskPO.builder() // run_start_time 和 run_end_time 不填
|
|
|
+ .id(taskId)
|
|
|
+ .pId(projectId)
|
|
|
+ .sceneId(sceneId)
|
|
|
+ .lastTargetId(lastTargetId)
|
|
|
+ .sceneName(scenePO.getName())
|
|
|
+ .sceneType(scenePO.getType())
|
|
|
+ .runState(DictConstants.TASK_PENDING)
|
|
|
+ .runResultFilePath(resultPathMinio + projectId + "/" + taskId)
|
|
|
+ .build();
|
|
|
+ taskPO.setCreateTime(TimeUtil.getNowForMysql());
|
|
|
+ taskPO.setCreateUserId(userId);
|
|
|
+ taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
+ taskPO.setModifyUserId(userId);
|
|
|
+ taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
+ taskPO.setIsDeleted("0");
|
|
|
+ taskMapper.insert(taskPO);
|
|
|
|
|
|
- try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
|
|
|
- IndexMapper indexMapper = sqlSession.getMapper(IndexMapper.class);
|
|
|
- TaskMapper taskMapper = sqlSession.getMapper(TaskMapper.class);
|
|
|
+ // 组装 task 消息
|
|
|
+ TaskTO taskTO = TaskTO.builder()
|
|
|
+ .info(InfoTO.builder()
|
|
|
+ .project_id(taskPO.getPId())
|
|
|
+ .task_id(taskPO.getId())
|
|
|
+ .task_path(taskPO.getRunResultFilePath())
|
|
|
+ .default_time(maxSimulationTime)
|
|
|
+ .build())
|
|
|
+ .scenario(ScenarioTO.builder()
|
|
|
+ .scenario_osc(scenePO.getScenarioOsc())
|
|
|
+ .scenario_odr(scenePO.getScenarioOdr())
|
|
|
+ .scenario_osgb(scenePO.getScenarioOsgb())
|
|
|
+ .build())
|
|
|
+ .vehicle(VehicleTO.builder()
|
|
|
+ .model(ModelTO.builder()
|
|
|
+ .model_label(vehiclePO.getModelLabel())
|
|
|
+ .build())
|
|
|
+ .dynamics(DynamicsTO.builder()
|
|
|
+ .dynamics_maxspeed(vehiclePO.getMaxSpeed())
|
|
|
+ .dynamics_enginepower(vehiclePO.getEnginePower())
|
|
|
+ .dynamics_maxdecel(vehiclePO.getMaxDeceleration())
|
|
|
+ .dynamics_maxsteering(vehiclePO.getMaxSteeringAngle())
|
|
|
+ .dynamics_mass(vehiclePO.getMass())
|
|
|
+ .dynamics_frontsurfaceeffective(vehiclePO.getFrontSurfaceEffective())
|
|
|
+ .dynamics_airdragcoefficient(vehiclePO.getAirDragCoefficient())
|
|
|
+ .dynamics_rollingresistance(vehiclePO.getRollingResistanceCoefficient())
|
|
|
+ .dynamics_wheeldiameter(vehiclePO.getWheelDiameter())
|
|
|
+ .dynamics_wheeldrive(vehiclePO.getWheelDrive())
|
|
|
+ .dynamics_overallefficiency(vehiclePO.getOverallEfficiency())
|
|
|
+ .dynamics_distfront(vehiclePO.getFrontDistance())
|
|
|
+ .dynamics_distrear(vehiclePO.getRearDistance())
|
|
|
+ .dynamics_distleft(vehiclePO.getLeftDistance())
|
|
|
+ .dynamics_distright(vehiclePO.getRightDistance())
|
|
|
+ .dynamics_distheight(vehiclePO.getHeightDistance())
|
|
|
+ .dynamics_wheelbase(vehiclePO.getWheelbase())
|
|
|
+ .build())
|
|
|
+ .sensors(SensorsTO.builder() // 根据 vehicleId 查询绑定的传感器列表
|
|
|
+ .camera(cameraPOList)
|
|
|
+ .OGT(ogtPOList)
|
|
|
+ .build())
|
|
|
+ .build())
|
|
|
+ .build();
|
|
|
|
|
|
- final int[] messageNumber = {0};
|
|
|
- scenePOSet.forEach(scenePO -> {
|
|
|
- String sceneId = scenePO.getId();
|
|
|
- //3-1 可能会存在多个指标下有同样的场景,所以会查出多个指标,多个指标的场景需要发送多次
|
|
|
- List<String> lastTargetIdList = indexMapper.selectLeafIndexIdByProjectAndSceneId(projectId, "%" + sceneId + "%");
|
|
|
- lastTargetIdList.forEach(lastTargetId -> {
|
|
|
- String taskId = StringUtil.getRandomUUID();
|
|
|
- // 设置任务重试次数为 0,方便任务进行最大3次的重试。
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":task:" + taskId + ":retry", "0");
|
|
|
- // 保存任务信息
|
|
|
- TaskPO taskPO = TaskPO.builder() // run_start_time 和 run_end_time 不填
|
|
|
- .id(taskId)
|
|
|
- .pId(projectId)
|
|
|
- .sceneId(sceneId)
|
|
|
- .lastTargetId(lastTargetId)
|
|
|
- .sceneName(scenePO.getName())
|
|
|
- .sceneType(scenePO.getType())
|
|
|
- .runState(DictConstants.TASK_PENDING)
|
|
|
- .runResultFilePath(resultPathMinio + projectId + "/" + taskId)
|
|
|
- .build();
|
|
|
- taskPO.setCreateTime(TimeUtil.getNowForMysql());
|
|
|
- taskPO.setCreateUserId(userId);
|
|
|
- taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
- taskPO.setModifyUserId(userId);
|
|
|
- taskPO.setModifyTime(TimeUtil.getNowForMysql());
|
|
|
- taskPO.setIsDeleted("0");
|
|
|
- taskMapper.insert(taskPO);
|
|
|
-
|
|
|
- // 组装 task 消息
|
|
|
- TaskTO taskTO = TaskTO.builder()
|
|
|
- .info(InfoTO.builder()
|
|
|
- .project_id(taskPO.getPId())
|
|
|
- .task_id(taskPO.getId())
|
|
|
- .task_path(taskPO.getRunResultFilePath())
|
|
|
- .default_time(maxSimulationTime)
|
|
|
- .build())
|
|
|
- .scenario(ScenarioTO.builder()
|
|
|
- .scenario_osc(scenePO.getScenarioOsc())
|
|
|
- .scenario_odr(scenePO.getScenarioOdr())
|
|
|
- .scenario_osgb(scenePO.getScenarioOsgb())
|
|
|
- .build())
|
|
|
- .vehicle(VehicleTO.builder()
|
|
|
- .model(ModelTO.builder()
|
|
|
- .model_label(vehiclePO.getModelLabel())
|
|
|
- .build())
|
|
|
- .dynamics(DynamicsTO.builder()
|
|
|
- .dynamics_maxspeed(vehiclePO.getMaxSpeed())
|
|
|
- .dynamics_enginepower(vehiclePO.getEnginePower())
|
|
|
- .dynamics_maxdecel(vehiclePO.getMaxDeceleration())
|
|
|
- .dynamics_maxsteering(vehiclePO.getMaxSteeringAngle())
|
|
|
- .dynamics_mass(vehiclePO.getMass())
|
|
|
- .dynamics_frontsurfaceeffective(vehiclePO.getFrontSurfaceEffective())
|
|
|
- .dynamics_airdragcoefficient(vehiclePO.getAirDragCoefficient())
|
|
|
- .dynamics_rollingresistance(vehiclePO.getRollingResistanceCoefficient())
|
|
|
- .dynamics_wheeldiameter(vehiclePO.getWheelDiameter())
|
|
|
- .dynamics_wheeldrive(vehiclePO.getWheelDrive())
|
|
|
- .dynamics_overallefficiency(vehiclePO.getOverallEfficiency())
|
|
|
- .dynamics_distfront(vehiclePO.getFrontDistance())
|
|
|
- .dynamics_distrear(vehiclePO.getRearDistance())
|
|
|
- .dynamics_distleft(vehiclePO.getLeftDistance())
|
|
|
- .dynamics_distright(vehiclePO.getRightDistance())
|
|
|
- .dynamics_distheight(vehiclePO.getHeightDistance())
|
|
|
- .dynamics_wheelbase(vehiclePO.getWheelbase())
|
|
|
- .build())
|
|
|
- .sensors(SensorsTO.builder() // 根据 vehicleId 查询绑定的传感器列表
|
|
|
- .camera(cameraPOList)
|
|
|
- .OGT(ogtPOList)
|
|
|
- .build())
|
|
|
- .build())
|
|
|
- .build();
|
|
|
-
|
|
|
- //4-4 将对象转成 json
|
|
|
- String taskJson = "";
|
|
|
- try {
|
|
|
- taskJson = JsonUtil.beanToJson(taskTO);
|
|
|
- } catch (JsonProcessingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- //4-5 将 projectId 作为 topic 名称,发送 task 信息到 kafka
|
|
|
- String finalTaskJson = taskJson;
|
|
|
- kafkaTemplate.send(projectId, taskJson).addCallback(success -> {
|
|
|
- // 消息发送到的topic
|
|
|
- assert success != null;
|
|
|
- String topic = success.getRecordMetadata().topic();
|
|
|
- // 消息发送到的分区
|
|
|
- int partition = success.getRecordMetadata().partition();
|
|
|
- // 消息在分区内的offset
|
|
|
- long offset = success.getRecordMetadata().offset();
|
|
|
- log.info("------- ManualProjectConsumer 发送消息成功:\n"
|
|
|
- + "主题 topic 为:" + topic + "\n"
|
|
|
- + "分区 partition 为:" + partition + "\n"
|
|
|
- + "偏移量为:" + offset + "\n"
|
|
|
- + "消息体为:" + finalTaskJson);
|
|
|
- }, failure -> {
|
|
|
- log.error("------- 发送消息失败:" + failure.getMessage());
|
|
|
- });
|
|
|
- messageNumber[0] = messageNumber[0] + 1;
|
|
|
- stringRedisTemplate.opsForValue().set(manualProjectTopic + ":" + userId + ":" + projectId + ":task:" + taskId + ":message", taskJson);
|
|
|
+ //4-4 将对象转成 json
|
|
|
+ String taskJson = "";
|
|
|
+ try {
|
|
|
+ taskJson = JsonUtil.beanToJson(taskTO);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ //4-5 将 projectId 作为 topic 名称,发送 task 信息到 kafka
|
|
|
+ String finalTaskJson = taskJson;
|
|
|
+ stringRedisTemplate.opsForValue().set(taskMessagePrefix, finalTaskJson);
|
|
|
+ kafkaTemplate.send(projectId, taskJson).addCallback(success -> {
|
|
|
+ // 消息发送到的topic
|
|
|
+ assert success != null;
|
|
|
+ String topic = success.getRecordMetadata().topic();
|
|
|
+ // 消息发送到的分区
|
|
|
+ int partition = success.getRecordMetadata().partition();
|
|
|
+ // 消息在分区内的offset
|
|
|
+ long offset = success.getRecordMetadata().offset();
|
|
|
+ log.info("------- ProjectConsumer 发送消息成功:\n"
|
|
|
+ + "主题 topic 为:" + topic + "\n"
|
|
|
+ + "分区 partition 为:" + partition + "\n"
|
|
|
+ + "偏移量为:" + offset + "\n"
|
|
|
+ + "消息体为:" + finalTaskJson);
|
|
|
+ }, failure -> {
|
|
|
+ log.error("------- 发送消息失败:" + failure.getMessage());
|
|
|
});
|
|
|
+ messageNumber[0] = messageNumber[0] + 1;
|
|
|
});
|
|
|
- log.info("------- ManualProjectConsumer 共发送了" + messageNumber[0] + " 条消息!");
|
|
|
- sqlSession.commit();
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("ManualProjectService--sendTaskMessage 发送任务消息出错:" + e.getMessage());
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+ log.info("ProjectConsumer 共发送了" + messageNumber[0] + " 条消息!");
|
|
|
}
|
|
|
|
|
|
|