Browse Source

Merge branch 'dev' into dev-zw

pull/101/head
cp3hnu 1 year ago
parent
commit
a234f49ab2
43 changed files with 807 additions and 150 deletions
  1. +1
    -1
      react-ui/config/config.ts
  2. +1
    -1
      react-ui/config/defaultSettings.ts
  3. +1
    -1
      react-ui/config/routes.ts
  4. BIN
      react-ui/public/assets/images/left-top-logo-1.png
  5. BIN
      react-ui/public/assets/images/left-top-logo.png
  6. +3
    -3
      react-ui/src/pages/User/Login/index.tsx
  7. +11
    -0
      ruoyi-modules/management-platform/pom.xml
  8. +46
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/aim/AimController.java
  9. +8
    -7
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/devEnvironment/DevEnvironmentController.java
  10. +9
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/jupyter/JupyterController.java
  11. +2
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/tensorBoard/TensorBoardController.java
  12. +5
    -5
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DevEnvironment.java
  13. +10
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java
  14. +4
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelDependencyDao.java
  15. +29
    -35
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/ExperimentInstanceStatusTask.java
  16. +14
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/AimService.java
  17. +2
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DevEnvironmentService.java
  18. +5
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java
  19. +4
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelDependencyService.java
  20. +2
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/TensorBoardService.java
  21. +158
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java
  22. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java
  23. +39
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DevEnvironmentServiceImpl.java
  24. +1
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java
  25. +49
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java
  26. +67
    -15
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java
  27. +22
    -8
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelDependencyServiceImpl.java
  28. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsVersionServiceImpl.java
  29. +3
    -3
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TensorBoardServiceImpl.java
  30. +3
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java
  31. +76
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/AIM64EncoderUtil.java
  32. +35
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java
  33. +1
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/JacksonUtil.java
  34. +25
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/JsonUtils.java
  35. +7
    -11
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java
  36. +44
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/DevEnvironmentVo.java
  37. +32
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/InsMetricInfoVo.java
  38. +7
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ModelVersionDependcyVo.java
  39. +2
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/PodStatusVo.java
  40. +19
    -17
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DevEnvironmentDaoMapper.xml
  41. +27
    -13
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentInsDaoMapper.xml
  42. +13
    -4
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ImageDaoMapper.xml
  43. +18
    -2
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ModelDependencyDaoMapper.xml

+ 1
- 1
react-ui/config/config.ts View File

