Ver Fonte

fix: 优化部署服务代码结构

weipengtao há 11 meses atrás
pai
commit
699487c329

+ 122 - 88
web/src/main/java/cn/seecoder/web/service/impl/pipeline/DeploymentServiceImpl.java

@@ -1,33 +1,33 @@
 package cn.seecoder.web.service.impl.pipeline;
 package cn.seecoder.web.service.impl.pipeline;
 
 
+import cn.seecoder.api.ApplicationProperties;
 import cn.seecoder.api.k8s.K8sConstants;
 import cn.seecoder.api.k8s.K8sConstants;
+import cn.seecoder.common.exceptions.AccessDeniedException;
+import cn.seecoder.common.exceptions.ServiceException;
 import cn.seecoder.common.util.LogTrackingUtil;
 import cn.seecoder.common.util.LogTrackingUtil;
 import cn.seecoder.common.util.OpType;
 import cn.seecoder.common.util.OpType;
+import cn.seecoder.web.core.pipeline.Pipeline;
+import cn.seecoder.web.core.pipeline.PipelineException;
+import cn.seecoder.web.core.pipeline.PipelineFactory;
+import cn.seecoder.web.core.pipeline.inspector.PipelineInspector;
+import cn.seecoder.web.core.pipeline.inspector.PipelineInspectorFactory;
 import cn.seecoder.web.dao.pipeline.DeploymentMapper;
 import cn.seecoder.web.dao.pipeline.DeploymentMapper;
-import cn.seecoder.web.dao.pipeline.PipelineRecordMapper;
 import cn.seecoder.web.dao.pipeline.PipelineMapper;
 import cn.seecoder.web.dao.pipeline.PipelineMapper;
+import cn.seecoder.web.dao.pipeline.PipelineRecordMapper;
 import cn.seecoder.web.dao.project.ProjectMapper;
 import cn.seecoder.web.dao.project.ProjectMapper;
 import cn.seecoder.web.model.po.pipeline.DeploymentPO;
 import cn.seecoder.web.model.po.pipeline.DeploymentPO;
-import cn.seecoder.web.model.po.pipeline.PipelineRecordPO;
 import cn.seecoder.web.model.po.pipeline.PipelinePO;
 import cn.seecoder.web.model.po.pipeline.PipelinePO;
+import cn.seecoder.web.model.po.pipeline.PipelineRecordPO;
 import cn.seecoder.web.model.po.project.ProjectPO;
 import cn.seecoder.web.model.po.project.ProjectPO;
+import cn.seecoder.web.model.vo.pipeline.DeploymentInfoVO;
+import cn.seecoder.web.service.pipeline.DeploymentService;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import io.kubernetes.client.openapi.models.V1DeploymentStatus;
 import io.kubernetes.client.openapi.models.V1DeploymentStatus;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpStatus;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
-import cn.seecoder.api.ApplicationProperties;
-import cn.seecoder.common.exceptions.AccessDeniedException;
-import cn.seecoder.common.exceptions.ServiceException;
-import cn.seecoder.web.core.pipeline.Pipeline;
-import cn.seecoder.web.core.pipeline.PipelineException;
-import cn.seecoder.web.core.pipeline.PipelineFactory;
-import cn.seecoder.web.core.pipeline.inspector.PipelineInspector;
-import cn.seecoder.web.core.pipeline.inspector.PipelineInspectorFactory;
-import cn.seecoder.web.model.vo.pipeline.DeploymentInfoVO;
-import cn.seecoder.web.service.pipeline.DeploymentService;
 
 
 import java.sql.Timestamp;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -38,74 +38,77 @@ import static cn.seecoder.web.core.pipeline.template.PipelineTemplateTable.MYSQL
 import static cn.seecoder.web.core.pipeline.template.PipelineTemplateTable.SONAR_JAVA8;
 import static cn.seecoder.web.core.pipeline.template.PipelineTemplateTable.SONAR_JAVA8;
 
 
 /**
 /**
- * @author PuHong Weng
- * @date 2021/3/12
- * @description:
+ * DeploymentServiceImpl
+ * 流水线部署服务实现类
  */
  */
 @Service
 @Service
 @Slf4j
 @Slf4j
