| @@ -11,7 +11,7 @@ http { | |||
| keepalive_timeout 65; | |||
| server { | |||
| listen 80; | |||
| listen 8000; | |||
| server_name localhost; | |||
| location / { | |||
| @@ -20,12 +20,12 @@ http { | |||
| index index.html index.htm; | |||
| } | |||
| location /prod-api/{ | |||
| location /api/{ | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ruoyi-gateway:8080/; | |||
| proxy_pass http://ci4s-gateway-service.ci4s-test.svc:8082/; | |||
| } | |||
| # 避免actuator暴露 | |||
| @@ -0,0 +1,35 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-front-deployment | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-front | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-front | |||
| spec: | |||
| containers: | |||
| - name: ci4s-front | |||
| image: ci4s-front:20240126 | |||
| ports: | |||
| - containerPort: 8000 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-front-service | |||
| namespace: ci4s-test | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 8000 | |||
| nodePort: 31213 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-front | |||
| @@ -10,6 +10,7 @@ import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| /** | |||
| * (Experiment)表控制层 | |||
| @@ -42,7 +43,7 @@ public class ExperimentController { | |||
| @GetMapping(("/status")) | |||
| @ApiOperation("查询实验状态") | |||
| public AjaxResult selectStatus(@RequestBody Experiment experiment, PageRequest pageRequest){ | |||
| public AjaxResult selectStatus(@RequestBody Experiment experiment, PageRequest pageRequest) throws IOException { | |||
| return AjaxResult.success(this.experimentService.selectStatus(experiment, pageRequest)); | |||
| } | |||
| @@ -61,7 +62,7 @@ public class ExperimentController { | |||
| */ | |||
| @GetMapping("{id}") | |||
| @ApiOperation("通过id查询实验") | |||
| public AjaxResult queryById(@PathVariable("id") Integer id) { | |||
| public AjaxResult queryById(@PathVariable("id") Integer id) throws IOException { | |||
| return AjaxResult.success(this.experimentService.queryById(id)); | |||
| } | |||
| @@ -85,7 +86,7 @@ public class ExperimentController { | |||
| */ | |||
| @PutMapping | |||
| @ApiOperation("编辑实验") | |||
| public AjaxResult edit(@RequestBody Experiment experiment) { | |||
| public AjaxResult edit(@RequestBody Experiment experiment) throws IOException { | |||
| return AjaxResult.success(this.experimentService.update(experiment)); | |||
| } | |||
| @@ -9,6 +9,7 @@ import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| import java.util.Map; | |||
| /** | |||
| @@ -35,7 +36,7 @@ public class ExperimentInsController { | |||
| */ | |||
| @GetMapping | |||
| @ApiOperation("分页查询") | |||
| public AjaxResult queryByPage(ExperimentIns experimentIns, int page, int size) { | |||
| public AjaxResult queryByPage(ExperimentIns experimentIns, int page, int size) throws IOException { | |||
| PageRequest pageRequest = PageRequest.of(page,size); | |||
| return AjaxResult.success(this.experimentInsService.queryByPage(experimentIns, pageRequest)); | |||
| } | |||
| @@ -48,7 +49,7 @@ public class ExperimentInsController { | |||
| */ | |||
| @GetMapping("{id}") | |||
| @ApiOperation("通过id查询实验实例") | |||
| public AjaxResult queryById(@PathVariable("id") Integer id) { | |||
| public AjaxResult queryById(@PathVariable("id") Integer id) throws IOException { | |||
| return AjaxResult.success(this.experimentInsService.queryById(id)); | |||
| } | |||
| @@ -60,7 +61,7 @@ public class ExperimentInsController { | |||
| */ | |||
| @GetMapping("/queryByExperimentId/{Experiment_id}") | |||
| @ApiOperation("通过实验id查询查询实验实例列表") | |||
| public AjaxResult queryByExperimentId(@PathVariable("Experiment_id") Integer experimentId) { | |||
| public AjaxResult queryByExperimentId(@PathVariable("Experiment_id") Integer experimentId) throws IOException { | |||
| return AjaxResult.success(this.experimentInsService.getByExperimentId(experimentId)); | |||
| } | |||
| @@ -84,7 +85,7 @@ public class ExperimentInsController { | |||
| */ | |||
| @PutMapping | |||
| @ApiOperation("编辑实验实例") | |||
| public AjaxResult edit(@RequestBody ExperimentIns experimentIns) { | |||
| public AjaxResult edit(@RequestBody ExperimentIns experimentIns) throws IOException { | |||
| return AjaxResult.success(this.experimentInsService.update(experimentIns)); | |||
| } | |||
| @@ -129,7 +129,7 @@ public class WorkflowController { | |||
| */ | |||
| @DeleteMapping("{id}") | |||
| @ApiOperation("删除流水线") | |||
| public AjaxResult deleteById(@PathVariable("id") Long id) { | |||
| public AjaxResult deleteById(@PathVariable("id") Long id) throws Exception { | |||
| return AjaxResult.success(this.workflowService.removeById(id)); | |||
| } | |||
| @@ -4,6 +4,7 @@ import com.ruoyi.platform.domain.ExperimentIns; | |||
| import org.springframework.data.domain.Page; | |||
| import org.springframework.data.domain.PageRequest; | |||
| import java.io.IOException; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @@ -21,7 +22,7 @@ public interface ExperimentInsService { | |||
| * @param id 主键 | |||
| * @return 实例对象 | |||
| */ | |||
| ExperimentIns queryById(Integer id); | |||
| ExperimentIns queryById(Integer id) throws IOException; | |||
| @@ -31,7 +32,7 @@ public interface ExperimentInsService { | |||
| * @param experimentId 实验id,不是实例id | |||
| * @return 实例列表 | |||
| */ | |||
| List<ExperimentIns> getByExperimentId(Integer experimentId); | |||
| List<ExperimentIns> getByExperimentId(Integer experimentId) throws IOException; | |||
| /** | |||
| * 分页查询 | |||
| @@ -40,7 +41,7 @@ public interface ExperimentInsService { | |||
| * @param pageRequest 分页对象 | |||
| * @return 查询结果 | |||
| */ | |||
| Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest); | |||
| Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) throws IOException; | |||
| /** | |||
| * 新增数据 | |||
| @@ -56,7 +57,7 @@ public interface ExperimentInsService { | |||
| * @param experimentIns 实例对象 | |||
| * @return 实例对象 | |||
| */ | |||
| ExperimentIns update(ExperimentIns experimentIns); | |||
| ExperimentIns update(ExperimentIns experimentIns) throws IOException; | |||
| @@ -5,6 +5,7 @@ import org.springframework.data.domain.Page; | |||
| import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.http.ResponseEntity; | |||
| import java.io.IOException; | |||
| import java.util.List; | |||
| /** | |||
| @@ -21,7 +22,7 @@ public interface ExperimentService { | |||
| * @param id 主键 | |||
| * @return 实例对象 | |||
| */ | |||
| Experiment queryById(Integer id); | |||
| Experiment queryById(Integer id) throws IOException; | |||
| /** | |||
| * 分页查询 | |||
| @@ -46,7 +47,7 @@ public interface ExperimentService { | |||
| * @param experiment 实例对象 | |||
| * @return 实例对象 | |||
| */ | |||
| Experiment update(Experiment experiment); | |||
| Experiment update(Experiment experiment) throws IOException; | |||
| /** | |||
| * 通过主键删除数据 | |||
| @@ -67,7 +68,7 @@ public interface ExperimentService { | |||
| * @param pageRequest 分页对象 | |||
| * @return 查询结果 | |||
| */ | |||
| Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest); | |||
| Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) throws IOException; | |||
| @@ -52,7 +52,7 @@ public interface WorkflowService { | |||
| * @return 是否成功 | |||
| */ | |||
| boolean deleteById(Long id); | |||
| String removeById(Long id); | |||
| String removeById(Long id) throws Exception; | |||
| /** | |||
| * 按流水线名字模糊分页查询 | |||
| * | |||
| @@ -18,6 +18,7 @@ import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.stereotype.Service; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| @@ -55,12 +56,12 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| * @return 实例对象 | |||
| */ | |||
| @Override | |||
| public ExperimentIns queryById(Integer id) { | |||
| public ExperimentIns queryById(Integer id) throws IOException { | |||
| ExperimentIns experimentIns = this.experimentInsDao.queryById(id); | |||
| if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns.getStatus())) { | |||
| if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) { | |||
| experimentIns = this.queryStatusFromArgo(experimentIns); | |||
| //只有当新状态是终止态时才更新数据库 | |||
| if (isTerminatedState(experimentIns.getStatus())) { | |||
| if (isTerminatedState(experimentIns)) { | |||
| //同时更新各个节点 | |||
| this.update(experimentIns); | |||
| } | |||
| @@ -77,17 +78,17 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| * @return 实验列表 | |||
| */ | |||
| @Override | |||
| public List<ExperimentIns> getByExperimentId(Integer experimentId) { | |||
| public List<ExperimentIns> getByExperimentId(Integer experimentId) throws IOException { | |||
| List<ExperimentIns> experimentInsList = experimentInsDao.getByExperimentId(experimentId); | |||
| List<ExperimentIns> result = new ArrayList<ExperimentIns>(); | |||
| if (experimentInsList!=null&&experimentInsList.size()>0) { | |||
| for (ExperimentIns experimentIns : experimentInsList) { | |||
| //当原本状态为null或非终止态时才调用argo接口 | |||
| if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns.getStatus())) { | |||
| if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) { | |||
| experimentIns = this.queryStatusFromArgo(experimentIns); | |||
| //只有当新状态是终止态时才更新数据库 | |||
| if (isTerminatedState(experimentIns.getStatus())) { | |||
| if (isTerminatedState(experimentIns)) { | |||
| //同时更新各个节点 | |||
| this.update(experimentIns); | |||
| } | |||
| @@ -108,7 +109,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| * @return 查询结果 | |||
| */ | |||
| @Override | |||
| public Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) { | |||
| public Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) throws IOException { | |||
| long total = this.experimentInsDao.count(experimentIns); | |||
| List<ExperimentIns> experimentInsList = this.experimentInsDao.queryAllByLimit(experimentIns, pageRequest); | |||
| if (experimentInsList!=null && experimentInsList.size()>0) { | |||
| @@ -151,7 +152,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| * @return 实例对象 | |||
| */ | |||
| @Override | |||
| public ExperimentIns update(ExperimentIns experimentIns) { | |||
| public ExperimentIns update(ExperimentIns experimentIns) throws IOException { | |||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||
| experimentIns.setUpdateBy(loginUser.getUsername()); | |||
| experimentIns.setUpdateTime(new Date()); | |||
| @@ -211,8 +212,8 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| String namespace = ins.getArgoInsNs(); | |||
| String name = ins.getArgoInsName(); | |||
| Integer id = ins.getId(); | |||
| ExperimentIns experimentIns = this.experimentInsDao.queryById(id); | |||
| // 创建请求数据map | |||
| ExperimentIns experimentIns = this.experimentInsDao.queryById(id); | |||
| Map<String,Object> requestData = new HashMap<>(); | |||
| requestData.put("namespace", namespace); | |||
| requestData.put("name", name); | |||
| @@ -240,11 +241,6 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| if (status == null || status.isEmpty()) { | |||
| throw new RuntimeException("工作流状态为空。"); | |||
| } | |||
| //解析流水线开始时间,开始时间一定存在,所以不需要判断 | |||
| Date startTime = DateUtils.convertUTCtoShanghaiDate((String) status.get("startedAt")); | |||
| experimentIns.setStartTime(startTime); | |||
| //解析流水线结束时间 | |||
| String finishedAtString = (String) status.get("finishedAt"); | |||
| @@ -255,21 +251,23 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| // 解析nodes字段,提取节点状态并转换为JSON字符串 | |||
| Map<String, Object> nodes = (Map<String, Object>) status.get("nodes"); | |||
| if (nodes == null || nodes.isEmpty()) { | |||
| throw new RuntimeException("工作流的节点数据为空。"); | |||
| } | |||
| Map<String, Object> modifiedNodes = new LinkedHashMap<>(); | |||
| for (Map.Entry<String, Object> nodeEntry : nodes.entrySet()) { | |||
| Map<String,Object> nodeDetails = (Map<String, Object>) nodeEntry.getValue(); | |||
| String templateName = (String) nodeDetails.get("displayName"); | |||
| modifiedNodes.put(templateName, nodeDetails); | |||
| if (nodes != null ) { | |||
| for (Map.Entry<String, Object> nodeEntry : nodes.entrySet()) { | |||
| Map<String,Object> nodeDetails = (Map<String, Object>) nodeEntry.getValue(); | |||
| String templateName = (String) nodeDetails.get("displayName"); | |||
| modifiedNodes.put(templateName, nodeDetails); | |||
| } | |||
| } | |||
| String nodeStatusJson = JsonUtils.mapToJson(modifiedNodes); | |||
| experimentIns.setNodesStatus(nodeStatusJson); | |||
| experimentIns.setStatus((String) status.get("phase")); | |||
| //终止态为终止不改 | |||
| if (!StringUtils.equals(experimentIns.getStatus(),"Terminated")) { | |||
| experimentIns.setStatus(StringUtils.isNotEmpty((String) status.get("phase"))?(String) status.get("phase"):"Pending"); | |||
| } | |||
| return experimentIns; | |||
| @@ -328,9 +326,11 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| // 从响应Map中直接获取"errCode"的值 | |||
| Integer errCode = (Integer) runResMap.get("errCode"); | |||
| if (errCode != null && errCode == 0) { | |||
| experimentIns.setStatus("Terminated"); | |||
| //更新experimentIns,确保状态更新被保存到数据库 | |||
| this.experimentInsDao.update(experimentIns); | |||
| ExperimentIns ins = queryStatusFromArgo(experimentIns); | |||
| ins.setStatus("Terminated"); | |||
| ins.setFinishTime(new Date()); | |||
| this.experimentInsDao.update(ins); | |||
| return true; | |||
| } else { | |||
| return false; | |||
| @@ -394,10 +394,27 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||
| } | |||
| } | |||
| private boolean isTerminatedState(String state) { | |||
| private boolean isTerminatedState(ExperimentIns ins) throws IOException { | |||
| // 定义终止态的列表,例如 "Succeeded", "Failed" 等 | |||
| List<String> terminatedStates = Arrays.asList("Succeeded", "Failed", "Terminated"); | |||
| return terminatedStates.contains(state); | |||
| String status = ins.getStatus(); | |||
| boolean flag = true; | |||
| List<String> terminatedStates = Arrays.asList("Succeeded", "Failed"); | |||
| flag = terminatedStates.contains(status); | |||
| if (StringUtils.equals(status, "Terminated")){ | |||
| //如果跟node_status里面不一样,就要去更新node_status的信息 | |||
| String nodesStatus = ins.getNodesStatus(); | |||
| Map<String, Object> nodeMap = JsonUtils.jsonToMap(nodesStatus); | |||
| String keyStartsWithWorkflow = nodeMap.keySet().stream() | |||
| .filter(key -> key.startsWith("workflow-")) | |||
| .findFirst() | |||
| .orElse(null); | |||
| Map workflowMap = (Map) nodeMap.get(keyStartsWithWorkflow); | |||
| if (workflowMap != null){ | |||
| flag = StringUtils.equals("Terminated", (String) workflowMap.get("phase")); | |||
| } | |||
| } | |||
| return flag; | |||
| } | |||
| } | |||
| @@ -23,6 +23,7 @@ import org.springframework.http.ResponseEntity; | |||
| import org.springframework.stereotype.Service; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| import java.util.*; | |||
| /** | |||
| @@ -66,7 +67,7 @@ public class ExperimentServiceImpl implements ExperimentService { | |||
| * @return 实例对象 | |||
| */ | |||
| @Override | |||
| public Experiment queryById(Integer id) { | |||
| public Experiment queryById(Integer id) throws IOException { | |||
| List<ExperimentIns> experimentInsList = this.experimentInsService.getByExperimentId(id); | |||
| Experiment experiment = this.experimentDao.queryById(id); | |||
| if (experiment == null) { | |||
| @@ -106,7 +107,7 @@ public class ExperimentServiceImpl implements ExperimentService { | |||
| * @param pageRequest 分页对象 | |||
| * @return 查询结果 | |||
| */ | |||
| public Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) { | |||
| public Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) throws IOException { | |||
| List<Experiment> experimentList = this.experimentDao.queryAllByLimit(experiment, pageRequest); | |||
| // 存储所有实验的ID列表 | |||
| List<Integer> experimentIds = new ArrayList<>(); | |||
| @@ -144,7 +145,7 @@ public class ExperimentServiceImpl implements ExperimentService { | |||
| * @return 实例对象 | |||
| */ | |||
| @Override | |||
| public Experiment update(Experiment experiment) { | |||
| public Experiment update(Experiment experiment) throws IOException { | |||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||
| experiment.setUpdateBy(loginUser.getUsername()); | |||
| experiment.setUpdateTime(new Date()); | |||
| @@ -107,7 +107,7 @@ public class WorkflowServiceImpl implements WorkflowService { | |||
| return this.workflowDao.deleteById(id) > 0; | |||
| } | |||
| @Override | |||
| public String removeById(Long id) { | |||
| public String removeById(Long id) throws Exception { | |||
| //先根据id提取出对应的流水线 | |||
| Workflow workflow = workflowDao.queryById(id); | |||
| @@ -116,16 +116,16 @@ public class WorkflowServiceImpl implements WorkflowService { | |||
| String username = loginUser.getUsername(); | |||
| String createdBy = workflow.getCreateBy(); | |||
| if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ | |||
| return "无权限删除该流水线"; | |||
| throw new Exception("无权限删除该流水线"); | |||
| } | |||
| if (workflow == null){ | |||
| return "流水线不存在"; | |||
| throw new Exception("流水线不存在"); | |||
| } | |||
| //判断这个流水线是否有相关实验存在 | |||
| List<Experiment> experimentList = experimentService.queryByWorkflowId(id); | |||
| if (experimentList!=null&&experimentList.size()>0){ | |||
| return "该流水线存在实验,无法删除"; | |||
| throw new Exception("该流水线存在实验,无法删除"); | |||
| } | |||
| workflow.setState(0); | |||
| return this.workflowDao.update(workflow)>0?"删除成功":"删除失败"; | |||
| @@ -143,7 +143,7 @@ public class WorkflowServiceImpl implements WorkflowService { | |||
| Workflow workflow = this.queryById(id); | |||
| if (workflow!= null) { | |||
| Workflow duplicateWorkflow = new Workflow(); | |||
| duplicateWorkflow.setName(workflow.getName()); | |||
| duplicateWorkflow.setName(workflow.getName()+"-copy"); | |||
| duplicateWorkflow.setDag(workflow.getDag()); | |||
| duplicateWorkflow.setDescription(workflow.getDescription()); | |||
| return this.insert(duplicateWorkflow); | |||