@@ -76,7 +76,7 @@ export default defineConfig({
* @name layout 插件
* @doc https://umijs.org/docs/max/layout-menu
*/
title: '智能软件开发平台',
title: '智能材料科研平台',
layout: {
locale: false,
...defaultSettings,


+ 1
- 1
react-ui/config/defaultSettings.ts View File

@@ -16,7 +16,7 @@ const Settings: ProLayoutProps & {
fixSiderbar: false,
splitMenus: false,
colorWeak: false,
title: '智能软件开发平台',
title: '智能材料科研平台',
pwa: true,
logo: '/assets/images/left-top-logo.png',
token: {


+ 1
- 1
react-ui/config/routes.ts View File

@@ -112,7 +112,7 @@ export default [
{
name: '开发环境',
path: '',
component: './DevelopmentEnvironment/List',
component: './DevelopmentEnvironment/Editor',
},
{
name: '创建编辑器',


BIN
react-ui/public/assets/images/left-top-logo-1.png View File

Before After
Width: 79  |  Height: 86  |  Size: 4.8 kB

BIN
react-ui/public/assets/images/left-top-logo.png View File

Before After
Width: 79  |  Height: 86  |  Size: 4.8 kB Width: 112  |  Height: 112  |  Size: 5.3 kB

+ 3
- 3
react-ui/src/pages/User/Login/index.tsx View File

@@ -241,10 +241,10 @@ const Login: React.FC = () => {
style={{ height: '42px', marginRight: '10px' }}
alt=""
/>
智能软件开发平台
智能材料科研平台
</div>
<div className={centerTitleBoX}>
<span style={{ whiteSpace: 'nowrap' }}>智能软件开发平台</span>
<span style={{ whiteSpace: 'nowrap' }}>智能材料科研平台</span>

<img
src="/assets/images/ai-logo.png"
@@ -271,7 +271,7 @@ const Login: React.FC = () => {
<div className={rightTopTitle}>
<span style={{ color: '#111111', fontSize: '36px' }}>hello~</span>
<span style={{ color: '#606b7a', fontSize: '32px', marginLeft: '10px' }}>欢迎登陆</span>
<span style={{ color: '#1664ff', fontSize: '32px' }}>智能软件开发平台</span>
<span style={{ color: '#1664ff', fontSize: '32px' }}>智能材料科研平台</span>
</div>
<div className={containerLoginForm}>
<div


+ 11
- 0
ruoyi-modules/management-platform/pom.xml View File

@@ -205,6 +205,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.0.8</version>
<scope>compile</scope>
</dependency>


</dependencies>


+ 46
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/aim/AimController.java View File

@@ -0,0 +1,46 @@
package com.ruoyi.platform.controller.aim;

import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.GenericsAjaxResult;
import com.ruoyi.platform.service.AimService;
import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.vo.InsMetricInfoVo;
import com.ruoyi.platform.vo.PodStatusVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("aim")
@Api("Aim管理")
public class AimController extends BaseController {

@Resource
private AimService aimService;


@GetMapping("/getExpTrainInfos/{experiment_id}")
@ApiOperation("获取当前实验的模型训练指标信息")
@ApiResponse
public GenericsAjaxResult<List<InsMetricInfoVo>> getExpTrainInfos(@PathVariable("experiment_id") Integer experimentId) throws Exception {
return genericsSuccess(aimService.getExpTrainInfos(experimentId));
}

@GetMapping("/getExpEvaluateInfos/{experiment_id}")
@ApiOperation("获取当前实验的模型推理指标信息")
@ApiResponse
public GenericsAjaxResult<List<InsMetricInfoVo>> getExpEvaluateInfos(@PathVariable("experiment_id") Integer experimentId) throws Exception {
return genericsSuccess(aimService.getExpEvaluateInfos(experimentId));
}

@PostMapping("/getExpMetrics")
@ApiOperation("获取当前实验的指标对比地址")
@ApiResponse
public GenericsAjaxResult<String> getExpMetrics(@RequestBody List<String> runIds) throws Exception {
return genericsSuccess(aimService.getExpMetrics(runIds));
}
}

+ 8
- 7
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/devEnvironment/DevEnvironmentController.java View File

@@ -4,6 +4,7 @@ import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.GenericsAjaxResult;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.service.DevEnvironmentService;
import com.ruoyi.platform.vo.DevEnvironmentVo;
import io.swagger.annotations.Api;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@@ -56,12 +57,12 @@ public class DevEnvironmentController extends BaseController {
/**
* 新增数据
*
* @param devEnvironment 实体
* @param devEnvironmentVo 实体
* @return 新增结果
*/
@PostMapping
public ResponseEntity<DevEnvironment> add(@RequestBody DevEnvironment devEnvironment) {
return ResponseEntity.ok(this.devEnvironmentService.insert(devEnvironment));
public GenericsAjaxResult<DevEnvironment> add(@RequestBody DevEnvironmentVo devEnvironmentVo) {
return genericsSuccess(this.devEnvironmentService.insert(devEnvironmentVo));
}

/**
@@ -71,8 +72,8 @@ public class DevEnvironmentController extends BaseController {
* @return 编辑结果
*/
@PutMapping
public ResponseEntity<DevEnvironment> edit(@RequestBody DevEnvironment devEnvironment) {
return ResponseEntity.ok(this.devEnvironmentService.update(devEnvironment));
public GenericsAjaxResult<DevEnvironment> edit(@RequestBody DevEnvironment devEnvironment) {
return genericsSuccess(this.devEnvironmentService.update(devEnvironment));
}

/**
@@ -82,8 +83,8 @@ public class DevEnvironmentController extends BaseController {
* @return 删除是否成功
*/
@DeleteMapping("{id}")
public ResponseEntity<String> deleteById(@PathVariable("id") Integer id) {
return ResponseEntity.ok(this.devEnvironmentService.removeById(id));
public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) {
return genericsSuccess(this.devEnvironmentService.removeById(id));
}

}


+ 9
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/jupyter/JupyterController.java View File

@@ -3,8 +3,10 @@ package com.ruoyi.platform.controller.jupyter;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.domain.GenericsAjaxResult;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.service.JupyterService;
import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.vo.PodStatusVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -56,6 +58,13 @@ public class JupyterController extends BaseController {
return genericsSuccess(this.jupyterService.stopJupyterService(id));
}

@PostMapping("/getStatus")
@ApiOperation("查询jupyter pod状态")
@ApiResponse
public GenericsAjaxResult<PodStatusVo> getStatus(DevEnvironment devEnvironment) throws Exception {
return genericsSuccess(this.jupyterService.getJupyterStatus(devEnvironment));
}


@GetMapping(value = "/upload")
public AjaxResult upload() throws Exception {


+ 2
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/tensorBoard/TensorBoardController.java View File

@@ -4,7 +4,7 @@ import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.GenericsAjaxResult;
import com.ruoyi.platform.service.TensorBoardService;
import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.vo.TensorboardStatusVo;
import com.ruoyi.platform.vo.PodStatusVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -37,7 +37,7 @@ public class TensorBoardController extends BaseController {
}
@PostMapping("/getStatus")
@ApiResponse
public GenericsAjaxResult<TensorboardStatusVo> getStatus(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception {
public GenericsAjaxResult<PodStatusVo> getStatus(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception {
return genericsSuccess(tensorBoardService.getTensorBoardStatus(frameLogPathVo));
}
}

+ 5
- 5
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DevEnvironment.java View File

@@ -54,7 +54,7 @@ public class DevEnvironment implements Serializable {
/**
* 备用字段1
*/
private String altField1;
private String url;
/**
* 备用字段2
*/
@@ -153,12 +153,12 @@ public class DevEnvironment implements Serializable {
this.model = model;
}

public String getAltField1() {
return altField1;
public String getUrl() {
return url;
}

public void setAltField1(String altField1) {
this.altField1 = altField1;
public void setUrl(String url) {
this.url = url;
}

public String getAltField2() {


+ 10
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java View File

@@ -48,6 +48,9 @@ public class ExperimentIns implements Serializable {
@ApiModelProperty(value = "实验实例全局参数", notes = "以JSON字符串格式存储")
@JsonRawValue
private String globalParam;
@ApiModelProperty(value = "参数记录", notes = "以JSON字符串格式存储")
@JsonRawValue
private String metricRecord;

@ApiModelProperty(value = "开始时间")
private Date startTime;
@@ -210,5 +213,12 @@ public class ExperimentIns implements Serializable {

public void setWorkflowId(Long workflowId) {this.workflowId = workflowId;}

public String getMetricRecord() {
return metricRecord;
}

public void setMetricRecord(String metricRecord) {
this.metricRecord = metricRecord;
}
}


+ 4
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelDependencyDao.java View File

@@ -84,5 +84,9 @@ public interface ModelDependencyDao {
List<ModelDependency> queryByModelDependency(@Param("modelDependency") ModelDependency modelDependency);

List<ModelDependency> queryChildrenByVersionId(@Param("model_id")String modelId, @Param("version")String version);

List<ModelDependency> queryByIns(@Param("expInsId")Integer expInsId);

ModelDependency queryByInsAndTrainTaskId(@Param("expInsId")Integer expInsId,@Param("taskId") String taskId);
}


+ 29
- 35
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/ExperimentInstanceStatusTask.java View File

@@ -7,20 +7,15 @@ import com.ruoyi.platform.mapper.ExperimentDao;
import com.ruoyi.platform.mapper.ExperimentInsDao;
import com.ruoyi.platform.mapper.ModelDependencyDao;
import com.ruoyi.platform.service.ExperimentInsService;
import com.ruoyi.platform.service.ModelDependencyService;
import com.ruoyi.platform.utils.JacksonUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;

@Component()
public class ExperimentInstanceStatusTask {
@@ -46,95 +41,94 @@ public class ExperimentInstanceStatusTask {
String oldStatus = experimentIns.getStatus();
try {
experimentIns = experimentInsService.queryStatusFromArgo(experimentIns);
}catch (Exception e){
} catch (Exception e) {
experimentIns.setStatus("Failed");
}
if (!StringUtils.equals(oldStatus,experimentIns.getStatus())){
experimentIns.setUpdateTime(new Date());
// 线程安全的添加操作
synchronized (experimentIds) {
experimentIds.add(experimentIns.getExperimentId());
}
updateList.add(experimentIns);

experimentIns.setUpdateTime(new Date());
// 线程安全的添加操作
synchronized (experimentIds) {
experimentIds.add(experimentIns.getExperimentId());
}
// experimentInsDao.update(experimentIns);
updateList.add(experimentIns);
}

}
if (updateList.size() > 0){
if (updateList.size() > 0) {
experimentInsDao.insertOrUpdateBatch(updateList);

//遍历模型关系表,找到
List<ModelDependency> modelDependencyList = new ArrayList<ModelDependency>();
for (ExperimentIns experimentIns : updateList){
for (ExperimentIns experimentIns : updateList) {
ModelDependency modelDependencyquery = new ModelDependency();
modelDependencyquery.setExpInsId(experimentIns.getId());
modelDependencyquery.setState(2);

List<ModelDependency> modelDependencyListquery = modelDependencyDao.queryByModelDependency(modelDependencyquery);
if (modelDependencyListquery==null||modelDependencyListquery.size()==0){
if (modelDependencyListquery == null || modelDependencyListquery.size() == 0) {
continue;
}
ModelDependency modelDependency = modelDependencyListquery.get(0);
//查看状态,
if (StringUtils.equals("Failed",experimentIns.getStatus())){
if (StringUtils.equals("Failed", experimentIns.getStatus())) {
//取出节点状态
String trainTask = modelDependency.getTrainTask();
Map<String, Object> trainMap = JacksonUtil.parseJSONStr2Map(trainTask);
String task_id = (String) trainMap.get("task_id");
if (StringUtils.isEmpty(task_id)){
if (StringUtils.isEmpty(task_id)) {
continue;
}
String nodesStatus = experimentIns.getNodesStatus();
Map<String, Object> nodeMaps = JacksonUtil.parseJSONStr2Map(nodesStatus);
Map<String, Object> nodeMap = JacksonUtil.parseJSONStr2Map(JacksonUtil.toJSONString(nodeMaps.get(task_id)));

if (nodeMap==null){
if (nodeMap == null) {
continue;
}
if (!StringUtils.equals("Succeeded",(String)nodeMap.get("phase"))){
if (!StringUtils.equals("Succeeded", (String) nodeMap.get("phase"))) {
modelDependency.setState(0);
modelDependencyList.add(modelDependency);
}
}
}
if (modelDependencyList.size()>0) {
if (modelDependencyList.size() > 0) {
modelDependencyDao.insertOrUpdateBatch(modelDependencyList);
}
}

}

@Scheduled(cron = "0/30 * * * * ?") // / 每30S执行一次
public void executeExperimentStatus() throws IOException {
if (experimentIds.size()==0){
if (experimentIds.size() == 0) {
return;
}
// 存储需要更新的实验对象列表
List<Experiment> updateExperiments = new ArrayList<>();
for (Integer experimentId : experimentIds){
for (Integer experimentId : experimentIds) {
// 获取当前实验的所有实例列表
List<ExperimentIns> insList = experimentInsService.getByExperimentId(experimentId);
List<String> statusList = new ArrayList<String>();
// 更新实验状态列表
for (int i=0;i<insList.size();i++){
for (int i = 0; i < insList.size(); i++) {
statusList.add(insList.get(i).getStatus());
}
String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1);
Experiment experiment = experimentDao.queryById(experimentId);
// 如果实验状态列表发生变化,则更新实验对象,并加入到需要更新的列表中
if (!StringUtils.equals(subStatus,experiment.getStatusList())){
if (!StringUtils.equals(subStatus, experiment.getStatusList())) {
experiment.setStatusList(subStatus);
updateExperiments.add(experiment);
}
}
if (!updateExperiments.isEmpty()) {
experimentDao.insertOrUpdateBatch(updateExperiments);
for (int index = 0; index < updateExperiments.size(); index++) {
// 线程安全的删除操作
synchronized (experimentIds) {
experimentIds.remove(index);
// 使用Iterator进行安全的删除操作
Iterator<Integer> iterator = experimentIds.iterator();
while (iterator.hasNext()) {
Integer experimentId = iterator.next();
for (Experiment experiment : updateExperiments) {
if (experiment.getId().equals(experimentId)) {
iterator.remove();
}
}
}
}


+ 14
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/AimService.java View File

@@ -0,0 +1,14 @@
package com.ruoyi.platform.service;

import com.ruoyi.platform.vo.InsMetricInfoVo;

import java.util.List;

public interface AimService {

List<InsMetricInfoVo> getExpTrainInfos(Integer experimentId) throws Exception;

List<InsMetricInfoVo> getExpEvaluateInfos(Integer experimentId) throws Exception;

String getExpMetrics(List<String> runIds) throws Exception;
}

+ 2
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DevEnvironmentService.java View File

@@ -1,6 +1,7 @@
package com.ruoyi.platform.service;

import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.vo.DevEnvironmentVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

@@ -35,7 +36,7 @@ public interface DevEnvironmentService {
* @param devEnvironment 实例对象
* @return 实例对象
*/
DevEnvironment insert(DevEnvironment devEnvironment);
DevEnvironment insert(DevEnvironmentVo devEnvironmentVo);

/**
* 修改数据


+ 5
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java View File

@@ -1,6 +1,7 @@
package com.ruoyi.platform.service;

import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.vo.PodStatusVo;

import java.io.InputStream;

@@ -11,7 +12,9 @@ public interface JupyterService {

void mlflow();

String runJupyterService(Integer id);
String runJupyterService(Integer id) throws Exception;

String stopJupyterService(Integer id) throws Exception;

PodStatusVo getJupyterStatus(DevEnvironment devEnvironment) throws Exception;
}

+ 4
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelDependencyService.java View File

@@ -62,4 +62,8 @@ public interface ModelDependencyService {
List<ModelDependency> queryByModelDependency(ModelDependency modelDependency) throws IOException;

ModelDependcyTreeVo getModelDependencyTree(ModelDependency modelDependency) throws Exception;

List<ModelDependency> queryByIns(Integer expInsId);

ModelDependency queryByInsAndTrainTaskId(Integer expInsId, String taskId);
}

+ 2
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/TensorBoardService.java View File

@@ -1,12 +1,12 @@
package com.ruoyi.platform.service;

import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.vo.TensorboardStatusVo;
import com.ruoyi.platform.vo.PodStatusVo;

public interface TensorBoardService {


TensorboardStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo);
PodStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo);
/**
* 在集群中启动TensorBoard容器,并且返回地址,4小时后销毁
* @param frameLogPathVo


+ 158
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java View File

@@ -0,0 +1,158 @@
package com.ruoyi.platform.service.impl;

import com.ruoyi.platform.domain.ExperimentIns;
import com.ruoyi.platform.domain.ModelDependency;
import com.ruoyi.platform.service.AimService;
import com.ruoyi.platform.service.ExperimentInsService;
import com.ruoyi.platform.service.ModelDependencyService;
import com.ruoyi.platform.utils.AIM64EncoderUtil;
import com.ruoyi.platform.utils.HttpUtils;
import com.ruoyi.platform.utils.JacksonUtil;
import com.ruoyi.platform.utils.JsonUtils;
import com.ruoyi.platform.vo.InsMetricInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AimServiceImpl implements AimService {
@Resource
private ExperimentInsService experimentInsService;

@Value("${aim.url}")
private String aimUrl;
@Value("${aim.proxyUrl}")
private String aimProxyUrl;

@Override
public List<InsMetricInfoVo> getExpTrainInfos(Integer experimentId) throws Exception {
return getAimRunInfos(true,experimentId);
}

@Override
public List<InsMetricInfoVo> getExpEvaluateInfos(Integer experimentId) throws Exception {
return getAimRunInfos(false,experimentId);
}

@Override
public String getExpMetrics(List<String> runIds) throws Exception {
String decode = AIM64EncoderUtil.decode(runIds);
return aimUrl+"/metrics?select="+decode;
}

private List<InsMetricInfoVo> getAimRunInfos(boolean isTrain,Integer experimentId) throws Exception {
String experimentName = "experiment-"+experimentId+"-train";
if (!isTrain){
experimentName = "experiment-"+experimentId+"-evaluate";
}
String encodedUrlString = URLEncoder.encode("run.experiment==\""+experimentName+"\"", "UTF-8");
String url = aimProxyUrl+"/api/runs/search/run?query="+encodedUrlString;
String s = HttpUtils.sendGetRequest(url);
List<Map<String, Object>> response = JacksonUtil.parseJSONStr2MapList(s);
System.out.println("response: "+JacksonUtil.toJSONString(response));
if (response == null || response.size() == 0){
return new ArrayList<>();
}
//查询实例数据
List<ExperimentIns> byExperimentId = experimentInsService.queryByExperimentId(experimentId);

if (byExperimentId == null || byExperimentId.size() == 0){
return new ArrayList<>();
}
List<InsMetricInfoVo> aimRunInfoList = new ArrayList<>();
for (Map<String, Object> run : response) {
InsMetricInfoVo aimRunInfo = new InsMetricInfoVo();
String runHash = (String) run.get("run_hash");

aimRunInfo.setRunId(runHash);

Map params= (Map) run.get("params");
Map<String, Object> paramMap = JsonUtils.flattenJson("", params);
aimRunInfo.setParams(paramMap);
String aimrunId = (String) paramMap.get("id");
Map<String, Object> tracesMap= (Map<String, Object>) run.get("traces");
List<Map<String, Object>> metricList = (List<Map<String, Object>>) tracesMap.get("metric");
//过滤name为__system__开头的对象
aimRunInfo.setMetrics(new HashMap<>());
if (metricList != null && metricList.size() > 0){
List<Map<String, Object>> metricRelList = metricList.stream()
.filter(map -> !StringUtils.startsWith((String) map.get("name"),"__system__" ))
.collect(Collectors.toList());
if (metricRelList!= null && metricRelList.size() > 0){
Map<String, Object> relMetricMap = new HashMap<>();
for (Map<String, Object> metricMap : metricRelList) {
relMetricMap.put((String)metricMap.get("name"), metricMap.get("last_value"));
}
aimRunInfo.setMetrics(relMetricMap);
}
}
//找到ins
for (ExperimentIns ins : byExperimentId) {
String metricRecordString = ins.getMetricRecord();
if (StringUtils.isEmpty(metricRecordString)){
continue;
}
if (metricRecordString.contains(aimrunId)){
aimRunInfo.setExperimentInsId(ins.getId());
aimRunInfo.setStatus(ins.getStatus());
aimRunInfo.setStartTime(ins.getCreateTime());
Map<String, Object> metricRecordMap = JacksonUtil.parseJSONStr2Map(metricRecordString);
if (isTrain){
List<Map<String, Object>> records = (List<Map<String, Object>>) metricRecordMap.get("train");
List<String> datasetList = getTrainDateSet(records, aimrunId);
aimRunInfo.setDataset(datasetList);
}else {
List<Map<String, Object>> records = (List<Map<String, Object>>) metricRecordMap.get("evaluate");
List<String> datasetList = getTrainDateSet(records, aimrunId);
aimRunInfo.setDataset(datasetList);
}
aimRunInfoList.add(aimRunInfo);
}
}

}
//判断哪个最长

// 获取所有 metrics 的 key 的并集
Set<String> metricsKeys = (Set<String>) aimRunInfoList.stream()
.map(InsMetricInfoVo::getMetrics)
.flatMap(metrics -> metrics.keySet().stream())
.collect(Collectors.toSet());
// 将并集赋值给每个 InsMetricInfoVo 的 metricsNames 属性
aimRunInfoList.forEach(vo -> vo.setMetricsNames(new ArrayList<>(metricsKeys)));

// 获取所有 params 的 key 的并集
Set<String> paramKeys = (Set<String>) aimRunInfoList.stream()
.map(InsMetricInfoVo::getParams)
.flatMap(params -> params.keySet().stream())
.collect(Collectors.toSet());
// 将并集赋值给每个 InsMetricInfoVo 的 paramsNames 属性
aimRunInfoList.forEach(vo -> vo.setParamsNames(new ArrayList<>(paramKeys)));

return aimRunInfoList;
}


private List<String> getTrainDateSet(List<Map<String, Object>> records, String aimrunId){
List<String> datasetList = new ArrayList<>();
for (Map<String, Object> record : records) {
if (StringUtils.equals(aimrunId, (String)record.get("run_id"))) {
List<Map<String, Object>> datasets = (List<Map<String, Object>>) record.get("datasets");
if (datasets == null || datasets.size() == 0){
continue;
}
for (Map<String, Object> dataset : datasets){
String datasetName = (String) dataset.get("dataset_name")+":"+(String) dataset.get("dataset_version");
datasetList.add(datasetName);
}
break;
}
}
return datasetList;
}
}

+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java View File

@@ -240,7 +240,7 @@ public class DatasetVersionServiceImpl implements DatasetVersionService {
datasetVersion.setFileName(dataset.getName()+"_"+labelDatasetVersionVo.getVersion()+"."+labelDatasetVersionVo.getExportType());

datasetVersion.setFileSize(formattedSize);
datasetVersion.setUrl(url);
datasetVersion.setUrl(objectName);
datasetVersion.setDescription(labelDatasetVersionVo.getDesc());
this.insert(datasetVersion);
}


+ 39
- 4
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DevEnvironmentServiceImpl.java View File

@@ -2,13 +2,17 @@ package com.ruoyi.platform.service.impl;

import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.domain.PodStatus;
import com.ruoyi.platform.mapper.DevEnvironmentDao;
import com.ruoyi.platform.service.DevEnvironmentService;
import com.ruoyi.platform.service.JupyterService;
import com.ruoyi.platform.utils.JacksonUtil;
import com.ruoyi.platform.vo.DevEnvironmentVo;
import com.ruoyi.platform.vo.PodStatusVo;
import com.ruoyi.system.api.model.LoginUser;
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
@@ -16,6 +20,7 @@ import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
@@ -29,8 +34,8 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService {
@Resource
private DevEnvironmentDao devEnvironmentDao;


@Resource
@Lazy
private JupyterService jupyterService;


@@ -55,23 +60,53 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService {
@Override
public Page<DevEnvironment> queryByPage(DevEnvironment devEnvironment, PageRequest pageRequest) {
long total = this.devEnvironmentDao.count(devEnvironment);
return new PageImpl<>(this.devEnvironmentDao.queryAllByLimit(devEnvironment, pageRequest), pageRequest, total);
List<DevEnvironment> devEnvironmentList = this.devEnvironmentDao.queryAllByLimit(devEnvironment, pageRequest);

//查询每个开发环境的pod状态,注意:只有pod为非终止态时才去调状态接口
devEnvironmentList.forEach(devEnv -> {
try{
if (!devEnv.getStatus().equals(PodStatus.Terminated.getName()) &&
!devEnv.getStatus().equals(PodStatus.Failed.getName())) {
PodStatusVo podStatusVo = this.jupyterService.getJupyterStatus(devEnv);
devEnv.setStatus(podStatusVo.getStatus());
devEnv.setUrl(podStatusVo.getUrl());
}
} catch (Exception e) {
devEnv.setStatus(PodStatus.Unknown.getName());
}
});

return new PageImpl<>(devEnvironmentList, pageRequest, total);
}

/**
* 新增数据
*
* @param devEnvironment 实例对象
* @param devEnvironmentVo 实例对象
* @return 实例对象
*/
@Override
public DevEnvironment insert(DevEnvironment devEnvironment) {
public DevEnvironment insert(DevEnvironmentVo devEnvironmentVo) {
//插入预备,此时不需要判断版本重复
DevEnvironment devEnvironment = new DevEnvironment();
LoginUser loginUser = SecurityUtils.getLoginUser();
devEnvironment.setName(devEnvironmentVo.getName());
//状态先设为未知
devEnvironment.setStatus("Unknown");
devEnvironment.setComputingResource(devEnvironmentVo.getComputingResource());
devEnvironment.setStandard(devEnvironmentVo.getStandard());
devEnvironment.setEnvVariable(devEnvironmentVo.getEnvVariable());
devEnvironment.setImage(devEnvironmentVo.getImage());
// 将 dataset 和 model 转换成 JSON 字符串
String datasetJson = JacksonUtil.toJSONString(devEnvironmentVo.getDataset());
String modelJson = JacksonUtil.toJSONString(devEnvironmentVo.getModel());
devEnvironment.setDataset(datasetJson);
devEnvironment.setModel(modelJson);
devEnvironment.setCreateBy(loginUser.getUsername());
devEnvironment.setUpdateBy(loginUser.getUsername());
devEnvironment.setUpdateTime(new Date());
devEnvironment.setCreateTime(new Date());
devEnvironment.setState(1);
this.devEnvironmentDao.insert(devEnvironment);
return devEnvironment;
}


+ 1
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java View File

@@ -102,7 +102,6 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
*/
@Override
public List<ExperimentIns> getByExperimentId(Integer experimentId) throws IOException {
List<ExperimentIns> experimentInsList = experimentInsDao.getByExperimentId(experimentId);

//代码全部迁移至定时任务
//搞个标记,当状态改变才去改表
@@ -138,7 +137,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
// experimentDao.update(experiment);
// }

return experimentInsList;
return experimentInsDao.getByExperimentId(experimentId);

}



+ 49
- 4
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java View File

@@ -251,9 +251,14 @@ public class ExperimentServiceImpl implements ExperimentService {
if (data == null || MapUtils.isEmpty(data)) {
throw new RuntimeException("Failed to run workflow.");
}



Map<String, Object> metadata = (Map<String, Object>) data.get("metadata");
// 插入记录到实验实例表
ExperimentIns experimentIns = new ExperimentIns();
//获取训练参数

experimentIns.setExperimentId(experiment.getId());
experimentIns.setArgoInsNs((String) metadata.get("namespace"));
experimentIns.setArgoInsName((String) metadata.get("name"));
@@ -264,16 +269,25 @@ public class ExperimentServiceImpl implements ExperimentService {
//替换argoInsName
String outputString = JsonUtils.mapToJson(output);
experimentIns.setNodesResult(outputString.replace("{{workflow.name}}", (String) metadata.get("name")));
//插入ExperimentIns表中
ExperimentIns insert = experimentInsService.insert(experimentIns);

//插入到模型依赖关系表

//得到dependendcy
Map<String, Object> converMap2 = JsonUtils.jsonToMap(JacksonUtil.replaceInAarry(convertRes, params));
Map<String ,Object> dependendcy = (Map<String, Object>)converMap2.get("model_dependency");
Map<String ,Object> trainInfo = (Map<String, Object>)converMap2.get("component_info");
insertModelDependency(dependendcy,trainInfo,insert.getId(),experiment.getName());

Map<String, Object> metricRecord = (Map<String, Object>) runResMap.get("metric_record");
if (metricRecord != null){
//把训练用的数据集也放进去
addDatesetToMetric(metricRecord, trainInfo);
experimentIns.setMetricRecord(JacksonUtil.toJSONString(metricRecord));
}
//插入ExperimentIns表中
ExperimentIns insert = experimentInsService.insert(experimentIns);
//插入到模型依赖关系表
if (dependendcy != null && trainInfo != null){
insertModelDependency(dependendcy,trainInfo,insert.getId(),experiment.getName());
}
}catch (Exception e){
throw new RuntimeException(e);
}
@@ -281,6 +295,37 @@ public class ExperimentServiceImpl implements ExperimentService {
experiment.setExperimentInsList(updatedExperimentInsList);
return experiment;
}
private void addDatesetToMetric(Map<String, Object> metricRecord, Map<String, Object> trainInfo) {
processMetricPart(metricRecord, trainInfo, "train", "model_train");
processMetricPart(metricRecord, trainInfo, "evaluate", "model_evaluate");
}

private void processMetricPart(Map<String, Object> metricRecord, Map<String, Object> trainInfo, String metricKey, String trainInfoKey) {
List<Map<String, Object>> metricList = (List<Map<String, Object>>) metricRecord.get(metricKey);
if (metricList != null) {
for (Map<String, Object> metricRecordItem : metricList) {
String taskId = (String) metricRecordItem.get("task_id");
Map<String, Object> trainInfoPart = (Map<String, Object>) trainInfo.get(trainInfoKey);
if (trainInfoPart != null) {
Map<String, Object> trainInfoDetails = (Map<String, Object>) trainInfoPart.get(taskId);
if (trainInfoDetails != null) {
List<Map<String, Object>> datasets = (List<Map<String, Object>>) trainInfoDetails.get("datasets");
if (datasets != null) {
//查询名字再回填
for (int i = 0; i < datasets.size(); i++) {
Dataset dataset = datasetService.queryById((Integer) datasets.get(i).get("dataset_id"));
datasets.get(i).put("dataset_name", dataset.getName());
}
metricRecordItem.put("datasets", datasets);
}
}
}
}
}
}



private void insertModelDependency(Map<String ,Object> dependendcy,Map<String ,Object> trainInfo, Integer experimentInsId, String experimentName) throws Exception {
Iterator<Map.Entry<String, Object>> dependendcyIterator = dependendcy.entrySet().iterator();
Map<String, Object> modelTrain = (Map<String, Object>) trainInfo.get("model_train");


+ 67
- 15
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java View File

@@ -3,6 +3,7 @@ package com.ruoyi.platform.service.impl;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.domain.PodStatus;
import com.ruoyi.platform.mapper.DevEnvironmentDao;
import com.ruoyi.platform.service.DevEnvironmentService;
import com.ruoyi.platform.service.JupyterService;
@@ -10,9 +11,12 @@ import com.ruoyi.platform.utils.JacksonUtil;
import com.ruoyi.platform.utils.K8sClientUtil;
import com.ruoyi.platform.utils.MinioUtil;
import com.ruoyi.platform.utils.MlflowUtil;
import com.ruoyi.platform.vo.PodStatusVo;
import com.ruoyi.system.api.model.LoginUser;
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim;
import io.kubernetes.client.openapi.models.V1Pod;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
@@ -37,6 +41,8 @@ public class JupyterServiceImpl implements JupyterService {
private String masterIp;
@Value("${k8s.storageClassName}")
private String storageClassName;
@Value("${minio.pvcName}")
private String minioPvcName;

private final MinioUtil minioUtil;

@@ -49,6 +55,7 @@ public class JupyterServiceImpl implements JupyterService {
private DevEnvironmentDao devEnvironmentDao;

@Resource
@Lazy
private DevEnvironmentService devEnvironmentService;

@Resource
@@ -69,10 +76,11 @@ public class JupyterServiceImpl implements JupyterService {
}

@Override
public String runJupyterService(Integer id) {
public String runJupyterService(Integer id) throws Exception {
DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id);
String envName = devEnvironment.getName();
//TODO 设置环境变量
if(devEnvironment == null){
throw new Exception("开发环境配置不存在");
}

// 提取数据集,模型信息,得到数据集模型的path
Map<String, Object> dataset = JacksonUtil.parseJSONStr2Map(devEnvironment.getDataset());
@@ -81,16 +89,26 @@ public class JupyterServiceImpl implements JupyterService {
String modelPath = (String) model.get("path");

LoginUser loginUser = SecurityUtils.getLoginUser();
String podName = loginUser.getUsername().toLowerCase() + "-editor-pod";
//手动构造pod名称
String podName = loginUser.getUsername().toLowerCase() +"-editor-pod" + "-" + id;
String pvcName = loginUser.getUsername().toLowerCase() + "-editor-pvc";
//新建编辑器的pvc
V1PersistentVolumeClaim pvc = k8sClientUtil.createPvc(namespace, pvcName, storage, storageClassName);

//TODO 设置镜像可配置,这里先用默认镜像启动pod

// 调用修改后的 createPod 方法,传入额外的参数
Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, pvc, image, datasetPath, modelPath);
return masterIp + ":" + podPort;

Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, pvc, image, minioPvcName, datasetPath, modelPath);
// // 简单的延迟,以便 Pod 有时间启动
// Thread.sleep(2500);
// //查询pod状态,更新到数据库
// String podStatus = k8sClientUtil.getPodStatus(podName, namespace);
String url = masterIp + ":" + podPort;
redisService.setCacheObject(podName,masterIp + ":" + podPort);
devEnvironment.setStatus("Pending");
devEnvironment.setUrl(url);
this.devEnvironmentService.update(devEnvironment);
return url ;

}

@@ -100,21 +118,54 @@ public class JupyterServiceImpl implements JupyterService {
if (devEnvironment==null){
throw new Exception("开发环境配置不存在");
}

LoginUser loginUser = SecurityUtils.getLoginUser();
String podName = loginUser.getUsername().toLowerCase() + "-editor-pod";

//手动构造pod名称
String podName = loginUser.getUsername().toLowerCase() +"-editor-pod" + "-" + id;
//得到pod
V1Pod pod = k8sClientUtil.getNSPodList(namespace, podName);
if(pod == null){
return "pod不存在!";
}
// 使用 Kubernetes API 删除 Pod
String deleteResult = k8sClientUtil.deletePod(podName, namespace);

// 检查 Pod 是否存在
boolean exists = k8sClientUtil.checkPodExists(podName, namespace);
if (exists) {
throw new Exception("Pod " + podName + " 删除失败");
}

devEnvironment.setStatus("Terminated");
this.devEnvironmentService.update(devEnvironment);
return deleteResult + ",编辑器已停止";
}

@Override
public PodStatusVo getJupyterStatus(DevEnvironment devEnvironment) throws Exception {
String status = PodStatus.Terminated.getName();
PodStatusVo JupyterStatusVo = new PodStatusVo();
JupyterStatusVo.setStatus(status);
if (devEnvironment==null){
return JupyterStatusVo;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
String podName = loginUser.getUsername().toLowerCase() +"-editor-pod" + "-" + devEnvironment.getId();

try {
// 查询相应pod状态
String podStatus = k8sClientUtil.getPodStatus(podName, namespace);
for (PodStatus s : PodStatus.values()) {
if (s.getName().equals(podStatus)) {
status = s.getName();
break;
}
}

} catch (Exception e) {
return JupyterStatusVo;
}
String url = redisService.getCacheObject(podName);
JupyterStatusVo.setStatus(status);
JupyterStatusVo.setUrl(url);
return JupyterStatusVo;

}


@Override
public void upload(InputStream inputStream) {
@@ -136,4 +187,5 @@ public class JupyterServiceImpl implements JupyterService {




}

+ 22
- 8
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelDependencyServiceImpl.java View File

@@ -17,10 +17,7 @@ import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

/**
@@ -97,6 +94,16 @@ public class ModelDependencyServiceImpl implements ModelDependencyService {
return modelDependcyTreeVo;
}

@Override
public List<ModelDependency> queryByIns(Integer expInsId) {
return modelDependencyDao.queryByIns(expInsId);
}

@Override
public ModelDependency queryByInsAndTrainTaskId(Integer expInsId, String taskId) {
return modelDependencyDao.queryByInsAndTrainTaskId(expInsId,taskId);
}

/**
* 递归父模型
* @param modelDependcyTreeVo
@@ -167,8 +174,6 @@ public class ModelDependencyServiceImpl implements ModelDependencyService {
modelsVersionquery.setModelsId(currentModelId);
modelsVersionquery.setVersion(modelDependency.getVersion());
ModelsVersion modelsVersion = modelsVersionService.queryByModelsVersion(modelsVersionquery);
ExperimentIns experimentIns = experimentInsService.queryById(expInsId);
Experiment experiment = experimentService.queryById(experimentIns.getExperimentId());
ModelVersionDependcyVo modelVersionDependcyVo = new ModelVersionDependcyVo();
modelVersionDependcyVo.setName(models.getName());
modelVersionDependcyVo.setAvailableRange(models.getAvailableRange());
@@ -180,9 +185,18 @@ public class ModelDependencyServiceImpl implements ModelDependencyService {
modelVersionDependcyVo.setFileName(modelsVersion.getFileName());
modelVersionDependcyVo.setFileSize(modelsVersion.getFileSize());
modelVersionDependcyVo.setUrl(modelsVersion.getUrl());
modelDependcyTreeVo.setWorkflowId(experiment.getWorkflowId());
modelVersionDependcyVo.setCreateBy(modelsVersion.getCreateBy());
modelVersionDependcyVo.setCreateTime(modelsVersion.getCreateTime());
modelDependcyTreeVo.setModelVersionDependcyVo(modelVersionDependcyVo);
ExperimentIns experimentIns = experimentInsService.queryById(expInsId);
if (experimentIns == null){
return modelDependcyTreeVo;
}
Experiment experiment = experimentService.queryById(experimentIns.getExperimentId());
if (experiment == null){
return modelDependcyTreeVo;
}
modelDependcyTreeVo.setWorkflowId(experiment.getWorkflowId());
return modelDependcyTreeVo;
}



+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsVersionServiceImpl.java View File

@@ -227,8 +227,8 @@ public class ModelsVersionServiceImpl implements ModelsVersionService {
for(ModelsVersion modelsVersion : modelsVersions) {
insertPrepare(modelsVersion);
}
insertModelsDependency(modelsVersions.get(0));
this.modelsVersionDao.insertBatch(modelsVersions);
insertModelsDependency(modelsVersions.get(0));
return "新增模型版本成功";
} catch (Exception e) {
// 如果出现异常,返回异常消息


+ 3
- 3
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TensorBoardServiceImpl.java View File

@@ -7,7 +7,7 @@ import com.ruoyi.platform.domain.PodStatus;
import com.ruoyi.platform.service.TensorBoardService;
import com.ruoyi.platform.utils.K8sClientUtil;
import com.ruoyi.platform.vo.FrameLogPathVo;
import com.ruoyi.platform.vo.TensorboardStatusVo;
import com.ruoyi.platform.vo.PodStatusVo;
import com.ruoyi.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -29,9 +29,9 @@ public class TensorBoardServiceImpl implements TensorBoardService {
@Resource
private K8sClientUtil k8sClientUtil;
@Override
public TensorboardStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo){
public PodStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo){
String status = PodStatus.Terminated.getName();
TensorboardStatusVo tensorboardStatusVo = new TensorboardStatusVo();
PodStatusVo tensorboardStatusVo = new PodStatusVo();
tensorboardStatusVo.setStatus(status);
if (StringUtils.isEmpty(frameLogPathVo.getPath())){
return tensorboardStatusVo;


+ 3
- 4
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java View File

@@ -133,7 +133,9 @@ public class WorkflowServiceImpl implements WorkflowService {
public String removeById(Long id) throws Exception {
//先根据id提取出对应的流水线
Workflow workflow = workflowDao.queryById(id);

if (workflow == null){
throw new Exception("流水线不存在");
}
//判断权限,只有admin和创建者本身可以删除该流水线
LoginUser loginUser = SecurityUtils.getLoginUser();
String username = loginUser.getUsername();
@@ -142,9 +144,6 @@ public class WorkflowServiceImpl implements WorkflowService {
throw new Exception("无权限删除该流水线");
}

if (workflow == null){
throw new Exception("流水线不存在");
}
//判断这个流水线是否有相关实验存在
List<Experiment> experimentList = experimentService.queryByWorkflowId(id);
if (experimentList!=null&&experimentList.size()>0){


+ 76
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/AIM64EncoderUtil.java View File

@@ -0,0 +1,76 @@
package com.ruoyi.platform.utils;

import com.alibaba.fastjson.JSON;

import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AIM64EncoderUtil {

private static final String AIM64_ENCODING_PREFIX = "O-";

private static final Map<String, String> BS64_REPLACE_CHARACTERS_ENCODING = new HashMap<>();
static {
BS64_REPLACE_CHARACTERS_ENCODING.put("=", "");
BS64_REPLACE_CHARACTERS_ENCODING.put("+", "-");
BS64_REPLACE_CHARACTERS_ENCODING.put("/", "_");
}

public static String aim64encode(Map<String, Object> value) {
String jsonEncoded = JSON.toJSONString(value);
String base64Encoded = Base64.getEncoder().encodeToString(jsonEncoded.getBytes());
String aim64Encoded = base64Encoded;
for (Map.Entry<String, String> entry : BS64_REPLACE_CHARACTERS_ENCODING.entrySet()) {
aim64Encoded = aim64Encoded.replace(entry.getKey(), entry.getValue());
}
return AIM64_ENCODING_PREFIX + aim64Encoded;
}

public static String encode(Map<String, Object> value, boolean oneWayHashing) {
if (oneWayHashing) {
return md5(JSON.toJSONString(value));
}
return aim64encode(value);
}

private static String md5(String input) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(input.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

public static String decode(List<String> runIds) {
// 确保 runIds 列表的大小为 3
if (runIds == null || runIds.size() == 0) {
throw new IllegalArgumentException("runIds 不能为空");
}
// 构建查询字符串
StringBuilder queryBuilder = new StringBuilder("run.hash in [");
for (int i = 0; i < runIds.size(); i++) {
if (i > 0) {
queryBuilder.append(",");
}
queryBuilder.append("\"").append(runIds.get(i)).append("\"");
}
queryBuilder.append("]");
String query = queryBuilder.toString();
Map<String, Object> map = new HashMap<>();
map.put("query", query);
map.put("advancedMode", true);
map.put("advancedQuery", query);

String searchQuery = encode(map, false);
return searchQuery;
}
}

+ 35
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java View File

@@ -25,6 +25,7 @@ import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
* HTTP请求工具类
@@ -447,4 +448,38 @@ public class HttpUtils {
return true;
}
}

public static String sendGetRequestgzip(String url) throws Exception {
String resultStr = null;
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Content-Type", "application/json");
httpGet.setHeader("Accept-Encoding", "gzip, deflate");
try {
HttpResponse response = httpClient.execute(httpGet);
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode != 200) {
throw new IOException("HTTP request failed with response code: " + responseCode);
}

// 获取响应内容
InputStream responseStream = response.getEntity().getContent();
// 检查响应是否被压缩
if ("gzip".equalsIgnoreCase(response.getEntity().getContentEncoding().getValue())) {
responseStream = new GZIPInputStream(responseStream);
}

// 读取解压缩后的内容
byte[] buffer = new byte[1024];
int len;
StringBuilder decompressedString = new StringBuilder();
while ((len = responseStream.read(buffer)) > 0) {
decompressedString.append(new String(buffer, 0, len));
}

resultStr = decompressedString.toString();
} catch (IOException e) {
e.printStackTrace();
}
return resultStr;
}
}

+ 1
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/JacksonUtil.java View File

@@ -218,6 +218,7 @@ public class JacksonUtil {
*/
public static <T> List<T> parseJSONStr2TList(String jsonStr, Class<T> clazz, String dateFormat) {
try {
if (StringUtils.isEmpty(jsonStr)) { return new ArrayList<T>(); }
ObjectMapper objectMapper = getObjectMapper(dateFormat, false, false, true);
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
return objectMapper.readValue(jsonStr, listType);


+ 25
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/JsonUtils.java View File

@@ -1,8 +1,11 @@
package com.ruoyi.platform.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class JsonUtils {
@@ -28,4 +31,26 @@ public class JsonUtils {
public static <T> T jsonToObject(String json, Class<T> clazz) throws IOException {
return objectMapper.readValue(json, clazz);
}



// 将JSON字符串转换为扁平化的Map
public static Map<String, Object> flattenJson(String prefix, Map<String, Object> map) {
Map<String, Object> flatMap = new HashMap<>();
Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();

while (entries.hasNext()) {
Map.Entry<String, Object> entry = entries.next();
String key = entry.getKey();
Object value = entry.getValue();

if (value instanceof Map) {
flatMap.putAll(flattenJson(prefix + key + ".", (Map<String, Object>) value));
} else {
flatMap.put(prefix + key, value);
}
}

return flatMap;
}
}

+ 7
- 11
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java View File

@@ -376,7 +376,7 @@ public class K8sClientUtil {
}


public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, String image, String datasetPath, String modelPath) {
public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, String image, String dataPvcName, String datasetPath, String modelPath) {
Map<String, String> selector = new LinkedHashMap<>();
selector.put("k8s-jupyter", podName);

@@ -402,13 +402,13 @@ public class K8sClientUtil {
// 配置卷和卷挂载
List<V1VolumeMount> volumeMounts = new ArrayList<>();
volumeMounts.add(new V1VolumeMount().name("workspace").mountPath(mountPath));
volumeMounts.add(new V1VolumeMount().name("dataset").mountPath("/datasets").subPath(datasetPath).readOnly(true));
volumeMounts.add(new V1VolumeMount().name("model").mountPath("/model").subPath(modelPath).readOnly(true));
volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/datasets").subPath(datasetPath).readOnly(true));
volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/model").subPath(modelPath).readOnly(true));

List<V1Volume> volumes = new ArrayList<>();
volumes.add(new V1Volume().name("workspace").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName())));
volumes.add(new V1Volume().name("dataset").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName())));
volumes.add(new V1Volume().name("model").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName())));
volumes.add(new V1Volume().name("minio-pvc").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(dataPvcName)));

V1Pod pod = new V1PodBuilder()
.withNewMetadata()
@@ -573,12 +573,8 @@ public class K8sClientUtil {
V1Pod pod = api.deleteNamespacedPod(podName, namespace, null, null, null, null, null, null);
return "Pod " + podName + " 删除请求已发送";
} catch (ApiException e) {
if (e.getCode() == 404) {
return "Pod " + podName + " 不存在";
} else {
log.error("删除pod异常:" + e.getResponseBody(), e);
throw e;
}
log.error("删除pod异常:" + e.getResponseBody(), e);
throw e;
}
}



+ 44
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/DevEnvironmentVo.java View File

@@ -0,0 +1,44 @@
package com.ruoyi.platform.vo;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;

import java.io.Serializable;
import java.util.Map;

@Data
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class DevEnvironmentVo implements Serializable {

private Integer id;

private String name;

/**
* 计算资源
*/
private String computingResource;
/**
* 资源规格
*/
private String standard;

/**
* 环境变量
*/
private String envVariable;
/**
* 所用镜像
*/
private String image;
/**
* 对应数据集
*/
private Map<String,Object> dataset;
/**
* 对应模型
*/
private Map<String,Object> model;

}

+ 32
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/InsMetricInfoVo.java View File

@@ -0,0 +1,32 @@
package com.ruoyi.platform.vo;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
@Data
public class InsMetricInfoVo implements Serializable {
@ApiModelProperty(value = "开始时间")
private Date startTime;
@ApiModelProperty(value = "实例运行状态")
private String status;
@ApiModelProperty(value = "使用数据集")
private List<String> dataset;
@ApiModelProperty(value = "实例ID")
private Integer experimentInsId;
@ApiModelProperty(value = "训练指标")
private Map metrics;
@ApiModelProperty(value = "训练参数")
private Map params;
@ApiModelProperty(value = "训练记录ID")
private String runId;
private List<String> metricsNames;
private List<String> paramsNames;
}

+ 7
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ModelVersionDependcyVo.java View File

@@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
@@ -45,4 +46,10 @@ public class ModelVersionDependcyVo implements Serializable {
@ApiModelProperty(value = "文件大小")
private String fileSize;

@ApiModelProperty(value = "创建者")
private String createBy;

@ApiModelProperty(value = "创建时间")
private Date createTime;

}

ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/TensorboardStatusVo.java → ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/PodStatusVo.java View File

@@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming;
import java.io.Serializable;

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TensorboardStatusVo implements Serializable {
public class PodStatusVo implements Serializable {
private String status;
private String url;

@@ -25,4 +25,5 @@ public class TensorboardStatusVo implements Serializable {
public void setUrl(String url) {
this.url = url;
}

}

+ 19
- 17
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DevEnvironmentDaoMapper.xml View File

@@ -12,7 +12,7 @@
<result property="image" column="image" jdbcType="VARCHAR"/>
<result property="dataset" column="dataset" jdbcType="VARCHAR"/>
<result property="model" column="model" jdbcType="VARCHAR"/>
<result property="altField1" column="alt_field1" jdbcType="VARCHAR"/>
<result property="url" column="url" jdbcType="VARCHAR"/>
<result property="altField2" column="alt_field2" jdbcType="VARCHAR"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
@@ -24,17 +24,18 @@
<!--查询单个-->
<select id="queryById" resultMap="DevEnvironmentMap">
select
id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state
id,name,status,computing_resource,standard,env_variable,image,dataset,model,url,alt_field2,create_by,create_time,update_by,update_time,state
from dev_environment
where id = #{id}
where id = #{id} and state = 1
</select>

<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="DevEnvironmentMap">
select
id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state
id,name,status,computing_resource,standard,env_variable,image,dataset,model,url,alt_field2,create_by,create_time,update_by,update_time,state
from dev_environment
<where>
state = 1
<if test="devEnvironment.id != null">
and id = #{devEnvironment.id}
</if>
@@ -62,8 +63,8 @@
<if test="devEnvironment.model != null and devEnvironment.model != ''">
and model = #{devEnvironment.model}
</if>
<if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''">
and alt_field1 = #{devEnvironment.altField1}
<if test="devEnvironment.url != null and devEnvironment.url != ''">
and url = #{devEnvironment.url}
</if>
<if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''">
and alt_field2 = #{devEnvironment.altField2}
@@ -93,6 +94,7 @@
select count(1)
from dev_environment
<where>
state = 1
<if test="devEnvironment.id != null">
and id = #{devEnvironment.id}
</if>
@@ -120,8 +122,8 @@
<if test="devEnvironment.model != null and devEnvironment.model != ''">
and model = #{devEnvironment.model}
</if>
<if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''">
and alt_field1 = #{devEnvironment.altField1}
<if test="devEnvironment.url != null and devEnvironment.url != ''">
and url = #{devEnvironment.url}
</if>
<if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''">
and alt_field2 = #{devEnvironment.altField2}
@@ -146,7 +148,7 @@

<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state)
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,url,alt_field2,create_by,create_time,update_by,update_time,state)
values (#{devEnvironment.name},
#{devEnvironment.status},
#{devEnvironment.computingResource},
@@ -155,7 +157,7 @@
#{devEnvironment.image},
#{devEnvironment.dataset},
#{devEnvironment.model},
#{devEnvironment.altField1},
#{devEnvironment.url},
#{devEnvironment.altField2},
#{devEnvironment.createBy},
#{devEnvironment.createTime},
@@ -166,21 +168,21 @@
</insert>

<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state )
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,url,alt_field2,create_by,create_time,update_by,update_time,state )
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.name},#{entity.status},#{entity.computingResource},#{entity.standard},#{entity.envVariable},#{entity.image},#{entity.dataset},#{entity.model},#{entity.altField1},#{entity.altField2},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state})
(#{entity.name},#{entity.status},#{entity.computingResource},#{entity.standard},#{entity.envVariable},#{entity.image},#{entity.dataset},#{entity.model},#{entity.url},#{entity.altField2},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state})
</foreach>
</insert>

<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state)
insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,url,alt_field2,create_by,create_time,update_by,update_time,state)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.name}#{entity.status}#{entity.computingResource}#{entity.standard}#{entity.envVariable}#{entity.image}#{entity.dataset}#{entity.model}#{entity.altField1}#{entity.altField2}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state})
(#{entity.name}#{entity.status}#{entity.computingResource}#{entity.standard}#{entity.envVariable}#{entity.image}#{entity.dataset}#{entity.model}#{entity.url}#{entity.altField2}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state})
</foreach>
on duplicate key update
name = values(name)status = values(status)computing_resource = values(computing_resource)standard = values(standard)env_variable = values(env_variable)image = values(image)dataset = values(dataset)model = values(model)alt_field1 = values(alt_field1)alt_field2 = values(alt_field2)create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state)
name = values(name)status = values(status)computing_resource = values(computing_resource)standard = values(standard)env_variable = values(env_variable)image = values(image)dataset = values(dataset)model = values(model)url = values(url)alt_field2 = values(alt_field2)create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state)
</insert>

<!--通过主键修改数据-->
@@ -211,8 +213,8 @@ name = values(name)status = values(status)computing_resource = values(computing_
<if test="devEnvironment.model != null and devEnvironment.model != ''">
model = #{devEnvironment.model},
</if>
<if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''">
alt_field1 = #{devEnvironment.altField1},
<if test="devEnvironment.url != null and devEnvironment.url != ''">
url = #{devEnvironment.url},
</if>
<if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''">
alt_field2 = #{devEnvironment.altField2},


+ 27
- 13
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentInsDaoMapper.xml View File

@@ -12,6 +12,7 @@
<result property="nodesResult" column="nodes_result" jdbcType="VARCHAR"/>
<result property="nodesLogs" column="nodes_logs" jdbcType="VARCHAR"/>
<result property="globalParam" column="global_param" jdbcType="VARCHAR"/>
<result property="metricRecord" column="metric_record" jdbcType="VARCHAR"/>
<result property="startTime" column="start_time" jdbcType="TIMESTAMP"/>
<result property="finishTime" column="finish_time" jdbcType="TIMESTAMP"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/>
@@ -23,7 +24,7 @@

<!--查询非终止态的实例-->
<select id="queryByExperimentIsNotTerminated" resultMap="ExperimentInsMap">
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
where (status NOT IN ('Terminated', 'Succeeded', 'Failed')
OR status IS NULL) and state = 1
@@ -31,14 +32,14 @@

<!--查询单个-->
<select id="queryById" resultMap="ExperimentInsMap">
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
where id = #{id} and state = 1
</select>

<!--查询列表-->
<select id="getByExperimentId" resultMap="ExperimentInsMap">
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
where experiment_id = #{experiment_id} and state = 1
order by create_time DESC
@@ -47,7 +48,7 @@

<!--查询最近的3个实例列表-->
<select id="getLatestInsList" resultMap="ExperimentInsMap">
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
where state = 1
order by create_time DESC
@@ -58,7 +59,7 @@

<select id="queryByExperiment" resultMap="ExperimentInsMap">
select
id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
<where>
state = 1
@@ -86,6 +87,9 @@
<if test="experimentIns.globalParam != null and experimentIns.globalParam != ''">
and global_param = #{experimentIns.globalParam}
</if>
<if test="experimentIns.metricRecord != null and experimentIns.metricRecord != ''">
and metric_record = #{experimentIns.metricRecord}
</if>
<if test="experimentIns.startTime != null">
and start_time = #{experimentIns.startTime}
</if>
@@ -110,7 +114,7 @@
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="ExperimentInsMap">
select
id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs,global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
<where>
state = 1
@@ -138,6 +142,9 @@
<if test="experimentIns.globalParam != null and experimentIns.globalParam != ''">
and global_param = #{experimentIns.globalParam}
</if>
<if test="experimentIns.metricRecord != null and experimentIns.metricRecord != ''">
and metric_record = #{experimentIns.metricRecord}
</if>
<if test="experimentIns.startTime != null">
and start_time = #{experimentIns.startTime}
</if>
@@ -191,6 +198,9 @@
<if test="experimentIns.globalParam != null and experimentIns.globalParam != ''">
and global_param = #{experimentIns.globalParam}
</if>
<if test="experimentIns.metricRecord != null and experimentIns.metricRecord != ''">
and metric_record = #{experimentIns.metricRecord}
</if>
<if test="experimentIns.startTime != null">
and start_time = #{experimentIns.startTime}
</if>
@@ -213,23 +223,23 @@
</select>

<select id="queryByExperimentId" resultMap="ExperimentInsMap">
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state
select id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status,nodes_result, nodes_logs, global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state
from experiment_ins
where experiment_id = #{id} and state = 1
</select>

<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into experiment_ins(experiment_id,argo_ins_name,argo_ins_ns,status,nodes_status,nodes_result,nodes_logs,global_param,start_time,finish_time,create_by,create_time,update_by,update_time,state)
values (#{experimentIns.experimentId},#{experimentIns.argoInsName},#{experimentIns.argoInsNs},#{experimentIns.status},#{experimentIns.nodesStatus},#{experimentIns.nodesResult},#{experimentIns.nodesLogs},#{experimentIns.globalParam},#{experimentIns.startTime},#{experimentIns.finishTime},#{experimentIns.createBy},#{experimentIns.createTime},#{experimentIns.updateBy},#{experimentIns.updateTime},#{experimentIns.state})
insert into experiment_ins(experiment_id,argo_ins_name,argo_ins_ns,status,nodes_status,nodes_result,nodes_logs,global_param,metric_record,start_time,finish_time,create_by,create_time,update_by,update_time,state)
values (#{experimentIns.experimentId},#{experimentIns.argoInsName},#{experimentIns.argoInsNs},#{experimentIns.status},#{experimentIns.nodesStatus},#{experimentIns.nodesResult},#{experimentIns.nodesLogs},#{experimentIns.globalParam},#{experimentIns.metricRecord},#{experimentIns.startTime},#{experimentIns.finishTime},#{experimentIns.createBy},#{experimentIns.createTime},#{experimentIns.updateBy},#{experimentIns.updateTime},#{experimentIns.state})
</insert>

<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into
experiment_ins(experiment_id,argo_ins_name,argo_ins_ns,status,nodes_status,nodes_result,nodes_logs,global_param,start_time,finish_time,create_by,create_time,update_by,update_time,state)
experiment_ins(experiment_id,argo_ins_name,argo_ins_ns,status,nodes_status,nodes_result,nodes_logs,global_param,metric_record,start_time,finish_time,create_by,create_time,update_by,update_time,state)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.experimentId},#{entity.argoInsName},#{entity.argoInsNs},#{entity.status},#{entity.nodesStatus},#{entity.nodesResult},#{entity.nodesLogs},#{entity.globalParam},#{entity.startTime},#{entity.finishTime},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state})
(#{entity.experimentId},#{entity.argoInsName},#{entity.argoInsNs},#{entity.status},#{entity.nodesStatus},#{entity.nodesResult},#{entity.nodesLogs},#{entity.globalParam},#{entity.metricRecord},#{entity.startTime},#{entity.finishTime},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state})
</foreach>
</insert>

@@ -244,10 +254,10 @@
<!-- experiment_id = values(experiment_id)argo_ins_name = values(argo_ins_name)argo_ins_ns = values(argo_ins_ns)status = values(status) nodes_status = values(nodes_status) create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state)-->
<!-- </insert>-->
<update id="insertOrUpdateBatch">
insert into experiment_ins (id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status, nodes_result, nodes_logs, global_param, start_time, finish_time, create_by, create_time, update_by, update_time, state)
insert into experiment_ins (id, experiment_id, argo_ins_name, argo_ins_ns, status, nodes_status, nodes_result, nodes_logs, global_param,metric_record, start_time, finish_time, create_by, create_time, update_by, update_time, state)
values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.id}, #{item.experimentId}, #{item.argoInsName}, #{item.argoInsNs}, #{item.status}, #{item.nodesStatus}, #{item.nodesResult}, #{item.nodesLogs}, #{item.globalParam}, #{item.startTime}, #{item.finishTime}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.state})
(#{item.id}, #{item.experimentId}, #{item.argoInsName}, #{item.argoInsNs}, #{item.status}, #{item.nodesStatus}, #{item.nodesResult}, #{item.nodesLogs}, #{item.globalParam},#{item.metricRecord}, #{item.startTime}, #{item.finishTime}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.state})
</foreach>
ON DUPLICATE KEY UPDATE
experiment_id = VALUES(experiment_id),
@@ -258,6 +268,7 @@
nodes_result = VALUES(nodes_result),
nodes_logs = VALUES(nodes_logs),
global_param = VALUES(global_param),
metric_record = VALUES(metric_record),
start_time = VALUES(start_time),
finish_time = VALUES(finish_time),
create_by = VALUES(create_by),
@@ -294,6 +305,9 @@
<if test="experimentIns.globalParam != null and experimentIns.globalParam != ''">
global_param = #{experimentIns.globalParam},
</if>
<if test="experimentIns.metricRecord != null and experimentIns.metricRecord != ''">
metric_record = #{experimentIns.metricRecord},
</if>
<if test="experimentIns.startTime != null">
start_time = #{experimentIns.startTime},
</if>


+ 13
- 4
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ImageDaoMapper.xml View File

@@ -14,12 +14,21 @@
<result property="state" column="state" jdbcType="INTEGER"/>
</resultMap>

<!--查询单个-->
<!-- 查询单个 -->
<select id="queryById" resultMap="ImageMap">
select
id,name,description,image_type,create_by,create_time,update_by,update_time,state
from image
where id = #{id} and state = 1
img.id,
img.name,
img.description,
img.image_type,
img.create_by,
img.create_time,
img.update_by,
img.update_time,
img.state,
(SELECT COUNT(*) FROM image_version WHERE image_version.image_id = img.id AND image_version.state = 1) as versionCount
from image img
where img.id = #{id} and img.state = 1
</select>

<!--查询指定行数据-->


+ 18
- 2
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ModelDependencyDaoMapper.xml View File

@@ -22,12 +22,28 @@
<result property="state" column="state" jdbcType="INTEGER"/>
</resultMap>

<select id="queryByIns" resultMap="ModelDependencyMap">
select
id,current_model_id,exp_ins_id,parent_models,ref_item,train_task,train_dataset,train_params,train_image,test_dataset,project_dependency,version,create_by,create_time,update_by,update_time,state
from model_dependency
<where>
exp_ins_id = #{expInsId} and state = 1
</where>
</select>
<select id="queryByInsAndTrainTaskId" resultMap="ModelDependencyMap">
select
id,current_model_id,exp_ins_id,parent_models,ref_item,train_task,train_dataset,train_params,train_image,test_dataset,project_dependency,version,create_by,create_time,update_by,update_time,state
from model_dependency
<where>
exp_ins_id = #{expInsId} and train_task like concat('%', #{taskId}, '%') limit 1
</where>
</select>
<select id="queryChildrenByVersionId" resultMap="ModelDependencyMap">
select
id,current_model_id,exp_ins_id,parent_models,ref_item,train_task,train_dataset,train_params,train_image,test_dataset,project_dependency,version,create_by,create_time,update_by,update_time,state
from model_dependency
<where>
parent_models like concat('%', #{model_id}, '%') AND parent_models like concat('%', #{version}, '%')
parent_models like concat('%', #{model_id}, '%') AND parent_models like concat('%', #{version}, '%') and state = 1
</where>
</select>

@@ -321,7 +337,7 @@
state = #{state},
</if>
</set>
where id = #{id} and state = 1
where id = #{id}
</update>

<!--通过主键删除-->


Loading…
Cancel
Save