+@RequiredArgsConstructor
 public class DeploymentServiceImpl implements DeploymentService {
 public class DeploymentServiceImpl implements DeploymentService {
 
 
     private final PipelineMapper pipelineMapper;
     private final PipelineMapper pipelineMapper;
-
     private final PipelineRecordMapper pipelineRecordMapper;
     private final PipelineRecordMapper pipelineRecordMapper;
-
     private final ProjectMapper projectMapper;
     private final ProjectMapper projectMapper;
-
     private final ApplicationProperties properties;
     private final ApplicationProperties properties;
-
     private final DeploymentMapper deploymentMapper;
     private final DeploymentMapper deploymentMapper;
 
 
-
-    @Autowired
-    public DeploymentServiceImpl(PipelineMapper pipelineMapper, PipelineRecordMapper pipelineRecordMapper, ProjectMapper projectMapper, ApplicationProperties properties, DeploymentMapper deploymentMapper) {
-        this.pipelineMapper = pipelineMapper;
-        this.pipelineRecordMapper = pipelineRecordMapper;
-        this.projectMapper = projectMapper;
-        this.properties = properties;
-        this.deploymentMapper = deploymentMapper;
-    }
-
-
+    /**
+     * 获取指定项目的部署信息列表
+     */
     @Override
     @Override
     public List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId) throws AccessDeniedException {
     public List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId) throws AccessDeniedException {
-        //projectAuthentication(projectId);
+        // 获取项目对应的流水线列表
         List<PipelinePO> pipelines = pipelineMapper.selectByProjectId(projectId);
         List<PipelinePO> pipelines = pipelineMapper.selectByProjectId(projectId);
-        if (pipelines.size() == 0) {
+        if (pipelines.isEmpty()) {
             return new ArrayList<>();
             return new ArrayList<>();
         }
         }
-        List<Integer> pipelineIds = pipelines.stream().map(PipelinePO::getId).collect(Collectors.toList());
+
+        List<Integer> pipelineIds = pipelines.stream()
+                .map(PipelinePO::getId)
+                .collect(Collectors.toList());
+
         List<DeploymentPO> deployments = deploymentMapper.selectByPipelineIds(pipelineIds);
         List<DeploymentPO> deployments = deploymentMapper.selectByPipelineIds(pipelineIds);
-        return deployments.stream().map(x -> {
-            PipelineInspector inspector = PipelineInspectorFactory.init(x.getNamespace(), x.getDeployName());
-            //获取状态
-            String status = null;
+
+        // 构建部署信息列表
+        return deployments.stream().map(deployment -> {
+            PipelineInspector inspector = PipelineInspectorFactory.init(
+                    deployment.getNamespace(),
+                    deployment.getDeployName()
+            );
+
+            // 获取部署状态
+            String status;
             V1DeploymentStatus deploymentStatus = inspector.inspectStatus();
             V1DeploymentStatus deploymentStatus = inspector.inspectStatus();
             if (deploymentStatus == null) {
             if (deploymentStatus == null) {
                 status = "部署不存在,请重新部署";
                 status = "部署不存在,请重新部署";
-            } else if (deploymentStatus.getAvailableReplicas() != null && deploymentStatus.getAvailableReplicas() >= 1) {
+            } else if (deploymentStatus.getAvailableReplicas() != null
+                    && deploymentStatus.getAvailableReplicas() >= 1) {
                 status = "正常运行";
                 status = "正常运行";
             } else {
             } else {
                 status = "不可用";
                 status = "不可用";
             }
             }
+
             return DeploymentInfoVO.builder()
             return DeploymentInfoVO.builder()
-                    .id(x.getId())
-                    .pipelineId(x.getPipelineId())
-                    .name(x.getDeployName() + "." + x.getNamespace())
-                    .deployedTime(x.getDeployedTime())
-                    .accessUrl(x.getAccessUrl())
+                    .id(deployment.getId())
+                    .pipelineId(deployment.getPipelineId())
+                    .name(deployment.getDeployName() + "." + deployment.getNamespace())
+                    .deployedTime(deployment.getDeployedTime())
+                    .accessUrl(deployment.getAccessUrl())
                     .status(status)
                     .status(status)
                     .build();
                     .build();
         }).collect(Collectors.toList());
         }).collect(Collectors.toList());
     }
     }
 
 
+    /**
+     * 部署指定项目流水线
+     */
     @Override
     @Override
     @Async
     @Async
     public void deploy(Integer projectId, Integer pipelineId, Integer userId) throws ServiceException {
     public void deploy(Integer projectId, Integer pipelineId, Integer userId) throws ServiceException {
-        //projectAuthentication(projectId);
         PipelinePO pipelinePO = pipelineMapper.selectById(pipelineId);
         PipelinePO pipelinePO = pipelineMapper.selectById(pipelineId);
         ProjectPO projectPO = projectMapper.getProjectById(projectId);
         ProjectPO projectPO = projectMapper.getProjectById(projectId);
-        //历史记录
+
+        // 创建部署历史记录
         PipelineRecordPO record = PipelineRecordPO.builder()
         PipelineRecordPO record = PipelineRecordPO.builder()
                 .result(PipelineRecordPO.DEPLOYING)
                 .result(PipelineRecordPO.DEPLOYING)
                 .pipelineId(pipelinePO.getId())
                 .pipelineId(pipelinePO.getId())
@@ -114,32 +117,28 @@ public class DeploymentServiceImpl implements DeploymentService {
                 .startTime(new Timestamp(System.currentTimeMillis()))
                 .startTime(new Timestamp(System.currentTimeMillis()))
                 .build();
                 .build();
         pipelineRecordMapper.insert(record);
         pipelineRecordMapper.insert(record);
-        log.info("流水线触发部署,对应id为:{}",record.getPipelineId());
-
-        // 有一些流水线是不产生部署产物的
-        boolean hasDeployment = true;
-        switch (pipelinePO.getTemplateName()) {
-            case SONAR_JAVA8:
-                hasDeployment = false;
-            default:
-        }
+        log.info("流水线触发部署,对应 Pipeline ID:{}", record.getPipelineId());
+
+        // 判断流水线是否产生部署产物
+        boolean hasDeployment = !SONAR_JAVA8.equals(pipelinePO.getTemplateName());
 
 
-        // 部署产物记录
+        // 处理部署产物记录
         if (hasDeployment) {
         if (hasDeployment) {
             DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
             DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
             if (deployment == null) {
             if (deployment == null) {
-                //第一次部署
+                // 第一次部署,生成访问 URL
                 String accessUrl;
                 String accessUrl;
-                //根据模板类型设置起的访问路径
-                switch (pipelinePO.getTemplateName()) {
-                    case MYSQL:
-                        //集群无法暴露tcp端口,只提供了集群内部访问的url
-                        accessUrl = pipelinePO.getName() + K8sConstants.SERVICE_SUFFIX + "." + projectPO.getUniqueK8sNamespace() + ".svc.cluster.local";
-                        break;
-                    default:
-                        accessUrl = pipelinePO.getName() + "-" + projectPO.getUniqueK8sNamespace() + properties.getK8s().getIngressHostSuffix();
-                        break;
+                if (MYSQL.equals(pipelinePO.getTemplateName())) {
+                    // MySQL 内部访问 URL
+                    accessUrl = pipelinePO.getName() + K8sConstants.SERVICE_SUFFIX + "."
+                            + projectPO.getUniqueK8sNamespace() + ".svc.cluster.local";
+                } else {
+                    // 其他模板通过 Ingress 暴露 URL
+                    accessUrl = pipelinePO.getName() + "-" + projectPO.getUniqueK8sNamespace()
+                            + properties.getK8s().getIngressHostSuffix();
                 }
                 }
+
+                // 插入部署记录
                 deploymentMapper.insert(DeploymentPO.builder()
                 deploymentMapper.insert(DeploymentPO.builder()
                         .namespace(projectPO.getUniqueK8sNamespace())
                         .namespace(projectPO.getUniqueK8sNamespace())
                         .deployName(pipelinePO.getName())
                         .deployName(pipelinePO.getName())
@@ -148,66 +147,101 @@ public class DeploymentServiceImpl implements DeploymentService {
                         .deployedTime(record.getStartTime())
                         .deployedTime(record.getStartTime())
                         .build());
                         .build());
             } else {
             } else {
+                // 更新已有部署记录的时间
                 deployment.setDeployedTime(record.getStartTime());
                 deployment.setDeployedTime(record.getStartTime());
                 deploymentMapper.update(deployment);
                 deploymentMapper.update(deployment);
             }
             }
         }
         }
 
 
+        // 执行流水线
         Pipeline pipeline = null;
         Pipeline pipeline = null;
         try {
         try {
-            pipeline = PipelineFactory.init(pipelinePO.getId(), pipelinePO.getConfigJson(), projectPO.getUniqueK8sNamespace(), pipelinePO.getName());
+            pipeline = PipelineFactory.init(
+                    pipelinePO.getId(),
+                    pipelinePO.getConfigJson(),
+                    projectPO.getUniqueK8sNamespace(),
+                    pipelinePO.getName()
+            );
+
             pipeline.addConfig("pipelineRecordId", record.getId().toString());
             pipeline.addConfig("pipelineRecordId", record.getId().toString());
             pipeline.start();
             pipeline.start();
+
+            // 部署成功,更新记录
             record.setResult(PipelineRecordPO.DEPLOY_SUCCESS);
             record.setResult(PipelineRecordPO.DEPLOY_SUCCESS);
             record.setDetails(pipeline.getContext().getResult());
             record.setDetails(pipeline.getContext().getResult());
+
         } catch (PipelineException e) {
         } catch (PipelineException e) {
             record.setResult(PipelineRecordPO.DEPLOY_FAIL);
             record.setResult(PipelineRecordPO.DEPLOY_FAIL);
             record.setDetails(pipeline.getContext().getResult());
             record.setDetails(pipeline.getContext().getResult());
-            log.error("流水线配置转换发生错误");
+            log.error("流水线配置转换发生错误", e);
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "应用部署失败", e);
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "应用部署失败", e);
+
         } catch (RuntimeException e) {
         } catch (RuntimeException e) {
             pipeline.getContext().appendErrorResult("运行时错误: ", e);
             pipeline.getContext().appendErrorResult("运行时错误: ", e);
             record.setResult(PipelineRecordPO.DEPLOY_FAIL);
             record.setResult(PipelineRecordPO.DEPLOY_FAIL);
             record.setDetails(pipeline.getContext().getResult());
             record.setDetails(pipeline.getContext().getResult());
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "应用部署失败", e);
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "应用部署失败", e);
+
         } finally {
         } finally {
             pipelineRecordMapper.update(record);
             pipelineRecordMapper.update(record);
         }
         }
-        //ANA 日志需要打出部署流水线的信息
-        List<Integer> pipelineIds = new ArrayList<>();
-        pipelineIds.add(pipelineId);
-        PipelineRecordPO pipelineRecordPO = pipelineRecordMapper.selectPipelinesLatestRecord(pipelineIds);
+
+        // ANA 日志记录部署信息
         try {
         try {
-            JSONObject object = new JSONObject();
-            object.put("user_id", userId);
-            object.put("project_id", projectId);
-            object.put("record_id", pipelineRecordPO.getId());
-            object.put("pipeline_id", pipelineId);
-            object.put("type", record.getResult());
-            object.put("result", record.getResult());
-            object.put("success", record.getResult().equals(PipelineRecordPO.DEPLOY_SUCCESS));
-            //success?
-            String data = JSONObject.toJSONString(object);
-            LogTrackingUtil.log(data, OpType.DEPLOY_PIPELINE);
-        } catch (Exception e) {
+            List<Integer> pipelineIds = new ArrayList<>();
+            pipelineIds.add(pipelineId);
+            PipelineRecordPO latestRecord = pipelineRecordMapper.selectPipelinesLatestRecord(pipelineIds);
+
+            JSONObject logObject = new JSONObject();
+            logObject.put("user_id", userId);
+            logObject.put("project_id", projectId);
+            logObject.put("record_id", latestRecord.getId());
+            logObject.put("pipeline_id", pipelineId);
+            logObject.put("type", record.getResult());
+            logObject.put("result", record.getResult());
+            logObject.put("success", PipelineRecordPO.DEPLOY_SUCCESS.equals(record.getResult()));
+
+            LogTrackingUtil.log(JSONObject.toJSONString(logObject), OpType.DEPLOY_PIPELINE);
+        } catch (Exception ignored) {
+            // ANA 日志异常不影响部署
         }
         }
     }
     }
 
 
+    /**
+     * 删除指定项目流水线部署
+     */
     @Override
     @Override
     @Async
     @Async
     public void delete(Integer projectId, Integer pipelineId) throws AccessDeniedException {
     public void delete(Integer projectId, Integer pipelineId) throws AccessDeniedException {
-        //projectAuthentication(projectId);
         DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
         DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
+
+        if (deployment == null) {
+            return;
+        }
+
         deploymentMapper.delete(pipelineId);
         deploymentMapper.delete(pipelineId);
-        PipelineInspector inspector = PipelineInspectorFactory.init(deployment.getNamespace(), deployment.getDeployName());
+        PipelineInspector inspector = PipelineInspectorFactory.init(
+                deployment.getNamespace(),
+                deployment.getDeployName()
+        );
         inspector.delete();
         inspector.delete();
-
     }
     }
 
 
+    /**
+     * 获取指定流水线部署日志
+     */
     @Override
     @Override
     public String log(Integer projectId, Integer pipelineId) {
     public String log(Integer projectId, Integer pipelineId) {
         DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
         DeploymentPO deployment = deploymentMapper.selectByPipelineId(pipelineId);
-        PipelineInspector inspector = PipelineInspectorFactory.init(deployment.getNamespace(), deployment.getDeployName());
+
+        if (deployment == null) {
+            return "";
+        }
+
+        PipelineInspector inspector = PipelineInspectorFactory.init(
+                deployment.getNamespace(),
+                deployment.getDeployName()
+        );
         return inspector.log();
         return inspector.log();
     }
     }
 }
 }